Hooks

Popups

48 hooks fired by Popups: 41 filters and 7 actions across 51 call sites.

48 hooks fired by Popups: 41 filters and 7 actions across 51 call sites. 47 of the 51 call sites are described by a docblock, at the call or on the constant that names the hook; the rest are listed with their signature and call sites only. Paths are relative to the plugin directory.

the_content

Filter · 1 argument · 2 call sites

WordPress core's content filter, applied to a popup's block content.

Popups renders its content once per request and caches the result, so this is where shortcodes, embeds and every other the_content listener get their turn — a plugin that only hooks the_content still works inside a popup because of this call.

By this point the global post has been swapped to the popup, so a listener that reads get_the_ID() sees the popup rather than the page the visitor is on. xpac_popups_render_in_popup_context is what decides that; return false from it and the same filter runs against the visitor's own post instead.

apply_filters( 'the_content', $raw )
  • $content (string) — The popup's raw block content.

Fired from:

  • packages/Popups/src/Front.php:396
  • packages/Popups/src/Front.php:424

the_title

Filter · 2 arguments · 1 call site

WordPress core's title filter, applied to a popup's title.

The title is the popup's aria-label, so this reaches assistive technology rather than anything drawn on screen. A listener that returns markup produces an unreadable label, since the value is used as an attribute and not as HTML.

apply_filters( 'the_title', $rows[$post_id]['title'] ?? '', $post_id )
  • $title (string) — The popup's saved title. Empty string if unknown.
  • $post_id (int) — Popup post ID.

Fired from:

  • packages/Popups/src/Front.php:1234

xpac-popup-display-rule-additional-components

Filter · 3 arguments · 1 call site

Filters extra components appended inside a display rule's modal.

The third argument writes back to the rule, so a component added here edits the same object the built-in panels do.

applyFilters( 'xpac-popup-display-rule-additional-components', [], options, onUpdate )
  • components (Array) — Components to render. Default empty.
  • options (Object) — The rule being edited.
  • onUpdate (Function) — Writes a change back to the rule.

Fired from:

  • assets/packages/popups/settings/sidebars/Settings/Panels/DisplayRules/Modal.js:241

xpac-popups-animation

Filter · 3 arguments · 1 call site

Filters the animation a popup opens with.

The value becomes an is-xpac-anim-{name} class, so a name the stylesheet does not define animates not at all rather than breaking. Every built-in animation collapses to a plain opacity fade under prefers-reduced-motion.

The result is reduced to [a-z0-9-] before it becomes a class, because classList.add throws InvalidCharacterError on a token containing a space — and a throw here happens before the popup is shown, so a stray space would stop the popup opening at all rather than animating oddly.

applyFilters( 'xpac-popups-animation', rule.animation || 'fade', rule, template )
  • animation (string) — The animation name.
  • rule (Object) — The rule opening the popup.
  • template (Element) — The popup's template element.

Fired from:

  • assets/packages/popups/front/utils.js:760

xpac-popups-conversion-selector

Filter · 1 argument · 1 call site

What a click has to land on to be a conversion.

Widen it for a CTA the shipped selector cannot see, narrow it for a popup full of anchors that are not calls to action. The whole selector is replaced by whatever comes back, so it can be narrowed as well as widened.

applyFilters( 'xpac-popups-conversion-selector', ACTION_SELECTOR )
  • selector (string) — A CSS selector list.

Fired from:

  • assets/packages/popups/front/stats.js:383

xpac-popups-display-rule-default-config

Filter · 1 argument · 1 call site

Filters the configuration a newly added display rule starts with.

Applied once when the editor module loads, not per rule, so the object is shared by every rule added in that session and must not be mutated in place.

applyFilters( 'xpac-popups-display-rule-default-config', { status: true, closeButton: true, closeEsc: true, closeOutside: true, type: 'lightbox', lightboxPosition: 'center', floatingPosition: 'top', inlinePosition: window.xpacPopups?.inlineLocations?.[0]?.value ?? '', inlineSticky: false, schedule: { start: '', end: '', }, page: { relation: 'or', dependencies: [], }, display: { relation: 'or', dependencies: [], }, hide: { relation: 'or', dependencies: [], }, dismiss: { interval: '', intervalUnit: 'day', trigger: 'open', triggerCount: '', }, } )
  • config (Object) — The default rule configuration.

