Files
wp-multisite-waas/inc/class-light-ajax.php
2024-12-07 00:09:47 -07:00

172 lines
3.7 KiB
PHP

<?php
/**
* Light Ajax Implementation
*
* Helper class that mimics the Admin Ajax URL.
* Based on the code found on: https://coderwall.com/p/of7y2q/faster-ajax-for-wordpress
*
* @package WP_Ultimo
* @subpackage Light_Ajax
* @since 2.0.0
*/
namespace WP_Ultimo;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Adds a lighter ajax option to WP Multisite WaaS.
*
* @since 1.9.14
*/
class Light_Ajax {
use \WP_Ultimo\Traits\Singleton;
/**
* Sets up the listener
*
* @since 2.0.0
*/
public function __construct() {
if (isset($_REQUEST['wu-ajax'])) {
$action = $this->get_when_to_run();
wu_x_header("X-Ultimo-Ajax-When: $action");
add_action($action, array($this, 'process_light_ajax'), 20);
} // end if;
} // end __construct;
/**
* Actions that can ignore the referer check.
*
* @since 2.0.4
* @return array
*/
protected function should_skip_referer_check(): bool {
$allowed_actions = apply_filters('wu_light_ajax_should_skip_referer_check', array(
/**
* Checkout Form Actions
*
* They're here because in some cases,
* the caching settings might prevent nonces from
* being properly refreshed, which could cause 403
* errors with the actions below.
*/
'wu_render_field_template',
'wu_create_order',
'wu_validate_form',
));
return in_array(wu_request('action', 'no-action'), $allowed_actions, true);
} // end should_skip_referer_check;
/**
* Gets the hook we should use to attach the light ajax runner to.
*
* By default, we use plugins_loaded to make sure we run as early
* as possible. This allows us to shave off almost 50% of the
* TTFB delay with these requests when compared with the regular
* WordPress admin-ajax.php.
*
* @since 2.0.0
* @return string
*/
public function get_when_to_run() {
/**
* For security reasons, we limit the number of actions
* available for hooking into. This filter allows developers
* to expand that list if necessary.
*
* @since 2.0.0
* @return array The hook list.
*/
$allowed_list = apply_filters('wu_light_ajax_allowed_hooks', array(
'plugins_loaded',
'setup_theme',
'after_setup_theme',
'init',
));
$action = isset($_REQUEST['wu-when']) ? base64_decode((string) $_REQUEST['wu-when']) : 'plugins_loaded';
return in_array($action, $allowed_list, true) ? $action : 'plugins_loaded';
} // end get_when_to_run;
/**
* Adds an wu_ajax handler.
*
* @since 1.9.14
* @return void
*/
public function process_light_ajax() {
// mimic the actual admin-ajax
define('DOING_AJAX', true); // phpcs:ignore
/**
* Do some light validation of the referrer,
* Just to make sure script kiddies are not using it
* as an API endpoint.
*/
$this->should_skip_referer_check() === false && check_ajax_referer('wu-ajax-nonce', 'r');
/**
* In some cases, we'll need to load extra juice to handle actions.
* This action can be used to load extra dependencies when needed.
*
* @since 2.0.0
*/
do_action('wu_before_light_ajax');
/** Allow for cross-domain requests (from the front end). */
send_origin_headers();
header('Content-Type: text/html; charset=' . get_blog_option(wu_get_main_site_id(), 'blog_charset'));
header('X-Robots-Tag: noindex');
if (empty($_REQUEST['action'])) {
status_header(400);
die('0');
} // end if;
send_nosniff_header();
// Disable caching
nocache_headers();
header('Pragma: no-cache');
$action = esc_attr(trim((string) $_REQUEST['action']));
if (is_user_logged_in()) {
do_action('wu_ajax_' . $action); // phpcs:ignore
} else {
do_action('wu_ajax_nopriv_' . $action); // phpcs:ignore
} // end if;
die('1');
} // end process_light_ajax;
} // end class Light_Ajax;