Hooks

Support

43 hooks fired by Support: 34 filters and 9 actions across 45 call sites.

43 hooks fired by Support: 34 filters and 9 actions across 45 call sites. 35 of the 45 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.

wp_react_settings_shared_context_initial_values

Filter · 1 argument · 1 call site

Filters the shared context given to controls on the Support settings tab.

This is the same filter the standalone settings page fires. Add-ons put connection state and other shared values here; firing it on both mounts keeps their controls populated whichever settings screen is open.

applyFilters( 'wp_react_settings_shared_context_initial_values', {} )
  • initialValues (Object) — Shared context values. Default empty object.

Fired from:

  • assets/packages/support/admin/screens/Settings.js:197

xpac-forms-after-settings-modal-content

Filter · 3 arguments · 1 call site

Content appended inside a settings panel's item modal.

applyFilters( 'xpac-forms-after-settings-modal-content', [], { value: options, onChange: onUpdate, }, `xpac-${ID}` )

Fired from:

  • assets/packages/support/forms-panel/Components/FormSettings.js:111

'xpac_form_upload_' . self::FILE_BLOCK . '_parent_post_id'

Filter · Dynamic name · 1 argument · 1 call site

Forms' upload-parent filter, re-read here to validate an import.

Support does not own the hook - Forms fires it when it stores an upload, and the variable part is the uploading field's block name. It is read again so an id arriving in the field's value can be checked against the parent Forms would have given it, which is what stops a hand-edited map, or a listener that removed this field from xpac_forms_uploader_blocks and so left a posted value unreplaced, from naming any attachment on the site and having it copied into a ticket.

A listener that changes the parent must answer the same way in both places, or the file it stored will not validate here and the ticket gets no attachment.

apply_filters( 'xpac_form_upload_' . self::FILE_BLOCK . '_parent_post_id', $submission->getFormId() )
  • $parentPostId (int) — Attachment parent. Defaults to the form's ID.

Fired from:

  • packages/Support/Integrations/Forms/Attachments.php:270

xpac_index_reconcile_failed

Action · 3 arguments · 1 call site

A declared index could not be brought to its declared shape.

do_action( 'xpac_index_reconcile_failed', $sql, $error, $what )
  • $sql (string) — The statement that failed, if there was one.
  • $error (string) — What the server said, if anything.
  • $what (string) — The table.index and how the two lists differ.

Fired from:

  • packages/Support/Database/Migrations/M004_IndexShapes.php:243

xpac_realtime_available

Filter · 1 argument · 2 call sites

apply_filters( 'xpac_realtime_available', false )

Fired from:

  • packages/Support/Admin/MenuPage.php:229
  • packages/Support/Core/RealtimeChannels.php:214

xpac_realtime_client_config

Filter · 3 arguments · 1 call site

apply_filters( 'xpac_realtime_client_config', [], $namespace, $params )

Fired from:

  • packages/Support/Core/RealtimeChannels.php:266

xpac_realtime_enqueue

Filter · 1 argument · 1 call site

apply_filters( 'xpac_realtime_enqueue', false )

Fired from:

  • packages/Support/Admin/MenuPage.php:107

xpac_realtime_polling_interval

Filter · 1 argument · 1 call site

apply_filters( 'xpac_realtime_polling_interval', $interval )

Fired from:

  • packages/Support/Core/Settings.php:189

xpac_realtime_publish

Filter · 4 arguments · 1 call site

Announce a change on a channel. False with no Realtime plugin, which is a supported configuration: the browsers poll Support's own route and read the same counters this class just wrote.

apply_filters( 'xpac_realtime_publish', false, $namespace, $params, $payload )

Fired from:

  • packages/Support/Core/Events.php:417

xpac_realtime_transport

Filter · 1 argument · 2 call sites

apply_filters( 'xpac_realtime_transport', 'polling' )

Fired from:

  • packages/Support/Admin/MenuPage.php:230
  • packages/Support/Core/RealtimeChannels.php:219

xpac_support_activation

Action · 0 arguments · 1 call site

Support has just been activated and its schema is in place.

do_action( self::ACTION_ACTIVATION )

Fired from:

  • packages/Support/Bootstrap.php:114

