Passed
Push — master ( 893fa6...9a7f47 )
by Mike
04:33
created

SystemStatusTools::clear_transients()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 2
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * REST API WC System Status Tools Controller
4
 *
5
 * Handles requests to the /system_status/tools/* endpoints.
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 Tools controller class.
16
 */
17
class SystemStatusTools extends AbstractController {
18
19
	/**
20
	 * Route base.
21
	 *
22
	 * @var string
23
	 */
24
	protected $rest_base = 'system_status/tools';
25
26
	/**
27
	 * Register the routes for /system_status/tools/*.
28
	 */
29
	public function register_routes() {
30
		register_rest_route(
31
			$this->namespace,
32
			'/' . $this->rest_base,
33
			array(
34
				array(
35
					'methods'             => \WP_REST_Server::READABLE,
36
					'callback'            => array( $this, 'get_items' ),
37
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
38
					'args'                => $this->get_collection_params(),
39
				),
40
				'schema' => array( $this, 'get_public_item_schema' ),
41
			),
42
			true
43
		);
44
45
		register_rest_route(
46
			$this->namespace,
47
			'/' . $this->rest_base . '/(?P<id>[\w-]+)',
48
			array(
49
				'args'   => array(
50
					'id' => array(
51
						'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
52
						'type'        => 'string',
53
					),
54
				),
55
				array(
56
					'methods'             => \WP_REST_Server::READABLE,
57
					'callback'            => array( $this, 'get_item' ),
58
					'permission_callback' => array( $this, 'get_item_permissions_check' ),
59
				),
60
				array(
61
					'methods'             => \WP_REST_Server::EDITABLE,
62
					'callback'            => array( $this, 'update_item' ),
63
					'permission_callback' => array( $this, 'update_item_permissions_check' ),
64
					'args'                => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
65
				),
66
				'schema' => array( $this, 'get_public_item_schema' ),
67
			),
68
			true
69
		);
70
	}
71
72
	/**
73
	 * Check whether a given request has permission to view system status tools.
74
	 *
75
	 * @param  \WP_REST_Request $request Full details about the request.
76
	 * @return \WP_Error|boolean
77
	 */
78
	public function get_items_permissions_check( $request ) {
79
		if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
80
			return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
81
		}
82
		return true;
83
	}
84
85
	/**
86
	 * Check whether a given request has permission to view a specific system status tool.
87
	 *
88
	 * @param  \WP_REST_Request $request Full details about the request.
89
	 * @return \WP_Error|boolean
90
	 */
91
	public function get_item_permissions_check( $request ) {
92
		if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
93
			return new \WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
94
		}
95
		return true;
96
	}
97
98
	/**
99
	 * Check whether a given request has permission to execute a specific system status tool.
100
	 *
101
	 * @param  \WP_REST_Request $request Full details about the request.
102
	 * @return \WP_Error|boolean
103
	 */
104
	public function update_item_permissions_check( $request ) {
105
		if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) {
106
			return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
107
		}
108
		return true;
109
	}
110
111
	/**
112
	 * A list of available tools for use in the system status section.
113
	 * 'button' becomes 'action' in the API.
114
	 *
115
	 * @return array
116
	 */
117
	public function get_tools() {
118
		$tools = array(
119
			'clear_transients'                   => array(
120
				'name'   => __( 'WooCommerce transients', 'woocommerce' ),
121
				'button' => __( 'Clear transients', 'woocommerce' ),
122
				'desc'   => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ),
123
			),
124
			'clear_expired_transients'           => array(
125
				'name'   => __( 'Expired transients', 'woocommerce' ),
126
				'button' => __( 'Clear transients', 'woocommerce' ),
127
				'desc'   => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ),
128
			),
129
			'delete_orphaned_variations'         => array(
130
				'name'   => __( 'Orphaned variations', 'woocommerce' ),
131
				'button' => __( 'Delete orphaned variations', 'woocommerce' ),
132
				'desc'   => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ),
133
			),
134
			'clear_expired_download_permissions' => array(
135
				'name'   => __( 'Used-up download permissions', 'woocommerce' ),
136
				'button' => __( 'Clean up download permissions', 'woocommerce' ),
137
				'desc'   => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ),