Fired from:

  • assets/packages/popups/settings/sidebars/Settings/Panels/DisplayRules/utils.js:18

xpac-popups-display-rule-render-trigger-rules

Filter · 2 arguments · 1 call site

Filters whether a rule's trigger controls are shown at all.

False hides them for that rule, which suits a type that opens on something other than a visitor action. It hides the controls only — a trigger already stored on the rule is still there and still fires.

applyFilters( 'xpac-popups-display-rule-render-trigger-rules', 'inline' !== options.type, options )
  • render (boolean) — Whether to render the trigger controls.
  • options (Object) — The rule being edited.

Fired from:

  • assets/packages/popups/settings/sidebars/Settings/Panels/DisplayRules/Modal.js:78

xpac-popups-is-conversion

Filter · 3 arguments · 1 call site

Whether this click counts as a conversion.

The verdict itself, where the selector filter above can only say what an action looks like. For the popup whose CTA is a <div> with a click handler and no role, which no selector describes without matching every div on the page — and for the "maybe later" link that matches every selector there is and must not count.

applyFilters( 'xpac-popups-is-conversion', !!matches && popup.contains(matches), event.target, popup )
  • isConversion (boolean) — What the selector decided.
  • target (Element) — The element that was clicked.
  • popup (Element) — The popup it is inside.

Fired from:

  • assets/packages/popups/front/stats.js:419

xpac-popups-is-modal

Filter · 3 arguments · 1 call site

Filters whether this popup behaves as a modal dialog.

True gives it role="dialog", aria-modal, a focus trap, focus moved in and out, and an inert background. False gives it role="region" and an accessible name and nothing else. Only lightbox is a modal by default — trapping the keyboard inside a cookie bar is the failure this prevents.

applyFilters( 'xpac-popups-is-modal', 'lightbox' === rule.type, rule, template )
  • isModal (boolean) — Whether the popup is modal.
  • rule (Object) — The rule opening the popup.
  • template (Element) — The popup's template element.

Fired from:

  • assets/packages/popups/front/utils.js:636

xpac-popups-popup-panels

Filter · 1 argument · 1 call site

Filters the panels in the popup editor's Settings sidebar.

Each entry carries a title, a priority and a component; the list is sorted by priority afterwards, so an add-on places its panel by number rather than by array position.

applyFilters( 'xpac-popups-popup-panels', initialPanels )
  • panels (Array) — The panels to render.

Fired from:

  • assets/packages/popups/settings/hooks/usePopupPanels.js:27

xpac-popups-triggers

Filter · 1 argument · 1 call site

applyFilters( 'xpac-popups-triggers', defaultHandlers )

Fired from:

  • assets/packages/popups/front/index.js:249

xpac-popups-type-labels

Filter · 1 argument · 1 call site

How a rule type reads on screen.

The editor lets other packages add types through the xpac-popups-types filter, which is a JS filter the server cannot see — so an unrecognised type is shown as itself rather than dropped, and every screen stays truthful on a site running an add-on this build knows nothing about. Callers do that by falling back to the raw key. The listing runs its own bundle, without the editor's filters, so TYPE_LABELS_FILTER_NAME is how an add-on names its own type on this screen too.

A module of its own rather than inline in the columns: two copies of a name drift in exactly the way a reader notices.

applyFilters( 'xpac-popups-type-labels', { lightbox: __('Lightbox', '{XPAC}'), floating: __('Floating Bar', '{XPAC}'), inline: __('Inline', '{XPAC}'), } )

Fired from:

  • assets/packages/popups/admin/labels.js:31

xpac-popups-types

Filter · 1 argument · 1 call site

Filters the popup types the editor offers.

The chosen value is stored verbatim on the rule and read by the front end, which renders lightbox, floating and inline itself and leaves anything else to whoever added it.

applyFilters( 'xpac-popups-types', typesRulesConfig )
  • types (Array) — The type rule configuration.

Fired from:

  • assets/packages/popups/settings/sidebars/Settings/Panels/DisplayRules/utils.js:58

xpac_agent_changed

Action · 4 arguments · 1 call site

Fires when a tool call changed something XPAC Agent cannot record by itself.

Popups fires it after set-rule or remove-rule saved a popup's rules, which live in the one option every popup shares. Agent keeps it only while one of its tool calls is running, and asks Popups to put the rules back through xpac_agent_undo. Outside a call, or while Agent is not active, nothing hears it.

