WordPress.org

Make WordPress Core

Ticket #15148: 18084.patch

File 18084.patch, 12.3 KB (added by mintindeed, 3 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 );