138
			),
139
			'regenerate_product_lookup_tables'   => array(
140
				'name'   => __( 'Product lookup tables', 'woocommerce' ),
141
				'button' => __( 'Regenerate', 'woocommerce' ),
142
				'desc'   => __( 'This tool will regenerate product lookup table data. This process may take a while.', 'woocommerce' ),
143
			),
144
			'recount_terms'                      => array(
145
				'name'   => __( 'Term counts', 'woocommerce' ),
146
				'button' => __( 'Recount terms', 'woocommerce' ),
147
				'desc'   => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ),
148
			),
149
			'reset_roles'                        => array(
150
				'name'   => __( 'Capabilities', 'woocommerce' ),
151
				'button' => __( 'Reset capabilities', 'woocommerce' ),
152
				'desc'   => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ),
153
			),
154
			'clear_sessions'                     => array(
155
				'name'   => __( 'Clear customer sessions', 'woocommerce' ),
156
				'button' => __( 'Clear', 'woocommerce' ),
157
				'desc'   => sprintf(
158
					'<strong class="red">%1$s</strong> %2$s',
159
					__( 'Note:', 'woocommerce' ),
160
					__( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' )
161
				),
162
			),
163
			'install_pages'                      => array(
164
				'name'   => __( 'Create default WooCommerce pages', 'woocommerce' ),
165
				'button' => __( 'Create pages', 'woocommerce' ),
166
				'desc'   => sprintf(
167
					'<strong class="red">%1$s</strong> %2$s',
168
					__( 'Note:', 'woocommerce' ),
169
					__( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' )
170
				),
171
			),
172
			'delete_taxes'                       => array(
173
				'name'   => __( 'Delete WooCommerce tax rates', 'woocommerce' ),
174
				'button' => __( 'Delete tax rates', 'woocommerce' ),
175
				'desc'   => sprintf(
176
					'<strong class="red">%1$s</strong> %2$s',
177
					__( 'Note:', 'woocommerce' ),
178
					__( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' )
179
				),
180
			),
181
			'regenerate_thumbnails'              => array(
182
				'name'   => __( 'Regenerate shop thumbnails', 'woocommerce' ),
183
				'button' => __( 'Regenerate', 'woocommerce' ),
184
				'desc'   => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ),
185
			),
186
			'db_update_routine'                  => array(
187
				'name'   => __( 'Update database', 'woocommerce' ),
188
				'button' => __( 'Update database', 'woocommerce' ),
189
				'desc'   => sprintf(
190
					'<strong class="red">%1$s</strong> %2$s',
191
					__( 'Note:', 'woocommerce' ),
192
					__( 'This tool will update your WooCommerce database to the latest version. Please ensure you make sufficient backups before proceeding.', 'woocommerce' )
193
				),
194
			),
195
		);
196
197
		// Jetpack does the image resizing heavy lifting so you don't have to.
198
		if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) {
0 ignored issues
show
Bug introduced by
The type WooCommerce\RestApi\Controllers\Version4\Jetpack 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...
199
			unset( $tools['regenerate_thumbnails'] );
200
		}
201
202
		return apply_filters( 'woocommerce_debug_tools', $tools );
203
	}
204
205
	/**
206
	 * Get a list of system status tools.
207
	 *
208
	 * @param \WP_REST_Request $request Full details about the request.
209
	 * @return \WP_Error|\WP_REST_Response
210
	 */
211
	public function get_items( $request ) {
212
		$tools = array();
213
		foreach ( $this->get_tools() as $id => $tool ) {
214
			$tools[] = $this->prepare_response_for_collection(
215
				$this->prepare_item_for_response(
216
					array(
217
						'id'          => $id,
218
						'name'        => $tool['name'],
219
						'action'      => $tool['button'],
220
						'description' => $tool['desc'],
221
					),
222
					$request
223
				)
224
			);
225
		}
226
227
		$response = rest_ensure_response( $tools );
228
		return $response;
229
	}
230
231
	/**
232
	 * Return a single tool.
233
	 *
234
	 * @param  \WP_REST_Request $request Request data.
235
	 * @return \WP_Error|\WP_REST_Response
236
	 */
