Skip to content

Handling multiple action triggers per request

Ammar Alakkad edited this page Aug 24, 2014 · 5 revisions

The WP Async Task library will only ever spawn one asynchronous request per instance of the library for a given page load. This means that if your action gets run more than once in a request, by default it will only use the prepared data from the last run of the action. Handling multiple calls to the triggering action requires a little bit of jury-rigging.

Let's imagine we want to handle the 'save_post' action multiple times in one page load. This is how we might go about doing that:

<?php

class JPB_Save_Post_Task extends WP_Async_Task {

    protected $action = 'save_post';

    protected function prepare_data( $data ) {
        $post = $data[1];
        if ( $post->post_type !== 'post' ) {
            throw new Exception( 'Wrong post type' );
        }
        /**
         * Internally, the library uses a protected property $_body_data
         * to store request data during a request lifetime, since the
         * async request doesn't happen until shutdown. We can use data
         * already stored there in subsequent runs of the action that
         * triggers requests.
         */
        $real_data = array(
            'posts' => array(),
        );
        if ( ! empty( $this->_body_data['posts'] ) ) {
            $real_data['posts'] = $this->_body_data['posts'];
        }
        // Store post ids in an array inside the body data
        $real_data['posts'][] = $post->ID;
        return $real_data;
    }

    protected function run_action() {
        $post_ids = wp_parse_id_list( $_POST['posts'] );
        array_walk( $post_ids, function( $post_id ) {
            $post = get_post( $post_id );
            if ( $post ) {
                do_action(
                    "wp_async_$this->action",
                    $post->ID,
                    $post
                );
            }
        } );
    }

}

$save_post_task = new JPB_Save_Post_Task( WP_Async_Task::LOGGED_IN );
Clone this wiki locally