Reference
PHP API Reference
The WPS facade, trigger builder, and WordPress filters exposed by the WordSocket plugin.
WPS Facade
The WPS class is the main entry point.
All methods are static. The class is a singleton; use WPS::instance() only when you need to access internal components directly.
WPS::instance()
Get the singleton instance.
Returns:
WPS
WPS::trigger($event)
Create a new trigger builder. Returns a fluent builder: chain ->on(), ->channel(), ->data(), ->when(), then call ->register() to wire it up.
| Parameter | Type | Description |
|---|---|---|
| $event | string | Event name (e.g. "post.updated", "comment.created"). |
Returns:
Trigger
A new trigger builder instance.
WPS::trigger( 'user.login' )
->on( 'wp_login', 10, 2 )
->data( function ( $user_login, $user ) {
return [ 'user_id' => $user->ID, 'login' => $user_login ];
} )
->register();
WPS::publish($channel, $event, $data)
Publish an event directly (no hook needed). Sends an HMAC-signed POST to the WPSignal server. The plugin must be configured (site_key, site_secret, base_url) or this returns a WP_Error.
| Parameter | Type | Description |
|---|---|---|
| $channel | string | Channel name (e.g. "events"). Scoped server-side. |
| $event | string | Event name (e.g. "post.updated"). |
| $data | mixed | Arbitrary data (will be JSON-encoded). |
Returns:
array|WP_Error
wp_remote_post response array on success, WP_Error on failure.
WPS::publish( 'events', 'custom.event', [ 'key' => 'value' ] );
Trigger Builder
WPS::trigger($event) returns a fluent builder.
Chain the methods below and call register() to wire the WordPress hook.
Register triggers inside an add_action('wpsignal_loaded', ...) callback (in a plugin)
or add_action('init', ...) (in a theme's functions.php).
->on(
$hook, $priority, $accepted_args
)
Set the WordPress action hook to listen on.
| Parameter | Type | Description |
|---|---|---|
| $hook | string | WordPress action hook name. |
| $priority | int | Optional. Hook priority. Default 10. |
| $accepted_args | int | Optional. Number of hook arguments. Default 1. |
Returns:
$this
->on( 'save_post', 20, 3 ) // priority 20, 3 args
->on( 'wp_login' ) // defaults: priority 10, 1 arg
->channel(
$channel
)
Set the channel to publish on. Defaults to "events" if not called. The server normalizes this to the full tenant-scoped channel name.
| Parameter | Type | Description |
|---|---|---|
| $channel | string | Channel name. |
Returns:
$this
->channel( 'orders' )
->data(
$callback
)
Set the data builder callback. The callback receives the same arguments as the WordPress hook and should return an associative array. This array becomes the `data` field in the published event payload.
| Parameter | Type | Description |
|---|---|---|
| $callback | callable | Data builder. Receives hook args, returns array. |
Returns:
$this
->data( function ( $post_id, $post, $update ) {
return [
'post_id' => $post_id,
'post_title' => $post->post_title,
];
} )
->when(
$callback
)
Set a condition callback. The callback receives the same arguments as the WordPress hook. Return false to skip publishing for this hook invocation. If not set, the trigger always fires.
| Parameter | Type | Description |
|---|---|---|
| $callback | callable | Condition check. Receives hook args, returns bool. |
Returns:
$this
->when( function ( $post_id, $post ) {
return 'publish' === $post->post_status;
} )
->register(
)
Register this trigger with the global trigger registry. This wires the WordPress hook so the trigger fires automatically. Must be called after configuring the builder.
Extension API
The surface a plugin built on WordSocket uses. Reach each one from the
singleton, for example WPS::instance()->channels(), inside
an add_action('wpsignal_loaded', ...) callback.
WPS::instance()->channels()
Reserve a channel namespace so only users passing a capability check may subscribe or publish. Reserving anything puts the site into strict mode, where channels that are not registered are refused.
->reserve(
$ns, $grant, $publish
)
Reserve a namespace for users with a capability, or for whom a callable returns true.
| Parameter | Type | Description |
|---|---|---|
| $ns | string | Namespace such as `woo:orders` (no `site:` prefix). A trailing colon is implied. |
| $grant | string|callable | Who may subscribe: a capability name, or `callable( int $user_id ): bool`. |
| $publish | string|callable|null | Who may publish and enter presence; defaults to `$grant`. |
->reservations(
)
Reserved namespaces with their grants.
Returns:
array<string,
string|callable>
->is_strict(
)
Whether any namespace is reserved (strict mode).
Returns:
bool
->allowed_prefixes(
$user_id, $site_id, $channels
)
Prefixes for a token.
| Parameter | Type | Description |
|---|---|---|
| $user_id | int | User the token is minted for (0 for visitors). |
| $site_id | string | Hashed site identifier used in channel names. |
| $channels | string[] | Channels the client auto-subscribes to (after the `wpsignal_token_channels` filter). |
Returns:
string[]
->allowed_publish_prefixes(
$user_id, $site_id
)
Prefixes a token may publish on. Strict mode grants nothing by default: only reserved namespaces whose publish grant the user passes. Plugins add plain channels through the `wpsignal_token_publish_prefixes` filter.
| Parameter | Type | Description |
|---|---|---|
| $user_id | int | User the token is minted for (0 for visitors). |
| $site_id | string | Hashed site identifier used in channel names. |
Returns:
string[]
WPS::instance()->extensions()
Register a plugin built on WordSocket so it appears on the Extensions tab and nests under WordSocket on the Plugins screen.
->register(
$slug, $args
)
Register an extension installed on this site.
| Parameter | Type | Description |
|---|---|---|
| $slug | string | Plugin slug, for example `shopsocket`. |
| $args | array | Extension metadata: `title`, `description`, `version`, |
->registered(
)
Registered extensions.
Returns:
array<string,
array>
->all(
)
Everything the Extensions tab shows: registered extensions first, then catalogue entries not installed here.
Returns:
array<int,
array>
->plugin_files(
)
The plugin file of every extension WordSocket knows, registered or catalogued: what `Plugins_Screen` matches the Plugins list against. A registered extension names its own file; everything else is assumed to sit where WordPress.org installs it, in a directory named after its slug.
Returns:
array<string,
string> Slug => plugin file.
WPS::instance()->publisher()
HMAC-signed publishing to the relay, and the site’s own connection figures. Most code should call WPS::publish() rather than reaching for this directly.
->publish(
$channel, $event, $data
)
Publish an event to the WPSignal server.
| Parameter | Type | Description |
|---|---|---|
| $channel | string | Channel name (e.g. "events"). Scoped server-side. |
| $event | string | Event name (e.g. "post.updated"). |
| $data | mixed | Arbitrary data (will be JSON-encoded). |
Returns:
array|WP_Error
wp_remote_post response array on success, WP_Error on failure.
$publisher = WPS::instance()->publisher();
$publisher->publish( 'events', 'post.updated', [
'post_id' => 42,
'post_title' => 'Hello World',
] );
->stats(
)
Ask the server about this site: browsers connected right now and the plan's connection limit. Signed like a publish over an empty body, so it needs no dashboard session. Extensions use it for "online now" figures.
Returns:
array{active_connections:
int, max_connections: int}|\WP_Error
->remote_error(
$response, $fallback
)
Turn a non-2xx server response into a `WP_Error` carrying the server's own code (prefixed `wpsignal_`) and message.
| Parameter | Type | Description |
|---|---|---|
| $response | array | wp_remote_* response. |
| $fallback | string | Code to use when the body has none. |
Returns:
WP_Error
WPS::instance()->trigger_registry()
Where registered triggers live once WPS::trigger(...)->register() has wired them, plus control over the built-in default trigger.
->add(
$trigger
)
Add a trigger and wire its WordPress action hook.
| Parameter | Type | Description |
|---|---|---|
| $trigger | Trigger | A configured trigger builder instance. |
->exclude_default_post_type(
$post_type
)
Exclude a post type from the built-in default trigger. Called by Custom_Triggers when registering a post-type trigger so the built-in save_post handler skips that type (avoiding duplicate publishes).
| Parameter | Type | Description |
|---|---|---|
| $post_type | string | Post type slug. |
->get_excluded_default_post_types(
)
Get post types excluded from the built-in default trigger.
Returns:
string[]
->all(
)
Return all registered triggers. Useful for inspection, debugging, and the Kitchen Sink triggers table.
Returns:
Trigger[]
Array of all registered trigger instances.
WordPress Filters
Use add_filter() to hook into these.
wpsignal_token_channels
Filters the channels the client auto-subscribes to on connect. Plugins can append their own channels so they are included in the initial WebSocket/SSE subscription without a separate subscribe call.
| Parameter | Type | Description |
|---|---|---|
| $channels | string[] | Default channels for this site. |
| $user_id | int | Current user ID. |
| $site_id | string | Hashed site identifier from the JWT. |
add_filter( 'wpsignal_token_channels', function ( $value ) {
// modify $value and return it
return $value;
} );
wpsignal_token_channel_prefixes
Filters the channel prefixes the JWT allows the client to subscribe to. The WPSignal server rejects subscribe/publish frames whose channel does not start with one of these prefixes. The default is the site wildcard `site:{site_id}:` until a plugin reserves a namespace through `WPS::instance()->channels()->reserve()`; from then on it is an explicit list (see `Channels::allowed_prefixes()`), so register every channel you subscribe to through `wpsignal_token_channels`.
| Parameter | Type | Description |
|---|---|---|
| $prefixes | string[] | Default allowed prefixes. |
| $user_id | int | Current user ID. |
| $site_id | string | Hashed site identifier from the JWT. |
add_filter( 'wpsignal_token_channel_prefixes', function ( $value ) {
// modify $value and return it
return $value;
} );
wpsignal_token_publish_prefixes
Filters the channel prefixes the JWT allows the client to publish on. Publishing covers `WPS.publish()`, binary frames, and presence. The default is the site wildcard until a plugin reserves a namespace; from then on only reserved namespaces whose publish grant the user passes (see `Channels::reserve()`), so a channel registered for reading stays read-only unless it is added here.
| Parameter | Type | Description |
|---|---|---|
| $prefixes | string[] | Default publish prefixes. |
| $user_id | int | Current user ID. |
| $site_id | string | Hashed site identifier from the JWT. |
add_filter( 'wpsignal_token_publish_prefixes', function ( $value ) {
// modify $value and return it
return $value;
} );
wpsignal_allow_client
Controls whether the WordSocket client script is enqueued for the current request. Return `false` to prevent the script from loading (e.g. on specific post types or for guest users). Return `true` to force-load it regardless of login state.
| Parameter | Type | Description |
|---|---|---|
| $allow | bool | Default: `is_user_logged_in()`. |
add_filter( 'wpsignal_allow_client', function ( $value ) {
// modify $value and return it
return $value;
} );
wpsignal_force_sse
Forces the client to use SSE instead of WebSocket. Return `true` to disable WebSocket and fall back to Server-Sent Events. Useful in environments where WebSocket connections are blocked.
| Parameter | Type | Description |
|---|---|---|
| $force | bool | Default: `false`. |
add_filter( 'wpsignal_force_sse', function ( $value ) {
// modify $value and return it
return $value;
} );
wpsignal_encryption_seed
Filters the seed used to derive the AES-256-GCM encryption key. The default seed is `AUTH_KEY . SECURE_AUTH_KEY` from WordPress salts. Override this to supply your own key material without modifying WordPress salts.
| Parameter | Type | Description |
|---|---|---|
| $seed | string | The default seed string. |
add_filter( 'wpsignal_encryption_seed', function ( $seed ) {
return 'my-application-specific-secret';
} );
WordPress Actions
Use add_action() to hook into these.
wpsignal_loaded
Fires when WPSignal is fully loaded and ready for trigger registration. NB: this can only be called by plugins since this runs on `plugins_loaded` hook. Themes will need to use `init` hook instead. Third-party plugins should hook here to register custom triggers:
add_action( 'wpsignal_loaded', function () {
WPS::trigger( 'order.completed' )
->on( 'woocommerce_order_status_completed' )
->channel( 'orders' )
->data( function ( $order_id ) {
$order = wc_get_order( $order_id );
return [ 'order_id' => $order_id, 'total' => $order->get_total() ];
} )
->register();
} );
Constants
Define these in wp-config.php to override default plugin behaviour.
WPSignal\BASE_URL
Define in wp-config.php to point the plugin at a self-hosted WPSignal server. When defined, overrides the default https://api.wpsignal.io endpoint for all publish, registration, and token requests.
define( 'WPSignal\\BASE_URL', 'https://signal.example.com' );
WPSIGNAL_SITE_KEY
Define in wp-config.php to hard-code the site key. Overrides the value stored in wp_options by the auto-registration flow. Useful for environments where the database is ephemeral (e.g. CI, staging clones) or when credentials are managed via environment variables.
const WPSIGNAL_SITE_KEY = 'your-32-char-hex-site-key';
// or using define:
define( 'WPSIGNAL_SITE_KEY', 'your-32-char-hex-site-key' );
WPSIGNAL_SITE_SECRET
Define in wp-config.php to hard-code the publish secret. Overrides the value stored in wp_options. Always pair with WPSIGNAL_SITE_KEY. Never expose this value to browsers.
const WPSIGNAL_SITE_SECRET = 'your-64-char-hex-secret';
// or using define:
define( 'WPSIGNAL_SITE_SECRET', 'your-64-char-hex-secret' );