xpac_support_admin_tabs

Filter · 2 arguments · 1 call site

Screens to add to Support's inbox app.

A callback appends descriptors to $tabs. Each is an array:

  • id (required) Unique within the app. Hash route and React key; sanitize_key is applied, and an id already used by one of Support's own tabs is refused in the browser so a built-in screen can never be shadowed.
  • label (required) The sidebar entry's text, already translated.
  • group Sidebar group id. Defaults to the tab's own id, which gives the tab a group to itself rather than letting it vanish. Pass an id Support already ships - inbox, automation, configuration - to sit inside one.
  • groupLabel Heading for that group when it is a new one. Defaults to the tab's label.
  • content The screen, as HTML. Run through wp_kses with the post allowlist plus form controls, so an activation form works and a stray <script> does not.
  • capability A WordPress capability the viewer must hold. Checked HERE, server-side, and an unmet one means the tab is not in the payload at all. Support's own tabs use the app's requires/caps pair instead; a contributed tab does not, because an unknown requires key is another silent drop.
  • priority Display order among contributed tabs. Default 20.

The page this renders on is already behind Capabilities::RESPOND, and a contributed screen is responsible for its own nonces and its own checks, exactly as it would be on a page of its own.

apply_filters( 'xpac_support_admin_tabs', [], $userId )
  • $tabs (array<int, array<string, mixed>>) — Descriptors so far.
  • $userId (int) — User the app is being built for.

Fired from:

  • packages/Support/Admin/Tabs.php:107

xpac_support_can_reply_to_ticket

Filter · 3 arguments · 1 call site

Whether this person may post to this ticket.

apply_filters( 'xpac_support_can_reply_to_ticket', $allowed, $userId, $ticket )
  • $allowed (bool) — Whether Support would allow it.
  • $userId (int) — The user being asked about; 0 is logged out.
  • $ticket (array<string, mixed>) — The ticket row.

Fired from:

  • packages/Support/Core/Policy.php:193

xpac_support_can_view_ticket

Filter · 3 arguments · 1 call site

Whether this person may see this ticket.

apply_filters( 'xpac_support_can_view_ticket', $allowed, $userId, $ticket )
  • $allowed (bool) — Whether Support would allow it.
  • $userId (int) — The user being asked about; 0 is logged out.
  • $ticket (array<string, mixed>) — The ticket row.

Fired from:

  • packages/Support/Core/Policy.php:167

xpac_support_canned_options

Filter · 2 arguments · 1 call site

Filters the canned replies offered to the composer.

id, title and shortcut only, because a site with 300 canned replies must not ship 300 bodies into the page; the body is fetched on insert. Empty until Modules\Canned answers it, which is the only listener there is.

apply_filters( 'xpac_support_canned_options', [], $userId )
  • $options (array) — Each entry ['id' => int, 'title' => string, 'shortcut' => string].
  • $userId (int) — The agent asking.

Fired from:

  • packages/Support/Core/Rest/AgentController.php:555

xpac_support_customer_billing

Filter · 4 arguments · 1 call site

Filters the billing history behind the panel's own button.

Up to four calls into a rate-limited API, which is why it is a second filter and a second route rather than another key on the first one.

apply_filters( 'xpac_support_customer_billing', [], (string) ($ticket['requester_email'] ?? ''), (int) ($ticket['requester_user_id'] ?? 0), (int) ($ticket['id'] ?? 0) )
  • $billing (array) — Orders, invoices and subscription line items.
  • $email (string) — The requester's address as the ticket recorded it.
  • $userId (int) — The requester's user id, or 0 for a guest.
  • $ticketId (int) — The ticket being opened.

Fired from:

  • packages/Support/Core/CustomerContext.php:72

xpac_support_customer_context

Filter · 4 arguments · 1 call site

Filters everything the agent inbox knows about the person asking.

Unanswered on a customer site, which is the supported configuration: the panel then renders "No account on file." rather than an error.

apply_filters( 'xpac_support_customer_context', [], (string) ($ticket['requester_email'] ?? ''), (int) ($ticket['requester_user_id'] ?? 0), (int) ($ticket['id'] ?? 0) )
  • $context (array) — Account, installs and ticket history.
  • $email (string) — The requester's address as the ticket recorded it.
  • $userId (int) — The requester's user id, or 0 for a guest.
  • $ticketId (int) — The ticket being opened.

