Commit d837ea1e authored by Erick Hitter's avatar Erick Hitter
Browse files

Handle cases where the cron option is updated directly

Fixes #90
parent d0da3ea2
......@@ -213,6 +213,8 @@ class Events_Store extends Singleton {
public function update_option( $new_value, $old_value ) {
if ( $this->is_unscheduling() ) {
$this->unschedule_job( $new_value, $this->option_before_unscheduling );
} elseif ( $this->is_direct_update() ) {
$this->force_update( $new_value );
} else {
$this->convert_option( $new_value );
}
......@@ -220,6 +222,22 @@ class Events_Store extends Singleton {
return $old_value;
}
/**
* Overwrite all existing data with a new value
*/
private function force_update( $new_value ) {
global $wpdb;
$this->suspend_event_creation();
$wpdb->update( $this->get_table_name(), array( 'status' => self::STATUS_COMPLETED, ), array( 'status' => self::STATUS_PENDING, ) );
$wpdb->update( $this->get_table_name(), array( 'status' => self::STATUS_COMPLETED, ), array( 'status' => self::STATUS_RUNNING, ) );
$this->option_before_unscheduling = null;
$this->flush_internal_caches();
$this->resume_event_creation();
$this->convert_option( $new_value );
}
/**
* Delete jobs that are unscheduled using `wp_unschedule_event()`
*/
......@@ -468,8 +486,38 @@ class Events_Store extends Singleton {
return (bool) $success;
}
/**
* Check if the cron option was updated using one of Core's cron callbacks
*
* If updated using `update_option()` or `_set_cron_array()`, without using a Core cron callback, it's considered direct
*
* @return bool
*/
private function is_direct_update() {
$trace = wp_debug_backtrace_summary( __CLASS__, null, false );
$cron_callbacks = array(
'wp_schedule_single_event',
'wp_schedule_event',
'wp_unschedule_event',
);
$called_by_cron = false;
foreach ( $cron_callbacks as $cb ) {
if ( false !== array_search( $cb, $trace ) ) {
$called_by_cron = true;
break;
}
}
return ! $called_by_cron;
}
/**
* Determine if current request is a call to `wp_unschedule_event()`
*
* @return bool
*/
private function is_unscheduling() {
return false !== array_search( 'wp_unschedule_event', wp_debug_backtrace_summary( __CLASS__, null, false ) );
......
......@@ -10,19 +10,6 @@ class Utils {
return \Automattic\WP\Cron_Control\Events_Store::instance()->get_table_name();
}
/**
* Start with a clean events store when running tests
*
* To be called during tests' `setUp` and `tearDown` methods
*
* Follows Core's approach when running cron tests, but `_set_cron_array()` doesn't work for us
*/
static function reset_events_store() {
global $wpdb;
$wpdb->delete( Utils::get_table_name(), array( 'status' => \Automattic\WP\Cron_Control\Events_Store::STATUS_PENDING, ) );
\Automattic\WP\Cron_Control\_flush_internal_caches();
}
/**
* Build a test event
*/
......
......@@ -18,7 +18,7 @@ class Events_Store_Tests extends \WP_UnitTestCase {
parent::setUp();
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
}
/**
......@@ -26,7 +26,7 @@ class Events_Store_Tests extends \WP_UnitTestCase {
*/
function tearDown() {
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
parent::tearDown();
}
......
......@@ -18,7 +18,7 @@ class Internal_Events_Tests extends \WP_UnitTestCase {
parent::setUp();
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
}
/**
......@@ -26,7 +26,7 @@ class Internal_Events_Tests extends \WP_UnitTestCase {
*/
function tearDown() {
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
parent::tearDown();
}
......
......@@ -18,7 +18,7 @@ class Misc_Tests extends \WP_UnitTestCase {
parent::setUp();
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
}
/**
......@@ -26,7 +26,7 @@ class Misc_Tests extends \WP_UnitTestCase {
*/
function tearDown() {
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
parent::tearDown();
}
......
......@@ -22,7 +22,7 @@ class REST_API_Tests extends \WP_UnitTestCase {
do_action( 'rest_api_init' );
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
}
/**
......@@ -33,7 +33,7 @@ class REST_API_Tests extends \WP_UnitTestCase {
$wp_rest_server = null;
// make sure the schedule is clear
Utils::reset_events_store();
_set_cron_array( array() );
parent::tearDown();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment