Completed
Push — renovate/jest-monorepo ( bbafd9...36469d )
by
unknown
33:09 queued 24:56
created

Jetpack_Debug_Data   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
dl 0
loc 338
rs 10
c 0
b 0
f 0
wmc 27
lcom 1
cbo 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A what_jetpack_plan() 0 4 2
A seconds_to_time() 0 24 5
A core_debug_data() 0 19 1
F debug_data() 0 229 19
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