File "Handler.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/the-events-calendar/common/src/Tribe/Process/Handler.php
File size: 9.78 KB
MIME-type: text/x-php
Charset: utf-8
<?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 );
}