do_action( 'xpac_agent_changed', self::HANDLER, self::HANDLER . ':' . $popup->ID, ['popup_id' => (int) $popup->ID, 'rules' => ['items' => array_values($items)]], sprintf( __('Display rules of "%s"', '{XPAC}'), $popup->post_title ) )
  • $handler (string) — Who puts it back: xpac-popups/rules.
  • $object (string) — What changed: xpac-popups/rules:<popup id>.
  • $before (array<string, mixed>) — {popup_id, rules: {items}}, the popup's rules before the write.
  • $label (string) — The change, named for a person.

Fired from:

  • packages/Popups/src/Abilities/Undo.php:64

xpac_agent_tool_enabled

Filter · 2 arguments · 2 call sites

Filters whether one XPAC tool may register as an ability.

XPAC Agent answers from its switches under XPAC → AI Agent → Tools, bound at priority 1. While the XPAC Agent plugin is not active nothing answers, and the default leaves every Popups ability unregistered.

apply_filters( 'xpac_agent_tool_enabled', false, self::NAMESPACE . '/' . $name )
apply_filters( 'xpac_agent_tool_enabled', false, 'xpac-wp/create-content' )
  • $enabled (bool) — Default false.
  • $name (string) — The full ability name, such as xpac-popups/create-popup.

Fired from:

  • packages/Popups/src/Abilities/Abilities.php:133
  • packages/Popups/src/Abilities/Abilities.php:278

xpac_inline_popup_attributes

Filter · 3 arguments · 1 call site

Filters the HTML attributes of an inline popup's outer element.

Return an associative array of attribute name to scalar value. class is merged with the required classes; role, aria-label, data-popup-id, data-rule-id and data-close-esc are owned by Popups and written after the filter so the accessible and statistics identities cannot be replaced.

apply_filters( 'xpac_inline_popup_attributes', [], $popup, $rule )
  • $attributes (array) — Attributes collected so far. Default empty.
  • $popup (array) — The resolved popup configuration.
  • $rule (array) — The inline rule being rendered.

Fired from:

  • packages/Popups/src/Inline.php:200

xpac_inline_popups_available_locations

Filter · 1 argument · 1 call site

Filters the positions an inline popup rule can be placed at.

Each row needs a non-empty value naming a front-end action and a label shown in the editor. This list is also the only set of actions an inline rule may print on: a rule naming anything else is not rendered. Existing rules keep their stored value when a location is removed from this list, and render again once it is offered again.

apply_filters( 'xpac_inline_popups_available_locations', [ [ 'value' => 'wp_body_open', 'label' => __('Before Header', '{XPAC}'), ], [ 'value' => 'wp_footer', 'label' => __('After Footer', '{XPAC}'), ], ] )
  • $locations (array) — Position rows. Defaults to wp_body_open and wp_footer.

Fired from:

  • packages/Popups/src/Inline.php:39

xpac_popup_render

Filter · 2 arguments · 1 call site

Filters whether one popup prints on this request.

False suppresses the markup. For a popup on a custom render hook it also skips the content render; for one on wp_body_open or wp_footer the content was already prepared, because that is what lets its styles reach <head> in time.

apply_filters( 'xpac_popup_render', true, self::$allPopups[$post_id] )
  • $render (bool) — Whether to print the popup.
  • $popup (array) — The popup's configuration.

Fired from:

  • packages/Popups/src/Front.php:644

xpac_popups_abilities

Filter · 1 argument · 1 call site

Filters which Popups abilities are registered for AI agents.

Asked whenever Popups reads which of its tools are on: when the Abilities API registers abilities and when Agent builds its instructions. Names are the part after xpac-popups/, such as create-popup. One left out is not registered at all, so no REST route, MCP server or WordPress AI feature can call it. The default is what XPAC Agent's switches allow, which is none while Agent is switched off or not installed. One added here is registered for the Abilities API and WordPress's AI features, but Agent's chat and MCP server still offer only what its switches allow.

apply_filters( 'xpac_popups_abilities', $allowed )
  • $abilities (string[]) — Ability names. Default the ones XPAC Agent's switches allow.

Fired from:

  • packages/Popups/src/Abilities/Abilities.php:153

xpac_popups_available_locations

Filter · 1 argument · 1 call site

Filters where in the page a popup may be anchored.

The values are offered in the popup editor and stored verbatim on the rule, so removing one that popups already use orphans those rules rather than migrating them.