237
	public function get_item( $request ) {
238
		$tools = $this->get_tools();
239
		if ( empty( $tools[ $request['id'] ] ) ) {
240
			return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) );
241
		}
242
		$tool = $tools[ $request['id'] ];
243
		return rest_ensure_response(
244
			$this->prepare_item_for_response(
245
				array(
246
					'id'          => $request['id'],
247
					'name'        => $tool['name'],
248
					'action'      => $tool['button'],
249
					'description' => $tool['desc'],
250
				),
251
				$request
252
			)
253
		);
254
	}
255
256
	/**
257
	 * Update (execute) a tool.
258
	 *
259
	 * @param  \WP_REST_Request $request Request data.
260
	 * @return \WP_Error|\WP_REST_Response
261
	 */
262
	public function update_item( $request ) {
263
		$tools = $this->get_tools();
264
		if ( empty( $tools[ $request['id'] ] ) ) {
265
			return new \WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) );
266
		}
267
268
		$tool = $tools[ $request['id'] ];
269
		$tool = array(
270
			'id'          => $request['id'],
271
			'name'        => $tool['name'],
272
			'action'      => $tool['button'],
273
			'description' => $tool['desc'],
274
		);
275
276
		$execute_return = $this->execute_tool( $request['id'] );
277
		$tool           = array_merge( $tool, $execute_return );
278
279
		/**
280
		 * Fires after a WooCommerce REST system status tool has been executed.
281
		 *
282
		 * @param array           $tool    Details about the tool that has been executed.
283
		 * @param \WP_REST_Request $request The current \WP_REST_Request object.
284
		 */
285
		do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request );
286
287
		$request->set_param( 'context', 'edit' );
288
		$response = $this->prepare_item_for_response( $tool, $request );
289
		return rest_ensure_response( $response );
290
	}
291
292
	/**
293
	 * Prepare a tool item for serialization.
294
	 *
295
	 * @param  array            $item     Object.
296
	 * @param  \WP_REST_Request $request  Request object.
297
	 * @return \WP_REST_Response $response Response data.
298
	 */
299
	public function prepare_item_for_response( $item, $request ) {
300
		$context = empty( $request['context'] ) ? 'view' : $request['context'];
301
		$data    = $this->add_additional_fields_to_object( $item, $request );
302
		$data    = $this->filter_response_by_context( $data, $context );
303
304
		$response = rest_ensure_response( $data );
305
306
		$response->add_links( $this->prepare_links( $item['id'] ) );
307
308
		return $response;
309
	}
310
311
	/**
312
	 * Get the system status tools schema, conforming to JSON Schema.
313
	 *
314
	 * @return array
315
	 */
316
	public function get_item_schema() {
317
		$schema = array(
318
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
319
			'title'      => 'system_status_tool',
320
			'type'       => 'object',
321
			'properties' => array(
322
				'id'          => array(
323
					'description' => __( 'A unique identifier for the tool.', 'woocommerce' ),
324
					'type'        => 'string',
325
					'context'     => array( 'view', 'edit' ),
326
					'arg_options' => array(
327
						'sanitize_callback' => 'sanitize_title',
328
					),
329
				),
330
				'name'        => array(
331
					'description' => __( 'Tool name.', 'woocommerce' ),
332
					'type'        => 'string',
333
					'context'     => array( 'view', 'edit' ),
334
					'arg_options' => array(
335
						'sanitize_callback' => 'sanitize_text_field',
336
					),
337
				),
338
				'action'      => array(
339
					'description' => __( 'What running the tool will do.', 'woocommerce' ),
340
					'type'        => 'string',
341
					'context'     => array( 'view', 'edit' ),
342
					'arg_options' => array(
343
						'sanitize_callback' => 'sanitize_text_field',
344
					),
345
				),
346
				'description' => array(
347
					'description' => __( 'Tool description.', 'woocommerce' ),
348
					'type'        => 'string',
349
					'context'     => array( 'view', 'edit' ),
350
					'arg_options' => array(
351
						'sanitize_callback' => 'sanitize_text_field',
352
					),
353
				),
354
				'success'     => array(
355
					'description' => __( 'Did the tool run successfully?', 'woocommerce' ),
356
					'type'        => 'boolean',
357
					'context'     => array( 'edit' ),
358
				),
359
				'message'     => array(
360
					'description' => __( 'Tool return message.', 'woocommerce' ),
361
					'type'        => 'string',
362
					'context'     => array( 'edit' ),
363
					'arg_options' => array(
364
						'sanitize_callback' => 'sanitize_text_field',
365
					),
366
				),
367
			),
368
		);
369
370
		return $this->add_additional_fields_schema( $schema );
371
	}
