PluginProbe
Plugin Check (PCP) / 1.5.0
Plugin Check (PCP) v1.5.0
2.1.0 trunk 0.1 0.2.0 0.2.1 0.2.2 0.2.3 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 ci-artifacts
plugin-check / includes / Admin / Admin_AJAX.php

Admin_AJAX.php in Plugin Check (PCP) 1.5.0, at includes/Admin/Admin_AJAX.php

324 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class WordPress\Plugin_Check\Admin\Admin_AJAX
4 *
5 * @package plugin-check
6 */
7
8 namespace WordPress\Plugin_Check\Admin;
9
10 use Exception;
11 use WordPress\Plugin_Check\Checker\AJAX_Runner;
12 use WordPress\Plugin_Check\Checker\Runtime_Check;
13 use WordPress\Plugin_Check\Checker\Runtime_Environment_Setup;
14 use WordPress\Plugin_Check\Utilities\Plugin_Request_Utility;
15 use WP_Error;
16
17 /**
18 * Class to handle the Admin AJAX requests.
19 *
20 * @since 1.0.0
21 */
22 final class Admin_AJAX {
23
24 /**
25 * Nonce key.
26 *
27 * @since 1.0.0
28 * @var string
29 */
30 const NONCE_KEY = 'plugin-check-run-checks';
31
32 /**
33 * Clean up Runtime Environment action name.
34 *
35 * @since 1.0.0
36 * @var string
37 */
38 const ACTION_CLEAN_UP_ENVIRONMENT = 'plugin_check_clean_up_environment';
39
40 /**
41 * Set up Runtime Environment action name.
42 *
43 * @since 1.0.0
44 * @var string
45 */
46 const ACTION_SET_UP_ENVIRONMENT = 'plugin_check_set_up_environment';
47
48 /**
49 * Get Checks to run action name.
50 *
51 * @since 1.0.0
52 * @var string
53 */
54 const ACTION_GET_CHECKS_TO_RUN = 'plugin_check_get_checks_to_run';
55
56 /**
57 * Run Checks action name.
58 *
59 * @since 1.0.0
60 * @var string
61 */
62 const ACTION_RUN_CHECKS = 'plugin_check_run_checks';
63
64 /**
65 * Registers WordPress hooks for the Admin AJAX.
66 *
67 * @since 1.0.0
68 */
69 public function add_hooks() {
70 add_action( 'wp_ajax_' . self::ACTION_CLEAN_UP_ENVIRONMENT, array( $this, 'clean_up_environment' ) );
71 add_action( 'wp_ajax_' . self::ACTION_SET_UP_ENVIRONMENT, array( $this, 'set_up_environment' ) );
72 add_action( 'wp_ajax_' . self::ACTION_GET_CHECKS_TO_RUN, array( $this, 'get_checks_to_run' ) );
73 add_action( 'wp_ajax_' . self::ACTION_RUN_CHECKS, array( $this, 'run_checks' ) );
74 }
75
76 /**
77 * Creates and returns the nonce.
78 *
79 * @since 1.0.0
80 */
81 public function get_nonce() {
82 return wp_create_nonce( self::NONCE_KEY );
83 }
84
85 /**
86 * Handles the AJAX request to setup the runtime environment if needed.
87 *
88 * @since 1.0.0
89 */
90 public function set_up_environment() {
91 // Verify the nonce before continuing.
92 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
93
94 if ( is_wp_error( $valid_request ) ) {
95 wp_send_json_error( $valid_request, 403 );
96 }
97 $runner = Plugin_Request_Utility::get_runner();
98
99 if ( is_null( $runner ) ) {
100 $runner = new AJAX_Runner();
101 }
102
103 // Make sure we are using the correct runner instance.
104 if ( ! ( $runner instanceof AJAX_Runner ) ) {
105 wp_send_json_error(
106 new WP_Error( 'invalid-runner', __( 'AJAX Runner was not initialized correctly.', 'plugin-check' ) ),
107 500
108 );
109 }
110
111 $checks = filter_input( INPUT_POST, 'checks', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
112 $checks = is_null( $checks ) ? array() : $checks;
113 $plugin = filter_input( INPUT_POST, 'plugin', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
114
115 $include_experimental = 1 === filter_input( INPUT_POST, 'include-experimental', FILTER_VALIDATE_INT );
116
117 try {
118 $runner->set_experimental_flag( $include_experimental );
119 $runner->set_check_slugs( $checks );
120 $runner->set_plugin( $plugin );
121
122 $checks_to_run = $runner->get_checks_to_run();
123 } catch ( Exception $error ) {
124 wp_send_json_error(
125 new WP_Error( 'invalid-request', $error->getMessage() ),
126 400
127 );
128 }
129
130 $message = __( 'No runtime checks, runtime environment was not setup.', 'plugin-check' );
131
132 if ( $this->has_runtime_check( $checks_to_run ) ) {
133 $runtime = new Runtime_Environment_Setup();
134 $runtime->set_up();
135 $message = __( 'Runtime environment setup successful.', 'plugin-check' );
136 }
137
138 wp_send_json_success(
139 array(
140 'message' => $message,
141 'plugin' => $plugin,
142 'checks' => $checks,
143 )
144 );
145 }
146
147 /**
148 * Handles the AJAX request to cleanup the runtime environment.
149 *
150 * @since 1.0.0
151 */
152 public function clean_up_environment() {
153 // Verify the nonce before continuing.
154 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
155
156 if ( is_wp_error( $valid_request ) ) {
157 wp_send_json_error( $valid_request, 403 );
158 }
159
160 // Test if the runtime environment is prepared (and thus needs cleanup).
161 $runtime = new Runtime_Environment_Setup();
162 if ( $runtime->is_set_up() ) {
163 $runtime->clean_up();
164 $message = __( 'Runtime environment cleanup successful.', 'plugin-check' );
165 } else {
166 $message = __( 'Runtime environment was not prepared, cleanup was not run.', 'plugin-check' );
167 }
168
169 wp_send_json_success(
170 array(
171 'message' => $message,
172 )
173 );
174 }
175
176 /**
177 * Handles the AJAX request that returns the checks to run.
178 *
179 * @since 1.0.0
180 */
181 public function get_checks_to_run() {
182 // Verify the nonce before continuing.
183 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
184
185 if ( is_wp_error( $valid_request ) ) {
186 wp_send_json_error( $valid_request, 403 );
187 }
188
189 $categories = filter_input( INPUT_POST, 'categories', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
190 $categories = is_null( $categories ) ? array() : $categories;
191 $checks = filter_input( INPUT_POST, 'checks', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
192 $checks = is_null( $checks ) ? array() : $checks;
193 $plugin = filter_input( INPUT_POST, 'plugin', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
194 $include_experimental = 1 === filter_input( INPUT_POST, 'include-experimental', FILTER_VALIDATE_INT );
195 $runner = Plugin_Request_Utility::get_runner();
196
197 if ( is_null( $runner ) ) {
198 $runner = new AJAX_Runner();
199 }
200
201 // Make sure we are using the correct runner instance.
202 if ( ! ( $runner instanceof AJAX_Runner ) ) {
203 wp_send_json_error(
204 new WP_Error( 'invalid-runner', __( 'AJAX Runner was not initialized correctly.', 'plugin-check' ) ),
205 403
206 );
207 }
208
209 try {
210 $runner->set_experimental_flag( $include_experimental );
211 $runner->set_check_slugs( $checks );
212 $runner->set_plugin( $plugin );
213 $runner->set_categories( $categories );
214
215 $plugin_basename = $runner->get_plugin_basename();
216 $checks_to_run = $runner->get_checks_to_run();
217 } catch ( Exception $error ) {
218 wp_send_json_error(
219 new WP_Error( 'invalid-checks', $error->getMessage() ),
220 403
221 );
222 }
223
224 wp_send_json_success(
225 array(
226 'plugin' => $plugin_basename,
227 'checks' => array_keys( $checks_to_run ),
228 )
229 );
230 }
231
232 /**
233 * Run checks.
234 *
235 * @since 1.0.0
236 */
237 public function run_checks() {
238 // Verify the nonce before continuing.
239 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
240
241 if ( is_wp_error( $valid_request ) ) {
242 wp_send_json_error( $valid_request, 403 );
243 }
244
245 $runner = Plugin_Request_Utility::get_runner();
246
247 if ( is_null( $runner ) ) {
248 $runner = new AJAX_Runner();
249 }
250
251 // Make sure we are using the correct runner instance.
252 if ( ! ( $runner instanceof AJAX_Runner ) ) {
253 wp_send_json_error(
254 new WP_Error( 'invalid-runner', __( 'AJAX Runner was not initialized correctly.', 'plugin-check' ) ),
255 500
256 );
257 }
258
259 $checks = filter_input( INPUT_POST, 'checks', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
260 $checks = is_null( $checks ) ? array() : $checks;
261 $plugin = filter_input( INPUT_POST, 'plugin', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
262
263 $include_experimental = 1 === filter_input( INPUT_POST, 'include-experimental', FILTER_VALIDATE_INT );
264
265 try {
266 $runner->set_experimental_flag( $include_experimental );
267 $runner->set_check_slugs( $checks );
268 $runner->set_plugin( $plugin );
269 $results = $runner->run();
270 } catch ( Exception $error ) {
271 wp_send_json_error(
272 new WP_Error( 'invalid-request', $error->getMessage() ),
273 400
274 );
275 }
276
277 wp_send_json_success(
278 array(
279 'message' => __( 'Checks run successfully', 'plugin-check' ),
280 'errors' => $results->get_errors(),
281 'warnings' => $results->get_warnings(),
282 )
283 );
284 }
285
286 /**
287 * Verify the request.
288 *
289 * @since 1.0.0
290 *
291 * @param string $nonce The request nonce passed.
292 * @return bool|WP_Error True if the nonce is valid. WP_Error if invalid.
293 */
294 private function verify_request( $nonce ) {
295 if ( ! wp_verify_nonce( $nonce, self::NONCE_KEY ) ) {
296 return new WP_Error( 'invalid-nonce', __( 'Invalid nonce', 'plugin-check' ) );
297 }
298
299 if ( ! current_user_can( 'activate_plugins' ) ) {
300 return new WP_Error( 'invalid-permissions', __( 'Invalid user permissions, you are not allowed to perform this request.', 'plugin-check' ) );
301 }
302
303 return true;
304 }
305
306 /**
307 * Check for a Runtime_Check in a list of checks.
308 *
309 * @since 1.0.0
310 *
311 * @param array $checks An array of Check instances.
312 * @return bool True if a Runtime_Check exists in the array, false if not.
313 */
314 private function has_runtime_check( array $checks ) {
315 foreach ( $checks as $check ) {
316 if ( $check instanceof Runtime_Check ) {
317 return true;
318 }
319 }
320
321 return false;
322 }
323 }
324