Cron: Move logic for finding the next event's timestamp.
Moves the logic for determining when an event will next run from `wp_next_scheduled()` to `wp_get_scheduled_event()`. This improves the performance of `wp_get_scheduled_event()` by avoiding duplicate function calls and object cache hits. Props peterwilsoncc. Fixes #45976. git-svn-id: https://develop.svn.wordpress.org/trunk@44693 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
8f94eec53c
commit
554ee5b53c
|
@ -481,7 +481,8 @@ function wp_unschedule_hook( $hook ) {
|
||||||
/**
|
/**
|
||||||
* Retrieve a scheduled event.
|
* Retrieve a scheduled event.
|
||||||
*
|
*
|
||||||
* Retrieve the full event object for a given event.
|
* Retrieve the full event object for a given event, if no timestamp is specified the next
|
||||||
|
* scheduled event is returned.
|
||||||
*
|
*
|
||||||
* @since 5.1.0
|
* @since 5.1.0
|
||||||
*
|
*
|
||||||
|
@ -493,11 +494,6 @@ function wp_unschedule_hook( $hook ) {
|
||||||
* @return bool|object The event object. False if the event does not exist.
|
* @return bool|object The event object. False if the event does not exist.
|
||||||
*/
|
*/
|
||||||
function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
|
function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
|
||||||
if ( ! $timestamp ) {
|
|
||||||
// Get the next scheduled event.
|
|
||||||
$timestamp = wp_next_scheduled( $hook, $args );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter to preflight or hijack retrieving a scheduled event.
|
* Filter to preflight or hijack retrieving a scheduled event.
|
||||||
*
|
*
|
||||||
|
@ -514,22 +510,39 @@ function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
|
||||||
* @param array $args Array containing each separate argument to pass to the hook's callback function.
|
* @param array $args Array containing each separate argument to pass to the hook's callback function.
|
||||||
* Although not passed to a callback, these arguments are used to uniquely identify the
|
* Although not passed to a callback, these arguments are used to uniquely identify the
|
||||||
* event.
|
* event.
|
||||||
* @param int $timestamp Unix timestamp (UTC) of the event.
|
* @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event.
|
||||||
*/
|
*/
|
||||||
$pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp );
|
$pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp );
|
||||||
if ( null !== $pre ) {
|
if ( null !== $pre ) {
|
||||||
return $pre;
|
return $pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
$crons = _get_cron_array();
|
if ( null !== $timestamp && ! is_numeric( $timestamp ) ) {
|
||||||
$key = md5( serialize( $args ) );
|
|
||||||
|
|
||||||
if ( ! $timestamp || ! isset( $crons[ $timestamp ] ) ) {
|
|
||||||
// No such event.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset( $crons[ $timestamp ][ $hook ] ) || ! isset( $crons[ $timestamp ][ $hook ][ $key ] ) ) {
|
$crons = _get_cron_array();
|
||||||
|
if ( empty( $crons ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = md5( serialize( $args ) );
|
||||||
|
|
||||||
|
if ( ! $timestamp ) {
|
||||||
|
// Get next event.
|
||||||
|
$next = false;
|
||||||
|
foreach ( $crons as $timestamp => $cron ) {
|
||||||
|
if ( isset( $cron[ $hook ][ $key ] ) ) {
|
||||||
|
$next = $timestamp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! $next ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$timestamp = $next;
|
||||||
|
} elseif ( ! isset( $crons[ $timestamp ][ $hook ][ $key ] ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +564,6 @@ function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
|
||||||
* Retrieve the next timestamp for an event.
|
* Retrieve the next timestamp for an event.
|
||||||
*
|
*
|
||||||
* @since 2.1.0
|
* @since 2.1.0
|
||||||
* @since 5.1.0 {@see 'pre_next_scheduled'} and {@see 'next_scheduled'} filters added.
|
|
||||||
*
|
*
|
||||||
* @param string $hook Action hook of the event.
|
* @param string $hook Action hook of the event.
|
||||||
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
|
* @param array $args Optional. Array containing each separate argument to pass to the hook's callback function.
|
||||||
|
@ -560,48 +572,12 @@ function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
|
||||||
* @return false|int The Unix timestamp of the next time the event will occur. False if the event doesn't exist.
|
* @return false|int The Unix timestamp of the next time the event will occur. False if the event doesn't exist.
|
||||||
*/
|
*/
|
||||||
function wp_next_scheduled( $hook, $args = array() ) {
|
function wp_next_scheduled( $hook, $args = array() ) {
|
||||||
/**
|
$next_event = wp_get_scheduled_event( $hook, $args );
|
||||||
* Filter to preflight or hijack retrieving the next scheduled event timestamp.
|
if ( ! $next_event ) {
|
||||||
*
|
return false;
|
||||||
* Returning a non-null value will short-circuit the normal retrieval
|
|
||||||
* process, causing the function to return the filtered value instead.
|
|
||||||
*
|
|
||||||
* Pass the timestamp of the next event if it exists, false if not.
|
|
||||||
*
|
|
||||||
* @since 5.1.0
|
|
||||||
*
|
|
||||||
* @param null|bool $pre Value to return instead. Default null to continue unscheduling the event.
|
|
||||||
* @param string $hook Action hook of the event.
|
|
||||||
* @param array $args Arguments to pass to the hook's callback function.
|
|
||||||
*/
|
|
||||||
$pre = apply_filters( 'pre_next_scheduled', null, $hook, $args );
|
|
||||||
if ( null !== $pre ) {
|
|
||||||
return $pre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$crons = _get_cron_array();
|
return $next_event->timestamp;
|
||||||
$key = md5( serialize( $args ) );
|
|
||||||
$next = false;
|
|
||||||
|
|
||||||
if ( ! empty( $crons ) ) {
|
|
||||||
foreach ( $crons as $timestamp => $cron ) {
|
|
||||||
if ( isset( $cron[ $hook ][ $key ] ) ) {
|
|
||||||
$next = $timestamp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter the next scheduled event timestamp.
|
|
||||||
*
|
|
||||||
* @since 5.1.0
|
|
||||||
*
|
|
||||||
* @param int|bool $next The UNIX timestamp when the scheduled event will next occur, or false if not found.
|
|
||||||
* @param string $hook Action hook to execute when cron is run.
|
|
||||||
* @param array $args Arguments to be passed to the callback function. Used for deduplicating events.
|
|
||||||
*/
|
|
||||||
return apply_filters( 'next_scheduled', $next, $hook, $args );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -458,7 +458,6 @@ class Tests_Cron extends WP_UnitTestCase {
|
||||||
*/
|
*/
|
||||||
function test_pre_scheduled_event_hooks() {
|
function test_pre_scheduled_event_hooks() {
|
||||||
add_filter( 'pre_get_scheduled_event', array( $this, 'filter_pre_scheduled_event_hooks' ) );
|
add_filter( 'pre_get_scheduled_event', array( $this, 'filter_pre_scheduled_event_hooks' ) );
|
||||||
add_filter( 'pre_next_scheduled', array( $this, 'filter_pre_scheduled_event_hooks' ) );
|
|
||||||
|
|
||||||
$actual = wp_get_scheduled_event( 'preflight_event', array(), $this->plus_thirty_minutes );
|
$actual = wp_get_scheduled_event( 'preflight_event', array(), $this->plus_thirty_minutes );
|
||||||
$actual2 = wp_next_scheduled( 'preflight_event', array() );
|
$actual2 = wp_next_scheduled( 'preflight_event', array() );
|
||||||
|
@ -471,7 +470,7 @@ class Tests_Cron extends WP_UnitTestCase {
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals( $expected, $actual );
|
$this->assertEquals( $expected, $actual );
|
||||||
$this->assertEquals( $expected, $actual2 );
|
$this->assertEquals( $expected->timestamp, $actual2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
function filter_pre_scheduled_event_hooks() {
|
function filter_pre_scheduled_event_hooks() {
|
||||||
|
@ -482,4 +481,119 @@ class Tests_Cron extends WP_UnitTestCase {
|
||||||
'args' => array(),
|
'args' => array(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure wp_get_scheduled_event() returns the expected one off events.
|
||||||
|
*
|
||||||
|
* When no timestamp is specified, the next event should be returned.
|
||||||
|
* When a timestamp is specified, a particular event should be returned.
|
||||||
|
*
|
||||||
|
* @ticket 45976.
|
||||||
|
*/
|
||||||
|
function test_get_scheduled_event_singles() {
|
||||||
|
$hook = __FUNCTION__;
|
||||||
|
$args = array( 'arg1' );
|
||||||
|
$ts_late = strtotime( '+30 minutes' );
|
||||||
|
$ts_next = strtotime( '+3 minutes' );
|
||||||
|
|
||||||
|
$expected1 = (object) array(
|
||||||
|
'hook' => $hook,
|
||||||
|
'timestamp' => $ts_late,
|
||||||
|
'schedule' => false,
|
||||||
|
'args' => $args,
|
||||||
|
);
|
||||||
|
|
||||||
|
$expected2 = (object) array(
|
||||||
|
'hook' => $hook,
|
||||||
|
'timestamp' => $ts_next,
|
||||||
|
'schedule' => false,
|
||||||
|
'args' => $args,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Schedule late running event.
|
||||||
|
wp_schedule_single_event( $ts_late, $hook, $args );
|
||||||
|
// Schedule next running event.
|
||||||
|
wp_schedule_single_event( $ts_next, $hook, $args );
|
||||||
|
|
||||||
|
// Late running, timestamp specified.
|
||||||
|
$this->assertEquals( $expected1, wp_get_scheduled_event( $hook, $args, $ts_late ) );
|
||||||
|
|
||||||
|
// Next running, timestamp specified.
|
||||||
|
$this->assertEquals( $expected2, wp_get_scheduled_event( $hook, $args, $ts_next ) );
|
||||||
|
|
||||||
|
// Next running, no timestamp specified.
|
||||||
|
$this->assertEquals( $expected2, wp_get_scheduled_event( $hook, $args ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure wp_get_scheduled_event() returns the expected recurring events.
|
||||||
|
*
|
||||||
|
* When no timestamp is specified, the next event should be returned.
|
||||||
|
* When a timestamp is specified, a particular event should be returned.
|
||||||
|
*
|
||||||
|
* @ticket 45976.
|
||||||
|
*/
|
||||||
|
function test_get_scheduled_event_recurring() {
|
||||||
|
$hook = __FUNCTION__;
|
||||||
|
$args = array( 'arg1' );
|
||||||
|
$ts_late = strtotime( '+30 minutes' );
|
||||||
|
$ts_next = strtotime( '+3 minutes' );
|
||||||
|
$schedule = 'hourly';
|
||||||
|
$interval = HOUR_IN_SECONDS;
|
||||||
|
|
||||||
|
$expected1 = (object) array(
|
||||||
|
'hook' => $hook,
|
||||||
|
'timestamp' => $ts_late,
|
||||||
|
'schedule' => $schedule,
|
||||||
|
'args' => $args,
|
||||||
|
'interval' => $interval,
|
||||||
|
);
|
||||||
|
|
||||||
|
$expected2 = (object) array(
|
||||||
|
'hook' => $hook,
|
||||||
|
'timestamp' => $ts_next,
|
||||||
|
'schedule' => $schedule,
|
||||||
|
'args' => $args,
|
||||||
|
'interval' => $interval,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Schedule late running event.
|
||||||
|
wp_schedule_event( $ts_late, $schedule, $hook, $args );
|
||||||
|
// Schedule next running event.
|
||||||
|
wp_schedule_event( $ts_next, $schedule, $hook, $args );
|
||||||
|
|
||||||
|
// Late running, timestamp specified.
|
||||||
|
$this->assertEquals( $expected1, wp_get_scheduled_event( $hook, $args, $ts_late ) );
|
||||||
|
|
||||||
|
// Next running, timestamp specified.
|
||||||
|
$this->assertEquals( $expected2, wp_get_scheduled_event( $hook, $args, $ts_next ) );
|
||||||
|
|
||||||
|
// Next running, no timestamp specified.
|
||||||
|
$this->assertEquals( $expected2, wp_get_scheduled_event( $hook, $args ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure wp_get_scheduled_event() returns false when expected.
|
||||||
|
*
|
||||||
|
* @ticket 45976.
|
||||||
|
*/
|
||||||
|
function test_get_scheduled_event_false() {
|
||||||
|
$hook = __FUNCTION__;
|
||||||
|
$args = array( 'arg1' );
|
||||||
|
$ts = strtotime( '+3 minutes' );
|
||||||
|
|
||||||
|
// No scheduled events.
|
||||||
|
// - With timestamp
|
||||||
|
$this->assertFalse( wp_get_scheduled_event( $hook, $args, $ts ) );
|
||||||
|
// - Get next, none scheduled.
|
||||||
|
$this->assertFalse( wp_get_scheduled_event( $hook, $args ) );
|
||||||
|
|
||||||
|
// Schedule an event.
|
||||||
|
wp_schedule_event( $ts, $hook, $args );
|
||||||
|
// - unregistered timestamp
|
||||||
|
$this->assertFalse( wp_get_scheduled_event( $hook, $args, strtotime( '+30 minutes' ) ) );
|
||||||
|
// - invalid timestamp.
|
||||||
|
$this->assertFalse( wp_get_scheduled_event( $hook, $args, 'Words Fail!' ) );
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue