Passed
Push — master ( 4b719c...0b770d )
by Mike
06:15
created

SystemStatus::get_wp_memory_limit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * REST API WC System Status controller
4
 *
5
 * Handles requests to the /system_status endpoint.
6
 *
7
 * @package WooCommerce/RestApi
8
 */
9
10
namespace WooCommerce\RestApi\Controllers\Version4;
11
12
defined( 'ABSPATH' ) || exit;
13
14
/**
15
 * REST API System Status controller class.
16
 */
17
class SystemStatus extends AbstractController {
18
19
	/**
20
	 * Route base.
21
	 *
22
	 * @var string
23
	 */
24
	protected $rest_base = 'system_status';
25
26
	/**
27
	 * Store available updates.
28
	 *
29
	 * @var array
30
	 */
31
	protected $available_updates = array();
32
33
	/**
34
	 * Register the route for /system_status
35
	 */
36
	public function register_routes() {
37
		register_rest_route(
38
			$this->namespace,
39
			'/' . $this->rest_base,
40
			array(
41
				array(
42
					'methods'             => \WP_REST_Server::READABLE,
43
					'callback'            => array( $this, 'get_items' ),
44
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
45
					'args'                => $this->get_collection_params(),
46
				),
47
				'schema' => array( $this, 'get_public_item_schema' ),
48
			),
49
			true
50
		);
51
	}
52
53
	/**
54
	 * Check whether a given request has permission to view system status.
55
	 *
56
	 * @param  \WP_REST_Request $request Full details about the request.
57
	 * @return \WP_Error|boolean
58
	 */
59
	public function get_items_permissions_check( $request ) {
60
		if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
61
			return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
62
		}
63
		return true;
64
	}
65
66
	/**
67
	 * Get a system status info, by section.
68
	 *
69
	 * @param \WP_REST_Request $request Full details about the request.
70
	 * @return \WP_Error|\WP_REST_Response
71
	 */
72
	public function get_items( $request ) {
73
		$schema   = $this->get_item_schema();
74
		$mappings = $this->get_item_mappings();
75
		$response = array();
76
77
		foreach ( $mappings as $section => $values ) {
78
			foreach ( $values as $key => $value ) {
79
				if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) {
80
					settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] );
81
				}
82
			}
83
			settype( $values, $schema['properties'][ $section ]['type'] );
84
			$response[ $section ] = $values;
85
		}
86
87
		$response = $this->prepare_item_for_response( $response, $request );
88
89
		return rest_ensure_response( $response );
90
	}
91
92
	/**
93
	 * Get the system status schema, conforming to JSON Schema.
94
	 *
95
	 * @return array
96
	 */
