Merge pull request #18752 from woocommerce/refactor/background-processing
Introduced new WC_Background_Process abstract class
This commit is contained in:
commit
db54911443
|
@ -0,0 +1,212 @@
|
|||
<?php
|
||||
/**
|
||||
* Abstract WP_Background_Process class.
|
||||
*
|
||||
* Uses https://github.com/A5hleyRich/wp-background-processing to handle DB
|
||||
* updates in the background.
|
||||
*
|
||||
* @package WooCommerce/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Request', false ) ) {
|
||||
include_once dirname( WC_PLUGIN_FILE ) . '/includes/libraries/wp-async-request.php';
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Background_Process', false ) ) {
|
||||
include_once dirname( WC_PLUGIN_FILE ) . '/includes/libraries/wp-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Background_Process class.
|
||||
*/
|
||||
abstract class WC_Background_Process extends WP_Background_Process {
|
||||
|
||||
/**
|
||||
* Is queue empty.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_queue_empty() {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->options;
|
||||
$column = 'option_name';
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$table = $wpdb->sitemeta;
|
||||
$column = 'meta_key';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
|
||||
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
|
||||
|
||||
return ( $count > 0 ) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get batch.
|
||||
*
|
||||
* @return stdClass Return the first batch from the queue.
|
||||
*/
|
||||
protected function get_batch() {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->options;
|
||||
$column = 'option_name';
|
||||
$key_column = 'option_id';
|
||||
$value_column = 'option_value';
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$table = $wpdb->sitemeta;
|
||||
$column = 'meta_key';
|
||||
$key_column = 'meta_id';
|
||||
$value_column = 'meta_value';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
|
||||
$query = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC LIMIT 1", $key ) ); // @codingStandardsIgnoreLine.
|
||||
|
||||
$batch = new stdClass();
|
||||
$batch->key = $query->$column;
|
||||
$batch->data = maybe_unserialize( $query->$value_column );
|
||||
|
||||
return $batch;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the batch limit has been exceeded.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function batch_limit_exceeded() {
|
||||
return $this->time_exceeded() || $this->memory_exceeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle.
|
||||
*
|
||||
* Pass each queue item to the task handler, while remaining
|
||||
* within server memory and time limit constraints.
|
||||
*/
|
||||
protected function handle() {
|
||||
$this->lock_process();
|
||||
|
||||
do {
|
||||
$batch = $this->get_batch();
|
||||
|
||||
foreach ( $batch->data as $key => $value ) {
|
||||
$task = $this->task( $value );
|
||||
|
||||
if ( false !== $task ) {
|
||||
$batch->data[ $key ] = $task;
|
||||
} else {
|
||||
unset( $batch->data[ $key ] );
|
||||
}
|
||||
|
||||
if ( $this->batch_limit_exceeded() ) {
|
||||
// Batch limits reached.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update or delete current batch.
|
||||
if ( ! empty( $batch->data ) ) {
|
||||
$this->update( $batch->key, $batch->data );
|
||||
} else {
|
||||
$this->delete( $batch->key );
|
||||
}
|
||||
} while ( ! $this->batch_limit_exceeded() && ! $this->is_queue_empty() );
|
||||
|
||||
$this->unlock_process();
|
||||
|
||||
// Start next batch or complete process.
|
||||
if ( ! $this->is_queue_empty() ) {
|
||||
$this->dispatch();
|
||||
} else {
|
||||
$this->complete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get memory limit.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get_memory_limit() {
|
||||
if ( function_exists( 'ini_get' ) ) {
|
||||
$memory_limit = ini_get( 'memory_limit' );
|
||||
} else {
|
||||
// Sensible default.
|
||||
$memory_limit = '128M';
|
||||
}
|
||||
|
||||
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
|
||||
// Unlimited, set to 32GB.
|
||||
$memory_limit = '32000M';
|
||||
}
|
||||
|
||||
return intval( $memory_limit ) * 1024 * 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule cron healthcheck.
|
||||
*
|
||||
* @param array $schedules Schedules.
|
||||
* @return array
|
||||
*/
|
||||
public function schedule_cron_healthcheck( $schedules ) {
|
||||
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
||||
|
||||
if ( property_exists( $this, 'cron_interval' ) ) {
|
||||
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval_identifier );
|
||||
}
|
||||
|
||||
// Adds every 5 minutes to the existing schedules.
|
||||
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
||||
'interval' => MINUTE_IN_SECONDS * $interval,
|
||||
/* translators: %d: interval */
|
||||
'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ),
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all batches.
|
||||
*
|
||||
* @return WC_Background_Process
|
||||
*/
|
||||
public function delete_all_batches() {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->options;
|
||||
$column = 'option_name';
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$table = $wpdb->sitemeta;
|
||||
$column = 'meta_key';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill process.
|
||||
*
|
||||
* Stop processing queue items, clear cronjob and delete all batches.
|
||||
*/
|
||||
public function kill_process() {
|
||||
if ( ! $this->is_queue_empty() ) {
|
||||
$this->delete_all_batches();
|
||||
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,31 +2,22 @@
|
|||
/**
|
||||
* Background Emailer
|
||||
*
|
||||
* Uses https://github.com/A5hleyRich/wp-background-processing to handle emails
|
||||
* in the background.
|
||||
*
|
||||
* @class WC_Background_Emailer
|
||||
* @version 3.0.1
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author WooCommerce
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Request', false ) ) {
|
||||
include_once( dirname( __FILE__ ) . '/libraries/wp-async-request.php' );
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Background_Process', false ) ) {
|
||||
include_once( dirname( __FILE__ ) . '/libraries/wp-background-process.php' );
|
||||
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
||||
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Background_Emailer Class.
|
||||
*/
|
||||
class WC_Background_Emailer extends WP_Background_Process {
|
||||
class WC_Background_Emailer extends WC_Background_Process {
|
||||
|
||||
/**
|
||||
* Initiate new background process.
|
||||
|
@ -59,7 +50,7 @@ class WC_Background_Emailer extends WP_Background_Process {
|
|||
* in the next pass through. Or, return false to remove the
|
||||
* item from the queue.
|
||||
*
|
||||
* @param array $callback Update callback function
|
||||
* @param array $callback Update callback function.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function task( $callback ) {
|
||||
|
@ -68,7 +59,7 @@ class WC_Background_Emailer extends WP_Background_Process {
|
|||
WC_Emails::send_queued_transactional_email( $callback['filter'], $callback['args'] );
|
||||
} catch ( Exception $e ) {
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
trigger_error( 'Transactional email triggered fatal error for callback ' . $callback['filter'], E_USER_WARNING );
|
||||
trigger_error( 'Transactional email triggered fatal error for callback ' . esc_html( $callback['filter'] ), E_USER_WARNING );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +121,10 @@ class WC_Background_Emailer extends WP_Background_Process {
|
|||
if ( 'PHPSESSID' === $name ) {
|
||||
continue;
|
||||
}
|
||||
$cookies[] = new WP_Http_Cookie( array( 'name' => $name, 'value' => $value ) );
|
||||
$cookies[] = new WP_Http_Cookie( array(
|
||||
'name' => $name,
|
||||
'value' => $value,
|
||||
) );
|
||||
}
|
||||
|
||||
return array(
|
||||
|
|
|
@ -2,31 +2,22 @@
|
|||
/**
|
||||
* Background Updater
|
||||
*
|
||||
* Uses https://github.com/A5hleyRich/wp-background-processing to handle DB
|
||||
* updates in the background.
|
||||
*
|
||||
* @class WC_Background_Updater
|
||||
* @version 2.6.0
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Request', false ) ) {
|
||||
include_once( dirname( __FILE__ ) . '/libraries/wp-async-request.php' );
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Background_Process', false ) ) {
|
||||
include_once( dirname( __FILE__ ) . '/libraries/wp-background-process.php' );
|
||||
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
||||
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Background_Updater Class.
|
||||
*/
|
||||
class WC_Background_Updater extends WP_Background_Process {
|
||||
class WC_Background_Updater extends WC_Background_Process {
|
||||
|
||||
/**
|
||||
* Initiate new background process.
|
||||
|
@ -88,6 +79,7 @@ class WC_Background_Updater extends WP_Background_Process {
|
|||
|
||||
/**
|
||||
* Is the updater running?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_updating() {
|
||||
|
@ -102,7 +94,7 @@ class WC_Background_Updater extends WP_Background_Process {
|
|||
* in the next pass through. Or, return false to remove the
|
||||
* item from the queue.
|
||||
*
|
||||
* @param string $callback Update callback function
|
||||
* @param string $callback Update callback function.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function task( $callback ) {
|
||||
|
@ -110,7 +102,7 @@ class WC_Background_Updater extends WP_Background_Process {
|
|||
|
||||
$logger = wc_get_logger();
|
||||
|
||||
include_once( dirname( __FILE__ ) . '/wc-update-functions.php' );
|
||||
include_once dirname( __FILE__ ) . '/wc-update-functions.php';
|
||||
|
||||
if ( is_callable( $callback ) ) {
|
||||
$logger->info( sprintf( 'Running %s callback', $callback ), array( 'source' => 'wc_db_updates' ) );
|
||||
|
|
|
@ -9,18 +9,14 @@
|
|||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Request', false ) ) {
|
||||
include_once dirname( __FILE__ ) . '/libraries/wp-async-request.php';
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'WP_Background_Process', false ) ) {
|
||||
include_once dirname( __FILE__ ) . '/libraries/wp-background-process.php';
|
||||
if ( ! class_exists( 'WC_Background_Process', false ) ) {
|
||||
include_once dirname( __FILE__ ) . '/abstracts/class-wc-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that extends WP_Background_Process to process image regeneration in the background
|
||||
* Class that extends WC_Background_Process to process image regeneration in the background.
|
||||
*/
|
||||
class WC_Regenerate_Images_Request extends WP_Background_Process {
|
||||
class WC_Regenerate_Images_Request extends WC_Background_Process {
|
||||
|
||||
/**
|
||||
* Stores the attachment ID being processed.
|
||||
|
|
|
@ -187,7 +187,7 @@ class WC_Regenerate_Images {
|
|||
private static function queue_image_regeneration() {
|
||||
global $wpdb;
|
||||
// First lets cancel existing running queue to avoid running it more than once.
|
||||
self::$background_process->cancel_process();
|
||||
self::$background_process->kill_process();
|
||||
|
||||
// Now lets find all product image attachments IDs and pop them onto the queue.
|
||||
$images = $wpdb->get_results( // @codingStandardsIgnoreLine
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
/**
|
||||
* WP Async Request
|
||||
*
|
||||
* @package WP-Background-Processing
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Abstract WP_Async_Request class.
|
||||
*
|
||||
* @package WP-Background-Processing
|
||||
* @abstract
|
||||
*/
|
||||
abstract class WP_Async_Request {
|
||||
|
||||
|
@ -155,4 +156,5 @@ abstract class WP_Async_Request {
|
|||
* during the async request.
|
||||
*/
|
||||
abstract protected function handle();
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WP_Background_Process class.
|
||||
* Abstract WP_Background_Process class.
|
||||
*/
|
||||
abstract class WP_Background_Process extends WP_Async_Request {
|
||||
|
||||
|
@ -59,11 +59,14 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
||||
|
||||
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
|
||||
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) ); // @codingStandardsIgnoreLine.
|
||||
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch.
|
||||
* Dispatch
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function dispatch() {
|
||||
// Schedule the cron healthcheck.
|
||||
|
@ -120,27 +123,12 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
/**
|
||||
* Delete queue
|
||||
*
|
||||
* @param string $key Key. Leave blank to delete all batches.
|
||||
* @param string $key Key.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete( $key = '' ) {
|
||||
if ( $key ) {
|
||||
public function delete( $key ) {
|
||||
delete_site_option( $key );
|
||||
} else {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->options;
|
||||
$column = 'option_name';
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$table = $wpdb->sitemeta;
|
||||
$column = 'meta_key';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -163,14 +151,14 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
}
|
||||
|
||||
/**
|
||||
* Maybe process queue.
|
||||
* Maybe process queue
|
||||
*
|
||||
* Checks whether data exists within the queue and that
|
||||
* the process is not already running.
|
||||
*/
|
||||
public function maybe_handle() {
|
||||
// Don't lock up other requests while processing.
|
||||
session_write_close(); // @codingStandardsIgnoreLine.
|
||||
// Don't lock up other requests while processing
|
||||
session_write_close();
|
||||
|
||||
if ( $this->is_process_running() ) {
|
||||
// Background process already running.
|
||||
|
@ -205,9 +193,13 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
$column = 'meta_key';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
$key = $this->identifier . '_batch_%';
|
||||
|
||||
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
|
||||
$count = $wpdb->get_var( $wpdb->prepare( "
|
||||
SELECT COUNT(*)
|
||||
FROM {$table}
|
||||
WHERE {$column} LIKE %s
|
||||
", $key ) );
|
||||
|
||||
return ( $count > 0 ) ? false : true;
|
||||
}
|
||||
|
@ -228,7 +220,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
}
|
||||
|
||||
/**
|
||||
* Lock process.
|
||||
* Lock process
|
||||
*
|
||||
* Lock the process so that multiple instances can't run simultaneously.
|
||||
* Override if applicable, but the duration should be greater than that
|
||||
|
@ -276,9 +268,15 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
$value_column = 'meta_value';
|
||||
}
|
||||
|
||||
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
||||
$key = $this->identifier . '_batch_%';
|
||||
|
||||
$query = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC LIMIT 1", $key ) ); // @codingStandardsIgnoreLine.
|
||||
$query = $wpdb->get_row( $wpdb->prepare( "
|
||||
SELECT *
|
||||
FROM {$table}
|
||||
WHERE {$column} LIKE %s
|
||||
ORDER BY {$key_column} ASC
|
||||
LIMIT 1
|
||||
", $key ) );
|
||||
|
||||
$batch = new stdClass();
|
||||
$batch->key = $query->$column;
|
||||
|
@ -287,15 +285,6 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
return $batch;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the batch limit has been exceeded.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function batch_limit_exceeded() {
|
||||
return $this->time_exceeded() || $this->memory_exceeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle
|
||||
*
|
||||
|
@ -317,7 +306,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
unset( $batch->data[ $key ] );
|
||||
}
|
||||
|
||||
if ( $this->batch_limit_exceeded() ) {
|
||||
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
||||
// Batch limits reached.
|
||||
break;
|
||||
}
|
||||
|
@ -329,7 +318,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
} else {
|
||||
$this->delete( $batch->key );
|
||||
}
|
||||
} while ( ! $this->batch_limit_exceeded() && ! $this->is_queue_empty() );
|
||||
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
||||
|
||||
$this->unlock_process();
|
||||
|
||||
|
@ -339,6 +328,8 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
} else {
|
||||
$this->complete();
|
||||
}
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,7 +365,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
$memory_limit = '128M';
|
||||
}
|
||||
|
||||
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
|
||||
if ( ! $memory_limit || -1 === $memory_limit ) {
|
||||
// Unlimited, set to 32GB.
|
||||
$memory_limit = '32000M';
|
||||
}
|
||||
|
@ -429,8 +420,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
// Adds every 5 minutes to the existing schedules.
|
||||
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
||||
'interval' => MINUTE_IN_SECONDS * $interval,
|
||||
/* translators: %d: interval */
|
||||
'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ),
|
||||
'display' => sprintf( __( 'Every %d Minutes' ), $interval ),
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
|
@ -483,12 +473,17 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
* Cancel Process
|
||||
*
|
||||
* Stop processing queue items, clear cronjob and delete batch.
|
||||
*
|
||||
*/
|
||||
public function cancel_process() {
|
||||
if ( ! $this->is_queue_empty() ) {
|
||||
$this->delete();
|
||||
$batch = $this->get_batch();
|
||||
|
||||
$this->delete( $batch->key );
|
||||
|
||||
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -504,4 +499,5 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|||
* @return mixed
|
||||
*/
|
||||
abstract protected function task( $item );
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* Test WP_Background_Process functionality
|
||||
* Test WC_Background_Process functionality
|
||||
*
|
||||
* A mock class for testing the WP_Background_Process functionality.
|
||||
* A mock class for testing the WC_Background_Process functionality.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
class WC_Mock_Background_Process extends WP_Background_Process {
|
||||
class WC_Mock_Background_Process extends WC_Background_Process {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue