PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 All 504 releases
← All changes | _inc/lib/debugger/class-jetpack-cxn-test-base.php +5 -538 13.7.216.3-a.1 View file →
@@ -1,551 +1,18 @@
1 1 <?php
2 2 /**
3 - * Base class for Jetpack's debugging tests.
3 + * Legacy base class for Jetpack's debugging tests.
4 4 *
5 + * @deprecated Use Connection_Health_Test_Base or Connection_Health_Tests from the connection package directly.
5 6 * @package automattic/jetpack
6 7 */
7 8
8 -use Automattic\Jetpack\Status;
9 +use Automattic\Jetpack\Connection\Connection_Health_Test_Base;
9 10
10 11 /**
11 - * Jetpack Connection Testing
12 - *
13 - * Framework for various "unit tests" against the Jetpack connection.
14 - *
15 - * Individual tests should be added to the class-jetpack-cxn-tests.php file.
16 - *
17 - * @author Brandon Kraft
18 - * @package automattic/jetpack
19 - */
20 -
21 -/**
22 12 * "Unit Tests" for the Jetpack connection.
23 13 *
24 14 * @since 7.1.0
15 + * @deprecated Use Connection_Health_Test_Base or Connection_Health_Tests from the connection package directly.
25 16 */
26 -class Jetpack_Cxn_Test_Base {
27 -
28 - /**
29 - * Tests to run on the Jetpack connection.
30 - *
31 - * @var array $tests
32 - */
33 - protected $tests = array();
34 -
35 - /**
36 - * Results of the Jetpack connection tests.
37 - *
38 - * @var array $results
39 - */
40 - protected $results = array();
41 -
42 - /**
43 - * Status of the testing suite.
44 - *
45 - * Used internally to determine if a test should be skipped since the tests are already failing. Assume passing.
46 - *
47 - * @var bool $pass
48 - */
49 - protected $pass = true;
50 -
51 - /**
52 - * Jetpack_Cxn_Test constructor.
53 - */
54 - public function __construct() {
55 - $this->tests = array();
56 - $this->results = array();
57 - }
58 -
59 - /**
60 - * Adds a new test to the Jetpack Connection Testing suite.
61 - *
62 - * @since 7.1.0
63 - * @since 7.3.0 Adds name parameter and returns WP_Error on failure.
64 - *
65 - * @param callable $callable Test to add to queue.
66 - * @param string $name Unique name for the test.
67 - * @param string $type Optional. Core Site Health type: 'direct' if test can be run during initial load or 'async' if test should run async.
68 - * @param array $groups Optional. Testing groups to add test to.
69 - *
70 - * @return mixed True if successfully added. WP_Error on failure.
71 - */
72 - public function add_test( $callable, $name, $type = 'direct', $groups = array( 'default' ) ) {
73 - if ( is_array( $name ) ) {
74 - // Pre-7.3.0 method passed the $groups parameter here.
75 - return new WP_Error( __( 'add_test arguments changed in 7.3.0. Please reference inline documentation.', 'jetpack' ) );
76 - }
77 - if ( array_key_exists( $name, $this->tests ) ) {
78 - return new WP_Error( __( 'Test names must be unique.', 'jetpack' ) );
79 - }
80 - if ( ! is_callable( $callable ) ) {
81 - return new WP_Error( __( 'Tests must be valid PHP callables.', 'jetpack' ) );
82 - }
83 -
84 - $this->tests[ $name ] = array(
85 - 'name' => $name,
86 - 'test' => $callable,
87 - 'group' => $groups,
88 - 'type' => $type,
89 - );
90 - return true;
91 - }
92 -
93 - /**
94 - * Lists all tests to run.
95 - *
96 - * @since 7.3.0
97 - *
98 - * @param string $type Optional. Core Site Health type: 'direct' or 'async'. All by default.
99 - * @param string $group Optional. A specific testing group. All by default.
100 - *
101 - * @return array $tests Array of tests with test information.
102 - */
103 - public function list_tests( $type = 'all', $group = 'all' ) {
104 - if ( ! ( 'all' === $type || 'direct' === $type || 'async' === $type ) ) {
105 - _doing_it_wrong( 'Jetpack_Cxn_Test_Base->list_tests', 'Type must be all, direct, or async', '7.3.0' );
106 - }
107 -
108 - $tests = array();
109 - foreach ( $this->tests as $name => $value ) {
110 - // Get all valid tests by group staged.
111 - if ( 'all' === $group || $group === $value['group'] ) {
112 - $tests[ $name ] = $value;
113 - }
114 -
115 - // Next filter out any that do not match the type.
116 - if ( 'all' !== $type && $type !== $value['type'] ) {
117 - unset( $tests[ $name ] );
118 - }
119 - }
120 -
121 - return $tests;
122 - }
123 -
124 - /**
125 - * Run a specific test.
126 - *
127 - * @since 7.3.0
128 - *
129 - * @param string $name Name of test.
130 - *
131 - * @return mixed $result Test result array or WP_Error if invalid name. {
132 - * @type string $name Test name
133 - * @type mixed $pass True if passed, false if failed, 'skipped' if skipped.
134 - * @type string $message Human-readable test result message.
135 - * @type string $resolution Human-readable resolution steps.
136 - * }
137 - */
138 - public function run_test( $name ) {
139 - if ( array_key_exists( $name, $this->tests ) ) {
140 - return call_user_func( $this->tests[ $name ]['test'] );
141 - }
142 - return new WP_Error( __( 'There is no test by that name: ', 'jetpack' ) . $name );
143 - }
144 -
145 - /**
146 - * Runs the Jetpack connection suite.
147 - */
148 - public function run_tests() {
149 - foreach ( $this->tests as $test ) {
150 - $result = call_user_func( $test['test'] );
151 - $result['group'] = $test['group'];
152 - $result['type'] = $test['type'];
153 - $this->results[] = $result;
154 - if ( false === $result['pass'] ) {
155 - $this->pass = false;
156 - }
157 - }
158 - }
159 -
160 - /**
161 - * Returns the full results array.
162 - *
163 - * @since 7.1.0
164 - * @since 7.3.0 Add 'type'
165 - *
166 - * @param string $type Test type, async or direct.
167 - * @param string $group Testing group whose results we want. Defaults to all tests.
168 - * @return array Array of test results.
169 - */
170 - public function raw_results( $type = 'all', $group = 'all' ) {
171 - if ( ! $this->results ) {
172 - $this->run_tests();
173 - }
174 -
175 - $results = $this->results;
176 -
177 - if ( 'all' !== $group ) {
178 - foreach ( $results as $test => $result ) {
179 - if ( ! in_array( $group, $result['group'], true ) ) {
180 - unset( $results[ $test ] );
181 - }
182 - }
183 - }
184 -
185 - if ( 'all' !== $type ) {
186 - foreach ( $results as $test => $result ) {
187 - if ( $type !== $result['type'] ) {
188 - unset( $results[ $test ] );
189 - }
190 - }
191 - }
192 -
193 - return $results;
194 - }
195 -
196 - /**
197 - * Returns the status of the connection suite.
198 - *
199 - * @since 7.1.0
200 - * @since 7.3.0 Add 'type'
201 - *
202 - * @param string $type Test type, async or direct. Optional, direct all tests.
203 - * @param string $group Testing group to check status of. Optional, default all tests.
204 - *
205 - * @return true|array True if all tests pass. Array of failed tests.
206 - */
207 - public function pass( $type = 'all', $group = 'all' ) {
208 - $results = $this->raw_results( $type, $group );
209 -
210 - foreach ( $results as $result ) {
211 - // 'pass' could be true, false, or 'skipped'. We only want false.
212 - if ( isset( $result['pass'] ) && false === $result['pass'] ) {
213 - return false;
214 - }
215 - }
216 -
217 - return true;
218 - }
219 -
220 - /**
221 - * Return array of failed test messages.
222 - *
223 - * @since 7.1.0
224 - * @since 7.3.0 Add 'type'
225 - *
226 - * @param string $type Test type, direct or async.
227 - * @param string $group Testing group whose failures we want. Defaults to "all".
228 - *
229 - * @return false|array False if no failed tests. Otherwise, array of failed tests.
230 - */
231 - public function list_fails( $type = 'all', $group = 'all' ) {
232 - $results = $this->raw_results( $type, $group );
233 -
234 - foreach ( $results as $test => $result ) {
235 - // We do not want tests that passed or ones that are misconfigured (no pass status or no failure message).
236 - if ( ! isset( $result['pass'] ) || false !== $result['pass'] || ! isset( $result['short_description'] ) ) {
237 - unset( $results[ $test ] );
238 - }
239 - }
240 -
241 - return $results;
242 - }
243 -
244 - /**
245 - * Helper function to return consistent responses for a passing test.
246 - * Possible Args:
247 - * - name: string The raw method name that runs the test. Default 'unnamed_test'.
248 - * - label: bool|string If false, tests will be labeled with their `name`. You can pass a string to override this behavior. Default false.
249 - * - short_description: bool|string A brief, non-html description that will appear in CLI results. Default 'Test passed!'.
250 - * - long_description: bool|string An html description that will appear in the site health page. Default false.
251 - * - severity: bool|string 'critical', 'recommended', or 'good'. Default: false.
252 - * - action: bool|string A URL for the recommended action. Default: false
253 - * - action_label: bool|string The label for the recommended action. Default: false
254 - * - show_in_site_health: bool True if the test should be shown on the Site Health page. Default: true
255 - *
256 - * @param array $args Arguments to override defaults.
257 - *
258 - * @return array Test results.
259 - */
260 - public static function passing_test( $args ) {
261 - $defaults = self::test_result_defaults();
262 - $defaults['short_description'] = __( 'Test passed!', 'jetpack' );
263 -
264 - $args = wp_parse_args( $args, $defaults );
265 -
266 - $args['pass'] = true;
267 -
268 - return $args;
269 - }
270 -
271 - /**
272 - * Helper function to return consistent responses for a skipped test.
273 - * Possible Args:
274 - * - name: string The raw method name that runs the test. Default unnamed_test.
275 - * - label: bool|string If false, tests will be labeled with their `name`. You can pass a string to override this behavior. Default false.
276 - * - short_description: bool|string A brief, non-html description that will appear in CLI results, and as headings in admin UIs. Default false.
277 - * - long_description: bool|string An html description that will appear in the site health page. Default false.
278 - * - severity: bool|string 'critical', 'recommended', or 'good'. Default: false.
279 - * - action: bool|string A URL for the recommended action. Default: false
280 - * - action_label: bool|string The label for the recommended action. Default: false
281 - * - show_in_site_health: bool True if the test should be shown on the Site Health page. Default: true
282 - *
283 - * @param array $args Arguments to override defaults.
284 - *
285 - * @return array Test results.
286 - */
287 - public static function skipped_test( $args = array() ) {
288 - $args = wp_parse_args(
289 - $args,
290 - self::test_result_defaults()
291 - );
292 -
293 - $args['pass'] = 'skipped';
294 -
295 - return $args;
296 - }
297 -
298 - /**
299 - * Helper function to return consistent responses for an informational test.
300 - * Possible Args:
301 - * - name: string The raw method name that runs the test. Default unnamed_test.
302 - * - label: bool|string If false, tests will be labeled with their `name`. You can pass a string to override this behavior. Default false.
303 - * - short_description: bool|string A brief, non-html description that will appear in CLI results, and as headings in admin UIs. Default false.
304 - * - long_description: bool|string An html description that will appear in the site health page. Default false.
305 - * - severity: bool|string 'critical', 'recommended', or 'good'. Default: false.
306 - * - action: bool|string A URL for the recommended action. Default: false
307 - * - action_label: bool|string The label for the recommended action. Default: false
308 - * - show_in_site_health: bool True if the test should be shown on the Site Health page. Default: true
309 - *
310 - * @param array $args Arguments to override defaults.
311 - *
312 - * @return array Test results.
313 - */
314 - public static function informational_test( $args = array() ) {
315 - $args = wp_parse_args(
316 - $args,
317 - self::test_result_defaults()
318 - );
319 -
320 - $args['pass'] = 'informational';
321 -
322 - return $args;
323 - }
324 -
325 - /**
326 - * Helper function to return consistent responses for a failing test.
327 - * Possible Args:
328 - * - name: string The raw method name that runs the test. Default unnamed_test.
329 - * - label: bool|string If false, tests will be labeled with their `name`. You can pass a string to override this behavior. Default false.
330 - * - short_description: bool|string A brief, non-html description that will appear in CLI results, and as headings in admin UIs. Default 'Test failed!'.
331 - * - long_description: bool|string An html description that will appear in the site health page. Default false.
332 - * - severity: bool|string 'critical', 'recommended', or 'good'. Default: 'critical'.
333 - * - action: bool|string A URL for the recommended action. Default: false.
334 - * - action_label: bool|string The label for the recommended action. Default: false.
335 - * - show_in_site_health: bool True if the test should be shown on the Site Health page. Default: true
336 - *
337 - * @since 7.1.0
338 - *
339 - * @param array $args Arguments to override defaults.
340 - *
341 - * @return array Test results.
342 - */
343 - public static function failing_test( $args ) {
344 - $defaults = self::test_result_defaults();
345 - $defaults['short_description'] = __( 'Test failed!', 'jetpack' );
346 - $defaults['severity'] = 'critical';
347 -
348 - $args = wp_parse_args( $args, $defaults );
349 -
350 - $args['pass'] = false;
351 -
352 - return $args;
353 - }
354 -
355 - /**
356 - * Provides defaults for test arguments.
357 - *
358 - * @since 8.5.0
359 - *
360 - * @return array Result defaults.
361 - */
362 - private static function test_result_defaults() {
363 - return array(
364 - 'name' => 'unnamed_test',
365 - 'label' => false,
366 - 'short_description' => false,
367 - 'long_description' => false,
368 - 'severity' => false,
369 - 'action' => false,
370 - 'action_label' => false,
371 - 'show_in_site_health' => true,
372 - );
373 - }
374 -
375 - /**
376 - * Provide WP_CLI friendly testing results.
377 - *
378 - * @since 7.1.0
379 - * @since 7.3.0 Add 'type'
380 - *
381 - * @param string $type Test type, direct or async.
382 - * @param string $group Testing group whose results we are outputting. Default all tests.
383 - */
384 - public function output_results_for_cli( $type = 'all', $group = 'all' ) {
385 - if ( defined( 'WP_CLI' ) && WP_CLI ) {
386 - if ( ( new Status() )->is_offline_mode() ) {
387 - WP_CLI::line( __( 'Jetpack is in Offline Mode:', 'jetpack' ) );
388 - WP_CLI::line( Jetpack::development_mode_trigger_text() );
389 - }
390 - WP_CLI::line( __( 'TEST RESULTS:', 'jetpack' ) );
391 - foreach ( $this->raw_results( $group ) as $test ) {
392 - if ( true === $test['pass'] ) {
393 - WP_CLI::log( WP_CLI::colorize( '%gPassed:%n ' . $test['name'] ) );
394 - } elseif ( 'skipped' === $test['pass'] ) {
395 - WP_CLI::log( WP_CLI::colorize( '%ySkipped:%n ' . $test['name'] ) );
396 - if ( $test['short_description'] ) {
397 - WP_CLI::log( ' ' . $test['short_description'] ); // Number of spaces to "tab indent" the reason.
398 - }
399 - } elseif ( 'informational' === $test['pass'] ) {
400 - WP_CLI::log( WP_CLI::colorize( '%yInfo:%n ' . $test['name'] ) );
401 - if ( $test['short_description'] ) {
402 - WP_CLI::log( ' ' . $test['short_description'] ); // Number of spaces to "tab indent" the reason.
403 - }
404 - } else { // Failed.
405 - WP_CLI::log( WP_CLI::colorize( '%rFailed:%n ' . $test['name'] ) );
406 - WP_CLI::log( ' ' . $test['short_description'] ); // Number of spaces to "tab indent" the reason.
407 - }
408 - }
409 - }
410 - }
411 -
412 - /**
413 - * Output results of failures in format expected by Core's Site Health tool for async tests.
414 - *
415 - * Specifically not asking for a testing group since we're opinionated that Site Heath should see all.
416 - *
417 - * @since 7.3.0
418 - *
419 - * @return array Array of test results
420 - */
421 - public function output_results_for_core_async_site_health() {
422 - $result = array(
423 - 'label' => __( 'Jetpack passed all async tests.', 'jetpack' ),
424 - 'status' => 'good',
425 - 'badge' => array(
426 - 'label' => __( 'Jetpack', 'jetpack' ),
427 - 'color' => 'green',
428 - ),
429 - 'description' => sprintf(
430 - '<p>%s</p>',
431 - __( "Jetpack's async local testing suite passed all tests!", 'jetpack' )
432 - ),
433 - 'actions' => '',
434 - 'test' => 'jetpack_debugger_local_testing_suite_core',
435 - );
436 -
437 - if ( $this->pass() ) {
438 - return $result;
439 - }
440 -
441 - $fails = $this->list_fails( 'async' );
442 - $error = false;
443 - foreach ( $fails as $fail ) {
444 - if ( ! $error ) {
445 - $error = true;
446 - $result['label'] = $fail['message'];
447 - $result['status'] = $fail['severity'];
448 - $result['description'] = sprintf(
449 - '<p>%s</p>',
450 - $fail['resolution']
451 - );
452 - if ( ! empty( $fail['action'] ) ) {
453 - $result['actions'] = sprintf(
454 - '<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
455 - esc_url( $fail['action'] ),
456 - __( 'Resolve', 'jetpack' ),
457 - /* translators: accessibility text */
458 - __( '(opens in a new tab)', 'jetpack' )
459 - );
460 - }
461 - } else {
462 - $result['description'] .= sprintf(
463 - '<p>%s</p>',
464 - __( 'There was another problem:', 'jetpack' )
465 - ) . ' ' . $fail['message'] . ': ' . $fail['resolution'];
466 - if ( 'critical' === $fail['severity'] ) { // In case the initial failure is only "recommended".
467 - $result['status'] = 'critical';
468 - }
469 - }
470 - }
471 -
472 - return $result;
473 - }
474 -
475 - /**
476 - * Provide single WP Error instance of all failures.
477 - *
478 - * @since 7.1.0
479 - * @since 7.3.0 Add 'type'
480 - *
481 - * @param string $type Test type, direct or async.
482 - * @param string $group Testing group whose failures we want converted. Default all tests.
483 - *
484 - * @return WP_Error|false WP_Error with all failed tests or false if there were no failures.
485 - */
486 - public function output_fails_as_wp_error( $type = 'all', $group = 'all' ) {
487 - if ( $this->pass( $group ) ) {
488 - return false;
489 - }
490 - $fails = $this->list_fails( $type, $group );
491 - $error = false;
492 -
493 - foreach ( $fails as $result ) {
494 - $code = 'failed_' . $result['name'];
495 - $message = $result['short_description'];
496 - $data = array(
497 - 'resolution' => $result['action'] ?
498 - $result['action_label'] . ' :' . $result['action'] :
499 - '',
500 - );
501 - if ( ! $error ) {
502 - $error = new WP_Error( $code, $message, $data );
503 - } else {
504 - $error->add( $code, $message, $data );
505 - }
506 - }
507 -
508 - return $error;
509 - }
510 -
511 - /**
512 - * Encrypt data for sending to WordPress.com.
513 - *
514 - * @todo When PHP minimum is 5.3+, add cipher detection to use an agreed better cipher than RC4. RC4 should be the last resort.
515 - *
516 - * @param string $data Data to encrypt with the WP.com Public Key.
517 - *
518 - * @return false|array False if functionality not available. Array of encrypted data, encryption key.
519 - */
520 - public function encrypt_string_for_wpcom( $data ) {
521 - $return = false;
522 - if ( ! function_exists( 'openssl_get_publickey' ) || ! function_exists( 'openssl_seal' ) ) {
523 - return $return;
524 - }
525 -
526 - $public_key = openssl_get_publickey( JETPACK__DEBUGGER_PUBLIC_KEY );
527 -
528 - // Select the first allowed cipher method.
529 - $allowed_methods = array( 'aes-256-ctr', 'aes-256-cbc' );
530 - $methods = array_intersect( $allowed_methods, openssl_get_cipher_methods() );
531 - $method = array_shift( $methods );
532 -
533 - $iv = '';
534 - if ( $public_key && $method && openssl_seal( $data, $encrypted_data, $env_key, array( $public_key ), $method, $iv ) ) {
535 - // We are returning base64-encoded values to ensure they're characters we can use in JSON responses without issue.
536 - $return = array(
537 - 'data' => base64_encode( $encrypted_data ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
538 - 'key' => base64_encode( $env_key[0] ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
539 - 'iv' => base64_encode( $iv ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
540 - 'cipher' => strtoupper( $method ),
541 - );
542 - }
543 -
544 - // openssl_free_key was deprecated as no longer needed in PHP 8.0+. Can remove when PHP 8.0 is our minimum. (lol).
545 - if ( PHP_VERSION_ID < 80000 ) {
546 - openssl_free_key( $public_key ); // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.openssl_free_keyDeprecated, Generic.PHP.DeprecatedFunctions.Deprecated
547 - }
548 -
549 - return $return;
550 - }
17 +class Jetpack_Cxn_Test_Base extends Connection_Health_Test_Base {
551 18 }