97
	public function get_item_schema() {
98
		$schema = array(
99
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
100
			'title'      => 'system_status',
101
			'type'       => 'object',
102
			'properties' => array(
103
				'environment'    => array(
104
					'description' => __( 'Environment.', 'woocommerce' ),
105
					'type'        => 'object',
106
					'context'     => array( 'view' ),
107
					'readonly'    => true,
108
					'properties'  => array(
109
						'home_url'                  => array(
110
							'description' => __( 'Home URL.', 'woocommerce' ),
111
							'type'        => 'string',
112
							'format'      => 'uri',
113
							'context'     => array( 'view' ),
114
							'readonly'    => true,
115
						),
116
						'site_url'                  => array(
117
							'description' => __( 'Site URL.', 'woocommerce' ),
118
							'type'        => 'string',
119
							'format'      => 'uri',
120
							'context'     => array( 'view' ),
121
							'readonly'    => true,
122
						),
123
						'wc_version'                => array(
124
							'description' => __( 'WooCommerce version.', 'woocommerce' ),
125
							'type'        => 'string',
126
							'context'     => array( 'view' ),
127
							'readonly'    => true,
128
						),
129
						'log_directory'             => array(
130
							'description' => __( 'Log directory.', 'woocommerce' ),
131
							'type'        => 'string',
132
							'context'     => array( 'view' ),
133
							'readonly'    => true,
134
						),
135
						'log_directory_writable'    => array(
136
							'description' => __( 'Is log directory writable?', 'woocommerce' ),
137
							'type'        => 'boolean',
138
							'context'     => array( 'view' ),
139
							'readonly'    => true,
140
						),
141
						'wp_version'                => array(
142
							'description' => __( 'WordPress version.', 'woocommerce' ),
143
							'type'        => 'string',
144
							'context'     => array( 'view' ),
145
							'readonly'    => true,
146
						),
147
						'wp_multisite'              => array(
148
							'description' => __( 'Is WordPress multisite?', 'woocommerce' ),
149
							'type'        => 'boolean',
150
							'context'     => array( 'view' ),
151
							'readonly'    => true,
152
						),
153
						'wp_memory_limit'           => array(
154
							'description' => __( 'WordPress memory limit.', 'woocommerce' ),
155
							'type'        => 'integer',
156
							'context'     => array( 'view' ),
157
							'readonly'    => true,
158
						),
159
						'wp_debug_mode'             => array(
160
							'description' => __( 'Is WordPress debug mode active?', 'woocommerce' ),
161
							'type'        => 'boolean',
162
							'context'     => array( 'view' ),
163
							'readonly'    => true,
164
						),
165
						'wp_cron'                   => array(
166
							'description' => __( 'Are WordPress cron jobs enabled?', 'woocommerce' ),
167
							'type'        => 'boolean',
168
							'context'     => array( 'view' ),
169
							'readonly'    => true,
170
						),
171
						'language'                  => array(
172
							'description' => __( 'WordPress language.', 'woocommerce' ),
173
							'type'        => 'string',
174
							'context'     => array( 'view' ),
175
							'readonly'    => true,
176
						),
177
						'server_info'               => array(
178
							'description' => __( 'Server info.', 'woocommerce' ),
179
							'type'        => 'string',
180
							'context'     => array( 'view' ),
181
							'readonly'    => true,
182
						),
183
						'php_version'               => array(
184
							'description' => __( 'PHP version.', 'woocommerce' ),
185
							'type'        => 'string',
186
							'context'     => array( 'view' ),
187
							'readonly'    => true,
188
						),
189
						'php_post_max_size'         => array(
190
							'description' => __( 'PHP post max size.', 'woocommerce' ),
191
							'type'        => 'integer',
192
							'context'     => array( 'view' ),
193
							'readonly'    => true,
194
						),
195
						'php_max_execution_time'    => array(
196
							'description' => __( 'PHP max execution time.', 'woocommerce' ),
197
							'type'        => 'integer',
198
							'context'     => array( 'view' ),
199
							'readonly'    => true,
200
						),
201
						'php_max_input_vars'        => array(
202
							'description' => __( 'PHP max input vars.', 'woocommerce' ),
203
							'type'        => 'integer',
204
							'context'     => array( 'view' ),
205
							'readonly'    => true,
206
						),
207
						'curl_version'              => array(
208
							'description' => __( 'cURL version.', 'woocommerce' ),
209
							'type'        => 'string',
210
							'context'     => array( 'view' ),
211
							'readonly'    => true,
212
						),
213
						'suhosin_installed'         => array(
214
							'description' => __( 'Is SUHOSIN installed?', 'woocommerce' ),
215
							'type'        => 'boolean',
216
							'context'     => array( 'view' ),
217
							'readonly'    => true,
218
						),
219
						'max_upload_size'           => array(
220
							'description' => __( 'Max upload size.', 'woocommerce' ),
221
							'type'        => 'integer',
222
							'context'     => array( 'view' ),
223
							'readonly'    => true,
224
						),
225
						'mysql_version'             => array(
226
							'description' => __( 'MySQL version.', 'woocommerce' ),
227
							'type'        => 'string',
228
							'context'     => array( 'view' ),
229
							'readonly'    => true,
230
						),
231
						'mysql_version_string'             => array(
232
							'description' => __( 'MySQL version string.', 'woocommerce' ),
233
							'type'        => 'string',
234
							'context'     => array( 'view' ),
235
							'readonly'    => true,
236
						),
237
						'default_timezone'          => array(
238
							'description' => __( 'Default timezone.', 'woocommerce' ),
239
							'type'        => 'string',
240
							'context'     => array( 'view' ),
241
							'readonly'    => true,
242
						),
243
						'fsockopen_or_curl_enabled' => array(
244
							'description' => __( 'Is fsockopen/cURL enabled?', 'woocommerce' ),
245
							'type'        => 'boolean',
246
							'context'     => array( 'view' ),
247
							'readonly'    => true,
248
						),
249
						'soapclient_enabled'        => array(
250
							'description' => __( 'Is SoapClient class enabled?', 'woocommerce' ),
251
							'type'        => 'boolean',
252
							'context'     => array( 'view' ),
253
							'readonly'    => true,
254
						),
255
						'domdocument_enabled'       => array(
256
							'description' => __( 'Is DomDocument class enabled?', 'woocommerce' ),
257
							'type'        => 'boolean',
258
							'context'     => array( 'view' ),
259
							'readonly'    => true,
260
						),
261
						'gzip_enabled'              => array(
262
							'description' => __( 'Is GZip enabled?', 'woocommerce' ),
263
							'type'        => 'boolean',
264
							'context'     => array( 'view' ),
265
							'readonly'    => true,
266
						),
267
						'mbstring_enabled'          => array(
268
							'description' => __( 'Is mbstring enabled?', 'woocommerce' ),
269
							'type'        => 'boolean',
270
							'context'     => array( 'view' ),
271
							'readonly'    => true,
272
						),
273
						'remote_post_successful'    => array(
274
							'description' => __( 'Remote POST successful?', 'woocommerce' ),
275
							'type'        => 'boolean',
276
							'context'     => array( 'view' ),
277
							'readonly'    => true,
278
						),
279
						'remote_post_response'      => array(
280
							'description' => __( 'Remote POST response.', 'woocommerce' ),
281
							'type'        => 'string',
282
							'context'     => array( 'view' ),
283
							'readonly'    => true,
284
						),
285
						'remote_get_successful'     => array(
286
							'description' => __( 'Remote GET successful?', 'woocommerce' ),
287
							'type'        => 'boolean',
288
							'context'     => array( 'view' ),
289
							'readonly'    => true,
290
						),
291
						'remote_get_response'       => array(
292
							'description' => __( 'Remote GET response.', 'woocommerce' ),
293
							'type'        => 'string',
294
							'context'     => array( 'view' ),
295
							'readonly'    => true,
296
						),
297
					),
298
				),
299
				'database'       => array(
300
					'description' => __( 'Database.', 'woocommerce' ),
301
					'type'        => 'object',
302
					'context'     => array( 'view' ),
303
					'readonly'    => true,
304
					'properties'  => array(
305
						'wc_database_version'    => array(
306
							'description' => __( 'WC database version.', 'woocommerce' ),
307
							'type'        => 'string',
308
							'context'     => array( 'view' ),
309
							'readonly'    => true,
310
						),
311
						'database_prefix'        => array(
312
							'description' => __( 'Database prefix.', 'woocommerce' ),
313
							'type'        => 'string',
314
							'context'     => array( 'view' ),
315
							'readonly'    => true,
316
						),
317
						'maxmind_geoip_database' => array(
318
							'description' => __( 'MaxMind GeoIP database.', 'woocommerce' ),
319
							'type'        => 'string',
320
							'context'     => array( 'view' ),
321
							'readonly'    => true,
322
						),
323
						'database_tables'        => array(
324
							'description' => __( 'Database tables.', 'woocommerce' ),
325
							'type'        => 'array',
326
							'context'     => array( 'view' ),
327
							'readonly'    => true,
328
							'items'       => array(
329
								'type' => 'string',
330
							),
331
						),
332
					),
333
				),
334
				'active_plugins' => array(
335
					'description' => __( 'Active plugins.', 'woocommerce' ),
336
					'type'        => 'array',
337
					'context'     => array( 'view' ),
338
					'readonly'    => true,
339
					'items'       => array(
340
						'type' => 'string',
341
					),
342
				),
343
				'inactive_plugins' => array(
344
					'description' => __( 'Inactive plugins.', 'woocommerce' ),
345
					'type'        => 'array',
346
					'context'     => array( 'view' ),
347
					'readonly'    => true,
348
					'items'       => array(
349
						'type' => 'string',
350
					),
351
				),
352
				'dropins_mu_plugins' => array(
353
					'description' => __( 'Dropins & MU plugins.', 'woocommerce' ),
354
					'type'        => 'array',
355
					'context'     => array( 'view' ),
356
					'readonly'    => true,
357
					'items'       => array(
358
						'type' => 'string',
359
					),
360
				),
361
				'theme'          => array(
362
					'description' => __( 'Theme.', 'woocommerce' ),
363
					'type'        => 'object',
364
					'context'     => array( 'view' ),
365
					'readonly'    => true,
366
					'properties'  => array(
367
						'name'                    => array(
368
							'description' => __( 'Theme name.', 'woocommerce' ),
369
							'type'        => 'string',
370
							'context'     => array( 'view' ),
371
							'readonly'    => true,
372
						),
373
						'version'                 => array(
374
							'description' => __( 'Theme version.', 'woocommerce' ),
375
							'type'        => 'string',
376
							'context'     => array( 'view' ),
377
							'readonly'    => true,
378
						),
379
						'version_latest'          => array(
380
							'description' => __( 'Latest version of theme.', 'woocommerce' ),
381
							'type'        => 'string',
382
							'context'     => array( 'view' ),
383
							'readonly'    => true,
384
						),
385
						'author_url'              => array(
386
							'description' => __( 'Theme author URL.', 'woocommerce' ),
387
							'type'        => 'string',
388
							'format'      => 'uri',
389
							'context'     => array( 'view' ),
390
							'readonly'    => true,
391
						),
392
						'is_child_theme'          => array(
393
							'description' => __( 'Is this theme a child theme?', 'woocommerce' ),
394
							'type'        => 'boolean',
395
							'context'     => array( 'view' ),
396
							'readonly'    => true,
397
						),
398
						'has_woocommerce_support' => array(
399
							'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ),
400
							'type'        => 'boolean',
401
							'context'     => array( 'view' ),
402
							'readonly'    => true,
403
						),
404
						'has_woocommerce_file'    => array(
405
							'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ),
406
							'type'        => 'boolean',
407
							'context'     => array( 'view' ),
408
							'readonly'    => true,
409
						),
410
						'has_outdated_templates'  => array(
411
							'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ),
412
							'type'        => 'boolean',
413
							'context'     => array( 'view' ),
414
							'readonly'    => true,
415
						),
416
						'overrides'               => array(
417
							'description' => __( 'Template overrides.', 'woocommerce' ),
418
							'type'        => 'array',
419
							'context'     => array( 'view' ),
420
							'readonly'    => true,
421
							'items'       => array(
422
								'type' => 'string',
423
							),
424
						),
425
						'parent_name'             => array(
426
							'description' => __( 'Parent theme name.', 'woocommerce' ),
427
							'type'        => 'string',
428
							'context'     => array( 'view' ),
429
							'readonly'    => true,
430
						),
431
						'parent_version'          => array(
432
							'description' => __( 'Parent theme version.', 'woocommerce' ),
433
							'type'        => 'string',
434
							'context'     => array( 'view' ),
435
							'readonly'    => true,
436
						),
437
						'parent_author_url'       => array(
438
							'description' => __( 'Parent theme author URL.', 'woocommerce' ),
439
							'type'        => 'string',
440
							'format'      => 'uri',
441
							'context'     => array( 'view' ),
442
							'readonly'    => true,
443
						),
444
					),
445
				),
446
				'settings'       => array(
447
					'description' => __( 'Settings.', 'woocommerce' ),
448
					'type'        => 'object',
449
					'context'     => array( 'view' ),
450
					'readonly'    => true,
451
					'properties'  => array(
452
						'api_enabled'              => array(
453
							'description' => __( 'REST API enabled?', 'woocommerce' ),
454
							'type'        => 'boolean',
455
							'context'     => array( 'view' ),
456
							'readonly'    => true,
457
						),
458
						'force_ssl'                => array(
459
							'description' => __( 'SSL forced?', 'woocommerce' ),
460
							'type'        => 'boolean',
461
							'context'     => array( 'view' ),
462
							'readonly'    => true,
463
						),
464
						'currency'                 => array(
465
							'description' => __( 'Currency.', 'woocommerce' ),
466
							'type'        => 'string',
467
							'context'     => array( 'view' ),
468
							'readonly'    => true,
469
						),
470
						'currency_symbol'          => array(
471
							'description' => __( 'Currency symbol.', 'woocommerce' ),
472
							'type'        => 'string',
473
							'context'     => array( 'view' ),
474
							'readonly'    => true,
475
						),
476
						'currency_position'        => array(
477
							'description' => __( 'Currency position.', 'woocommerce' ),
478
							'type'        => 'string',
479
							'context'     => array( 'view' ),
480
							'readonly'    => true,
481
						),
482
						'thousand_separator'       => array(
483
							'description' => __( 'Thousand separator.', 'woocommerce' ),
484
							'type'        => 'string',
485
							'context'     => array( 'view' ),
486
							'readonly'    => true,
487
						),
488
						'decimal_separator'        => array(
489
							'description' => __( 'Decimal separator.', 'woocommerce' ),
490
							'type'        => 'string',
491
							'context'     => array( 'view' ),
492
							'readonly'    => true,
493
						),
494
						'number_of_decimals'       => array(
495
							'description' => __( 'Number of decimals.', 'woocommerce' ),
496
							'type'        => 'integer',
497
							'context'     => array( 'view' ),
498
							'readonly'    => true,
499
						),
500
						'geolocation_enabled'      => array(
501
							'description' => __( 'Geolocation enabled?', 'woocommerce' ),
502
							'type'        => 'boolean',
503
							'context'     => array( 'view' ),
504
							'readonly'    => true,
505
						),
506
						'taxonomies'               => array(
507
							'description' => __( 'Taxonomy terms for product/order statuses.', 'woocommerce' ),
508
							'type'        => 'array',
509
							'context'     => array( 'view' ),
510
							'readonly'    => true,
511
							'items'       => array(
512
								'type' => 'string',
513
							),
514
						),
515
						'product_visibility_terms' => array(
516
							'description' => __( 'Terms in the product visibility taxonomy.', 'woocommerce' ),
517
							'type'        => 'array',
518
							'context'     => array( 'view' ),
519
							'readonly'    => true,
520
							'items'       => array(
521
								'type' => 'string',
522
							),
523
						),
524
					),
525
				),
526
				'security'       => array(
527
					'description' => __( 'Security.', 'woocommerce' ),
528
					'type'        => 'object',
529
					'context'     => array( 'view' ),
530
					'readonly'    => true,
531
					'properties'  => array(
532
						'secure_connection' => array(
533
							'description' => __( 'Is the connection to your store secure?', 'woocommerce' ),
534
							'type'        => 'boolean',
535
							'context'     => array( 'view' ),
536
							'readonly'    => true,
537
						),
538
						'hide_errors'       => array(
539
							'description' => __( 'Hide errors from visitors?', 'woocommerce' ),
540
							'type'        => 'boolean',
541
							'context'     => array( 'view' ),
542
							'readonly'    => true,
543
						),
544
					),
545
				),
546
				'pages'          => array(
547
					'description' => __( 'WooCommerce pages.', 'woocommerce' ),
548
					'type'        => 'array',
549
					'context'     => array( 'view' ),
550
					'readonly'    => true,
551
					'items'       => array(
552
						'type' => 'string',
553
					),
554
				),
555
				'post_type_counts' => array(
556
					'description' => __( 'Post type counts.', 'woocommerce' ),
557
					'type'        => 'array',
558
					'context'     => array( 'view' ),
559
					'readonly'    => true,
560
					'items'       => array(
561
						'type' => 'string',
562
					),
563
				),
564
			),
565
		);
566
567
		return $this->add_additional_fields_schema( $schema );
568
	}
