File Editor
Directories:
.. (Back)
Files:
Handler.php
Post_Thumbnail_Setter.php
Queue.php
Tester.php
Create New File
Create
Edit File: Handler.php
<?php /** * Class Tribe__Process__Handler * * The base class for all The Events Calendar async process handlers. * * @since 4.7.12 * @since 4.9.5 Removed dependency on `WP_Async_Request` class. * * @see Tribe__Service_Providers__Processes for more insight about this class utility. */ abstract class Tribe__Process__Handler { /** * The default handler action name. * * @var string */ protected $action = 'async_request'; /** * The handler identifier. * * @var string */ protected $identifier; /** * An array of data for the process. * * @var array */ protected $data = []; /** * This handler cron identifier. * * @var string */ protected $healthcheck_cron_hook_id; /** * @var string The common identified prefix to all our async process handlers. */ protected $prefix = 'tribe_process'; /** * An instance of the object abstracting the feature detection functionality. * * @var Tribe__Feature_Detection */ protected $feature_detection; /** * An array of query arguments that should be used in place of the default ones. * Extending classes can override/set this to replace the default entirely. * * @var array */ protected $query_args; /** * The absolute URL that should be used to POST requests. * Extending classes can override/set this to replace the default entirely. * * @var string */ protected $query_url; /** * An array of arguments that should be used as body of the POST request. * Extending classes can override/set this to replace the default entirely. * * @var array */ protected $post_args; /** * Tribe__Process__Handler constructor. * * @since 4.7.12 */ public function __construct() { $class = get_class( $this ); $this->action = call_user_func( [ $class, 'action' ] ); $this->identifier = $this->prefix . '_' . $this->action; add_action( 'wp_ajax_' . $this->identifier, [ $this, 'maybe_handle' ] ); /** * Filters whether background processing should be triggered and handled on * non-private AJAX requests as the ones triggered by a non logged in user. * Defaults to `true` to exploit any possible chance to process. * * @since 4.9.5 * * @param bool $allow_nopriv Whether background processing should be triggered and handled on * non-private AJAX requests or not. * @param static $this This handler instance. */ $allow_nopriv = apply_filters( 'tribe_process_allow_nopriv_handling', true, $this ); if ( $allow_nopriv ) { add_action( 'wp_ajax_nopriv_' . $this->identifier, [ $this, 'maybe_handle' ] ); } $this->healthcheck_cron_hook_id = $this->identifier; $this->feature_detection = tribe( 'feature-detection' ); /* * This object might have been built while processing crons so * we hook on the the object cron identifier to handle the task * if the cron-triggered action ever fires. */ add_action( $this->healthcheck_cron_hook_id, [ $this, 'maybe_handle' ] ); } /** * Returns the async process action name. * * Extending classes must override this method to return their unique action slug. * * @since 4.7.12 * * @return string * * @throws RuntimeException If the extending class does not override this method. */ public static function action() { $class = static::class; throw new RuntimeException( "Class {$class} should override the `action` method to define its own unique identifier." ); } /** * Handles the process request if valid and if authorized. * * @since 4.7.23 * @since 4.9.5 Pulled the `maybe_handle` implementation of the `WP_Async_Request` class. * * @param array|null $data_source A source of data if not provided in the request; used for * cron-based fallback. */ public function maybe_handle( $data_source = null ) { $data_source = (array) $data_source; if ( $this->feature_detection->supports_async_process() ) { // Don't lock up other requests while processing. session_write_close(); check_ajax_referer( $this->identifier, 'nonce' ); // Let's make sure to hydrate date from the request if not set. if ( count( array_filter( $data_source ) ) < 1 ) { $data_source = $_POST; } do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'async_handling', 'data_source' => $data_source, 'payload' => $_POST, ] ); $this->handle( $data_source ); wp_die(); } /* * If the environment does not support AJAX-based async processing then * fallback to use the cron-based approach and just call the handle method * removing it first from the action to avoid multiple calls. */ wp_clear_scheduled_hook( $this->healthcheck_cron_hook_id, [ $data_source ] ); do_action( 'tribe_log', 'debug', $this->identifier, array_merge( [ 'action' => 'cron_handling' ], $data_source ) ); $this->handle( $data_source ); } /** * Overrides the base `dispatch` method to allow for constants and/or environment vars to run * async requests in sync mode. * * @since 4.7.12 * @since 4.9.5 Pulled `dispatch` method logic from the `WP_Async_Request` class. * * @return mixed */ public function dispatch() { if ( ( defined( 'TRIBE_NO_ASYNC' ) && true === TRIBE_NO_ASYNC ) || true === (bool) getenv( 'TRIBE_NO_ASYNC' ) ) { do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'sync_handle', 'data' => $this->data ] ); return $this->sync_handle( $this->data ); } if ( $this->feature_detection->supports_async_process() ) { $url = add_query_arg( $this->get_query_args(), $this->get_query_url() ); $args = $this->get_post_args(); do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'async_dispatch', 'data' => $this->data ] ); return wp_remote_post( esc_url_raw( $url ), $args ); } /* * If async AJAX-based processing is not available then we "dispatch" * by scheduling a single cron event immediately (as soon as possible) * for this handler cron identifier. */ if ( ! wp_next_scheduled( $this->healthcheck_cron_hook_id, [ $this->data ] ) ) { // Schedule the event to happen as soon as possible. $scheduled = wp_schedule_single_event( time() - 1, $this->healthcheck_cron_hook_id, [ $this->data ] ); if ( false === $scheduled ) { /** @var Tribe__Log__Logger $logger */ $logger = tribe( 'logger' ); $class = get_class( $this ); $src = call_user_func( [ $class, 'action' ] ); $logger->log( 'Could not schedule event for cron-based handling', Tribe__Log::ERROR, $src ); do_action( 'tribe_log', 'error', $this->identifier, [ 'action' => 'schedule_cron', 'data' => $this->data ] ); } do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'schedule_cron', 'data' => $this->data ] ); } return true; } /** * Handles the process immediately, not in an async manner. * * @since 4.7.12 * * @param array|null $data_source If not provided the method will read the handler data from the * request array. * * @return mixed|null The result of the synchronous handling. */ abstract public function sync_handle( array $data_source = null ); /** * Returns an array of arguments that will be used to send the POST request. * * @since 4.9.5 Pulled from the `WP_Async_Request` class. * * @return array An array of arguments for the POST request. */ protected function get_query_args() { if ( null !== $this->query_args ) { return $this->query_args; } return [ 'action' => $this->identifier, 'nonce' => wp_create_nonce( $this->identifier ), ]; } /** * Returns the URL that wil be used to post the request. * * @since 4.9.5 Pulled from the `WP_Async_Request` class. * * @return string The URL that will be used to POST the dispatch request; defaults * to the `admin-ajax.php` one. */ protected function get_query_url() { if ( null !== $this->query_url ) { return $this->query_url; } return admin_url( 'admin-ajax.php' ); } /** * Returns the arguments that will be used to send the POST request. * * @since 4.9.5 Pulled from the `WP_Async_Request` class. * * @return array An array of arguments that will be used to send the POST request. */ protected function get_post_args() { if ( null !== $this->post_args ) { return $this->post_args; } return [ 'timeout' => 0.01, 'blocking' => false, 'body' => $this->data, 'cookies' => $_COOKIE, 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), ]; } /** * Returns this handler cron hook identifier. * * The handler cron hook identifier is the one that the handler * will use to schedule a single cron event when the `dispatch` * method is called and the environment does not support async * processing. * * @since 4.7.23 * * @return string The complete cron hook name (identifier) for * this handler. */ public function get_healthcheck_cron_hook_id() { return $this->healthcheck_cron_hook_id; } /** * Sets the that will be used during the request. * * @since 4.9.5 Pulled from the `WP_Async_Request` class. * * @param array $data Data. * * @return $this This handler instance. */ public function data( $data ) { $this->data = $data; return $this; } /** * Handles the request and performs an action. * * @since 4.9.5 Pulled from the `WP_Async_Request` class. * * @param array|null $data_source A source of data if not provided in the request; used for * cron-based fallback. * * @return null|array Depending on the context of the call, cron or async, either the result * of the handling (cron) or nothing (async). */ abstract protected function handle( array $data_source = null ); }
Save Changes
Rename File
Rename