Fired from:

  • packages/Support/Core/CustomerContext.php:40

xpac_support_entitled

Filter · 3 arguments · 1 call site

Whether this install is entitled to $feature.

Fires wherever Support has a decision an outside licensing plugin could own. It arrives true and is returned unclamped, so a callback may answer either way - see the class docblock for why this one is not deny-only.

A callback runs on every install, licensed or not, so it must decide from what it already knows. Anything that would reach the network belongs behind the licensing plugin's own cache and not in here: this runs while an admin screen is being built.

apply_filters( 'xpac_support_entitled', true, $feature, $context )
  • $allowed (bool) — True, the default answer.
  • $feature (string) — Feature id being asked about.
  • $context (array<string, mixed>) — What the caller knows about the request.

Fired from:

  • packages/Support/Core/Entitlement.php:90

xpac_support_erasure_deletes_tickets

Filter · 2 arguments · 1 call site

Whether erasure deletes the whole ticket rather than emptying the subject's contribution to it.

apply_filters( 'xpac_support_erasure_deletes_tickets', false, $address )
  • $delete (bool) — Off by default.
  • $email (string) — The data subject.

Fired from:

  • packages/Support/Core/Privacy/Eraser.php:87

xpac_support_export_internal_notes

Filter · 2 arguments · 1 call site

Whether an internal note is part of this person's export.

apply_filters( 'xpac_support_export_internal_notes', false, $email )
  • $include (bool) — Off by default.
  • $email (string) — The data subject.

Fired from:

  • packages/Support/Core/Privacy/Exporter.php:49

xpac_support_hub_article_slug

Filter · 1 argument · 1 call site

apply_filters( 'xpac_support_hub_article_slug', 'support-hub/articles' )

Fired from:

  • packages/Support/Hub/Articles.php:58

xpac_support_init

Action · 1 argument · 1 call site

Fires when Support is ready to be extended.

Runs on init at priority 200, late enough that every add-on has been loaded and that anything registered on init itself is in place. Consumers of once-read filters subscribe at 201.

do_action( self::ACTION_INIT, $this )
  • $plugin (Bootstrap) — The plugin instance.

Fired from:

  • packages/Support/Bootstrap.php:199

xpac_support_intake_ticket_args

Filter · 3 arguments · 1 call site

Filters the routable arguments a new ticket is created from.

The one place a site routes on product or stamps a plan before the row exists.

$routable HOLDS NO IDENTITY. requester_user_id, requester_email and requester_name are structurally absent from it, not merely overwritten afterward, because this filter runs against whatever the Forms bridge mapped from a public submission. $identity is passed as a third, READ-ONLY argument so a listener can still route on who is asking — a VIP's plan, a product by department — without ever being able to become someone else: nothing this filter returns under an identity key survives, because the merge below runs after it for exactly that reason.

apply_filters( 'xpac_support_intake_ticket_args', $routable, $opening, $identity )
  • $routable (array) — Ticket arguments a site may legitimately influence: subject, priority, source, source_ref, plan, custom_fields, state, status, locale.
  • $opening (array) — The opening message.
  • $identity (Identity) — Read-only. Who is opening this ticket.

Fired from:

  • packages/Support/Core/Intake.php:164

xpac_support_is_agent

Filter · 2 arguments · 1 call site

Whether this user staffs the helpdesk.

apply_filters( 'xpac_support_is_agent', $isAgent, $userId )
  • $isAgent (bool) — Whether the user holds Capabilities::RESPOND.
  • $userId (int) — The user being asked about; 0 is logged out.

Fired from:

  • packages/Support/Core/Policy.php:50

xpac_support_login_url

Filter · 2 arguments · 1 call site

apply_filters( 'xpac_support_login_url', wp_login_url(get_permalink()), get_permalink() )

Fired from:

  • packages/Support/Blocks/Portal/Block.php:231

xpac_support_notification_email

Filter · 4 arguments · 1 call site

Filters the values one notification template is rendered with.

