PluginProbe
Plugin Check (PCP) / 1.0.2
Plugin Check (PCP) v1.0.2
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.0.2, at includes/Admin/Admin_AJAX.php

324 lines 8.5 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 try {
116 $runner->set_check_slugs( $checks );
117 $runner->set_plugin( $plugin );
118
119 $checks_to_run = $runner->get_checks_to_run();
120 } catch ( Exception $error ) {
121 wp_send_json_error(
122 new WP_Error( 'invalid-request', $error->getMessage() ),
123 400
124 );
125 }
126
127 $message = __( 'No runtime checks, runtime environment was not setup.', 'plugin-check' );
128
129 if ( $this->has_runtime_check( $checks_to_run ) ) {
130 $runtime = new Runtime_Environment_Setup();
131 $runtime->set_up();
132 $message = __( 'Runtime environment setup successful.', 'plugin-check' );
133 }
134
135 wp_send_json_success(
136 array(
137 'message' => $message,
138 'plugin' => $plugin,
139 'checks' => $checks,
140 )
141 );
142 }
143
144 /**
145 * Handles the AJAX request to cleanup the runtime environment.
146 *
147 * @since 1.0.0
148 */
149 public function clean_up_environment() {
150 global $wpdb, $table_prefix;
151
152 // Verify the nonce before continuing.
153 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
154
155 if ( is_wp_error( $valid_request ) ) {
156 wp_send_json_error( $valid_request, 403 );
157 }
158
159 // Set the new prefix.
160 $old_prefix = $wpdb->set_prefix( $table_prefix . 'pc_' );
161
162 $message = __( 'Runtime environment was not prepared, cleanup was not run.', 'plugin-check' );
163
164 // Test if the runtime environment tables exist.
165 if ( $wpdb->posts === $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->posts ) ) || defined( 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION' ) ) {
166 $runtime = new Runtime_Environment_Setup();
167 $runtime->clean_up();
168 $message = __( 'Runtime environment cleanup successful.', 'plugin-check' );
169 }
170
171 // Restore the old prefix.
172 $wpdb->set_prefix( $old_prefix );
173
174 wp_send_json_success(
175 array(
176 'message' => $message,
177 )
178 );
179 }
180
181 /**
182 * Handles the AJAX request that returns the checks to run.
183 *
184 * @since 1.0.0
185 */
186 public function get_checks_to_run() {
187 // Verify the nonce before continuing.
188 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
189
190 if ( is_wp_error( $valid_request ) ) {
191 wp_send_json_error( $valid_request, 403 );
192 }
193
194 $categories = filter_input( INPUT_POST, 'categories', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
195 $categories = is_null( $categories ) ? array() : $categories;
196 $checks = filter_input( INPUT_POST, 'checks', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
197 $checks = is_null( $checks ) ? array() : $checks;
198 $plugin = filter_input( INPUT_POST, 'plugin', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
199 $runner = Plugin_Request_Utility::get_runner();
200
201 if ( is_null( $runner ) ) {
202 $runner = new AJAX_Runner();
203 }
204
205 // Make sure we are using the correct runner instance.
206 if ( ! ( $runner instanceof AJAX_Runner ) ) {
207 wp_send_json_error(
208 new WP_Error( 'invalid-runner', __( 'AJAX Runner was not initialized correctly.', 'plugin-check' ) ),
209 403
210 );
211 }
212
213 try {
214 $runner->set_check_slugs( $checks );
215 $runner->set_plugin( $plugin );
216 $runner->set_categories( $categories );
217
218 $plugin_basename = $runner->get_plugin_basename();
219 $checks_to_run = $runner->get_checks_to_run();
220 } catch ( Exception $error ) {
221 wp_send_json_error(
222 new WP_Error( 'invalid-checks', $error->getMessage() ),
223 403
224 );
225 }
226
227 wp_send_json_success(
228 array(
229 'plugin' => $plugin_basename,
230 'checks' => array_keys( $checks_to_run ),
231 )
232 );
233 }
234
235 /**
236 * Run checks.
237 *
238 * @since 1.0.0
239 */
240 public function run_checks() {
241 // Verify the nonce before continuing.
242 $valid_request = $this->verify_request( filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
243
244 if ( is_wp_error( $valid_request ) ) {
245 wp_send_json_error( $valid_request, 403 );
246 }
247
248 $runner = Plugin_Request_Utility::get_runner();
249
250 if ( is_null( $runner ) ) {
251 $runner = new AJAX_Runner();
252 }
253
254 // Make sure we are using the correct runner instance.
255 if ( ! ( $runner instanceof AJAX_Runner ) ) {
256 wp_send_json_error(
257 new WP_Error( 'invalid-runner', __( 'AJAX Runner was not initialized correctly.', 'plugin-check' ) ),
258 500
259 );
260 }
261
262 $checks = filter_input( INPUT_POST, 'checks', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
263 $checks = is_null( $checks ) ? array() : $checks;
264 $plugin = filter_input( INPUT_POST, 'plugin', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
265
266 try {
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