372
373
	/**
374
	 * Prepare links for the request.
375
	 *
376
	 * @param string $id ID.
377
	 * @return array
378
	 */
379
	protected function prepare_links( $id ) {
380
		$base  = '/' . $this->namespace . '/' . $this->rest_base;
381
		$links = array(
382
			'item' => array(
383
				'href'       => rest_url( trailingslashit( $base ) . $id ),
384
				'embeddable' => true,
385
			),
386
		);
387
388
		return $links;
389
	}
390
391
	/**
392
	 * Get any query params needed.
393
	 *
394
	 * @return array
395
	 */
396
	public function get_collection_params() {
397
		return array(
398
			'context' => $this->get_context_param( array( 'default' => 'view' ) ),
399
		);
400
	}
401
402
	/**
403
	 * Actually executes a tool.
404
	 *
405
	 * @throws Exception When the tool cannot run.
406
	 * @param  string $tool Tool.
407
	 * @return array
408
	 */
409
	public function execute_tool( $tool ) {
410
		$ran   = false;
411
		$tools = $this->get_tools();
412
413
		try {
414
			if ( ! isset( $tools[ $tool ] ) ) {
415
				throw new Exception( __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' ) );
0 ignored issues
show
Bug introduced by
The type WooCommerce\RestApi\Controllers\Version4\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
416
			}
417
418
			$callback = isset( $tools[ $tool ]['callback'] ) ? $tools[ $tool ]['callback'] : array( $this, $tool );
419
420
			if ( ! is_callable( $callback ) ) {
421
				throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) );
422
			}
423
424
			$message = call_user_func( $callback );
425
426
			if ( false === $message ) {
427
				throw new Exception( __( 'There was an error calling this tool. Invalid callback.', 'woocommerce' ) );
428
			}
429
430
			if ( empty( $message ) || ! is_string( $message ) ) {
431
				$message = __( 'Tool ran.', 'woocommerce' );
432
			}
433
434
			$ran = true;
435
		} catch ( Exception $e ) {
436
			$message = $e->getMessage();
437
			$ran     = false;
438
		}
439
440
		return array(
441
			'success' => $ran,
442
			'message' => $message,
443
		);
444
	}
445
446
	/**
447
	 * Tool: clear_transients.
448
	 *
449
	 * @return string Success message.
450
	 */
451
	protected function clear_transients() {
452
		wc_delete_product_transients();
453
		wc_delete_shop_order_transients();
454
		delete_transient( 'wc_count_comments' );
455
456
		$attribute_taxonomies = wc_get_attribute_taxonomies();
457
458
		if ( ! empty( $attribute_taxonomies ) ) {
459
			foreach ( $attribute_taxonomies as $attribute ) {
460
				delete_transient( 'wc_layered_nav_counts_pa_' . $attribute->attribute_name );
461
			}
462
		}
463
464
		\WC_Cache_Helper::get_transient_version( 'shipping', true );
465
		return __( 'Product transients cleared', 'woocommerce' );
466
	}
467
468
	/**
469
	 * Tool: clear_expired_transients.
470
	 *
471
	 * @return string Success message.
472
	 */
473
	protected function clear_expired_transients() {
474
		/* translators: %d: amount of expired transients */
475
		return sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() );
476
	}
477
478
	/**
479
	 * Tool: delete_orphaned_variations.
480
	 *
481
	 * @return string Success message.
482
	 */
483
	protected function delete_orphaned_variations() {
484
		global $wpdb;
485
486
		$result = absint(
487
			$wpdb->query(
488
				"DELETE products
489
			FROM {$wpdb->posts} products
490
			LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent
491
			WHERE wp.ID IS NULL AND products.post_type = 'product_variation';"
492
			)
493
		);
494
		/* translators: %d: amount of orphaned variations */
495
		return sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result );
