class-acf-ajax.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // Exit if accessed directly
  4. }
  5. if ( ! class_exists( 'ACF_Ajax' ) ) :
  6. class ACF_Ajax {
  7. /** @var string The AJAX action name. */
  8. var $action = '';
  9. /** @var array The $_REQUEST data. */
  10. var $request;
  11. /** @var bool Prevents access for non-logged in users. */
  12. var $public = false;
  13. /**
  14. * __construct
  15. *
  16. * Sets up the class functionality.
  17. *
  18. * @date 31/7/18
  19. * @since 5.7.2
  20. *
  21. * @param void
  22. * @return void
  23. */
  24. function __construct() {
  25. $this->initialize();
  26. $this->add_actions();
  27. }
  28. /**
  29. * has
  30. *
  31. * Returns true if the request has data for the given key.
  32. *
  33. * @date 31/7/18
  34. * @since 5.7.2
  35. *
  36. * @param string $key The data key.
  37. * @return boolean
  38. */
  39. function has( $key = '' ) {
  40. return isset( $this->request[ $key ] );
  41. }
  42. /**
  43. * get
  44. *
  45. * Returns request data for the given key.
  46. *
  47. * @date 31/7/18
  48. * @since 5.7.2
  49. *
  50. * @param string $key The data key.
  51. * @return mixed
  52. */
  53. function get( $key = '' ) {
  54. return isset( $this->request[ $key ] ) ? $this->request[ $key ] : null;
  55. }
  56. /**
  57. * Sets request data for the given key.
  58. *
  59. * @date 31/7/18
  60. * @since 5.7.2
  61. *
  62. * @param string $key The data key.
  63. * @param mixed $value The data value.
  64. * @return ACF_Ajax
  65. */
  66. function set( $key = '', $value = null ) {
  67. $this->request[ $key ] = $value;
  68. return $this;
  69. }
  70. /**
  71. * initialize
  72. *
  73. * Allows easy access to modifying properties without changing constructor.
  74. *
  75. * @date 31/7/18
  76. * @since 5.7.2
  77. *
  78. * @param void
  79. * @return void
  80. */
  81. function initialize() {
  82. /* do nothing */
  83. }
  84. /**
  85. * add_actions
  86. *
  87. * Adds the ajax actions for this response.
  88. *
  89. * @date 31/7/18
  90. * @since 5.7.2
  91. *
  92. * @param void
  93. * @return void
  94. */
  95. function add_actions() {
  96. // add action for logged-in users
  97. add_action( "wp_ajax_{$this->action}", array( $this, 'request' ) );
  98. // add action for non logged-in users
  99. if ( $this->public ) {
  100. add_action( "wp_ajax_nopriv_{$this->action}", array( $this, 'request' ) );
  101. }
  102. }
  103. /**
  104. * request
  105. *
  106. * Callback for ajax action. Sets up properties and calls the get_response() function.
  107. *
  108. * @date 1/8/18
  109. * @since 5.7.2
  110. *
  111. * @param void
  112. * @return void
  113. */
  114. function request() {
  115. // Store data for has() and get() functions.
  116. $this->request = wp_unslash( $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Verified below in verify_request().
  117. // Verify request and handle error.
  118. $error = $this->verify_request( $this->request );
  119. if ( is_wp_error( $error ) ) {
  120. $this->send( $error );
  121. }
  122. // Send response.
  123. $this->send( $this->get_response( $this->request ) );
  124. }
  125. /**
  126. * Verifies the request.
  127. *
  128. * @date 9/3/20
  129. * @since 5.8.8
  130. *
  131. * @param array $request The request args.
  132. * @return (bool|WP_Error) True on success, WP_Error on fail.
  133. */
  134. function verify_request( $request ) {
  135. // Verify nonce.
  136. if ( ! acf_verify_ajax() ) {
  137. return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) );
  138. }
  139. return true;
  140. }
  141. /**
  142. * get_response
  143. *
  144. * Returns the response data to sent back.
  145. *
  146. * @date 31/7/18
  147. * @since 5.7.2
  148. *
  149. * @param array $request The request args.
  150. * @return mixed The response data or WP_Error.
  151. */
  152. function get_response( $request ) {
  153. return true;
  154. }
  155. /**
  156. * send
  157. *
  158. * Sends back JSON based on the $response as either success or failure.
  159. *
  160. * @date 31/7/18
  161. * @since 5.7.2
  162. *
  163. * @param mixed $response The response to send back.
  164. * @return void
  165. */
  166. function send( $response ) {
  167. // Return error.
  168. if ( is_wp_error( $response ) ) {
  169. $this->send_error( $response );
  170. // Return success.
  171. } else {
  172. wp_send_json( $response );
  173. }
  174. }
  175. /**
  176. * Sends a JSON response for the given WP_Error object.
  177. *
  178. * @date 8/3/20
  179. * @since 5.8.8
  180. *
  181. * @param WP_Error error The error object.
  182. * @return void
  183. */
  184. function send_error( $error ) {
  185. // Get error status
  186. $error_data = $error->get_error_data();
  187. if ( is_array( $error_data ) && isset( $error_data['status'] ) ) {
  188. $status_code = $error_data['status'];
  189. } else {
  190. $status_code = 500;
  191. }
  192. wp_send_json(
  193. array(
  194. 'code' => $error->get_error_code(),
  195. 'message' => $error->get_error_message(),
  196. 'data' => $error->get_error_data(),
  197. ),
  198. $status_code
  199. );
  200. }
  201. }
  202. endif; // class_exists check