1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Jetpack Debug Data for the legacy Jetpack debugger page and the WP 5.2-era Site Health sections. |
4
|
|
|
* |
5
|
|
|
* @package Automattic/jetpack-debugger |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Automattic\Jetpack\Debugger; |
9
|
|
|
|
10
|
|
|
use Automattic\Jetpack\Constants; |
11
|
|
|
use Automattic\Jetpack\Sync\Modules; |
12
|
|
|
use Automattic\Jetpack\Sync\Functions; |
13
|
|
|
use Automattic\Jetpack\Sync\Sender; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Class Jetpack_Debug_Data |
17
|
|
|
* |
18
|
|
|
* Collect and return debug data for Jetpack. |
19
|
|
|
* |
20
|
|
|
* @since 7.3.0 |
21
|
|
|
*/ |
22
|
|
|
class Data { |
23
|
|
|
/** |
24
|
|
|
* Determine the active plan and normalize it for the debugger results. |
25
|
|
|
* |
26
|
|
|
* @since 7.3.0 |
27
|
|
|
* |
28
|
|
|
* @return string The plan slug. |
29
|
|
|
*/ |
30
|
|
|
public static function what_jetpack_plan() { |
31
|
|
|
$plan = \Jetpack_Plan::get(); |
32
|
|
|
return ! empty( $plan['class'] ) ? $plan['class'] : 'undefined'; |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Convert seconds to human readable time. |
37
|
|
|
* |
38
|
|
|
* A dedication function instead of using Core functionality to allow for output in seconds. |
39
|
|
|
* |
40
|
|
|
* @since 7.3.0 |
41
|
|
|
* |
42
|
|
|
* @param int $seconds Number of seconds to convert to human time. |
43
|
|
|
* |
44
|
|
|
* @return string Human readable time. |
45
|
|
|
*/ |
46
|
|
|
public static function seconds_to_time( $seconds ) { |
47
|
|
|
$seconds = intval( $seconds ); |
48
|
|
|
$units = array( |
49
|
|
|
'week' => WEEK_IN_SECONDS, |
50
|
|
|
'day' => DAY_IN_SECONDS, |
51
|
|
|
'hour' => HOUR_IN_SECONDS, |
52
|
|
|
'minute' => MINUTE_IN_SECONDS, |
53
|
|
|
'second' => 1, |
54
|
|
|
); |
55
|
|
|
// specifically handle zero. |
56
|
|
|
if ( 0 === $seconds ) { |
57
|
|
|
return '0 seconds'; |
58
|
|
|
} |
59
|
|
|
$human_readable = ''; |
60
|
|
|
foreach ( $units as $name => $divisor ) { |
61
|
|
|
$quot = intval( $seconds / $divisor ); |
62
|
|
|
if ( $quot ) { |
63
|
|
|
$human_readable .= "$quot $name"; |
64
|
|
|
$human_readable .= ( abs( $quot ) > 1 ? 's' : '' ) . ', '; |
65
|
|
|
$seconds -= $quot * $divisor; |
66
|
|
|
} |
67
|
|
|
} |
68
|
|
|
return substr( $human_readable, 0, -2 ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Return debug data in the format expected by Core's Site Health Info tab. |
73
|
|
|
* |
74
|
|
|
* @since 7.3.0 |
75
|
|
|
* |
76
|
|
|
* @param array $debug { |
77
|
|
|
* The debug information already compiled by Core. |
78
|
|
|
* |
79
|
|
|
* @type string $label The title for this section of the debug output. |
80
|
|
|
* @type string $description Optional. A description for your information section which may contain basic HTML |
81
|
|
|
* markup: `em`, `strong` and `a` for linking to documentation or putting emphasis. |
82
|
|
|
* @type boolean $show_count Optional. If set to `true` the amount of fields will be included in the title for |
83
|
|
|
* this section. |
84
|
|
|
* @type boolean $private Optional. If set to `true` the section and all associated fields will be excluded |
85
|
|
|
* from the copy-paste text area. |
86
|
|
|
* @type array $fields { |
87
|
|
|
* An associative array containing the data to be displayed. |
88
|
|
|
* |
89
|
|
|
* @type string $label The label for this piece of information. |
90
|
|
|
* @type string $value The output that is of interest for this field. |
91
|
|
|
* @type boolean $private Optional. If set to `true` the field will not be included in the copy-paste text area |
92
|
|
|
* on top of the page, allowing you to show, for example, API keys here. |
93
|
|
|
* } |
94
|
|
|
* } |
95
|
|
|
* |
96
|
|
|
* @return array $args Debug information in the same format as the initial argument. |
97
|
|
|
*/ |
98
|
|
|
public static function core_debug_data( $debug ) { |
99
|
|
|
$support_url = \Jetpack::is_development_version() |
100
|
|
|
? 'https://jetpack.com/contact-support/beta-group/' |
101
|
|
|
: 'https://jetpack.com/contact-support/'; |
102
|
|
|
|
103
|
|
|
$jetpack = array( |
104
|
|
|
'jetpack' => array( |
105
|
|
|
'label' => __( 'Jetpack', 'jetpack' ), |
106
|
|
|
'description' => sprintf( |
107
|
|
|
/* translators: %1$s is URL to jetpack.com's contact support page. %2$s accessibility text */ |
108
|
|
|
__( |
109
|
|
|
'Diagnostic information helpful to <a href="%1$s" target="_blank" rel="noopener noreferrer">your Jetpack Happiness team<span class="screen-reader-text">%2$s</span></a>', |
110
|
|
|
'jetpack' |
111
|
|
|
), |
112
|
|
|
esc_url( $support_url ), |
113
|
|
|
__( '(opens in a new tab)', 'jetpack' ) |
114
|
|
|
), |
115
|
|
|
'fields' => self::debug_data(), |
116
|
|
|
), |
117
|
|
|
); |
118
|
|
|
$debug = array_merge( $debug, $jetpack ); |
119
|
|
|
return $debug; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Compile and return array of debug information. |
124
|
|
|
* |
125
|
|
|
* @since 7.3.0 |
126
|
|
|
* |
127
|
|
|
* @return array $args { |
128
|
|
|
* Associated array of arrays with the following. |
129
|
|
|
* @type string $label The label for this piece of information. |
130
|
|
|
* @type string $value The output that is of interest for this field. |
131
|
|
|
* @type boolean $private Optional. Set to true if data is sensitive (API keys, etc). |
132
|
|
|
* } |
133
|
|
|
*/ |
134
|
|
|
public static function debug_data() { |
135
|
|
|
$debug_info = array(); |
136
|
|
|
|
137
|
|
|
/* Add various important Jetpack options */ |
138
|
|
|
$debug_info['site_id'] = array( |
139
|
|
|
'label' => 'Jetpack Site ID', |
140
|
|
|
'value' => \Jetpack_Options::get_option( 'id' ), |
141
|
|
|
'private' => false, |
142
|
|
|
); |
143
|
|
|
$debug_info['ssl_cert'] = array( |
144
|
|
|
'label' => 'Jetpack SSL Verfication Bypass', |
145
|
|
|
'value' => ( \Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' ) ) ? 'Yes' : 'No', |
146
|
|
|
'private' => false, |
147
|
|
|
); |
148
|
|
|
$debug_info['time_diff'] = array( |
149
|
|
|
'label' => "Offset between Jetpack server's time and this server's time.", |
150
|
|
|
'value' => \Jetpack_Options::get_option( 'time_diff' ), |
151
|
|
|
'private' => false, |
152
|
|
|
); |
153
|
|
|
$debug_info['version_option'] = array( |
154
|
|
|
'label' => 'Current Jetpack Version Option', |
155
|
|
|
'value' => \Jetpack_Options::get_option( 'version' ), |
156
|
|
|
'private' => false, |
157
|
|
|
); |
158
|
|
|
$debug_info['old_version'] = array( |
159
|
|
|
'label' => 'Previous Jetpack Version', |
160
|
|
|
'value' => \Jetpack_Options::get_option( 'old_version' ), |
161
|
|
|
'private' => false, |
162
|
|
|
); |
163
|
|
|
$debug_info['public'] = array( |
164
|
|
|
'label' => 'Jetpack Site Public', |
165
|
|
|
'value' => ( \Jetpack_Options::get_option( 'public' ) ) ? 'Public' : 'Private', |
166
|
|
|
'private' => false, |
167
|
|
|
); |
168
|
|
|
$debug_info['master_user'] = array( |
169
|
|
|
'label' => 'Jetpack Master User', |
170
|
|
|
'value' => self::human_readable_master_user(), |
171
|
|
|
'private' => false, |
172
|
|
|
); |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Token information is private, but awareness if there one is set is helpful. |
176
|
|
|
* |
177
|
|
|
* To balance out information vs privacy, we only display and include the "key", |
178
|
|
|
* which is a segment of the token prior to a period within the token and is |
179
|
|
|
* technically not private. |
180
|
|
|
* |
181
|
|
|
* If a token does not contain a period, then it is malformed and we report it as such. |
182
|
|
|
*/ |
183
|
|
|
$user_id = get_current_user_id(); |
184
|
|
|
$blog_token = \Jetpack_Data::get_access_token(); |
|
|
|
|
185
|
|
|
$user_token = \Jetpack_Data::get_access_token( $user_id ); |
|
|
|
|
186
|
|
|
|
187
|
|
|
$tokenset = ''; |
188
|
|
View Code Duplication |
if ( $blog_token ) { |
189
|
|
|
$tokenset = 'Blog '; |
190
|
|
|
$blog_key = substr( $blog_token->secret, 0, strpos( $blog_token->secret, '.' ) ); |
191
|
|
|
// Intentionally not translated since this is helpful when sent to Happiness. |
192
|
|
|
$blog_key = ( $blog_key ) ? $blog_key : 'Potentially Malformed Token.'; |
193
|
|
|
} |
194
|
|
View Code Duplication |
if ( $user_token ) { |
195
|
|
|
$tokenset .= 'User'; |
196
|
|
|
$user_key = substr( $user_token->secret, 0, strpos( $user_token->secret, '.' ) ); |
197
|
|
|
// Intentionally not translated since this is helpful when sent to Happiness. |
198
|
|
|
$user_key = ( $user_key ) ? $user_key : 'Potentially Malformed Token.'; |
199
|
|
|
} |
200
|
|
|
if ( ! $tokenset ) { |
201
|
|
|
$tokenset = 'None'; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
$debug_info['current_user'] = array( |
205
|
|
|
'label' => 'Current User', |
206
|
|
|
'value' => self::human_readable_user( $user_id ), |
207
|
|
|
'private' => false, |
208
|
|
|
); |
209
|
|
|
$debug_info['tokens_set'] = array( |
210
|
|
|
'label' => 'Tokens defined', |
211
|
|
|
'value' => $tokenset, |
212
|
|
|
'private' => false, |
213
|
|
|
); |
214
|
|
|
$debug_info['blog_token'] = array( |
215
|
|
|
'label' => 'Blog Public Key', |
216
|
|
|
'value' => ( $blog_token ) ? $blog_key : 'Not set.', |
|
|
|
|
217
|
|
|
'private' => false, |
218
|
|
|
); |
219
|
|
|
$debug_info['user_token'] = array( |
220
|
|
|
'label' => 'User Public Key', |
221
|
|
|
'value' => ( $user_token ) ? $user_key : 'Not set.', |
|
|
|
|
222
|
|
|
'private' => false, |
223
|
|
|
); |
224
|
|
|
|
225
|
|
|
/** Jetpack Environmental Information */ |
226
|
|
|
$debug_info['version'] = array( |
227
|
|
|
'label' => 'Jetpack Version', |
228
|
|
|
'value' => JETPACK__VERSION, |
229
|
|
|
'private' => false, |
230
|
|
|
); |
231
|
|
|
$debug_info['jp_plugin_dir'] = array( |
232
|
|
|
'label' => 'Jetpack Directory', |
233
|
|
|
'value' => JETPACK__PLUGIN_DIR, |
234
|
|
|
'private' => false, |
235
|
|
|
); |
236
|
|
|
$debug_info['plan'] = array( |
237
|
|
|
'label' => 'Plan Type', |
238
|
|
|
'value' => self::what_jetpack_plan(), |
239
|
|
|
'private' => false, |
240
|
|
|
); |
241
|
|
|
|
242
|
|
|
foreach ( array( |
243
|
|
|
'HTTP_HOST', |
244
|
|
|
'SERVER_PORT', |
245
|
|
|
'HTTPS', |
246
|
|
|
'GD_PHP_HANDLER', |
247
|
|
|
'HTTP_AKAMAI_ORIGIN_HOP', |
248
|
|
|
'HTTP_CF_CONNECTING_IP', |
249
|
|
|
'HTTP_CLIENT_IP', |
250
|
|
|
'HTTP_FASTLY_CLIENT_IP', |
251
|
|
|
'HTTP_FORWARDED', |
252
|
|
|
'HTTP_FORWARDED_FOR', |
253
|
|
|
'HTTP_INCAP_CLIENT_IP', |
254
|
|
|
'HTTP_TRUE_CLIENT_IP', |
255
|
|
|
'HTTP_X_CLIENTIP', |
256
|
|
|
'HTTP_X_CLUSTER_CLIENT_IP', |
257
|
|
|
'HTTP_X_FORWARDED', |
258
|
|
|
'HTTP_X_FORWARDED_FOR', |
259
|
|
|
'HTTP_X_IP_TRAIL', |
260
|
|
|
'HTTP_X_REAL_IP', |
261
|
|
|
'HTTP_X_VARNISH', |
262
|
|
|
'REMOTE_ADDR', |
263
|
|
|
) as $header ) { |
264
|
|
|
if ( isset( $_SERVER[ $header ] ) ) { |
265
|
|
|
$debug_info[ $header ] = array( |
266
|
|
|
'label' => 'Server Variable ' . $header, |
267
|
|
|
'value' => ( $_SERVER[ $header ] ) ? $_SERVER[ $header ] : 'false', |
268
|
|
|
'private' => false, |
269
|
|
|
); |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
$debug_info['protect_header'] = array( |
274
|
|
|
'label' => 'Trusted IP', |
275
|
|
|
'value' => wp_json_encode( get_site_option( 'trusted_ip_header' ) ), |
276
|
|
|
'private' => false, |
277
|
|
|
); |
278
|
|
|
|
279
|
|
|
/** Sync Debug Information */ |
280
|
|
|
$sync_module = Modules::get_module( 'full-sync' ); |
281
|
|
|
if ( $sync_module ) { |
282
|
|
|
$sync_statuses = $sync_module->get_status(); |
283
|
|
|
$human_readable_sync_status = array(); |
284
|
|
|
foreach ( $sync_statuses as $sync_status => $sync_status_value ) { |
285
|
|
|
$human_readable_sync_status[ $sync_status ] = |
286
|
|
|
in_array( $sync_status, array( 'started', 'queue_finished', 'send_started', 'finished' ), true ) |
287
|
|
|
? gmdate( 'r', $sync_status_value ) : $sync_status_value; |
288
|
|
|
} |
289
|
|
|
$debug_info['full_sync'] = array( |
290
|
|
|
'label' => 'Full Sync Status', |
291
|
|
|
'value' => wp_json_encode( $human_readable_sync_status ), |
292
|
|
|
'private' => false, |
293
|
|
|
); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
$queue = Sender::get_instance()->get_sync_queue(); |
297
|
|
|
|
298
|
|
|
$debug_info['sync_size'] = array( |
299
|
|
|
'label' => 'Sync Queue Size', |
300
|
|
|
'value' => $queue->size(), |
301
|
|
|
'private' => false, |
302
|
|
|
); |
303
|
|
|
$debug_info['sync_lag'] = array( |
304
|
|
|
'label' => 'Sync Queue Lag', |
305
|
|
|
'value' => self::seconds_to_time( $queue->lag() ), |
306
|
|
|
'private' => false, |
307
|
|
|
); |
308
|
|
|
|
309
|
|
|
$full_sync_queue = Sender::get_instance()->get_full_sync_queue(); |
310
|
|
|
|
311
|
|
|
$debug_info['full_sync_size'] = array( |
312
|
|
|
'label' => 'Full Sync Queue Size', |
313
|
|
|
'value' => $full_sync_queue->size(), |
314
|
|
|
'private' => false, |
315
|
|
|
); |
316
|
|
|
$debug_info['full_sync_lag'] = array( |
317
|
|
|
'label' => 'Full Sync Queue Lag', |
318
|
|
|
'value' => self::seconds_to_time( $full_sync_queue->lag() ), |
319
|
|
|
'private' => false, |
320
|
|
|
); |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* IDC Information |
324
|
|
|
* |
325
|
|
|
* Must follow sync debug since it depends on sync functionality. |
326
|
|
|
*/ |
327
|
|
|
$idc_urls = array( |
328
|
|
|
'home' => Functions::home_url(), |
329
|
|
|
'siteurl' => Functions::site_url(), |
330
|
|
|
'WP_HOME' => Constants::is_defined( 'WP_HOME' ) ? Constants::get_constant( 'WP_HOME' ) : '', |
331
|
|
|
'WP_SITEURL' => Constants::is_defined( 'WP_SITEURL' ) ? Constants::get_constant( 'WP_SITEURL' ) : '', |
332
|
|
|
); |
333
|
|
|
|
334
|
|
|
$debug_info['idc_urls'] = array( |
335
|
|
|
'label' => 'IDC URLs', |
336
|
|
|
'value' => wp_json_encode( $idc_urls ), |
337
|
|
|
'private' => false, |
338
|
|
|
); |
339
|
|
|
$debug_info['idc_error_option'] = array( |
340
|
|
|
'label' => 'IDC Error Option', |
341
|
|
|
'value' => wp_json_encode( \Jetpack_Options::get_option( 'sync_error_idc' ) ), |
342
|
|
|
'private' => false, |
343
|
|
|
); |
344
|
|
|
$debug_info['idc_optin'] = array( |
345
|
|
|
'label' => 'IDC Opt-in', |
346
|
|
|
'value' => \Jetpack::sync_idc_optin(), |
347
|
|
|
'private' => false, |
348
|
|
|
); |
349
|
|
|
|
350
|
|
|
// @todo -- Add testing results? |
351
|
|
|
$cxn_tests = new Tests(); |
352
|
|
|
$debug_info['cxn_tests'] = array( |
353
|
|
|
'label' => 'Connection Tests', |
354
|
|
|
'value' => '', |
355
|
|
|
'private' => false, |
356
|
|
|
); |
357
|
|
|
if ( $cxn_tests->pass() ) { |
358
|
|
|
$debug_info['cxn_tests']['value'] = 'All Pass.'; |
359
|
|
|
} else { |
360
|
|
|
$debug_info['cxn_tests']['value'] = wp_json_encode( $cxn_tests->list_fails() ); |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
return $debug_info; |
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
/** |
367
|
|
|
* Returns a human readable string for which user is the master user. |
368
|
|
|
* |
369
|
|
|
* @return string |
370
|
|
|
*/ |
371
|
|
|
private static function human_readable_master_user() { |
372
|
|
|
$master_user = \Jetpack_Options::get_option( 'master_user' ); |
373
|
|
|
|
374
|
|
|
if ( ! $master_user ) { |
375
|
|
|
return __( 'No master user set.', 'jetpack' ); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
$user = new \WP_User( $master_user ); |
379
|
|
|
|
380
|
|
|
if ( ! $user ) { |
381
|
|
|
return __( 'Master user no longer exists. Please disconnect and reconnect Jetpack.', 'jetpack' ); |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
return self::human_readable_user( $user ); |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
/** |
388
|
|
|
* Return human readable string for a given user object. |
389
|
|
|
* |
390
|
|
|
* @param \WP_User|int $user Object or ID. |
391
|
|
|
* |
392
|
|
|
* @return string |
393
|
|
|
*/ |
394
|
|
|
private static function human_readable_user( $user ) { |
395
|
|
|
$user = new \WP_User( $user ); |
396
|
|
|
|
397
|
|
|
return sprintf( '#%1$d %2$s (%3$s)', $user->ID, $user->user_login, $user->user_email ); // Format: "#1 username ([email protected])". |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Test runner for Core's Site Health module. |
402
|
|
|
* |
403
|
|
|
* @since 7.3.0 |
404
|
|
|
*/ |
405
|
|
|
public static function ajax_local_testing_suite() { |
406
|
|
|
check_ajax_referer( 'health-check-site-status' ); |
407
|
|
|
if ( ! current_user_can( 'jetpack_manage_modules' ) ) { |
408
|
|
|
wp_send_json_error(); |
409
|
|
|
} |
410
|
|
|
$tests = new Tests(); |
411
|
|
|
wp_send_json_success( $tests->output_results_for_core_async_site_health() ); |
412
|
|
|
} |
413
|
|
|
/** |
414
|
|
|
* Adds the Jetpack Local Testing Suite to the Core Site Health system. |
415
|
|
|
* |
416
|
|
|
* @since 7.3.0 |
417
|
|
|
* |
418
|
|
|
* @param array $core_tests Array of tests from Core's Site Health. |
419
|
|
|
* |
420
|
|
|
* @return array $core_tests Array of tests for Core's Site Health. |
421
|
|
|
*/ |
422
|
|
|
public static function site_status_tests( $core_tests ) { |
423
|
|
|
$cxn_tests = new Tests(); |
424
|
|
|
$tests = $cxn_tests->list_tests( 'direct' ); |
425
|
|
|
foreach ( $tests as $test ) { |
426
|
|
|
$core_tests['direct'][ $test['name'] ] = array( |
427
|
|
|
'label' => __( 'Jetpack: ', 'jetpack' ) . $test['name'], |
428
|
|
|
'test' => function() use ( $test, $cxn_tests ) { // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewClosure.Found |
429
|
|
|
$results = $cxn_tests->run_test( $test['name'] ); |
430
|
|
|
// Test names are, by default, `test__some_string_of_text`. Let's convert to "Some String Of Text" for humans. |
431
|
|
|
$label = ucwords( |
432
|
|
|
str_replace( |
433
|
|
|
'_', |
434
|
|
|
' ', |
435
|
|
|
str_replace( 'test__', '', $test['name'] ) |
436
|
|
|
) |
437
|
|
|
); |
438
|
|
|
$return = array( |
439
|
|
|
'label' => $label, |
440
|
|
|
'status' => 'good', |
441
|
|
|
'badge' => array( |
442
|
|
|
'label' => __( 'Jetpack', 'jetpack' ), |
443
|
|
|
'color' => 'green', |
444
|
|
|
), |
445
|
|
|
'description' => sprintf( |
446
|
|
|
'<p>%s</p>', |
447
|
|
|
__( 'This test successfully passed!', 'jetpack' ) |
448
|
|
|
), |
449
|
|
|
'actions' => '', |
450
|
|
|
'test' => 'jetpack_' . $test['name'], |
451
|
|
|
); |
452
|
|
|
if ( is_wp_error( $results ) ) { |
453
|
|
|
return; |
454
|
|
|
} |
455
|
|
|
if ( false === $results['pass'] ) { |
456
|
|
|
$return['label'] = $results['message']; |
457
|
|
|
|
458
|
|
|
if ( $results['label'] ) { |
459
|
|
|
// Allow tests to override the strange message => label logic with an actual label. |
460
|
|
|
$return['label'] = $results['label']; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
// Most tests pass a `resolution` property to use as a description. |
464
|
|
|
$return['description'] = sprintf( |
465
|
|
|
'<p>%s</p>', |
466
|
|
|
$results['resolution'] |
467
|
|
|
); |
468
|
|
|
|
469
|
|
|
if ( $results['description'] ) { |
470
|
|
|
// Allow tests to override 'resolution' with their own HTML description. |
471
|
|
|
$return['description'] = $results['description']; |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
$return['status'] = $results['severity']; |
475
|
|
|
if ( ! empty( $results['action'] ) ) { |
476
|
|
|
$return['actions'] = sprintf( |
477
|
|
|
'<a 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>', |
478
|
|
|
esc_url( $results['action'] ), |
479
|
|
|
$results['action_label'], |
480
|
|
|
/* translators: accessibility text */ |
481
|
|
|
__( '(opens in a new tab)', 'jetpack' ) |
482
|
|
|
); |
483
|
|
|
} |
484
|
|
|
} elseif ( true === $results['pass'] ) { |
485
|
|
|
// Passing tests can chose to override defaults. |
486
|
|
|
if ( $results['label'] ) { |
487
|
|
|
$return['label'] = $results['label']; |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
if ( $results['description'] ) { |
491
|
|
|
$return['description'] = $results['description']; |
492
|
|
|
} |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
return $return; |
496
|
|
|
}, |
497
|
|
|
); |
498
|
|
|
} |
499
|
|
|
$core_tests['async']['jetpack_test_suite'] = array( |
500
|
|
|
'label' => __( 'Jetpack Tests', 'jetpack' ), |
501
|
|
|
'test' => 'jetpack_local_testing_suite', |
502
|
|
|
); |
503
|
|
|
|
504
|
|
|
return $core_tests; |
505
|
|
|
} |
506
|
|
|
} |
507
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.