apply_filters( 'xpac_popups_available_locations', [ [ 'value' => 'standard', 'label' => __('Standard', '{XPAC}') ], [ 'value' => 'topBar', 'label' => __('Top Bar', '{XPAC}') ], [ 'value' => 'bottomBar', 'label' => __('Bottom Bar', '{XPAC}') ] ] )
  • $locations (array) — List of value / label pairs.

Fired from:

  • packages/Popups/src/Utils.php:22

xpac_popups_block_usage_cache_ttl

Filter · 1 argument · 1 call site

Filters how long, in seconds, the popup-block usage scan is held.

The scan is a LIKE '%…%' over every published post's content, which no index can serve, so it reads the posts table end to end. A day is long because the answer only changes when a post changes, and any write that can change it drops the cache — the expiry is a backstop for a write that reached the database without wp_after_insert_post, such as an import or a direct SQL edit, not the thing keeping the answer fresh.

Return 0 or less to bypass the transient entirely, which is worth it only on a site whose posts change outside WordPress often enough for the backstop to be the thing being waited on. The per-request memo is not affected: the scan still runs at most once per request.

apply_filters( 'xpac_popups_block_usage_cache_ttl', DAY_IN_SECONDS )
  • $ttl (int) — Seconds to hold the scan. Default DAY_IN_SECONDS.

Fired from:

  • packages/Popups/src/Admin/Rest.php:1270

xpac_popups_count_visitor

Filter · 2 arguments · 1 call site

Filters whether this request's visitor is counted.

False withholds the beacon's configuration, so the front-end module finds nothing, collects nothing and sends nothing — the request is never made rather than made and thrown away. True prints it for a visitor the package would have left out, which is the only way to count an editor's own page views.

The default is that counting is on for the site and the visitor cannot edit_posts. Narrow it with && rather than returning a bare true, or the site's own "count visits" setting stops meaning anything — $enabled is passed so a callback that only wants to add people can still honour that switch.

apply_filters( 'xpac_popups_count_visitor', $count, $enabled )
  • $count (bool) — Whether to count this visitor.
  • $enabled (bool) — Whether the site has counting switched on.

Fired from:

  • packages/Popups/src/Front.php:1288

xpac_popups_cpt_script_dependencies

Filter · 1 argument · 1 call site

Filters the scripts the popup editor screen waits for.

Applies on the post editor for this post type only — the callback has already returned null for any other screen by the time this runs.

apply_filters( 'xpac_popups_cpt_script_dependencies', [] )
  • $deps (string[]) — Handles to depend on. Default empty.

Fired from:

  • packages/Popups/src/PostType.php:236

xpac_popups_cpt_style_dependencies

Filter · 1 argument · 1 call site

Filters the stylesheets the popup editor screen waits for.

Applies on the post editor for this post type only — the callback has already returned null for any other screen by the time this runs.

apply_filters( 'xpac_popups_cpt_style_dependencies', [] )
  • $deps (string[]) — Handles to depend on. Default empty.

Fired from:

  • packages/Popups/src/PostType.php:192

xpac_popups_front_script_dependencies

Filter · 1 argument · 1 call site

Filters the scripts the popup front end waits for.

Names are added to the handle's registered dependencies, so an add-on whose own scripts must load first declares itself here rather than re-registering the handle.

apply_filters( 'xpac_popups_front_script_dependencies', [] )
  • $deps (string[]) — Handles to depend on. Default empty.

Fired from:

  • packages/Popups/src/Front.php:910

xpac_popups_front_style_dependencies

Filter · 1 argument · 1 call site

Filters the stylesheets the popup front end waits for.

Names are added to the handle's registered dependencies, so an add-on whose own stylesheets must load first declares itself here rather than re-registering the handle.

apply_filters( 'xpac_popups_front_style_dependencies', [] )
  • $deps (string[]) — Handles to depend on. Default empty.

Fired from:

  • packages/Popups/src/Front.php:940

xpac_popups_imported

Action · 2 arguments · 1 call site

Fires once an imported popup exists, with its rules already stored.

do_action( 'xpac_popups_imported', $id, $entry )
  • $id (int) — New popup post ID.
  • $entry (array) — The entry it was built from.

Fired from:

  • packages/Popups/src/Admin/Portability.php:448

xpac_popups_init

Action · 0 arguments · 1 call site

Fires when Popups is ready to be extended.