apply_filters( 'xpac_support_notification_email', $context, $event, $ticket, $recipient )
  • $context (array) — Template values.
  • $event (string) — Key of Mail\Notifier::EVENTS.
  • $ticket (array) — The ticket row.
  • $recipient (array) — ['email' => string, 'name' => string, 'user_id' => int].

Fired from:

  • packages/Support/Mail/Mailer.php:183

xpac_support_notification_enabled

Filter · 4 arguments · 1 call site

Filters whether one notification is sent at all.

Asked only when the owner has the email switched on, so it can narrow that choice but never override an email switched off.

apply_filters( 'xpac_support_notification_enabled', true, $event, $ticketId, $context )
  • $enabled (bool) — Always true before a callback narrows it.
  • $event (string) — Key of Mail\Notifier::EVENTS.
  • $ticketId (int) — Ticket the event is about.
  • $context (array) — Event context passed by Core\Events.

Fired from:

  • packages/Support/Mail/Notifier.php:88

xpac_support_notification_recipients

Filter · 3 arguments · 1 call site

Filters the addresses one notification is sent to.

Each entry is ['email' => string, 'name' => string, 'user_id' => int]. The list is de-duplicated and stripped of invalid addresses afterwards, and an agent email never reaches the ticket's requester.

apply_filters( 'xpac_support_notification_recipients', $candidates, $event, $ticket )
  • $recipients (array) — Resolved recipients.
  • $event (string) — Key of Mail\Notifier::EVENTS.
  • $ticket (array) — The ticket row.

Fired from:

  • packages/Support/Mail/Notifier.php:171

xpac_support_notification_template

Filter · 3 arguments · 1 call site

Filters the file one notification template is rendered from.

Asked after the theme and the packaged copy have been looked up, so it wins over both. The name is the event with underscores replaced by hyphens, suffixed -html or -text, plus wrapper-html and wrapper-text.

apply_filters( 'xpac_support_notification_template', $path, $name, $context )
  • $path (string) — Absolute path resolved so far.
  • $name (string) — Template name without the .php extension.
  • $context (array) — Values the template will be handed.

Fired from:

  • packages/Support/Mail/Mailer.php:222

xpac_support_owned_options

Filter · 1 argument · 1 call site

Options removed when the site has opted into data removal on uninstall.

apply_filters( 'xpac_support_owned_options', $options )
  • $options (string[]) — Option names.

Fired from:

  • packages/Support/Database/Schema.php:91

xpac_support_polling_interval

Filter · 1 argument · 1 call site

Seconds between polls on the no-socket tier.

apply_filters( 'xpac_support_polling_interval', $interval )
  • $interval (int) — The interval settled above, already floored.

Fired from:

  • packages/Support/Core/Settings.php:197

xpac_support_portal_agent_name

Filter · 2 arguments · 1 call site

apply_filters( 'xpac_support_portal_agent_name', $name, $userId )

Fired from:

  • packages/Support/Core/Rest/DTOs/PortalReply.php:126

xpac_support_portal_url

Filter · 1 argument · 1 call site

Where the portal lives, for a site that mounted the block somewhere this cannot guess.

apply_filters( 'xpac_support_portal_url', '' )
  • $url (string) — Empty when neither the setting nor the account page answers.

Fired from:

  • packages/Support/Core/Api.php:145

xpac_support_reply_created

Action · 3 arguments · 1 call site

Fires after a thread entry is stored, before anything is published.

The listener branches on visibility: a public reply reaches the customer and ticket channels, an internal note can only reach xp-support-ticket-staff. The note is not filtered out of a customer payload; it is never handed to a function that can reach one.

THIS IS THE ONLY FIRING SITE. Core\Events::replyAdded() runs after it on the same reply and does not fire it again, so a listener sees one reply once, always as (int, int, array). tests/checks/support/58-reply-hook-contract.php fails on a second firing site or a different argument shape.

do_action( 'xpac_support_reply_created', $replyId, $ticketId, [ 'visibility' => $visibility, 'type' => $type, 'author_role' => isset($args['author_role']) ? (int) $args['author_role'] : Reply::AUTHOR_CUSTOMER, ] )
  • $replyId (int) — The new entry.
  • $ticketId (int) — The ticket it belongs to.
  • $payload (array) — ['visibility' => int, 'type' => int, 'author_role' => int].

