1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423: 424: 425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464: 465: 466: 467: 468: 469: 470:
<?php
/**
* Simple Lightweight Ajax Handler For WP Theme/Plugin Developers
*
* @author Varun Sridharan <varunsridharan23@gmail.com>
* @copyright 2018 Varun Sridharan
* @license GPLV3 Or Greater
*/
namespace Varunsridharan\WordPress;
if ( ! class_exists( '\Varunsridharan\WordPress\Ajaxer' ) ) {
/**
* Class Ajaxer
*
* @package Varunsridharan\WordPress
* @author Varun Sridharan <varunsridharan23@gmail.com>
* @since 1.0
*/
abstract class Ajaxer {
/**
* Ajax Action Prefix
*
* @example for wordpress_show_popup wordpress is the prefix
*
* @var string
*/
protected $action_prefix = '';
/**
* Ajax Action Surfix
*
* @example for wordpress_show_popup_data data is the surfix
*
* @var string
*/
protected $action_surfix = '';
/**
* Action Name
* provide value if all ajax requests runs in a single action key.
*
* @var string
*/
protected $action = '';
/**
* Array of ajax actions
*
* @example array('ajax_action_1' => true,'ajax_action_2' => false)
* if value set to true then it runs for both loggedout / logged in users
* if value set to false then it runs only for the logged in user
*
* @example array('ajax_action_1' => array('auth' => false,'callback' => array(CLASSNAME,METHODNAME)))
* if auth value set to true then it runs for both loggedout / logged in users
* if auth value set to false then it runs only for the logged in user
* callback can either be a string,array or a actual dynamic function.
*
* @var array
*/
protected $actions = array();
/**
* Set to true if plugin's ajax runs in a single action
* OR
* Set a custom key so convert plugin-slug=ajax-action into your-key=ajax-action
*
* @example Single Ajax Action :
* admin-ajax.php?action=plugin-slug&plugin-slug-action=ajax-action¶m1=value1¶m2=value=2
* Multiple Ajax Actions :
* admin-ajax.php?action=plugin-slug-ajax-action1¶m1=value1=param2=value2
*
* @example Single Ajax Action :
* admin-ajax.php?action=plugin-slug&custom-key-action=ajax-action¶m1=value1¶m2=value=2
*
* Multiple Ajax Actions:
* admin-ajax.php?action=plugin-slug-ajax-action1¶m1=value1=param2=value2
*
* @var bool
*/
protected $is_single = false;
/**
* Ajaxer constructor.
*/
public function __construct() {
if ( false !== $this->is_single ) {
\add_action( 'wp_ajax_' . $this->action, array( &$this, 'ajax_request_single' ) );
\add_action( 'wp_ajax_nopriv_' . $this->action, array( &$this, 'ajax_request_single' ) );
} else {
foreach ( $this->actions as $action => $nopriv ) {
\add_action( 'wp_ajax_' . $this->ajax_slug( $action ), array( &$this, 'ajax_request' ) );
if ( ( ! is_array( $nopriv ) && true === $nopriv ) || ( is_array( $nopriv ) && isset( $nopriv['auth'] ) && true === $nopriv['auth'] ) ) {
\add_action( 'wp_ajax_nopriv_' . $this->ajax_slug( $action ), array( &$this, 'ajax_request' ) );
}
}
}
}
/**
* Returns Modified Ajax Action Slug
*
* @param $action
*
* @return string
*/
final protected function ajax_slug( $action ) {
$action = ( ! empty( $this->action_prefix ) ) ? $this->action_prefix . '_' . $action : $action;
return ( ! empty( $this->action_surfix ) ) ? $action . '_' . $this->action_surfix : $action;
}
/**
* Triggers A Callback to a ajax request
*
* @hook ajax_before_{ajax_action}
* @hook ajax_after_{ajax_action}
*
* if method not exists then below hook fires
* @hook ajax_{ajax_action}
* ajax_action will be replaced with {$this->action}-action from url
*/
final public function ajax_request_single() {
$action = false;
$action_key = ( true === $this->is_single ) ? $this->action : $this->is_single;
if ( isset( $_REQUEST[ $action_key . '-action' ] ) && ! empty( $_REQUEST[ $action_key . '-action' ] ) ) {
$action = $_REQUEST[ $action_key . '-action' ];
} elseif ( isset( $_REQUEST[ $action_key ] ) && ! empty( $_REQUEST[ $action_key ] ) ) {
$action = $_REQUEST[ $action_key ];
}
$_action = $this->extract_action_slug( $action );
if ( false !== $action && isset( $this->actions[ $_action ] ) ) {
if ( false === $this->is_logged_in() && true === $this->actions[ $_action ] ) {
$this->trigger_ajax_callback( $action );
} elseif ( $this->is_logged_in() === true ) {
$this->trigger_ajax_callback( $action );
}
}
\wp_die( 0 );
}
/**
* Extracts Action Without Prefix / Surfix ($this->action_prefix | $this->action_surfix)
*
* @param $action
*
* @return string
*/
final protected function extract_action_slug( $action ) {
return trim( trim( str_replace( array(
$this->action_prefix,
$this->action_surfix,
), '', $action ), ' ' ), '_' );
}
/**
* Triggers A AjaxCallback
*
* @hook ajax_before_{ajax_action}
* @hook ajax_after_{ajax_action}
* if method not exists then below hook fires
* @hook ajax_{ajax_action}
*
* @param $action
*/
protected function trigger_ajax_callback( $action ) {
$_function_action = $this->extract_action_slug( $action );
$_function_name = str_replace( '-', '_', \sanitize_key( $_function_action ) );
if ( method_exists( $this, $_function_name ) ) {
\do_action( 'ajax_before_' . $action );
$this->$_function_name();
\do_action( 'ajax_after_' . $action );
} else {
\do_action( 'ajax_' . $action );
}
}
/**
* Handles Multiple Ajax Requests.
*/
final public function ajax_request() {
$action = ( isset( $_REQUEST['action'] ) && ! empty( $_REQUEST['action'] ) ) ? $_REQUEST['action'] : false;
$_action = $this->extract_action_slug( $action );
if ( false !== $action && isset( $this->actions[ $_action ] ) ) {
if ( is_array( $this->actions[ $_action ] ) && isset( $this->actions[ $_action ]['callback'] ) ) {
call_user_func( $this->actions[ $_action ]['callback'] );
\wp_die();
} else {
$this->trigger_ajax_callback( $_action );
}
}
\wp_die( 0 );
}
/**
* Checks / Returns the type of request method for the current request.
*
* @param string|array $type The type of request you want to check. If an array
* this method will return true if the request matches any type.
*
* @return string
*/
protected function request_type( $type = null ) {
$type = ( ! is_array( $type ) ) ? array( $type ) : $type;
if ( ! is_null( $type ) && is_array( $type ) ) {
return in_array( $_SERVER['REQUEST_METHOD'], array_map( 'strtoupper', $type ), true );
}
return $_SERVER['REQUEST_METHOD'];
}
/**
* Checks if Current Request Method Is GET
*
* @return string|bool|boolean
*/
public function is_get() {
return $this->request_type( 'GET' );
}
/**
* Checks if Current Request Method Is POST
*
* @return string|bool|boolean
*/
public function is_post() {
return $this->request_type( 'POST' );
}
/**
* Checks for the given key in the given method and returns it.
*
* @param $key
* @param $default
* @param $type
*
* @return mixed
*/
private function get_post_request( $key, $default, $type ) {
$return = $default;
if ( false !== $this->has( $key, $type ) ) {
switch ( $type ) {
case 'GET':
$return = $_GET[ $key ];
break;
case 'POST':
$return = $_POST[ $key ];
break;
case 'REQUEST':
$return = $_REQUEST[ $key ];
break;
default:
$return = $default;
break;
}
}
return $return;
}
/**
* Checks if given key exists in given request global array ($_GET/$_POST/$_REQUEST)
*
* @param string $key
* @param string $type
*
* @return bool
*/
protected function has( $key = '', $type = 'GET' ) {
switch ( $type ) {
case 'GET':
$has = ( isset( $_GET[ $key ] ) ) ? $_GET[ $key ] : false;
break;
case 'POST':
$has = ( isset( $_POST[ $key ] ) ) ? $_POST[ $key ] : false;
break;
default:
$has = ( isset( $_REQUEST[ $key ] ) ) ? $_REQUEST[ $key ] : false;
break;
}
return $has;
}
/**
* @param $key
*
* @return bool
*/
public function has_get( $key ) {
return $this->has( $key, 'GET' );
}
/**
* @param $key
*
* @return bool
*/
public function has_post( $key ) {
return $this->has( $key, 'POST' );
}
/**
* @param $key
*
* @return bool
*/
public function has_request( $key ) {
return $this->has( $key, 'REQUEST' );
}
/**
* Returns give key's value from $_GET
*
* @param string $key
* @param bool $default
*
* @return bool|mixed
*/
public function get( $key = '', $default = false ) {
return $this->get_post_request( $key, $default, 'GET' );
}
/**
* Returns give key's value from $_GET
*
* @param string $key
* @param bool $default
*
* @return bool|mixed
*/
public function post( $key = '', $default = false ) {
return $this->get_post_request( $key, $default, 'POST' );
}
/**
* Returns give key's value from $_REQUEST
*
* @param string $key
* @param bool $default
*
* @return bool|mixed
*/
public function request( $key = '', $default = false ) {
return $this->get_post_request( $key, $default, 'REQUEST' );
}
/**
* @param bool|string $error_title
* @param bool|string $error_message
*
* @return array
*/
protected function error_message( $error_title = false, $error_message = false ) {
return array(
'title' => $error_title,
'message' => $error_message,
);
}
/**
* @param bool|string $success_title
* @param bool|string $success_message
*
* @return array
*/
protected function success_message( $success_title = false, $success_message = false ) {
return array(
'title' => $success_title,
'message' => $success_message,
);
}
/**
* @param mixed $data
* @param null $status_code
*/
public function json_error( $data = null, $status_code = null ) {
wp_send_json_error( $data, $status_code );
}
/**
* @param mixed $data
* @param null $status_code
*/
public function json_success( $data = null, $status_code = null ) {
wp_send_json_success( $data, $status_code );
}
/**
* @param string $key
* @param string|bool $error_title
* @param string|bool $error_message
* @param string $type
*
* @return bool|mixed
*/
protected function validate( $key, $error_title = false, $error_message = false, $type = 'GET' ) {
if ( ( false === $key || false === $this->has( $key, $type ) ) || ( true === $this->has( $key, $type ) && empty( $this->get_post_request( $key, false, $type ) ) ) ) {
$this->json_error( $this->error_message( $error_title, $error_message ) );
return false;
}
return $this->get_post_request( $key, false, $type );
}
/**
* Sends WP Error.
*
* @param string|bool $error_title
* @param string|bool $error_message
* @param array $args
*/
public function error( $error_title = false, $error_message = false, $args = array() ) {
$this->json_error( wp_parse_args( $args, $this->error_message( $error_title, $error_message ) ) );
}
/**
* @param bool|string $success_title
* @param bool|string $success_message
* @param array $args
*/
public function success( $success_title = false, $success_message = false, $args = array() ) {
$this->json_success( wp_parse_args( $args, $this->success_message( $success_title, $success_message ) ) );
}
/**
* @param string $key
* @param string|bool $error_title
* @param string|bool $error_message
*
* @return bool|mixed
*/
public function validate_post( $key, $error_title = false, $error_message = false ) {
return $this->validate( $key, $error_title, $error_message, 'POST' );
}
/**
* @param string $key
* @param string|bool $error_title
* @param string|bool $error_message
*
* @return bool|mixed
*/
public function validate_get( $key, $error_title = false, $error_message = false ) {
return $this->validate( $key, $error_title, $error_message, 'GET' );
}
/**
* @param string $key
* @param string|bool $error_title
* @param string|bool $error_message
*
* @return bool|mixed
*/
public function validate_request( $key, $error_title = false, $error_message = false ) {
return $this->validate( $key, $error_title, $error_message, 'REQUEST' );
}
/**
* Checks if user is logged in.
*
* @return bool
*/
public function is_logged_in() {
return ( function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) ? true : false;
}
}
}