569
570
	/**
571
	 * Return an array of sections and the data associated with each.
572
	 *
573
	 * @return array
574
	 */
575
	public function get_item_mappings() {
576
		return array(
577
			'environment'        => $this->get_environment_info(),
578
			'database'           => $this->get_database_info(),
579
			'active_plugins'     => $this->get_active_plugins(),
580
			'inactive_plugins'   => $this->get_inactive_plugins(),
581
			'dropins_mu_plugins' => $this->get_dropins_mu_plugins(),
582
			'theme'              => $this->get_theme_info(),
583
			'settings'           => $this->get_settings(),
584
			'security'           => $this->get_security_info(),
585
			'pages'              => $this->get_pages(),
586
			'post_type_counts'   => $this->get_post_type_counts(),
587
		);
588
	}
589
590
	/**
591
	 * Get array of environment information. Includes thing like software
592
	 * versions, and various server settings.
593
	 *
594
	 * @return array
595
	 */
596
	public function get_environment_info() {
597
		$post_request     = $this->test_post_request();
598
		$get_request      = $this->test_get_request();
599
		$database_version = wc_get_server_database_version();
600
601
		// Return all environment info. Described by JSON Schema.
602
		return array(
603
			'home_url'                  => get_option( 'home' ),
604
			'site_url'                  => get_option( 'siteurl' ),
605
			'version'                   => WC()->version,
606
			'log_directory'             => WC_LOG_DIR,
0 ignored issues
show
Bug introduced by
The constant WooCommerce\RestApi\Cont...ers\Version4\WC_LOG_DIR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
607
			'log_directory_writable'    => (bool) @fopen( WC_LOG_DIR . 'test-log.log', 'a' ), // phpcs:ignore
608
			'wp_version'                => get_bloginfo( 'version' ),
609
			'wp_multisite'              => is_multisite(),
610
			'wp_memory_limit'           => $this->get_wp_memory_limit(),
611
			'wp_debug_mode'             => $this->is_constant_true( 'WP_DEBUG' ),
612
			'wp_cron'                   => ! $this->is_constant_true( 'DISABLE_WP_CRON' ),
613
			'language'                  => get_locale(),
614
			'external_object_cache'     => wp_using_ext_object_cache(),
615
			'server_info'               => $this->get_server_software(),
616
			'php_version'               => phpversion(),
617
			'php_post_max_size'         => wc_let_to_num( ini_get( 'post_max_size' ) ),
618
			'php_max_execution_time'    => ini_get( 'max_execution_time' ),
619
			'php_max_input_vars'        => ini_get( 'max_input_vars' ),
620
			'curl_version'              => $this->get_curl_version(),
621
			'suhosin_installed'         => extension_loaded( 'suhosin' ),
622
			'max_upload_size'           => wp_max_upload_size(),
623
			'mysql_version'             => $database_version['number'],
624
			'mysql_version_string'      => $database_version['string'],
625
			'default_timezone'          => date_default_timezone_get(),
626
			'fsockopen_or_curl_enabled' => $this->fsockopen_or_curl_enabled(),
627
			'soapclient_enabled'        => class_exists( 'SoapClient' ),
628
			'domdocument_enabled'       => class_exists( 'DOMDocument' ),
629
			'gzip_enabled'              => is_callable( 'gzopen' ),
630
			'mbstring_enabled'          => extension_loaded( 'mbstring' ),
631
			'remote_post_successful'    => $post_request['success'],
632
			'remote_post_response'      => $post_request['response'],
633
			'remote_get_successful'     => $get_request['success'],
634
			'remote_get_response'       => $get_request['response'],
635
		);
636
	}
