golden hour
/home/godaofbq/besthyperbaric.com/wp-content/plugins/oxygen/plugin/ajax
⬆️ Go Up
Upload
File/Folder
Size
Actions
.htaccess
420 B
Del
OK
ajax_at_any_url.php
948 B
Del
OK
api.php
9.22 KB
Del
OK
base.php
163 B
Del
OK
endpoints
-
Del
OK
Edit: api.php
<?php namespace Breakdance\AJAX; use Exception; use function Breakdance\Admin\is_breakdance_development_environment; use function Breakdance\BreakdanceOxygen\Strings\__bdox; /** * @param string $route * @param callable $callback * @param string $minimum_permissions * @param bool $any_url * @param RegisterAjaxHandlerOptions $options * @param bool $skip_nonce_check * @return void * @throws Exception * * In case of renaming/moving to another namespace don't forget to adjust the readme.md file */ function register_handler($route, callable $callback, $minimum_permissions = 'never', $any_url = false, $options = [], $skip_nonce_check = false) { HandlerNamesHolder::getInstance()->add($route); if ($minimum_permissions === 'never') { // bad request throw new Exception('You must specify the minimum permissions to access your AJAX action.', 500); } $action_name = 'wp_ajax_' . $route; $any_action_name = 'breakdance_ajax_' . $route; $handler = function () use ($callback, $any_url, $minimum_permissions, $route, $options, $skip_nonce_check) { try { ob_start(); $isHandlerForRemoteRequest = !empty($options['remote']) && $options['remote']; $allowed = $isHandlerForRemoteRequest ? true : \Breakdance\Permissions\hasMinimumPermission($minimum_permissions); if (!$allowed) { if (!is_user_logged_in()) { throw new BreakdanceAjaxHandlerException( "You need to be logged in and have minimum permission level of \"{$minimum_permissions}\"", 401 ); } // forbidden request $error = sprintf( "Not enough permissions to perform the action \"%s\", minimum permission level is \"%s\".", $route, $minimum_permissions ); throw new BreakdanceAjaxHandlerException($error, 403); } if (!$isHandlerForRemoteRequest && !$skip_nonce_check) { $nonceTick = check_ajax_referer(get_nonce_key_for_ajax_requests(), false, !$isHandlerForRemoteRequest); if (!$nonceTick) { throw new BreakdanceAjaxHandlerException( "Failed security check", 419, null, 'Expired' ); } if ($nonceTick === 2) { $refreshNonce = get_nonce_for_ajax_requests(); header('Breakdance-Refresh-Nonce:' . $refreshNonce); } } $callback_args = []; if (!empty($options['args'])) { /** @var null|false|array<string, string|int|null|bool|array> $callback_args_filtered */ $callback_args_filtered = filter_input_array(INPUT_POST, $options['args'], true); if ($callback_args_filtered === false || $callback_args_filtered === null) { $error_message = !is_breakdance_development_environment() ? 'Bad request' : 'All of the required POST parameters are missing'; throw new BreakdanceAjaxHandlerException($error_message, 400); } $erroneous_arg_names = []; foreach ($callback_args_filtered as $arg_name => $arg_value) { $is_optional_arg = isset($options['optional_args']) && in_array($arg_name, $options['optional_args']); if ($arg_value === false || ($arg_value === null && !$is_optional_arg)) { $erroneous_arg_names[] = $arg_name; } } if (sizeof($erroneous_arg_names)) { $error_message = !is_breakdance_development_environment() ? 'Bad request' : sprintf( 'Required POST parameters are missing or invalid: "%s"', implode('", "', $erroneous_arg_names) ); throw new BreakdanceAjaxHandlerException($error_message, 400); } $callback_args = $callback_args_filtered; } try { /** @var mixed $return_value */ /** @psalm-suppress MixedAssignment */ $return_value = call_user_func_array($callback, array_values($callback_args)); } catch (Exception $callback_exec_exception) { throw new BreakdanceAjaxHandlerException($callback_exec_exception->getMessage(), 500, $callback_exec_exception); } if (is_array($return_value) && array_key_exists('error', $return_value)) { throw new BreakdanceAjaxHandlerCustomException((string) $return_value['error'], 500); } elseif (!is_array($return_value) && !$return_value) { $return_value = (object) []; } elseif (!is_array($return_value)) { $error = sprintf( "AJAX callbacks should return an associative array ([\"key\" => \"value\") or a blank array ([]). Got %s for route \"%s\"", print_r($return_value, true), $route ); throw new BreakdanceAjaxHandlerException($error, 500); } $unexpected_output = ob_get_clean(); if ($unexpected_output) { $error = 'Unexpected output during AJAX request. AJAX Callbacks should return an associative array. --------- ' . wp_strip_all_tags( $unexpected_output ); // bad request throw new BreakdanceAjaxHandlerException($error, 500); } else { wp_send_json($return_value, 200); } } catch (BreakdanceAjaxHandlerException $e) { if (ob_get_level()) { ob_end_clean(); } throw $e; } }; add_action($action_name, $handler); add_action('wp_ajax_nopriv_' . $route, $handler); if ($any_url) { add_action($any_action_name, $handler); } } /** * @return string */ function get_nonce_key_for_ajax_requests() { return 'breakdance_ajax'; } /** * @return string */ function get_nonce_for_ajax_requests() { return wp_create_nonce(get_nonce_key_for_ajax_requests()); } add_action( 'wp_login', /** * @param string $userLogin * @return void */ static function ($userLogin) { $transient = 'breakdance_nonce_updated_' . $userLogin; set_transient($transient, 1, 0); } ); /** * Broadcast updated nonce to the builder on login * or if breakdanceRefreshSession parameter is set * * @return void */ function broadcastNonce() { if (!is_user_logged_in()) { return; } if (!\Breakdance\Permissions\hasPermission('full')) { return; } $currentUser = wp_get_current_user(); $transient = 'breakdance_nonce_updated_' . $currentUser->user_login; /** @var int|false $hasRefreshNonceTransient */ $hasRefreshNonceTransient = get_transient($transient); $hasRefreshNonceQueryParam = (bool) filter_input(INPUT_GET, 'breakdanceRefreshSession', FILTER_VALIDATE_BOOLEAN); if ($hasRefreshNonceQueryParam || $hasRefreshNonceTransient) { $nonce = \Breakdance\AJAX\get_nonce_for_ajax_requests(); $script = <<<JS const broadcastChannel = new BroadcastChannel('breakdance'); broadcastChannel.postMessage({event: 'nonceRefresh', nonce: '$nonce'}); broadcastChannel.close(); JS; wp_register_script('nonceRefreshBroadcast', ''); wp_enqueue_script('nonceRefreshBroadcast'); wp_add_inline_script('nonceRefreshBroadcast', $script, 'before'); delete_transient($transient); if ($hasRefreshNonceQueryParam) { add_action('admin_notices', static function () { echo '<div class="updated"><p>Your ' . __bdox('plugin_name') . ' session token has been refreshed</p></div>'; }); } } } add_action('admin_enqueue_scripts', '\Breakdance\AJAX\broadcastNonce'); class BreakdanceAjaxHandlerException extends \Exception { /** * @var string */ protected $statusDescription = ''; /** * @param string $message * @param int $code * @param \Throwable|null $previous * @param string $description */ public function __construct($message = "", $code = 0, \Throwable $previous = null, $description = '') { $this->statusDescription = $description; parent::__construct($message, $code, $previous); } /** * @return string */ public function getStatusDescription() { return $this->statusDescription; } } class BreakdanceAjaxHandlerCustomException extends BreakdanceAjaxHandlerException { } class HandlerNamesHolder { use \Breakdance\Singleton; /** * @var string[] */ public $handlerNames = []; /** * @param string $name * @return void */ public function add($name) { $this->handlerNames[] = $name; } }
Save