Runs on init at priority 200, the same place Forms fires xpac_forms_init, so the two packages are learned once.

The package's only reader of xpac_popups_post_meta_default_values and xpac_popups_post_meta_schema is Settings::registerPostMeta(), which reads both once on init at 201, after this action, so an add-on adding to either from here is in time. Everything else the package puts on init lands at 5 or 10 and reads nothing an add-on could change from here.

UserTargeting, which hooks here, registers asset definitions and filters whose earliest consumer is wp, wp_enqueue_scripts or an admin_print_* action, all of which are later than any init priority.

do_action( 'xpac_popups_init' )

Fired from:

  • packages/Popups/Bootstrap.php:237

xpac_popups_popup_configuration

Filter · 2 arguments · 1 call site

Filters one popup's stored configuration before the page uses it.

Runs after the option row and the post meta have been merged and before the id, content and isAttachedToBlock keys are written over the top, so those four cannot be changed here.

apply_filters( 'xpac_popups_popup_configuration', array_merge($popup, $metadata), $post_id )
  • $config (array) — The popup's merged configuration.
  • $post_id (int) — Popup post ID.

Fired from:

  • packages/Popups/src/Front.php:229

xpac_popups_popup_settings_schema

Filter · 1 argument · 1 call site

Filters the schema one popup's display-rule row is validated against.

Unlike the post-meta schema filter, this one receives the package's own properties rather than being merged with them, so a callback that does not preserve what it was given removes rule validation for every popup on the site.

apply_filters( 'xpac_popups_popup_settings_schema', self::getSettingsMuSchema() )
  • $properties (array) — The rule schema properties.

Fired from:

  • packages/Popups/src/Settings.php:604

xpac_popups_post_meta_default_values

Filter · 1 argument · 1 call site

Filters the values a popup's settings meta starts life with.

The package's own defaults are merged over the top, so this adds defaults for keys an add-on introduced rather than changing the ones that ship.

apply_filters( 'xpac_popups_post_meta_default_values', [] )
  • $defaults (array) — Additional default values. Default empty.

Fired from:

  • packages/Popups/src/Settings.php:154

xpac_popups_post_meta_schema

Filter · 1 argument · 1 call site

Filters the schema properties a popup's settings meta accepts.

The package's own properties are merged over the top. Anything not described here is still stored, because the schema is registered with additionalProperties, but it is not validated on the way in.

apply_filters( 'xpac_popups_post_meta_schema', [] )
  • $properties (array) — Additional schema properties. Default empty.

Fired from:

  • packages/Popups/src/Settings.php:165

xpac_popups_remove_data_on_uninstall

Filter · 1 argument · 1 call site

Filters whether uninstalling Popups deletes the data it owns.

False by default. The popups themselves are posts and survive an uninstall, and xpac_popups holds every one of their display rules, so deleting it would leave a reinstalled site with its popups listed in the admin, each with no rules and appearing nowhere.

A site that wants the rows gone opts in; a site that clicked Delete on a plugin it is about to reinstall keeps everything. Add the filter from an mu-plugin — the plugin being uninstalled is already deactivated by the time this runs, so nothing inside it can.

apply_filters( 'xpac_popups_remove_data_on_uninstall', false )
  • $remove (bool) — Whether to drop the stats table and delete the options.

Fired from:

  • packages/Popups/Bootstrap.php:167

xpac_popups_render_hooks

Filter · 4 arguments · 1 call site

Filters the extra actions popups are rendered on.

Each entry needs an action and a popup_id that names a popup this page resolved; anything else is dropped. types is the subset of 'lightbox' / 'floating' the default markup prints, and defaults to whatever this page resolved for that popup — which is nothing for a popup whose rules all failed, so a valid entry may still print nothing. priority is the action priority, 10 when it is omitted. renderer replaces the default markup, and the fourth argument is a callable that answers whether a page condition matches, so an add-on scopes its own hooks the same way the package does. Nothing checks that the action is ever fired on the page in question.

apply_filters( 'xpac_popups_render_hooks', [], self::$allPopups, $options, static function (string $relation, array $rules) { return Conditions::match($relation, $rules); } )
  • $hooks (array) — Hook definitions to add. Default empty.
  • $allPopups (array) — Every popup this page resolved, keyed by ID.
  • $options (array) — The raw rules configuration.
  • $matches (callable) — fn(string $relation, array $rules): bool.