Fired from:

  • packages/Support/Database/DAO/ReplyDAO.php:225

xpac_support_schema_installed

Action · 1 argument · 1 call site

The schema is present and current.

do_action( 'xpac_support_schema_installed', $synced )
  • $synced (string[]) — Columns and indexes added to existing tables.

Fired from:

  • packages/Support/Database/Installer.php:103

xpac_support_ticket_closed

Action · 2 arguments · 1 call site

A ticket stopped being open.

do_action( 'xpac_support_ticket_closed', $ticketId, $fromState )
  • $ticketId (int) — The ticket.
  • $fromState (int) — The open state it left.

Fired from:

  • packages/Support/Core/Events.php:264

xpac_support_ticket_created

Action · 2 arguments · 1 call site

Fires once a ticket row exists, with the counters already stamped.

The realtime layer turns this into RevisionStore::set() on the customer, agent and inbox channels; the mail layer turns it into an Action Scheduler job. Both are listeners rather than calls, so Support works with Realtime absent and with mail switched off.

do_action( 'xpac_support_ticket_created', $ticketId, [ 'event' => TicketEvent::CREATED, 'revision' => 1, 'staff_revision' => 1, ] )
  • $ticketId (int) — The new ticket.
  • $payload (array) — ['event' => string, 'revision' => int, 'staff_revision' => int].

Fired from:

  • packages/Support/Database/DAO/TicketDAO.php:199

xpac_support_ticket_priorities

Filter · 1 argument · 1 call site

The site's priority labels.

apply_filters( 'xpac_support_ticket_priorities', $priorities )
  • $priorities (array<int, array{value: int, label: string}>)

Fired from:

  • packages/Support/Core/Policy.php:227

xpac_support_ticket_status_changed

Action · 3 arguments · 1 call site

A ticket moved from one state to another.

do_action( 'xpac_support_ticket_status_changed', $ticketId, $fromState, $toState )
  • $ticketId (int) — The ticket.
  • $fromState (int) — The state it left.
  • $toState (int) — The state it is in now.

Fired from:

  • packages/Support/Core/Events.php:255

xpac_support_ticket_statuses

Filter · 1 argument · 1 call site

The site's status labels, one entry per Ticket state.

apply_filters( 'xpac_support_ticket_statuses', $statuses )
  • $statuses (array<int, array{state: int, slug: string, label: string}>)

Fired from:

  • packages/Support/Core/Policy.php:210

xpac_support_ticket_updated

Action · 2 arguments · 1 call site

Fires after a ticket row changed, with the counters it produced.

do_action( 'xpac_support_ticket_updated', $ticketId, [ 'event' => isset($event['event']) ? (string) $event['event'] : '', 'scope' => isset($event['scope']) ? (int) $event['scope'] : TicketEvent::SCOPE_STAFF, 'revision' => $counters['revision'], 'staff_revision' => $counters['staff_revision'], 'event_id' => $eventId, ] )
  • $ticketId (int) — The ticket.
  • $payload (array) — ['event' => string, 'scope' => int, 'revision' => int, 'staff_revision' => int, 'event_id' => int].

Fired from:

  • packages/Support/Database/DAO/TicketDAO.php:353

xpac_support_ticket_viewers

Filter · 2 arguments · 1 call site

Filters the agents currently looking at this ticket.

For a presence layer over xp-support-viewing, which is agent-only, to answer. Empty when nothing answers it, which is a supported configuration rather than a degraded one.

apply_filters( 'xpac_support_ticket_viewers', [], $ticketId )
  • $viewers (array) — Each entry ['id' => int, 'name' => string, 'avatar' => string].
  • $ticketId (int) — The ticket being opened.

Fired from:

  • packages/Support/Core/Rest/AgentController.php:919

xpac_support_upload_policy

Filter · 1 argument · 1 call site

What this site accepts as an attachment.

apply_filters( 'xpac_support_upload_policy', $policy )
  • $policy (array{max_bytes:int,max_per_reply:int,mimes:array<int,string>})

Fired from:

  • packages/Support/Core/Settings.php:152

On this page