637
638
	/**
639
	 * Test POST to an external server.
640
	 *
641
	 * @return array
642
	 */
643
	protected function test_post_request() {
644
		$post_response_code = get_transient( 'woocommerce_test_remote_post' );
645
646
		if ( false === $post_response_code || is_wp_error( $post_response_code ) ) {
647
			$response = wp_safe_remote_post(
648
				'https://www.paypal.com/cgi-bin/webscr',
649
				array(
650
					'timeout'     => 10,
651
					'user-agent'  => 'WooCommerce/' . WC()->version,
652
					'httpversion' => '1.1',
653
					'body'        => array(
654
						'cmd' => '_notify-validate',
655
					),
656
				)
657
			);
658
			if ( ! is_wp_error( $response ) ) {
659
				$post_response_code = $response['response']['code'];
660
			}
661
			set_transient( 'woocommerce_test_remote_post', $post_response_code, HOUR_IN_SECONDS );
662
		}
663
664
		if ( is_wp_error( $post_response_code ) ) {
665
			return array(
666
				'success'  => false,
667
				'response' => $post_response_code->get_error_message(),
668
			);
669
		}
670
671
		return array(
672
			'success'  => $post_response_code >= 200 && $post_response_code < 300,
673
			'response' => $post_response_code,
674
		);
675
	}
