PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / trunk
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! vtrunk
3.8.0 3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 All 112 releases
templately / includes / Utils / Response / AjaxResponder.php

AjaxResponder.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! trunk, at includes/Utils/Response/AjaxResponder.php

119 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Templately\Utils\Response;
4
5 use WP_Error;
6
7 /**
8 * Emits the SAME envelope over admin-ajax that REST emits (spec 043 / FR-001).
9 *
10 * The plugin talks to its frontend over two transports — REST and admin-ajax
11 * (the FSI/SSE paths) — and they historically disagreed on the response shape,
12 * which is why the client grew two error readers. They now emit a
13 * byte-identical body.
14 *
15 * The one deliberate difference is the HTTP status: admin-ajax always answers
16 * **200**, with the real status carried in `data.status`. A non-200 admin-ajax
17 * response is swallowed by some hosts' error pages and by the SSE reader, so
18 * the status has to travel in the body to survive the trip.
19 */
20 class AjaxResponder {
21
22 /**
23 * Nonce + capability gate for an admin-ajax handler (spec 043 / PRD PHP-5).
24 *
25 * Every `wp_ajax_templately_*` action ran its own inline copy of this check and
26 * answered with `wp_send_json_error( [ 'message' => 'Invalid nonce' ] )` — a
27 * bare string with no machine code, so the client could only tell an expired
28 * nonce from a missing capability by reading English prose. They are now
29 * distinct codes, and `INVALID_NONCE` is marked retryable so the existing
30 * asset-reload-and-retry path can recover from it automatically instead of
31 * showing the user an error for what is really a stale page.
32 *
33 * Sends the envelope and terminates on failure, exactly like the checks it
34 * replaces; returns true when the request may proceed.
35 *
36 * @param string $nonce_action
37 * @param string[] $capabilities ALL are required.
38 * @return bool
39 */
40 public static function guard( $nonce_action = 'templately_nonce', $capabilities = [] ) {
41 // This block IS the nonce verification — the value must be read before it
42 // can be checked — but it is still sanitized like any other input.
43 // phpcs:disable WordPress.Security.NonceVerification -- verifying the nonce is what this does.
44 $nonce = null;
45 if ( isset( $_POST['nonce'] ) ) {
46 $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ) );
47 }
48 if ( isset( $_GET['nonce'] ) ) {
49 $nonce = sanitize_text_field( wp_unslash( $_GET['nonce'] ) );
50 }
51 // phpcs:enable WordPress.Security.NonceVerification
52
53 if ( ! $nonce || ! wp_verify_nonce( $nonce, $nonce_action ) ) {
54 self::error( ErrorCode::INVALID_NONCE );
55 return false;
56 }
57
58 foreach ( $capabilities as $capability ) {
59 if ( ! current_user_can( $capability ) ) {
60 self::error( ErrorCode::FORBIDDEN );
61 return false;
62 }
63 }
64
65 return true;
66 }
67
68 /**
69 * @param mixed $data
70 * @param array $meta
71 * @return void
72 */
73 public static function success( $data = null, $meta = [] ) {
74 self::send( Envelope::success( $data, $meta ) );
75 }
76
77 /**
78 * @param TemplatelyError|WP_Error|string $error
79 * @param string $message
80 * @param array $data
81 * @return void
82 */
83 public static function error( $error, $message = '', $data = [] ) {
84 self::send( Envelope::error( $error, $message, $data ) );
85 }
86
87 /**
88 * The envelope, at HTTP 200, always.
89 *
90 * @param array $envelope
91 * @return void
92 */
93 public static function send( $envelope ) {
94 wp_send_json( $envelope, 200 );
95 }
96
97 /**
98 * Build the body without sending it — for SSE frames and for tests, which
99 * cannot survive `wp_send_json()`'s `die()`.
100 *
101 * @param mixed $data
102 * @param array $meta
103 * @return array
104 */
105 public static function success_body( $data = null, $meta = [] ) {
106 return Envelope::success( $data, $meta );
107 }
108
109 /**
110 * @param TemplatelyError|WP_Error|string $error
111 * @param string $message
112 * @param array $data
113 * @return array
114 */
115 public static function error_body( $error, $message = '', $data = [] ) {
116 return Envelope::error( $error, $message, $data );
117 }
118 }
119