Fired from:

  • packages/Popups/src/Front.php:289

xpac_popups_render_in_popup_context

Filter · 2 arguments · 1 call site

Filters whether a popup's blocks resolve against the popup post.

False renders the content against the post the visitor is on.

apply_filters( 'xpac_popups_render_in_popup_context', true, $post_id )
  • $swap (bool) — Whether to swap the global post.
  • $post_id (int) — Popup post ID.

Fired from:

  • packages/Popups/src/Front.php:393

xpac_popups_rendered_types

Filter · 1 argument · 1 call site

Filters the popup types the admin screens treat as renderable.

A type left out of this list is reported as one the site cannot render: its rules never count as active, the listing shows the popup with no type, and the overview names it among the popups that never appear. An add-on that renders a type of its own through xpac_popups_render_hooks adds that type here.

apply_filters( 'xpac_popups_rendered_types', self::TYPES )
  • $types (string[]) — Type names. Defaults to the three built-in types.

Fired from:

  • packages/Popups/src/RuleSummary.php:396

xpac_popups_rule_schedule

Filter · 2 arguments · 1 call site

Filters the window a rule runs in.

Return an empty array to run the rule regardless of what the editor stored. start and end are strings a DateTimeImmutable can read, in the site's timezone; a date with no time reads as the start of that day for start and the end of it for end.

apply_filters( 'xpac_popups_rule_schedule', $rule['schedule'] ?? [], $rule )
  • $schedule (array) — The stored window.
  • $rule (array) — The rule it belongs to.

Fired from:

  • packages/Popups/src/Schedule.php:43

xpac_popups_settings_updated

Action · 2 arguments · 1 call site

Fires after the site-wide popup settings are saved.

Every one of these is read server-side, per request, and printed into the page, so a site fronted by a full-page cache keeps serving the answer it cached until that cache is cleared — pausing every popup included. Nothing here knows about any particular caching plugin; this is where a site hooks its own purge.

do_action( 'xpac_popups_settings_updated', $stored, $previous )
  • $stored (array<string, mixed>) — The settings as stored.
  • $previous (array<string, mixed>) — The settings as they were.

Fired from:

  • packages/Popups/src/Settings/GlobalSettings.php:147

xpac_popups_stats_device

Filter · 3 arguments · 1 call site

The device bucket a batch is counted against.

A server-side override of what the browser said, for a site with a better source than a viewport media query, such as an edge that already classifies devices, or one that wants an in-app browser folded into one of the three.

Whatever this returns is checked against the same enum again: the column is varchar(7), so a longer value would be stored truncated rather than refused. Anything outside the enum gives '', unknown.

apply_filters( 'xpac_popups_stats_device', $device, $reported, $request )
  • $device (string) — The bucket, one of desktop|mobile|tablet, or '' for unknown.
  • $reported (string) — What the browser actually sent, unchecked.
  • $request (WP_REST_Request) — The batch's request.

Fired from:

  • packages/Popups/src/Stats/Rest.php:330

xpac_popups_stats_pruned

Action · 3 arguments · 1 call site

Fires once a prune has run, whether or not it removed anything.

The count this reports is the only record that a prune happened: the event is scheduled daily and nothing else logs it, so a site wanting to know that history is being dropped — or to raise a notice the day a prune suddenly removes ten times its usual number of rows — has no other place to look.

The rows are already gone by the time this runs, which is what the past tense says. A site that wants to archive them has to copy them before the DELETE, and the only seam earlier than this one is xpac_popups_stats_retention_days — it receives the same window and runs immediately above, while every row it describes still exists. Reaching for that is a deliberate abuse of a filter, so it is named here rather than left to be discovered.

Only a prune that actually ran fires this. A site with no stats table and one that keeps everything both return before the DELETE, and neither pruned anything.

do_action( 'xpac_popups_stats_pruned', $deleted, $cutoff, $days )
  • $deleted (int) — Rows removed. Zero when there was nothing old enough.
  • $cutoff (string) — The oldest day kept, Y-m-d in the site's calendar.
  • $days (int) — Days of history the site asked to keep.

Fired from:

  • packages/Popups/src/Stats/Retention.php:236

xpac_popups_stats_rate_limit

Filter · 1 argument · 1 call site

How many batches one address may post inside the window unclamped.