676
677
	/**
678
	 * Test GET to an external server.
679
	 *
680
	 * @return array
681
	 */
682
	protected function test_get_request() {
683
		$get_response_code = get_transient( 'woocommerce_test_remote_get' );
684
685
		if ( false === $get_response_code || is_wp_error( $get_response_code ) ) {
686
			$response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) );
687
			if ( ! is_wp_error( $response ) ) {
688
				$get_response_code = $response['response']['code'];
689
			}
690
			set_transient( 'woocommerce_test_remote_get', $get_response_code, HOUR_IN_SECONDS );
691
		}
692
693
		if ( is_wp_error( $get_response_code ) ) {
694
			return array(
695
				'success'  => false,
696
				'response' => $get_response_code->get_error_message(),
697
			);
698
		}
699
700
		return array(
701
			'success'  => $get_response_code >= 200 && $get_response_code < 300,
702
			'response' => $get_response_code,
703
		);
704
	}
705
706
	/**
707
	 * Return if a constant is defined and true.
708
	 *
709
	 * @param string $name Constant name.
710
	 * @return bool
711
	 */
712
	protected function is_constant_true( $name ) {
713
		return defined( $name ) && (bool) constant( $name );
714
	}
715
716
	/**
717
	 * Return info about server software running.
718
	 *
719
	 * @return string
720
	 */
721
	protected function get_server_software() {
722
		return isset( $_SERVER['SERVER_SOFTWARE'] ) ? wc_clean( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
723
	}
724
725
	/**
726
	 * Get CURL version running on server.
727
	 *
728
	 * @return string
729
	 */
730
	protected function get_curl_version() {
731
		$curl_version = '';
732
		if ( function_exists( 'curl_version' ) ) {
733
			$curl_version = curl_version();
734
			$curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
735
		} elseif ( extension_loaded( 'curl' ) ) {
736
			$curl_version = __( 'cURL installed but unable to retrieve version.', 'woocommerce' );
737
		}
738
		return $curl_version;
739
	}
740
741
	/**
742
	 * Get WP memory limit.
743
	 *
744
	 * @return string
745
	 */
746
	protected function get_wp_memory_limit() {
747
		$wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT );
748
		if ( function_exists( 'memory_get_usage' ) ) {
749
			$wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) );
750
		}
751
		return (string) $wp_memory_limit;
752
	}
753
754
	/**
755
	 * See if modules are enabled.
756
	 *
757
	 * @return bool
758
	 */
759
	protected function fsockopen_or_curl_enabled() {
760
		return function_exists( 'fsockopen' ) || function_exists( 'curl_init' );
761
	}
762
763
	/**
764
	 * Add prefix to table.
765
	 *
766
	 * @param string $table Table name.
767
	 * @return stromg
0 ignored issues
show
Bug introduced by
The type WooCommerce\RestApi\Controllers\Version4\stromg was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
768
	 */
769
	protected function add_db_table_prefix( $table ) {
770
		global $wpdb;
771
		return $wpdb->prefix . $table;
772
	}
773
774
	/**
775
	 * Get array of database information. Version, prefix, and table existence.
776
	 *
777
	 * @return array
778
	 */
