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 jetpack |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class Jetpack_Debug_Data |
10
|
|
|
* |
11
|
|
|
* Collect and return debug data for Jetpack. |
12
|
|
|
* |
13
|
|
|
* @since 7.3.0 |
14
|
|
|
*/ |
15
|
|
|
class Jetpack_Debug_Data { |
16
|
|
|
/** |
17
|
|
|
* Determine the active plan and normalize it for the debugger results. |
18
|
|
|
* |
19
|
|
|
* @since 7.3.0 |
20
|
|
|
* |
21
|
|
|
* @return string The plan slug. |
22
|
|
|
*/ |
23
|
|
|
public static function what_jetpack_plan() { |
24
|
|
|
$plan = Jetpack_Plan::get(); |
25
|
|
|
return ! empty( $plan['class'] ) ? $plan['class'] : 'undefined'; |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Convert seconds to human readable time. |
30
|
|
|
* |
31
|
|
|
* A dedication function instead of using Core functionality to allow for output in seconds. |
32
|
|
|
* |
33
|
|
|
* @since 7.3.0 |
34
|
|
|
* |
35
|
|
|
* @param int $seconds Number of seconds to convert to human time. |
36
|
|
|
* |
37
|
|
|
* @return string Human readable time. |
38
|
|
|
*/ |
39
|
|
|
public static function seconds_to_time( $seconds ) { |
40
|
|
|
$seconds = intval( $seconds ); |
41
|
|
|
$units = array( |
42
|
|
|
'week' => WEEK_IN_SECONDS, |
43
|
|
|
'day' => DAY_IN_SECONDS, |
44
|
|
|
'hour' => HOUR_IN_SECONDS, |
45
|
|
|
'minute' => MINUTE_IN_SECONDS, |
46
|
|
|
'second' => 1, |
47
|
|
|
); |
48
|
|
|
// specifically handle zero. |
49
|
|
|
if ( 0 === $seconds ) { |
50
|
|
|
return '0 seconds'; |
51
|
|
|
} |
52
|
|
|
$human_readable = ''; |
53
|
|
|
foreach ( $units as $name => $divisor ) { |
54
|
|
|
$quot = intval( $seconds / $divisor ); |
55
|
|
|
if ( $quot ) { |
56
|
|
|
$human_readable .= "$quot $name"; |
57
|
|
|
$human_readable .= ( abs( $quot ) > 1 ? 's' : '' ) . ', '; |
58
|
|
|
$seconds -= $quot * $divisor; |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
return substr( $human_readable, 0, -2 ); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Return debug data in the format expected by Core's Site Health Info tab. |
66
|
|
|
* |
67
|
|
|
* @since 7.3.0 |
68
|
|
|
* |
69
|
|
|
* @param array $debug { |
70
|
|
|
* The debug information already compiled by Core. |
71
|
|
|
* |
72
|
|
|
* @type string $label The title for this section of the debug output. |
73
|
|
|
* @type string $description Optional. A description for your information section which may contain basic HTML |
74
|
|
|
* markup: `em`, `strong` and `a` for linking to documentation or putting emphasis. |
75
|
|
|
* @type boolean $show_count Optional. If set to `true` the amount of fields will be included in the title for |
76
|
|
|
* this section. |
77
|
|
|
* @type boolean $private Optional. If set to `true` the section and all associated fields will be excluded |
78
|
|
|
* from the copy-paste text area. |
79
|
|
|
* @type array $fields { |
80
|
|
|
* An associative array containing the data to be displayed. |
81
|
|
|
* |
82
|
|
|
* @type string $label The label for this piece of information. |
83
|
|
|
* @type string $value The output that is of interest for this field. |
84
|
|
|
* @type boolean $private Optional. If set to `true` the field will not be included in the copy-paste text area |
85
|
|
|
* on top of the page, allowing you to show, for example, API keys here. |
86
|
|
|
* } |
87
|
|
|
* } |
88
|
|
|
* |
89
|
|
|
* @return array $args Debug information in the same format as the initial argument. |
90
|
|
|
*/ |
91
|
|
|
public static function core_debug_data( $debug ) { |
92
|
|
|
$jetpack = array( |
93
|
|
|
'jetpack' => array( |
94
|
|
|
'label' => __( 'Jetpack', 'jetpack' ), |
95
|
|
|
'description' => sprintf( |
96
|
|
|
/* translators: %1$s is URL to jetpack.com's contact support page. %2$s accessibility text */ |
97
|
|
|
__( |
98
|
|
|
'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>', |
99
|
|
|
'jetpack' |
100
|
|
|
), |
101
|
|
|
esc_html( 'https://jetpack.com/contact-support/' ), |
102
|
|
|
__( '(opens in a new tab)', 'jetpack' ) |
103
|
|
|
), |
104
|
|
|
'fields' => self::debug_data(), |
105
|
|
|
), |
106
|
|
|
); |
107
|
|
|
$debug = array_merge( $debug, $jetpack ); |
108
|
|
|
return $debug; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Compile and return array of debug information. |
113
|
|
|
* |
114
|
|
|
* @since 7.3.0 |
115
|
|
|
* |
116
|
|
|
* @return array $args { |
117
|
|
|
* Associated array of arrays with the following. |
118
|
|
|
* @type string $label The label for this piece of information. |
119
|
|
|
* @type string $value The output that is of interest for this field. |
120
|
|
|
* @type boolean $private Optional. Set to true if data is sensitive (API keys, etc). |
121
|
|
|
* } |
122
|
|
|
*/ |
123
|
|
|
public static function debug_data() { |
124
|
|
|
$debug_info = array(); |
125
|
|
|
|
126
|
|
|
/* Add various important Jetpack options */ |
127
|
|
|
$debug_info['site_id'] = array( |
128
|
|
|
'label' => 'Jetpack Site ID', |
129
|
|
|
'value' => Jetpack_Options::get_option( 'id' ), |
130
|
|
|
'private' => false, |
131
|
|
|
); |
132
|
|
|
$debug_info['ssl_cert'] = array( |
133
|
|
|
'label' => 'Jetpack SSL Verfication Bypass', |
134
|
|
|
'value' => ( Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' ) ) ? 'Yes' : 'No', |
135
|
|
|
'private' => false, |
136
|
|
|
); |
137
|
|
|
$debug_info['time_diff'] = array( |
138
|
|
|
'label' => "Offset between Jetpack server's time and this server's time.", |
139
|
|
|
'value' => Jetpack_Options::get_option( 'time_diff' ), |
140
|
|
|
'private' => false, |
141
|
|
|
); |
142
|
|
|
$debug_info['version_option'] = array( |
143
|
|
|
'label' => 'Current Jetpack Version Option', |
144
|
|
|
'value' => Jetpack_Options::get_option( 'version' ), |
145
|
|
|
'private' => false, |
146
|
|
|
); |
147
|
|
|
$debug_info['old_version'] = array( |
148
|
|
|
'label' => 'Previous Jetpack Version', |
149
|
|
|
'value' => Jetpack_Options::get_option( 'old_version' ), |
150
|
|
|
'private' => false, |
151
|
|
|
); |
152
|
|
|
$debug_info['public'] = array( |
153
|
|
|
'label' => 'Jetpack Site Public', |
154
|
|
|
'value' => ( Jetpack_Options::get_option( 'public' ) ) ? 'Public' : 'Private', |
155
|
|
|
'private' => false, |
156
|
|
|
); |
157
|
|
|
$debug_info['master_user'] = array( |
158
|
|
|
'label' => 'Jetpack Master User', |
159
|
|
|
'value' => Jetpack_Options::get_option( 'master_user' ), |
160
|
|
|
'private' => false, |
161
|
|
|
); |
162
|
|
|
|
163
|
|
|
/* Token information is private, but awareness if there one is set is helpful. */ |
164
|
|
|
$user_id = get_current_user_id(); |
165
|
|
|
$user_tokens = Jetpack_Options::get_option( 'user_tokens' ); |
166
|
|
|
$blog_token = Jetpack_Options::get_option( 'blog_token' ); |
167
|
|
|
$user_token = null; |
168
|
|
|
if ( is_array( $user_tokens ) && array_key_exists( $user_id, $user_tokens ) ) { |
169
|
|
|
$user_token = $user_tokens[ $user_id ]; |
170
|
|
|
} |
171
|
|
|
unset( $user_tokens ); |
172
|
|
|
|
173
|
|
|
$tokenset = ''; |
174
|
|
|
if ( $blog_token ) { |
175
|
|
|
$tokenset = 'Blog '; |
176
|
|
|
} |
177
|
|
|
if ( $user_token ) { |
178
|
|
|
$tokenset .= 'User'; |
179
|
|
|
} |
180
|
|
|
if ( ! $tokenset ) { |
181
|
|
|
$tokenset = 'None'; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
$debug_info['current_user'] = array( |
185
|
|
|
'label' => 'Current User', |
186
|
|
|
'value' => $user_id, |
187
|
|
|
'private' => false, |
188
|
|
|
); |
189
|
|
|
$debug_info['tokens_set'] = array( |
190
|
|
|
'label' => 'Tokens defined', |
191
|
|
|
'value' => $tokenset, |
192
|
|
|
'private => false,', |
193
|
|
|
); |
194
|
|
|
$debug_info['blog_token'] = array( |
195
|
|
|
'label' => 'Blog token', |
196
|
|
|
'value' => ( $blog_token ) ? $blog_token : 'Not set.', |
197
|
|
|
'private' => true, |
198
|
|
|
); |
199
|
|
|
$debug_info['user_token'] = array( |
200
|
|
|
'label' => 'User token', |
201
|
|
|
'value' => ( $user_token ) ? $user_token : 'Not set.', |
202
|
|
|
'private' => true, |
203
|
|
|
); |
204
|
|
|
|
205
|
|
|
/** Jetpack Environmental Information */ |
206
|
|
|
$debug_info['version'] = array( |
207
|
|
|
'label' => 'Jetpack Version', |
208
|
|
|
'value' => JETPACK__VERSION, |
209
|
|
|
'private' => false, |
210
|
|
|
); |
211
|
|
|
$debug_info['jp_plugin_dir'] = array( |
212
|
|
|
'label' => 'Jetpack Directory', |
213
|
|
|
'value' => JETPACK__PLUGIN_DIR, |
214
|
|
|
'private' => false, |
215
|
|
|
); |
216
|
|
|
$debug_info['plan'] = array( |
217
|
|
|
'label' => 'Plan Type', |
218
|
|
|
'value' => self::what_jetpack_plan(), |
219
|
|
|
'private' => false, |
220
|
|
|
); |
221
|
|
|
|
222
|
|
|
foreach ( array( |
223
|
|
|
'HTTP_HOST', |
224
|
|
|
'SERVER_PORT', |
225
|
|
|
'HTTPS', |
226
|
|
|
'GD_PHP_HANDLER', |
227
|
|
|
'HTTP_AKAMAI_ORIGIN_HOP', |
228
|
|
|
'HTTP_CF_CONNECTING_IP', |
229
|
|
|
'HTTP_CLIENT_IP', |
230
|
|
|
'HTTP_FASTLY_CLIENT_IP', |
231
|
|
|
'HTTP_FORWARDED', |
232
|
|
|
'HTTP_FORWARDED_FOR', |
233
|
|
|
'HTTP_INCAP_CLIENT_IP', |
234
|
|
|
'HTTP_TRUE_CLIENT_IP', |
235
|
|
|
'HTTP_X_CLIENTIP', |
236
|
|
|
'HTTP_X_CLUSTER_CLIENT_IP', |
237
|
|
|
'HTTP_X_FORWARDED', |
238
|
|
|
'HTTP_X_FORWARDED_FOR', |
239
|
|
|
'HTTP_X_IP_TRAIL', |
240
|
|
|
'HTTP_X_REAL_IP', |
241
|
|
|
'HTTP_X_VARNISH', |
242
|
|
|
'REMOTE_ADDR', |
243
|
|
|
) as $header ) { |
244
|
|
|
if ( isset( $_SERVER[ $header ] ) ) { |
245
|
|
|
$debug_info[ $header ] = array( |
246
|
|
|
'label' => 'Server Variable ' . $header, |
247
|
|
|
'value' => ( $_SERVER[ $header ] ) ? $_SERVER[ $header ] : 'false', |
248
|
|
|
'private' => false, |
249
|
|
|
); |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
$debug_info['protect_header'] = array( |
254
|
|
|
'label' => 'Trusted IP', |
255
|
|
|
'value' => wp_json_encode( get_site_option( 'trusted_ip_header' ) ), |
256
|
|
|
'private' => false, |
257
|
|
|
); |
258
|
|
|
|
259
|
|
|
/** Sync Debug Information */ |
260
|
|
|
/** Load Sync modules */ |
261
|
|
|
require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-modules.php'; |
262
|
|
|
/** Load Sync sender */ |
263
|
|
|
require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-sender.php'; |
264
|
|
|
/** Load Sync functions */ |
265
|
|
|
require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-functions.php'; |
266
|
|
|
|
267
|
|
|
$sync_module = Jetpack_Sync_Modules::get_module( 'full-sync' ); |
268
|
|
|
if ( $sync_module ) { |
269
|
|
|
$sync_statuses = $sync_module->get_status(); |
270
|
|
|
$human_readable_sync_status = array(); |
271
|
|
|
foreach ( $sync_statuses as $sync_status => $sync_status_value ) { |
272
|
|
|
$human_readable_sync_status[ $sync_status ] = |
273
|
|
|
in_array( $sync_status, array( 'started', 'queue_finished', 'send_started', 'finished' ), true ) |
274
|
|
|
? date( 'r', $sync_status_value ) : $sync_status_value; |
275
|
|
|
} |
276
|
|
|
$debug_info['full_sync'] = array( |
277
|
|
|
'label' => 'Full Sync Status', |
278
|
|
|
'value' => wp_json_encode( $human_readable_sync_status ), |
279
|
|
|
'private' => false, |
280
|
|
|
); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
$queue = Jetpack_Sync_Sender::get_instance()->get_sync_queue(); |
284
|
|
|
|
285
|
|
|
$debug_info['sync_size'] = array( |
286
|
|
|
'label' => 'Sync Queue Size', |
287
|
|
|
'value' => $queue->size(), |
288
|
|
|
'private' => false, |
289
|
|
|
); |
290
|
|
|
$debug_info['sync_lag'] = array( |
291
|
|
|
'label' => 'Sync Queue Lag', |
292
|
|
|
'value' => self::seconds_to_time( $queue->lag() ), |
293
|
|
|
'private' => false, |
294
|
|
|
); |
295
|
|
|
|
296
|
|
|
$full_sync_queue = Jetpack_Sync_Sender::get_instance()->get_full_sync_queue(); |
297
|
|
|
|
298
|
|
|
$debug_info['full_sync_size'] = array( |
299
|
|
|
'label' => 'Full Sync Queue Size', |
300
|
|
|
'value' => $full_sync_queue->size(), |
301
|
|
|
'private' => false, |
302
|
|
|
); |
303
|
|
|
$debug_info['full_sync_lag'] = array( |
304
|
|
|
'label' => 'Full Sync Queue Lag', |
305
|
|
|
'value' => self::seconds_to_time( $full_sync_queue->lag() ), |
306
|
|
|
'private' => false, |
307
|
|
|
); |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* IDC Information |
311
|
|
|
* |
312
|
|
|
* Must follow sync debug since it depends on sync functionality. |
313
|
|
|
*/ |
314
|
|
|
$idc_urls = array( |
315
|
|
|
'home' => Jetpack_Sync_Functions::home_url(), |
316
|
|
|
'siteurl' => Jetpack_Sync_Functions::site_url(), |
317
|
|
|
'WP_HOME' => Jetpack_Constants::is_defined( 'WP_HOME' ) ? Jetpack_Constants::get_constant( 'WP_HOME' ) : '', |
318
|
|
|
'WP_SITEURL' => Jetpack_Constants::is_defined( 'WP_SITEURL' ) ? Jetpack_Constants::get_constant( 'WP_SITEURL' ) : '', |
319
|
|
|
); |
320
|
|
|
|
321
|
|
|
$debug_info['idc_urls'] = array( |
322
|
|
|
'label' => 'IDC URLs', |
323
|
|
|
'value' => wp_json_encode( $idc_urls ), |
324
|
|
|
'private' => false, |
325
|
|
|
); |
326
|
|
|
$debug_info['idc_error_option'] = array( |
327
|
|
|
'label' => 'IDC Error Option', |
328
|
|
|
'value' => wp_json_encode( Jetpack_Options::get_option( 'sync_error_idc' ) ), |
329
|
|
|
'private' => false, |
330
|
|
|
); |
331
|
|
|
$debug_info['idc_optin'] = array( |
332
|
|
|
'label' => 'IDC Opt-in', |
333
|
|
|
'value' => Jetpack::sync_idc_optin(), |
334
|
|
|
'private' => false, |
335
|
|
|
); |
336
|
|
|
|
337
|
|
|
// @todo -- Add testing results? |
338
|
|
|
$cxn_tests = new Jetpack_Cxn_Tests(); |
339
|
|
|
$debug_info['cxn_tests'] = array( |
340
|
|
|
'label' => 'Connection Tests', |
341
|
|
|
'value' => '', |
342
|
|
|
'private' => false, |
343
|
|
|
); |
344
|
|
|
if ( $cxn_tests->pass() ) { |
345
|
|
|
$debug_info['cxn_tests']['value'] = 'All Pass.'; |
346
|
|
|
} else { |
347
|
|
|
$debug_info['cxn_tests']['value'] = wp_json_encode( $cxn_tests->list_fails() ); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
return $debug_info; |
351
|
|
|
} |
352
|
|
|
} |
353
|
|
|
|