496
	}
497
498
	/**
499
	 * Tool: clear_expired_download_permissions.
500
	 *
501
	 * @return string Success message.
502
	 */
503
	protected function clear_expired_download_permissions() {
504
		global $wpdb;
505
506
		$result = absint(
507
			$wpdb->query(
508
				$wpdb->prepare(
509
					"DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
510
					WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )",
511
					date( 'Y-m-d', current_time( 'timestamp' ) )
512
				)
513
			)
514
		);
515
		/* translators: %d: amount of permissions */
516
		return sprintf( __( '%d permissions deleted', 'woocommerce' ), $result );
517
	}
518
519
	/**
520
	 * Tool: regenerate_product_lookup_tables.
521
	 *
522
	 * @return string Success message.
523
	 */
524
	protected function regenerate_product_lookup_tables() {
525
		if ( ! wc_update_product_lookup_tables_is_running() ) {
526
			wc_update_product_lookup_tables();
527
		}
528
		return __( 'Lookup tables are regenerating', 'woocommerce' );
529
	}
530
531
	/**
532
	 * Tool: reset_roles.
533
	 *
534
	 * @return string Success message.
535
	 */
536
	protected function reset_roles() {
537
		\WC_Install::remove_roles();
538
		\WC_Install::create_roles();
539
		return __( 'Roles successfully reset', 'woocommerce' );
540
	}
541
542
	/**
543
	 * Tool: recount_terms.
544
	 *
545
	 * @return string Success message.
546
	 */
547
	protected function recount_terms() {
548
		$product_cats = get_terms(
549
			'product_cat',
550
			array(
551
				'hide_empty' => false,
552
				'fields'     => 'id=>parent',
553
			)
554
		);
555
		_wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
556
		$product_tags = get_terms(
557
			'product_tag',
558
			array(
559
				'hide_empty' => false,
560
				'fields'     => 'id=>parent',
561
			)
562
		);
563
		_wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
564
		return __( 'Terms successfully recounted', 'woocommerce' );
565
	}
566
567
	/**
568
	 * Tool: clear_sessions.
569
	 *
570
	 * @return string Success message.
571
	 */
572
	protected function clear_sessions() {
573
		global $wpdb;
574
575
		$wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" );
576
		$result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok.
577
		wp_cache_flush();
578
		/* translators: %d: amount of sessions */
579
		return sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) );
580
	}
581
582
	/**
583
	 * Tool: install_pages.
584
	 *
585
	 * @return string Success message.
586
	 */
587
	protected function install_pages() {
588
		\WC_Install::create_pages();
589
		return __( 'All missing WooCommerce pages successfully installed', 'woocommerce' );
590
	}
591
592
	/**
593
	 * Tool: delete_taxes.
594
	 *
595
	 * @return string Success message.
596
	 */
597
	protected function delete_taxes() {
598
		global $wpdb;
599
		$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" );
600
		$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" );
601
		\WC_Cache_Helper::incr_cache_prefix( 'taxes' );
602
		return __( 'Tax rates successfully deleted', 'woocommerce' );
603
	}
604
605
	/**
606
	 * Tool: regenerate_thumbnails.
607
	 *
608
	 * @return string Success message.
609
	 */
610
	protected function regenerate_thumbnails() {
611
		\WC_Regenerate_Images::queue_image_regeneration();
612
		return __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' );
613
	}
614
615
	/**
616
	 * Tool: db_update_routine.
617
	 *
618
	 * @return string Success message.
619
	 */
620
	protected function db_update_routine() {
621
		$blog_id = get_current_blog_id();
622
		// Used to fire an action added in WP_Background_Process::_construct() that calls WP_Background_Process::handle_cron_healthcheck().
623
		// This method will make sure the database updates are executed even if cron is disabled. Nothing will happen if the updates are already running.
624
		do_action( 'wp_' . $blog_id . '_wc_updater_cron' );
625
		return __( 'Database upgrade routine has been scheduled to run in the background.', 'woocommerce' );
626
	}
627
}
628