779
	public function get_database_info() {
780
		global $wpdb;
781
782
		$database_table_information = $wpdb->get_results(
783
			$wpdb->prepare(
784
				"SELECT
785
				    table_name AS 'name',
786
					engine,
787
				    round( ( data_length / 1024 / 1024 ), 2 ) 'data',
788
				    round( ( index_length / 1024 / 1024 ), 2 ) 'index'
789
				FROM information_schema.TABLES
790
				WHERE table_schema = %s
791
				ORDER BY name ASC;",
792
				DB_NAME
793
			)
794
		);
795
796
		// WC Core tables to check existence of.
797
		$core_tables = apply_filters(
798
			'woocommerce_database_tables',
799
			array(
800
				'woocommerce_sessions',
801
				'woocommerce_api_keys',
802
				'woocommerce_attribute_taxonomies',
803
				'woocommerce_downloadable_product_permissions',
804
				'woocommerce_order_items',
805
				'woocommerce_order_itemmeta',
806
				'woocommerce_tax_rates',
807
				'woocommerce_tax_rate_locations',
808
				'woocommerce_shipping_zones',
809
				'woocommerce_shipping_zone_locations',
810
				'woocommerce_shipping_zone_methods',
811
				'woocommerce_payment_tokens',
812
				'woocommerce_payment_tokenmeta',
813
				'woocommerce_log',
814
			)
815
		);
816
817
		/**
818
		 * Adding the prefix to the tables array, for backwards compatibility.
819
		 *
820
		 * If we changed the tables above to include the prefix, then any filters against that table could break.
821
		 */
822
		$core_tables = array_map( array( $this, 'add_db_table_prefix' ), $core_tables );
823
824
		/**
825
		 * Organize WooCommerce and non-WooCommerce tables separately for display purposes later.
826
		 *
827
		 * To ensure we include all WC tables, even if they do not exist, pre-populate the WC array with all the tables.
828
		 */
829
		$tables = array(
830
			'woocommerce' => array_fill_keys( $core_tables, false ),
831
			'other'       => array(),
832
		);
833
834
		$database_size = array(
835
			'data'  => 0,
836
			'index' => 0,
837
		);
838
839
		$site_tables_prefix = $wpdb->get_blog_prefix( get_current_blog_id() );
840
		$global_tables      = $wpdb->tables( 'global', true );
841
		foreach ( $database_table_information as $table ) {
842
			// Only include tables matching the prefix of the current site, this is to prevent displaying all tables on a MS install not relating to the current.
843
			if ( is_multisite() && 0 !== strpos( $table->name, $site_tables_prefix ) && ! in_array( $table->name, $global_tables, true ) ) {
844
				continue;
845
			}
846
			$table_type = in_array( $table->name, $core_tables, true ) ? 'woocommerce' : 'other';
847
848
			$tables[ $table_type ][ $table->name ] = array(
849
				'data'   => $table->data,
850
				'index'  => $table->index,
851
				'engine' => $table->engine,
852
			);
853
854
			$database_size['data']  += $table->data;
855
			$database_size['index'] += $table->index;
856
		}
857
858
		// Return all database info. Described by JSON Schema.
859
		return array(
860
			'wc_database_version'    => get_option( 'woocommerce_db_version' ),
861
			'database_prefix'        => $wpdb->prefix,
862
			'maxmind_geoip_database' => \WC_Geolocation::get_local_database_path(),
863
			'database_tables'        => $tables,
864
			'database_size'          => $database_size,
865
		);
866
	}
867
868
	/**
869
	 * Get array of counts of objects. Orders, products, etc.
870
	 *
871
	 * @return array
872
	 */
873
	public function get_post_type_counts() {
874
		global $wpdb;
875
876
		$post_type_counts = $wpdb->get_results( "SELECT post_type AS 'type', count(1) AS 'count' FROM {$wpdb->posts} GROUP BY post_type;" );
877
878
		return is_array( $post_type_counts ) ? $post_type_counts : array();
879
	}
880
881
	/**
882
	 * Get a list of plugins active on the site.
883
	 *
884
	 * @return array
885
	 */
886
	public function get_active_plugins() {
887
		require_once ABSPATH . 'wp-admin/includes/plugin.php';
888
889
		if ( ! function_exists( 'get_plugin_data' ) ) {
890
			return array();
891
		}
892
893
		$active_plugins = (array) get_option( 'active_plugins', array() );
894
		if ( is_multisite() ) {
895
			$network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
896
			$active_plugins            = array_merge( $active_plugins, $network_activated_plugins );
897
		}
898
899
		$active_plugins_data = array();
900
901
		foreach ( $active_plugins as $plugin ) {
902
			$data                  = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
903
			$active_plugins_data[] = $this->format_plugin_data( $plugin, $data );
904
		}
905
906
		return $active_plugins_data;
907
	}
908
909
	/**
910
	 * Get a list of inplugins active on the site.
911
	 *
912
	 * @return array
913
	 */
914
	public function get_inactive_plugins() {
915
		require_once ABSPATH . 'wp-admin/includes/plugin.php';
916
917
		if ( ! function_exists( 'get_plugins' ) ) {
918
			return array();
919
		}
920
921
		$plugins        = get_plugins();
922
		$active_plugins = (array) get_option( 'active_plugins', array() );
923
924
		if ( is_multisite() ) {
925
			$network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
926
			$active_plugins            = array_merge( $active_plugins, $network_activated_plugins );
927
		}
928
929
		$plugins_data = array();
930
931
		foreach ( $plugins as $plugin => $data ) {
932
			if ( in_array( $plugin, $active_plugins, true ) ) {
933
				continue;
934
			}
935
			$plugins_data[] = $this->format_plugin_data( $plugin, $data );
936
		}
937
938
		return $plugins_data;
939
	}
940
941
	/**
942
	 * Format plugin data, including data on updates, into a standard format.
943
	 *
944
	 * @since 3.6.0
945
	 * @param string $plugin Plugin directory/file.
946
	 * @param array  $data Plugin data from WP.
947
	 * @return array Formatted data.
948
	 */
949
	protected function format_plugin_data( $plugin, $data ) {
950
		require_once ABSPATH . 'wp-admin/includes/update.php';
951
952
		if ( ! function_exists( 'get_plugin_updates' ) ) {
953
			return array();
954
		}
955
956
		// Use WP API to lookup latest updates for plugins. WC_Helper injects updates for premium plugins.
957
		if ( empty( $this->available_updates ) ) {
958
			$this->available_updates = get_plugin_updates();
959
		}
960
961
		$version_latest = $data['Version'];
962
963
		// Find latest version.
964
		if ( isset( $this->available_updates[ $plugin ]->update->new_version ) ) {
965
			$version_latest = $this->available_updates[ $plugin ]->update->new_version;
966
		}
967
968
		return array(
969
			'plugin'            => $plugin,
970
			'name'              => $data['Name'],
971
			'version'           => $data['Version'],
972
			'version_latest'    => $version_latest,
973
			'url'               => $data['PluginURI'],
974
			'author_name'       => $data['AuthorName'],
975
			'author_url'        => esc_url_raw( $data['AuthorURI'] ),
976
			'network_activated' => $data['Network'],
977
		);
978
	}
