Skip to content
Tom J Nowell edited this page Aug 8, 2020 · 10 revisions

The Event object is responsible for deciding when to trigger message delivery based on an action hook. It also handles passing the data received from the action hook to allow for creating dynamic messages, recipients, and follow up actions to be appended to a message.

Like the other objects of Workflows it provides a fluent interface to define the event's properties and behaviour.

Static Methods

register( string $id ) : Event

Creates and returns an Event object instance that can be referenced later. If no specific action or listener is set the id is used as the action hook.

$event = Event::register( '<id>' );

get( string $id ) : Event | null

Retrieves a registered Event object by its id.

$event = Event::get( '<id>' );

remove( string $id ) : void

Removes a registered Event.

Event::remove( '<id>' );

Default Events

The following events are built into the Workflows plugin and appear as options in the UI.

draft_to_pending

Triggered when a post is pending review.

See {$old_status}_to_{$new_status}

publish_post

Triggered when a post is published.

See {$new_status}_{$post->post_type}

publish_page

Triggered when a page is published. See {$new_status}_{$post->post_type}

transition_post_status

Triggered when a post changes status. Use the UI data to specify which status to look for transitions to and from, as well as the post type.

For example, here is the even for a post published for the first time:

Event::get( 'transition_post_status' )
	->get_ui()
		->set_data( [
			'from' => [
				'draft',
				'new',
				'pending',
			],
			'to' => 'publish',
			'types' => [
				'post',
			],
		] );

See transition_post_status for more information about this action.

published_comment

Triggered when a new comment is published.

See wp_insert_comment

new_editorial_comment

Triggered when a new editorial comment is added.

See wp_insert_comment

Public Methods

set_listener( string|array|callable $listener ) : Event

This method sets the action hook or function to "listen" on. It can be set in a few ways to give you full control over how your event is triggered.

string

Treated as an existing action hook within WordPress such as update_option_{$option} or publish_post.

array

This is useful if you need to pre-process data returned by an action hook or control the priority and number of accepted arguments the action passes. The keys should be as below:

  • action: Required. An action hook name.
  • callback: Optional. A function to run on the action hook - any data returned here is passed to message tag callbacks, message actions and recipient handlers. If omitted the data passed by the action is passed on. In addition returning null will prevent the event from triggering.
  • priority: Optional. Allows you to control the priority you listen to on the action hook. Default is 10.
  • accepted_args: Optional. Number of args to expect from the action hook. Default is 1.

Below is a more complex example of pre-processing the action data, and number of args to accept:

Event::register( 'archiving_live_post' )
  ->set_listener( [
    'action'   => 'transition_post_status',
    'callback' => function ( $new_status, $old_status, WP_Post $post ) {
       if ( $new_status === 'archive' && $old_status === 'publish' ) {
         return $post; // Pass the post object to message tags & recipient handlers.
       }
       return null; // Stop event from firing.
    },
    'accepted_args' => 3,
  ] );

add_message_tags( array $tags ) : Event

Because an event receives data that you may wish to use in your messages this method allows you to add the tags that will be interpolated before a message is delivered.

The $tags array should be of key/value pairs where the key corresponds to a tag like %tagname% in the message and the value is a callable that receives the data from the action/listener that returns the desired text.

Event::register( 'message_with_tags' )
  ->set_listener( 'publish_post' )
  ->add_message_tags( [
    'title' => function ( $post_id ) {
      return get_the_title( $post_id );
    },
  ] );

In the above example a Workflow with the message text "I published '%title%'!" the result would become "I published 'Learning React & ES6'!".

add_message_action( string $id, string $text, string|callable $callback_or_url, array|null $args = null, array $schema = [], array $data = [] ) : Event

This method is the most complex on this object. Message actions are appended to messages as links that when clicked perform some action in WordPress and then optionally redirect the user to an appropriate location. They are effectively webhooks that can be used from anywhere, eg. slack, email or anywhere else you send notifications.

string $id

This is an identifier used to dispatch the appropriate callback when the webhook link is clicked.

string $text

A label for the action eg. "Preview post".

string|callable $callback_or_url

This can either be a URL to take people to or a callback. If a callback is passed it will receive the data specified by the following parameters $args and $schema.

It is recommended not to perform actions that modify the database but it is possible. You should always use a current_user_can() check if you do this.

The callback should return a URL which the user will then be redirected to, this could be a post edit screen or preview, or any other relevant and useful URL. If no URL is returned then a basic success / error message is displayed.

callable $args

This parameter allows you to process the data from the Event listener and return a keyed array of values to send to the webhook. It is this data that is passed to the callback from $callback_or_url if one was specified.

The reason for this is that not all data returned from the listener is suitable for serialising in a query string such as post objects. This forces you to send only the data you really need to the webhook handler.

Event::register( 'action_that_passes_post_object' )
  ->add_message_action( 
    'view', 
    'View post', 
    function ( $post_id ) { 
      return get_the_permalink( $post_id ); 
    },
    function ( WP_Post $post ) {
      return [
        'post_id' => $post->ID,
      ];
    },
    [
      'post_id' => 'intval',
    ]
  );

array $schema

The schema is am optional way to sanitise the data returned with the action webhook. By default sanitize_text_field() is used. In the above code example you can see we are telling the webhook handler to sanitise the post_id parameter with the intval() function.

array $data

This is arbitrary data passed to Destination handlers. You can ignore this most of the time as it is used internally to pass configurable data from UI objects to Event and Destination objects.

add_recipient_handler( string $id, callable $callback, string $name = '' ) : Event

A recipient handler takes data from the event callback and transforms it into an array of user IDs or user objects. This allows you to deliver notifications to dynamic recipients for an event.

Example usage:

Event::register( 'action_that_passes_post_object' )
  ->add_recipient_handler(
    'author',
    function ( WP_Post $post ) {
      return [ get_user_by( 'id', $post->post_author ) ];
    },
    __( 'Post Author' ) // Optional human readable name used in the admin UI.
  ); 

add_ui( string|UI $ui ) : Event

Adding a UI to the event allows website administrators to use this event trigger to create custom workflows in the admin.

The minimum requirement is a string label describing the event that users can select from in the admin. You can also pass a full UI object with custom fields to create configurable event handlers.

Example:

Event::register( 'publish_post' )
  ->add_ui( __( 'When a post is published' ) );

get_ui() : UI

Returns the UI object associated with an event if one exists. You can use this to chain configuration of your UI or make changes to an existing one.

Event::register( 'publish_post' )
  ->add_ui( __( 'When a post of the following type is published' ) )
  ->get_ui()
    ->add_field( 
      'type', 
      __( 'Post types' ), 
      'select', 
      [
        'options' => array_values( array_map( function ( WP_Post_Type $post_type ) {
          return [
            'label' => $post_type->label,
            'value' => $post_type->name,
          ];
        }, get_post_types( [ 'public' => true ], 'objects' ) ) ),
      ] 
    );