2018-02-01 13:42:13 +00:00
< ? 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 ) ) {
2018-02-01 13:52:14 +00:00
include_once dirname ( WC_PLUGIN_FILE ) . '/includes/libraries/wp-async-request.php' ;
2018-02-01 13:42:13 +00:00
}
if ( ! class_exists ( 'WP_Background_Process' , false ) ) {
2018-02-01 13:52:14 +00:00
include_once dirname ( WC_PLUGIN_FILE ) . '/includes/libraries/wp-background-process.php' ;
2018-02-01 13:42:13 +00:00
}
/**
* WC_Background_Process class .
*/
abstract class WC_Background_Process extends WP_Background_Process {
/**
2018-02-01 14:02:03 +00:00
* Is queue empty .
2018-02-01 13:42:13 +00:00
*
* @ 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.
2018-03-21 23:05:19 +00:00
return ! ( $count > 0 );
2018-02-01 13:42:13 +00:00
}
/**
2018-02-01 14:02:03 +00:00
* Get batch .
2018-02-01 13:42:13 +00:00
*
2018-02-01 14:02:03 +00:00
* @ return stdClass Return the first batch from the queue .
2018-02-01 13:42:13 +00:00
*/
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 ;
2018-03-29 10:09:41 +00:00
$batch -> data = array_filter ( ( array ) maybe_unserialize ( $query -> $value_column ) );
2018-02-01 13:42:13 +00:00
return $batch ;
}
/**
* See if the batch limit has been exceeded .
*
* @ return bool
*/
protected function batch_limit_exceeded () {
return $this -> time_exceeded () || $this -> memory_exceeded ();
}
/**
2018-02-01 14:02:03 +00:00
* Handle .
2018-02-01 13:42:13 +00:00
*
* 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 ();
}
}
/**
2018-02-01 14:02:03 +00:00
* Get memory limit .
2018-02-01 13:42:13 +00:00
*
* @ 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.
2018-10-15 06:26:45 +00:00
$memory_limit = '32G' ;
2018-02-01 13:42:13 +00:00
}
2018-10-15 06:26:45 +00:00
return wp_convert_hr_to_bytes ( $memory_limit );
2018-02-01 13:42:13 +00:00
}
/**
2018-02-01 14:02:03 +00:00
* Schedule cron healthcheck .
2018-02-01 13:42:13 +00:00
*
2018-02-01 14:02:03 +00:00
* @ param array $schedules Schedules .
* @ return array
2018-02-01 13:42:13 +00:00
*/
public function schedule_cron_healthcheck ( $schedules ) {
$interval = apply_filters ( $this -> identifier . '_cron_interval' , 5 );
if ( property_exists ( $this , 'cron_interval' ) ) {
2018-04-17 14:21:03 +00:00
$interval = apply_filters ( $this -> identifier . '_cron_interval' , $this -> cron_interval );
2018-02-01 13:42:13 +00:00
}
// 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 ;
}
/**
2018-02-01 14:02:03 +00:00
* 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 .
2018-02-01 13:42:13 +00:00
*
2018-02-01 14:02:03 +00:00
* Stop processing queue items , clear cronjob and delete all batches .
2018-02-01 13:42:13 +00:00
*/
2018-02-01 14:02:03 +00:00
public function kill_process () {
2018-02-01 13:42:13 +00:00
if ( ! $this -> is_queue_empty () ) {
2018-02-01 14:02:03 +00:00
$this -> delete_all_batches ();
2018-02-01 13:42:13 +00:00
wp_clear_scheduled_hook ( $this -> cron_hook_identifier );
}
}
}