979
980
	/**
981
	 * Get a list of Dropins and MU plugins.
982
	 *
983
	 * @since 3.6.0
984
	 * @return array
985
	 */
986
	public function get_dropins_mu_plugins() {
987
		$dropins = get_dropins();
988
		$plugins = array(
989
			'dropins'    => array(),
990
			'mu_plugins' => array(),
991
		);
992
		foreach ( $dropins as $key => $dropin ) {
993
			$plugins['dropins'][] = array(
994
				'plugin' => $key,
995
				'name'   => $dropin['Name'],
996
			);
997
		}
998
999
		$mu_plugins = get_mu_plugins();
1000
		foreach ( $mu_plugins as $plugin => $mu_plugin ) {
1001
			$plugins['mu_plugins'][] = array(
1002
				'plugin'      => $plugin,
1003
				'name'        => $mu_plugin['Name'],
1004
				'version'     => $mu_plugin['Version'],
1005
				'url'         => $mu_plugin['PluginURI'],
1006
				'author_name' => $mu_plugin['AuthorName'],
1007
				'author_url'  => esc_url_raw( $mu_plugin['AuthorURI'] ),
1008
			);
1009
		}
1010
		return $plugins;
1011
	}
1012
1013
	/**
1014
	 * Get info on the current active theme, info on parent theme (if presnet)
1015
	 * and a list of template overrides.
1016
	 *
1017
	 * @return array
1018
	 */
1019
	public function get_theme_info() {
1020
		$active_theme = wp_get_theme();
1021
1022
		// Get parent theme info if this theme is a child theme, otherwise
1023
		// pass empty info in the response.
1024
		if ( is_child_theme() ) {
1025
			$parent_theme      = wp_get_theme( $active_theme->template );
1026
			$parent_theme_info = array(
1027
				'parent_name'           => $parent_theme->name,
1028
				'parent_version'        => $parent_theme->version,
1029
				'parent_version_latest' => \WC_Admin_Status::get_latest_theme_version( $parent_theme ),
1030
				'parent_author_url'     => $parent_theme->{'Author URI'},
1031
			);
1032
		} else {
1033
			$parent_theme_info = array(
1034
				'parent_name'           => '',
1035
				'parent_version'        => '',
1036
				'parent_version_latest' => '',
1037
				'parent_author_url'     => '',
1038
			);
1039
		}
1040
1041
		/**
1042
		 * Scan the theme directory for all WC templates to see if our theme
1043
		 * overrides any of them.
1044
		 */
1045
		$override_files     = array();
1046
		$outdated_templates = false;
1047
		$scan_files         = \WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' );
1048
		foreach ( $scan_files as $file ) {
1049
			$located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' );
1050
1051
			if ( file_exists( $located ) ) {
1052
				$theme_file = $located;
1053
			} elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
1054
				$theme_file = get_stylesheet_directory() . '/' . $file;
1055
			} elseif ( file_exists( get_stylesheet_directory() . '/' . WC()->template_path() . $file ) ) {
1056
				$theme_file = get_stylesheet_directory() . '/' . WC()->template_path() . $file;
1057
			} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
1058
				$theme_file = get_template_directory() . '/' . $file;
1059
			} elseif ( file_exists( get_template_directory() . '/' . WC()->template_path() . $file ) ) {
1060
				$theme_file = get_template_directory() . '/' . WC()->template_path() . $file;
1061
			} else {
1062
				$theme_file = false;
1063
			}
1064
1065
			if ( ! empty( $theme_file ) ) {
1066
				$core_version  = \WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file );
1067
				$theme_version = \WC_Admin_Status::get_file_version( $theme_file );
1068
				if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
1069
					if ( ! $outdated_templates ) {
1070
						$outdated_templates = true;
1071
					}
1072
				}
1073
				$override_files[] = array(
1074
					'file'         => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
1075
					'version'      => $theme_version,
1076
					'core_version' => $core_version,
1077
				);
1078
			}
1079
		}
1080
1081
		$active_theme_info = array(
1082
			'name'                    => $active_theme->name,
1083
			'version'                 => $active_theme->version,
1084
			'version_latest'          => \WC_Admin_Status::get_latest_theme_version( $active_theme ),
1085
			'author_url'              => esc_url_raw( $active_theme->{'Author URI'} ),
1086
			'is_child_theme'          => is_child_theme(),
1087
			'has_woocommerce_support' => current_theme_supports( 'woocommerce' ),
1088
			'has_woocommerce_file'    => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ),
1089
			'has_outdated_templates'  => $outdated_templates,
1090
			'overrides'               => $override_files,
1091
		);
1092
1093
		return array_merge( $active_theme_info, $parent_theme_info );
1094
	}
1095
1096
	/**
1097
	 * Get some setting values for the site that are useful for debugging
1098
	 * purposes. For full settings access, use the settings api.
1099
	 *
1100
	 * @return array
1101
	 */