Nothing is refused at any value: past the limit a batch is trimmed to twenty popup/rule pairs, and then stored. Zero or less switches the window off altogether, which is the setting for a site whose edge hides every visitor behind one address and which would rather have every visitor's counts than the bound. Only read where a persistent object cache is in use, because nowhere else is there a window.

apply_filters( 'xpac_popups_stats_rate_limit', self::RATE_LIMIT )
  • $limit (int) — Batches per window before clamping starts. Default 30.

Fired from:

  • packages/Popups/src/Stats/Rest.php:516

xpac_popups_stats_rate_window

Filter · 1 argument · 1 call site

How long one address's window lasts, in seconds.

Widening it applies the limit over a longer stretch — sixty batches an hour rather than thirty a minute — which is the shape a site behind a shared address wants if it wants a bound at all. Zero or less switches the window off, the same as a limit of zero.

apply_filters( 'xpac_popups_stats_rate_window', self::RATE_WINDOW )
  • $window (int) — Seconds. Default MINUTE_IN_SECONDS.

Fired from:

  • packages/Popups/src/Stats/Rest.php:528

xpac_popups_stats_recorded

Action · 2 arguments · 1 call site

Fires once a batch of popup counts has been stored.

Does not fire when no row was written, so a listener that purges a cache or sends a notification acts only on a real change. Failed rows are announced through xpac_popups_stats_write_failed.

do_action( 'xpac_popups_stats_recorded', $recorded, $day )
  • $recorded (array) — Successfully stored rows, keyed "popupId|ruleId|device".
  • $day (string) — The date they were counted against.

Fired from:

  • packages/Popups/src/Stats/Recorder.php:233

xpac_popups_stats_retention_days

Filter · 1 argument · 1 call site

Filters how many days of popup counts are kept.

Zero or less keeps everything.

A site raising this above the default buys the Overview's "Last 12 months" comparison back: an equal-length previous window needs 2 x period - 1 days of history to be complete, so 365 days of retention covers every period the screen offers except that one, and 729 covers them all.

apply_filters( 'xpac_popups_stats_retention_days', self::DEFAULT_DAYS )
  • $days (int) — Days to keep. Default 365.

Fired from:

  • packages/Popups/src/Stats/Retention.php:94

xpac_popups_stats_write_failed

Action · 2 arguments · 2 call sites

Fires when a day row could not be written.

Lets a site log a table that has gone read-only, lost a column or filled its disk, which otherwise looks like a quiet week.

do_action( 'xpac_popups_stats_write_failed', $row, (string) $wpdb->last_error )
do_action( 'xpac_popups_stats_write_failed', ['events' => $events], Database::exists() ? 'The counts table is behind the schema this code writes.' : 'The counts table is missing and could not be created.' )
  • $row (array) — The row as it was attempted, stat_date included.
  • $error (string) — What the database said, or an empty string.

Fired from:

  • packages/Popups/src/Stats/Recorder.php:219
  • packages/Popups/src/Stats/Recorder.php:249

xpac_popups_trigger_types

Filter · 1 argument · 1 call site

Filters the trigger names a rule may be stored with.

A name added here still needs a handler registered through the xpac-popups-triggers JavaScript filter; this only decides what the server will store.

apply_filters( 'xpac_popups_trigger_types', ['exitIntent', 'timeOnPage', 'scrollDistance', 'htmlElement', 'inactivity', 'pageViews', 'form'] )
  • $types (string[]) — Trigger names.

Fired from:

  • packages/Popups/src/Settings.php:915

xpac_popups_trust_proxy

Filter · 1 argument · 1 call site

Whether forwarded-for headers may be believed.

apply_filters( 'xpac_popups_trust_proxy', $trusted )
  • $trusted (bool) — True only when the site's edge is known to overwrite the headers in PROXY_HEADERS.

Fired from:

  • packages/Popups/src/Stats/Rest.php:648

xpac_popups_type_needs_trigger

Filter · 2 arguments · 1 call site

Filters whether a popup type needs a display trigger to ever appear.

A lightbox with nothing to open it never opens, which is why a missing trigger is reported as a fault. A type that is placed rather than opened has no trigger by design and has to say so here, or every rule using it is reported as missing a control it was never offered.

apply_filters( 'xpac_popups_type_needs_trigger', Inline::TYPE !== $type, $type )
  • $needs (bool) — Whether a trigger is required. Default true.
  • $type (string) — Popup type name.

Fired from:

  • packages/Popups/src/RuleSummary.php:419

On this page