WordPress.org

Make WordPress Core

Ticket #15148: 18084.patch

File 18084.patch, 12.3 KB (added by mintindeed, 7 years ago)

Updated WP_Cron_Store

  • wp-includes/cron.php

     
    2020 * @param array $args Optional. Arguments to pass to the hook's callback function.
    2121 */
    2222function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
     23        global $wp_cron_store;
     24
    2325        // don't schedule a duplicate if there's already an identical event due in the next 10 minutes
    2426        $next = wp_next_scheduled($hook, $args);
    2527        if ( $next && $next <= $timestamp + 600 )
    2628                return;
    2729
    28         $crons = _get_cron_array();
    29         $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
     30        // Create an object and apply filters for backwards compatibility
     31        $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args, 'recurrence' => false, 'interval' => false );
     32
    3033        $event = apply_filters('schedule_event', $event);
    3134
    3235        // A plugin disallowed this event
    3336        if ( ! $event )
    3437                return false;
    3538
    36         $key = md5(serialize($event->args));
    37 
    38         $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args );
    39         uksort( $crons, "strnatcasecmp" );
    40         _set_cron_array( $crons );
     39        $wp_cron_store->insert_event( $event->timestamp, $event->hook, $event->args, $event->recurrence, $event->interval );
    4140}
    4241
    4342/**
     
    6160 * @return bool|null False on failure, null when complete with scheduling event.
    6261 */
    6362function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    64         $crons = _get_cron_array();
     63        global $wp_cron_store;
     64
    6565        $schedules = wp_get_schedules();
    6666
    6767        if ( !isset( $schedules[$recurrence] ) )
    6868                return false;
    6969
     70        // Create an object and apply filters for backwards compatibility
    7071        $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
     72
    7173        $event = apply_filters('schedule_event', $event);
    7274
    7375        // A plugin disallowed this event
    7476        if ( ! $event )
    7577                return false;
    7678
    77         $key = md5(serialize($event->args));
    78 
    79         $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
    80         uksort( $crons, "strnatcasecmp" );
    81         _set_cron_array( $crons );
     79        $wp_cron_store->insert_event( $event->timestamp, $event->hook, $event->args, $event->schedule, $event->interval );
    8280}
    8381
    8482/**
     
    9391 * @return bool|null False on failure. Null when event is rescheduled.
    9492 */
    9593function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    96         $crons = _get_cron_array();
    97         $schedules = wp_get_schedules();
    98         $key = md5(serialize($args));
     94        global $wp_cron_store;
     95
    9996        $interval = 0;
    10097
    10198        // First we try to get it from the schedule
    102         if ( 0 == $interval )
     99        $schedules = wp_get_schedules();
     100        if ( isset($schedules[$recurrence]) )
    103101                $interval = $schedules[$recurrence]['interval'];
     102
    104103        // Now we try to get it from the saved interval in case the schedule disappears
    105         if ( 0 == $interval )
    106                 $interval = $crons[$timestamp][$hook][$key]['interval'];
     104        if ( 0 == $interval ) {
     105                $event = $wp_cron_store->get_event( $hook, $timestamp, $args );
     106                if ( $event )
     107                        $interval = $event->interval;
     108        }
     109
    107110        // Now we assume something is wrong and fail to schedule
    108111        if ( 0 == $interval )
    109112                return false;
     
    134137 * as those used when originally scheduling the event.
    135138 */
    136139function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
    137         $crons = _get_cron_array();
    138         $key = md5(serialize($args));
    139         unset( $crons[$timestamp][$hook][$key] );
    140         if ( empty($crons[$timestamp][$hook]) )
    141                 unset( $crons[$timestamp][$hook] );
    142         if ( empty($crons[$timestamp]) )
    143                 unset( $crons[$timestamp] );
    144         _set_cron_array( $crons );
     140        global $wp_cron_store;
     141
     142        $wp_cron_store->complete_event( $timestamp, $hook, $args );
    145143}
    146144
    147145/**
     
    174172 * @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
    175173 */
    176174function wp_next_scheduled( $hook, $args = array() ) {
    177         $crons = _get_cron_array();
    178         $key = md5(serialize($args));
    179         if ( empty($crons) )
     175        global $wp_cron_store;
     176
     177        $event = $wp_cron_store->get_event( $hook, 'next', $args );
     178
     179        if ( !$event )
    180180                return false;
    181         foreach ( $crons as $timestamp => $cron ) {
    182                 if ( isset( $cron[$hook][$key] ) )
    183                         return $timestamp;
    184         }
    185         return false;
     181
     182        return $event->timestamp;
    186183}
    187184
    188185/**
     
    193190 * @return null Cron could not be spawned, because it is not needed to run.
    194191 */
    195192function spawn_cron( $local_time = 0 ) {
     193        global $wp_cron_store;
    196194
    197195        if ( !$local_time )
    198196                $local_time = time();
     
    214212                return;
    215213
    216214        //sanity check
    217         $crons = _get_cron_array();
    218         if ( !is_array($crons) )
     215        $crons = $wp_cron_store->get_events();
     216        if ( empty($crons) )
    219217                return;
    220218
    221219        $keys = array_keys( $crons );
     
    254252 * @return null When doesn't need to run Cron.
    255253 */
    256254function wp_cron() {
     255        global $wp_cron_store;
    257256
    258257        // Prevent infinite loops caused by lack of wp-cron.php
    259258        if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
    260259                return;
    261260
    262         if ( false === $crons = _get_cron_array() )
     261        if ( false === $crons = $wp_cron_store->get_events() )
    263262                return;
    264263
    265264        $local_time = time();
     
    328327 * @return string|bool False, if no schedule. Schedule on success.
    329328 */
    330329function wp_get_schedule($hook, $args = array()) {
    331         $crons = _get_cron_array();
    332         $key = md5(serialize($args));
    333         if ( empty($crons) )
     330        global $wp_cron_store;
     331
     332        $event = $wp_cron_store->get_event( $hook, 'next', $args );
     333
     334        if ( !$event )
    334335                return false;
    335         foreach ( $crons as $timestamp => $cron ) {
    336                 if ( isset( $cron[$hook][$key] ) )
    337                         return $cron[$hook][$key]['schedule'];
    338         }
    339         return false;
     336
     337        return $event->schedule;
    340338}
    341339
    342340//
    343341// Private functions
    344342//
    345343
    346 /**
    347  * Retrieve cron info array option.
    348  *
    349  * @since 2.1.0
    350  * @access private
    351  *
    352  * @return array CRON info array.
    353  */
    354 function _get_cron_array()  {
    355         $cron = get_option('cron');
    356         if ( ! is_array($cron) )
     344class WP_Cron_Store {
     345        /**
     346         * Array of pending cron jobs
     347         */
     348        protected $_cron_array = array();
     349
     350        /**
     351         * Marks the event as completed and removes it from the current instance of
     352         * $this->_cron_array
     353         *
     354         * @since ?
     355         *
     356         * @param int $timestamp
     357         * @param string $hook
     358         * @param array $args
     359         */
     360        public function complete_event( $timestamp, $hook, $args ) {
     361                $crons = $this->_get_cron_array();
     362                $key = md5(serialize($args));
     363                unset( $crons[$timestamp][$hook][$key] );
     364                if ( empty($crons[$timestamp][$hook]) )
     365                        unset( $crons[$timestamp][$hook] );
     366                if ( empty($crons[$timestamp]) )
     367                        unset( $crons[$timestamp] );
     368                $this->_set_cron_array( $crons );
     369        }
     370
     371        /**
     372         * Searches for a scheduled event
     373         *
     374         * @since ?
     375         *
     376         * @param string $hook
     377         * @param int $timestamp
     378         * @param array $args
     379         *
     380         * @return obj|false $event object or false if it doesn't exist
     381         */
     382        public function get_event( $hook, $timestamp, $args = array() ) {
     383                $crons = $this->_get_cron_array();
     384                $key = md5(serialize($args));
     385                if ( empty($crons) )
     386                        return false;
     387
     388                if ( empty($timestamp) || 'next' == $timestamp ) {
     389                        foreach ( $crons as $cron_timestamp => $cron ) {
     390                                if ( isset( $cron[$hook][$key] ) )
     391                                        return (object) array( 'hook' => $hook, 'args' => $args, 'timestamp' => $cron_timestamp, 'schedule' => $cron[$hook][$key]['schedule'], 'interval' => $cron[$hook][$key]['interval']);
     392                        }
     393                        return false;
     394                }
     395
     396                if ( isset($crons[$timestamp][$hook][$key]) )
     397                        return (object) array( 'hook' => $hook, 'args' => $args, 'timestamp' => $timestamp, 'schedule' => $crons[$timestamp][$hook][$key]['schedule'], 'interval' => $crons[$timestamp][$hook][$key]['interval']);
     398
    357399                return false;
     400        }
    358401
    359         if ( !isset($cron['version']) )
    360                 $cron = _upgrade_cron_array($cron);
     402        /**
     403         * Returns an array of all pending jobs within the next 10 minutes
     404         *
     405         * @since ?
     406         *
     407         * @param array $args Unused
     408         *
     409         * @return array
     410         */
     411        public function get_events( $args = array() ) {
     412                return $this->_get_cron_array();
     413        }
    361414
    362         unset($cron['version']);
     415        /**
     416         * Inserts a new event
     417         *
     418         * @since ?
     419         *
     420         * @param int $timestamp
     421         * @param string $hook
     422         * @param array $args
     423         * @param null|string $recurrence
     424         * @param null|int $interval
     425         */
     426        public function insert_event( $timestamp, $hook, $args, $recurrence = null, $interval = null ) {
     427                $crons = $this->_get_cron_array();
     428                $key = md5(serialize($args));
    363429
    364         return $cron;
    365 }
     430                $crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $interval );
     431                uksort( $crons, "strnatcasecmp" );
     432                $this->_set_cron_array( $crons );
     433        }
    366434
    367 /**
    368  * Updates the CRON option with the new CRON array.
    369  *
    370  * @since 2.1.0
    371  * @access private
    372  *
    373  * @param array $cron Cron info array from {@link _get_cron_array()}.
    374  */
    375 function _set_cron_array($cron) {
    376         $cron['version'] = 2;
    377         update_option( 'cron', $cron );
    378 }
     435        /**
     436         * Retrieve cron info array option.
     437         *
     438         * @since 2.1.0
     439         *
     440         * @return array CRON info array.
     441         */
     442        protected function _get_cron_array()  {
     443                $crons = get_option('cron', array());
     444                if ( !is_array($crons) || empty($crons) )
     445                        return array();
    379446
    380 /**
    381  * Upgrade a Cron info array.
    382  *
    383  * This function upgrades the Cron info array to version 2.
    384  *
    385  * @since 2.1.0
    386  * @access private
    387  *
    388  * @param array $cron Cron info array from {@link _get_cron_array()}.
    389  * @return array An upgraded Cron info array.
    390  */
    391 function _upgrade_cron_array($cron) {
    392         if ( isset($cron['version']) && 2 == $cron['version'])
    393                 return $cron;
     447                if ( !isset($crons['version']) )
     448                        $crons = $this->_upgrade_cron_array($crons);
    394449
    395         $new_cron = array();
     450                unset($crons['version']);
    396451
    397         foreach ( (array) $cron as $timestamp => $hooks) {
    398                 foreach ( (array) $hooks as $hook => $args ) {
    399                         $key = md5(serialize($args['args']));
    400                         $new_cron[$timestamp][$hook][$key] = $args;
     452                return $crons;
     453        }
     454
     455        /**
     456         * Updates the CRON option with the new CRON array.
     457         *
     458         * @since 2.1.0
     459         *
     460         * @param array $crons Cron info array from {@link _get_cron_array()}.
     461         */
     462        protected function _set_cron_array( $crons = array() ) {
     463                $crons['version'] = 2;
     464                update_option( 'cron', $crons );
     465        }
     466
     467        /**
     468         * Upgrade a Cron info array.
     469         *
     470         * This function upgrades the Cron info array to version 2.
     471         *
     472         * @since 2.1.0
     473         *
     474         * @param array $cron Cron info array from {@link _get_cron_array()}.
     475         * @return array An upgraded Cron info array.
     476         */
     477        protected function _upgrade_cron_array($crons) {
     478                if ( isset($crons['version']) && 2 == $crons['version'])
     479                        return $crons;
     480
     481                $new_crons = array();
     482
     483                foreach ( (array) $crons as $timestamp => $hooks) {
     484                        foreach ( (array) $hooks as $hook => $args ) {
     485                                $key = md5(serialize($args['args']));
     486                                $new_crons[$timestamp][$hook][$key] = $args;
     487                        }
    401488                }
     489
     490                $new_crons['version'] = 2;
     491                update_option( 'cron', $new_crons );
     492                return $new_crons;
    402493        }
    403 
    404         $new_cron['version'] = 2;
    405         update_option( 'cron', $new_cron );
    406         return $new_cron;
    407494}
  • wp-settings.php

     
    100100// Run the installer if WordPress is not installed.
    101101wp_not_installed();
    102102
     103// Load cron
     104require_once( ABSPATH . WPINC . '/cron.php' );
     105if ( file_exists( WP_CONTENT_DIR . '/cron.php' ) )
     106        require_once( WP_CONTENT_DIR . '/cron.php' );
     107
     108if ( !isset( $wp_cron_store ) )
     109        $wp_cron_store = new WP_Cron_Store;
     110
    103111// Load most of WordPress.
    104112require( ABSPATH . WPINC . '/class-wp-walker.php' );
    105113require( ABSPATH . WPINC . '/class-wp-ajax-response.php' );
     
    123131require( ABSPATH . WPINC . '/bookmark.php' );
    124132require( ABSPATH . WPINC . '/bookmark-template.php' );
    125133require( ABSPATH . WPINC . '/kses.php' );
    126 require( ABSPATH . WPINC . '/cron.php' );
    127134require( ABSPATH . WPINC . '/deprecated.php' );
    128135require( ABSPATH . WPINC . '/script-loader.php' );
    129136require( ABSPATH . WPINC . '/taxonomy.php' );
  • wp-cron.php

     
    2626        require_once('./wp-load.php');
    2727}
    2828
    29 if ( false === $crons = _get_cron_array() )
     29if ( false === $crons = $wp_cron_store->get_events() )
    3030        die();
    3131
    3232$keys = array_keys( $crons );