1102
	public function get_settings() {
1103
		// Get a list of terms used for product/order taxonomies.
1104
		$term_response = array();
1105
		$terms         = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
1106
		foreach ( $terms as $term ) {
1107
			$term_response[ $term->slug ] = strtolower( $term->name );
1108
		}
1109
1110
		// Get a list of terms used for product visibility.
1111
		$product_visibility_terms = array();
1112
		$terms                    = get_terms( 'product_visibility', array( 'hide_empty' => 0 ) );
1113
		foreach ( $terms as $term ) {
1114
			$product_visibility_terms[ $term->slug ] = strtolower( $term->name );
1115
		}
1116
1117
		// Check if WooCommerce.com account is connected.
1118
		$woo_com_connected = 'no';
1119
		$helper_options    = get_option( 'woocommerce_helper_data', array() );
1120
		if ( array_key_exists( 'auth', $helper_options ) && ! empty( $helper_options['auth'] ) ) {
0 ignored issues
show
Bug introduced by
It seems like $helper_options can also be of type false; however, parameter $search of array_key_exists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1120
		if ( array_key_exists( 'auth', /** @scrutinizer ignore-type */ $helper_options ) && ! empty( $helper_options['auth'] ) ) {
Loading history...
1121
			$woo_com_connected = 'yes';
1122
		}
1123
1124
		// Return array of useful settings for debugging.
1125
		return array(
1126
			'api_enabled'               => 'yes' === get_option( 'woocommerce_api_enabled' ),
1127
			'force_ssl'                 => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ),
1128
			'currency'                  => get_woocommerce_currency(),
1129
			'currency_symbol'           => get_woocommerce_currency_symbol(),
1130
			'currency_position'         => get_option( 'woocommerce_currency_pos' ),
1131
			'thousand_separator'        => wc_get_price_thousand_separator(),
1132
			'decimal_separator'         => wc_get_price_decimal_separator(),
1133
			'number_of_decimals'        => wc_get_price_decimals(),
1134
			'geolocation_enabled'       => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ),
1135
			'taxonomies'                => $term_response,
1136
			'product_visibility_terms'  => $product_visibility_terms,
1137
			'woocommerce_com_connected' => $woo_com_connected,
1138
		);
1139
	}
1140
1141
	/**
1142
	 * Returns security tips.
1143
	 *
1144
	 * @return array
1145
	 */
1146
	public function get_security_info() {
1147
		$check_page = wc_get_page_permalink( 'shop' );
1148
		return array(
1149
			'secure_connection' => 'https' === substr( $check_page, 0, 5 ),
1150
			'hide_errors'       => ! ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG && WP_DEBUG_DISPLAY ) || 0 === intval( ini_get( 'display_errors' ) ),
1151
		);
1152
	}
1153
1154
	/**
1155
	 * Returns a mini-report on WC pages and if they are configured correctly:
1156
	 * Present, visible, and including the correct shortcode.
1157
	 *
1158
	 * @return array
1159
	 */
1160
	public function get_pages() {
1161
		// WC pages to check against.
1162
		$check_pages = array(
1163
			_x( 'Shop base', 'Page setting', 'woocommerce' ) => array(
1164
				'option'    => 'woocommerce_shop_page_id',
1165
				'shortcode' => '',
1166
			),
1167
			_x( 'Cart', 'Page setting', 'woocommerce' ) => array(
1168
				'option'    => 'woocommerce_cart_page_id',
1169
				'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
1170
			),
1171
			_x( 'Checkout', 'Page setting', 'woocommerce' ) => array(
1172
				'option'    => 'woocommerce_checkout_page_id',
1173
				'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
1174
			),
1175
			_x( 'My account', 'Page setting', 'woocommerce' ) => array(
1176
				'option'    => 'woocommerce_myaccount_page_id',
1177
				'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
1178
			),
1179
			_x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array(
1180
				'option'    => 'woocommerce_terms_page_id',
1181
				'shortcode' => '',
1182
			),
1183
		);
1184
1185
		$pages_output = array();
1186
		foreach ( $check_pages as $page_name => $values ) {
1187
			$page_id            = get_option( $values['option'] );
1188
			$page_set           = false;
1189
			$page_exists        = false;
1190
			$page_visible       = false;
1191
			$shortcode_present  = false;
1192
			$shortcode_required = false;
1193
1194
			// Page checks.
1195
			if ( $page_id ) {
1196
				$page_set = true;
1197
			}
1198
			if ( get_post( $page_id ) ) {
1199
				$page_exists = true;
1200
			}
1201
			if ( 'publish' === get_post_status( $page_id ) ) {
1202
				$page_visible = true;
1203
			}
1204
1205
			// Shortcode checks.
1206
			if ( $values['shortcode'] && get_post( $page_id ) ) {
1207
				$shortcode_required = true;
1208
				$page               = get_post( $page_id );
1209
				if ( strstr( $page->post_content, $values['shortcode'] ) ) {
1210
					$shortcode_present = true;
1211
				}
1212
			}
1213
1214
			// Wrap up our findings into an output array.
1215
			$pages_output[] = array(
1216
				'page_name'          => $page_name,
1217
				'page_id'            => $page_id,
1218
				'page_set'           => $page_set,
1219
				'page_exists'        => $page_exists,
1220
				'page_visible'       => $page_visible,
1221
				'shortcode'          => $values['shortcode'],
1222
				'shortcode_required' => $shortcode_required,
1223
				'shortcode_present'  => $shortcode_present,
1224
			);
1225
		}
1226
1227
		return $pages_output;
1228
	}
1229
1230
	/**
1231
	 * Get any query params needed.
1232
	 *
1233
	 * @return array
1234
	 */
1235
	public function get_collection_params() {
1236
		return array(
1237
			'context' => $this->get_context_param( array( 'default' => 'view' ) ),
1238
		);
1239
	}
1240
1241
	/**
1242
	 * Prepare the system status response
1243
	 *
1244
	 * @param  array           $system_status System status data.
1245
	 * @param  \WP_REST_Request $request       Request object.
1246
	 * @return \WP_REST_Response
1247
	 */
1248
	public function prepare_item_for_response( $system_status, $request ) {
1249
		$data = $this->add_additional_fields_to_object( $system_status, $request );
1250
		$data = $this->filter_response_by_context( $data, 'view' );
1251
1252
		$response = rest_ensure_response( $data );
1253
1254
		/**
1255
		 * Filter the system status returned from the REST API.
1256
		 *
1257
		 * @param \WP_REST_Response   $response The response object.
1258
		 * @param mixed              $system_status System status
1259
		 * @param \WP_REST_Request    $request  Request object.
1260
		 */
1261
		return apply_filters( 'woocommerce_rest_prepare_system_status', $response, $system_status, $request );
1262
	}
1263
}
1264