WordPress.org

Make WordPress Core

Ticket #32656: 32656.5.diff

File 32656.5.diff, 24.8 KB (added by peterwilsoncc, 16 months ago)
  • src/wp-includes/cron.php

    diff --git src/wp-includes/cron.php src/wp-includes/cron.php
    index fbf5a629af..320122a44c 100644
     
    2121 * Use wp_schedule_event() to schedule a recurring event.
    2222 *
    2323 * @since 2.1.0
     24 * @since 5.0.0 {@see pre_schedule_event} filter added to allow hijacking,
     25 *              return values modified to boolean indicating success or failure.
     26 *
    2427 * @link https://codex.wordpress.org/Function_Reference/wp_schedule_single_event
    2528 *
    2629 * @param int    $timestamp  Unix timestamp (UTC) for when to next run the event.
    2730 * @param string $hook       Action hook to execute when the event is run.
    2831 * @param array  $args       Optional. Array containing each separate argument to pass to the hook's callback function.
    29  * @return false|void False if the event did not get scheduled.
     32 * @return bool Whether or not the requested event has been scheduled.
    3033 */
    3134function wp_schedule_single_event( $timestamp, $hook, $args = array() ) {
    3235        // Make sure timestamp is a positive integer
    function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 
    3437                return false;
    3538        }
    3639
    37         // Don't schedule a duplicate if there's already an identical event due within 10 minutes of it
    38         $next = wp_next_scheduled( $hook, $args );
    39         if ( $next && abs( $next - $timestamp ) <= 10 * MINUTE_IN_SECONDS ) {
    40                 return false;
    41         }
    42 
    43         $crons = _get_cron_array();
    4440        $event = (object) array(
    4541                'hook'      => $hook,
    4642                'timestamp' => $timestamp,
    function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 
    4844                'args'      => $args,
    4945        );
    5046
     47        /**
     48         * Filter to preflight or hijack scheduling an event.
     49         *
     50         * Passing a non-null value will short-circuit adding the event to the cron
     51         * array, returning the passed value instead.
     52         *
     53         * Both single events and recurring events are passed through this filter;
     54         * single events have `$event->schedule` as false, whereas recurring events
     55         * have this set to a recurrence from {@see wp_get_schedules}. Recurring
     56         * events also have the integer recurrence interval set as `$event->interval`.
     57         *
     58         * Before scheduling, it is recommended you check for an identical event
     59         * within ten minutes and apply the {@see schedule_event} filter to check
     60         * if another plugin has disallowed the event.
     61         *
     62         * Pass true if the event was successfully scheduled, false if not.
     63         *
     64         * @since 5.0.0
     65         *
     66         * @param null|bool $pre   Value to return instead. Default null to continue adding the event.
     67         * @param stdClass  $event {
     68         *     An object containing an event's data.
     69         *
     70         *     @type string       $hook      Action hook to execute when the event is run.
     71         *     @type int          $timestamp Unix timestamp (UTC) for when to next run the event.
     72         *     @type string|false $schedule  How often the event should subsequently recur.
     73         *     @type array        $args      Array containing each separate argument to pass to the hook's callback function.
     74         *     @type int          $interval  The interval time in seconds for the schedule. Only present for recurring events.
     75         * }
     76         */
     77        $pre = apply_filters( 'pre_schedule_event', null, $event );
     78        if ( null !== $pre ) {
     79                return $pre;
     80        }
     81
     82        // Don't schedule a duplicate if there's already an identical event due within 10 minutes of it
     83        $next = wp_next_scheduled( $hook, $args );
     84        if ( $next && abs( $next - $timestamp ) <= 10 * MINUTE_IN_SECONDS ) {
     85                return false;
     86        }
     87
    5188        /**
    5289         * Filters a single event before it is scheduled.
    5390         *
    function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 
    72109
    73110        $key = md5( serialize( $event->args ) );
    74111
     112        $crons = _get_cron_array();
    75113        $crons[ $event->timestamp ][ $event->hook ][ $key ] = array(
    76114                'schedule' => $event->schedule,
    77115                'args'     => $event->args,
    78116        );
    79117        uksort( $crons, 'strnatcasecmp' );
    80         _set_cron_array( $crons );
     118        return _set_cron_array( $crons );
    81119}
    82120
    83121/**
    function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 
    99137 * Use wp_schedule_single_event() to schedule a non-recurring event.
    100138 *
    101139 * @since 2.1.0
     140 * @since 5.0.0 {@see pre_schedule_event} filter added to allow hijacking,
     141 *              return values modified to boolean indicating success or failure.
     142 *
    102143 * @link https://codex.wordpress.org/Function_Reference/wp_schedule_event
    103144 *
    104145 * @param int    $timestamp  Unix timestamp (UTC) for when to next run the event.
    105146 * @param string $recurrence How often the event should subsequently recur. See wp_get_schedules() for accepted values.
    106147 * @param string $hook       Action hook to execute when the event is run.
    107148 * @param array  $args       Optional. Array containing each separate argument to pass to the hook's callback function.
    108  * @return false|void False if the event did not get scheduled.
     149 * @return bool Whether or not the requested event has been scheduled.
    109150 */
    110151function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) {
    111152        // Make sure timestamp is a positive integer
    function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 
    113154                return false;
    114155        }
    115156
    116         $crons     = _get_cron_array();
    117157        $schedules = wp_get_schedules();
    118158
    119159        if ( ! isset( $schedules[ $recurrence ] ) ) {
    function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 
    127167                'args'      => $args,
    128168                'interval'  => $schedules[ $recurrence ]['interval'],
    129169        );
     170
     171        /** This filter is documented in wp-includes/cron.php */
     172        $pre = apply_filters( 'pre_schedule_event', null, $event );
     173        if ( null !== $pre ) {
     174                return $pre;
     175        }
     176
    130177        /** This filter is documented in wp-includes/cron.php */
    131178        $event = apply_filters( 'schedule_event', $event );
    132179
    function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 
    137184
    138185        $key = md5( serialize( $event->args ) );
    139186
     187        $crons = _get_cron_array();
    140188        $crons[ $event->timestamp ][ $event->hook ][ $key ] = array(
    141189                'schedule' => $event->schedule,
    142190                'args'     => $event->args,
    143191                'interval' => $event->interval,
    144192        );
    145193        uksort( $crons, 'strnatcasecmp' );
    146         _set_cron_array( $crons );
     194        return _set_cron_array( $crons );
    147195}
    148196
    149197/**
    150198 * Reschedules a recurring event.
    151199 *
    152200 * @since 2.1.0
     201 * @since 5.0.0 {@see pre_reschedule_event} filter added to allow hijacking,
     202 *              return values modified to boolean indicating success or failure.
    153203 *
    154204 * @param int    $timestamp  Unix timestamp (UTC) for when to next run the event.
    155205 * @param string $recurrence How often the event should subsequently recur. See wp_get_schedules() for accepted values.
    156206 * @param string $hook       Action hook to execute when the event is run.
    157207 * @param array  $args       Optional. Array containing each separate argument to pass to the hook's callback function.
    158  * @return false|void False if the event did not get rescheduled.
     208 * @return bool Whether or not the requested event has been rescheduled.
    159209 */
    160210function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) {
    161211        // Make sure timestamp is a positive integer
    function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 
    163213                return false;
    164214        }
    165215
    166         $crons     = _get_cron_array();
    167216        $schedules = wp_get_schedules();
    168         $key       = md5( serialize( $args ) );
    169217        $interval  = 0;
    170218
    171         // First we try to get it from the schedule
     219        // First we try to get the interval from the schedule.
    172220        if ( isset( $schedules[ $recurrence ] ) ) {
    173221                $interval = $schedules[ $recurrence ]['interval'];
    174222        }
    175         // Now we try to get it from the saved interval in case the schedule disappears
    176         if ( 0 == $interval ) {
    177                 $interval = $crons[ $timestamp ][ $hook ][ $key ]['interval'];
     223
     224        // Now we try to get it from the saved interval in case the schedule disappears.
     225        if ( 0 === $interval ) {
     226                $scheduled_event = wp_get_scheduled_event( $hook, $args, $timestamp );
     227                if ( $scheduled_event && isset( $scheduled_event->interval ) ) {
     228                        $interval = $scheduled_event->interval;
     229                }
     230        }
     231
     232        $event = (object) array(
     233                'hook'      => $hook,
     234                'timestamp' => $timestamp,
     235                'schedule'  => $recurrence,
     236                'args'      => $args,
     237                'interval'  => $interval,
     238        );
     239
     240        /**
     241         * Filter to preflight or hijack rescheduling of events.
     242         *
     243         * Passing a non-null value will short-circuit the normal rescheduling
     244         * process, returning the passed value instead.
     245         *
     246         * Pass true if the event was successfully scheduled, false if not.
     247         *
     248         * @since 5.0.0
     249         *
     250         * @param null|bool $pre   Value to return instead. Default null to continue adding the event.
     251         * @param stdClass  $event {
     252         *     An object containing an event's data.
     253         *
     254         *     @type string       $hook      Action hook to execute when the event is run.
     255         *     @type int          $timestamp Unix timestamp (UTC) for when to next run the event.
     256         *     @type string|false $schedule  How often the event should subsequently recur.
     257         *     @type array        $args      Array containing each separate argument to pass to the hook's callback function.
     258         *     @type int          $interval  The interval time in seconds for the schedule. Only present for recurring events.
     259         * }
     260         */
     261        $pre = apply_filters( 'pre_reschedule_event', null, $event );
     262        if ( null !== $pre ) {
     263                return $pre;
    178264        }
     265
    179266        // Now we assume something is wrong and fail to schedule
    180267        if ( 0 == $interval ) {
    181268                return false;
    function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 
    189276                $timestamp = $now + ( $interval - ( ( $now - $timestamp ) % $interval ) );
    190277        }
    191278
    192         wp_schedule_event( $timestamp, $recurrence, $hook, $args );
     279        return wp_schedule_event( $timestamp, $recurrence, $hook, $args );
    193280}
    194281
    195282/**
    function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 
    199286 * identified.
    200287 *
    201288 * @since 2.1.0
     289 * @since 5.0.0 {@see pre_unschedule_event} filter added to allow hijacking,
     290 *              return values modified to boolean indicating success or failure.
    202291 *
    203292 * @param int    $timestamp Unix timestamp (UTC) of the event.
    204293 * @param string $hook      Action hook of the event.
    205294 * @param array  $args      Optional. Array containing each separate argument to pass to the hook's callback function.
    206295 *                          Although not passed to a callback, these arguments are used to uniquely identify the
    207296 *                          event, so they should be the same as those used when originally scheduling the event.
    208  * @return false|void False if the event did not get unscheduled.
     297 * @return bool Whether or not the requested event has been unscheduled.
    209298 */
    210299function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
    211300        // Make sure timestamp is a positive integer
    function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 
    213302                return false;
    214303        }
    215304
     305        /**
     306         * Filter to preflight or hijack unscheduling of events.
     307         *
     308         * Passing a non-null value will short-circuit the normal unscheduling
     309         * process, returning the passed value instead.
     310         *
     311         * Pass true if the event was successfully unscheduled, false if not.
     312         *
     313         * @since 5.0.0
     314         *
     315         * @param null|bool $pre       Value to return instead. Default null to continue unscheduling the event.
     316         * @param int       $timestamp Timestamp for when to run the event.
     317         * @param string    $hook      Action hook, the execution of which will be unscheduled.
     318         * @param array     $args      Arguments to pass to the hook's callback function.
     319         */
     320        $pre = apply_filters( 'pre_unschedule_event', null, $timestamp, $hook, $args );
     321        if ( null !== $pre ) {
     322                return $pre;
     323        }
     324
    216325        $crons = _get_cron_array();
    217326        $key   = md5( serialize( $args ) );
    218327        unset( $crons[ $timestamp ][ $hook ][ $key ] );
    function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 
    222331        if ( empty( $crons[ $timestamp ] ) ) {
    223332                unset( $crons[ $timestamp ] );
    224333        }
    225         _set_cron_array( $crons );
     334        return _set_cron_array( $crons );
    226335}
    227336
    228337/**
    229338 * Unschedules all events attached to the hook with the specified arguments.
    230339 *
    231340 * @since 2.1.0
     341 * @since 5.0.0 {@see pre_clear_scheduled_hook} filter added to allow hijacking,
     342 *              return value modified to array of {@see wp_unschedule_event} results.
    232343 *
    233344 * @param string $hook Action hook, the execution of which will be unscheduled.
    234345 * @param array $args Optional. Arguments that were to be passed to the hook's callback function.
     346 * @return array Boolean values, indicating the result of attempting to unschedule each indicated event, with timestamps as keys.
    235347 */
    236348function wp_clear_scheduled_hook( $hook, $args = array() ) {
    237349        // Backward compatibility
    function wp_clear_scheduled_hook( $hook, $args = array() ) { 
    241353                $args = array_slice( func_get_args(), 1 );
    242354        }
    243355
     356        /**
     357         * Filter to preflight or hijack clearing a scheduled hook.
     358         *
     359         * Passing a non-null value will short-circuit the normal unscheduling
     360         * process, returning the passed value instead.
     361         *
     362         * Pass an empty array if no events are unscheduled, an array of boolean
     363         * values if events are unscheduled see {@see wp_clear_scheduled_hook}.
     364         *
     365         * @since 5.0.0
     366         *
     367         * @param null|array $pre  Value to return instead. Default null to continue unscheduling the event.
     368         * @param string     $hook Action hook, the execution of which will be unscheduled.
     369         * @param array      $args Arguments to pass to the hook's callback function.
     370         */
     371        $pre = apply_filters( 'pre_clear_scheduled_hook', null, $hook, $args );
     372        if ( null !== $pre ) {
     373                return $pre;
     374        }
     375
    244376        // This logic duplicates wp_next_scheduled()
    245377        // It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing,
    246378        // and, wp_next_scheduled() returns the same schedule in an infinite loop.
    247379        $crons = _get_cron_array();
    248380        if ( empty( $crons ) ) {
    249                 return;
     381                return array();
    250382        }
    251383
    252         $key = md5( serialize( $args ) );
     384        $results = array();
     385        $key     = md5( serialize( $args ) );
    253386        foreach ( $crons as $timestamp => $cron ) {
    254387                if ( isset( $cron[ $hook ][ $key ] ) ) {
    255                         wp_unschedule_event( $timestamp, $hook, $args );
     388                        $results[ $timestamp ] = wp_unschedule_event( $timestamp, $hook, $args );
    256389                }
    257390        }
     391        return $results;
    258392}
    259393
    260394/**
    function wp_clear_scheduled_hook( $hook, $args = array() ) { 
    263397 * Can be useful for plugins when deactivating to clean up the cron queue.
    264398 *
    265399 * @since 4.9.0
     400 * @since 5.0.0 {@see pre_unschedule_hook} filter added to allow hijacking,
     401 *              return values modified to indicate success or failure.
    266402 *
    267403 * @param string $hook Action hook, the execution of which will be unscheduled.
     404 * @return bool Whether or not the requested events have been unscheduled.
    268405 */
    269406function wp_unschedule_hook( $hook ) {
     407        /**
     408         * Filter to preflight or hijack clearing all events attached to the hook.
     409         *
     410         * Passing a non-null value will short-circuit the normal unscheduling
     411         * process, returning the passed value instead.
     412         *
     413         * Pass true if events are cleared, false if not.
     414         *
     415         * @since 5.0.0
     416         *
     417         * @param null|array $pre  Value to return instead. Default null to continue unscheduling the hook.
     418         * @param string     $hook Action hook, the execution of which will be unscheduled.
     419         */
     420        $pre = apply_filters( 'pre_unschedule_hook', null, $hook );
     421        if ( null !== $pre ) {
     422                return $pre;
     423        }
     424
    270425        $crons = _get_cron_array();
    271426
    272427        foreach ( $crons as $timestamp => $args ) {
    function wp_unschedule_hook( $hook ) { 
    277432                }
    278433        }
    279434
    280         _set_cron_array( $crons );
     435        return _set_cron_array( $crons );
     436}
     437
     438/**
     439 * Retrieve a scheduled event.
     440 *
     441 * Retrieve the full event object for a given event.
     442 *
     443 * @since 5.0.0
     444 *
     445 * @param string   $hook      Action hook of the event.
     446 * @param array    $args      Optional. Array containing each separate argument to pass to the hook's callback function.
     447 *                            Although not passed to a callback, these arguments are used to uniquely identify the
     448 *                            event, so they should be the same as those used when originally scheduling the event.
     449 * @param int|null $timestamp Optional. Unix timestamp (UTC) of the event. If not specified, the next scheduled event is returned.
     450 * @return bool|object The event object. False if the event does not exist.
     451 */
     452function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) {
     453        if ( ! $timestamp ) {
     454                // Get the next scheduled event.
     455                $timestamp = wp_next_scheduled( $hook, $args );
     456        }
     457
     458        /**
     459         * Filter to preflight or hijack retrieving a scheduled event.
     460         *
     461         * Passing a non-null value will short-circuit the normal
     462         * process, returning the passed value instead.
     463         *
     464         * Pass false if the event does not exist, otherwise an event object
     465         * should be returned.
     466         *
     467         * @since 5.0.0
     468         *
     469         * @param null|bool $pre       Value to return instead. Default null to continue retrieving the event.
     470         * @param string    $hook      Action hook of the event.
     471         * @param array     $args      Array containing each separate argument to pass to the hook's callback function.
     472         *                             Although not passed to a callback, these arguments are used to uniquely identify the
     473         *                             event.
     474         * @param int       $timestamp Unix timestamp (UTC) of the event.
     475         */
     476        $pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp );
     477        if ( null !== $pre ) {
     478                return $pre;
     479        }
     480
     481        $crons = _get_cron_array();
     482        $key   = md5( serialize( $args ) );
     483
     484        if ( ! $timestamp || ! isset( $crons[ $timestamp ] ) ) {
     485                // No such event.
     486                return false;
     487        }
     488
     489        if ( ! isset( $crons[ $timestamp ][ $hook ] ) || ! isset( $crons[ $timestamp ][ $hook ][ $key ] ) ) {
     490                return false;
     491        }
     492
     493        $event = (object) array(
     494                'hook'      => $hook,
     495                'timestamp' => $timestamp,
     496                'schedule'  => $crons[ $timestamp ][ $hook ][ $key ]['schedule'],
     497                'args'      => $args,
     498        );
     499
     500        if ( isset( $crons[ $timestamp ][ $hook ][ $key ]['interval'] ) ) {
     501                $event->interval = $crons[ $timestamp ][ $hook ][ $key ]['interval'];
     502        }
     503
     504        return $event;
    281505}
    282506
    283507/**
    284508 * Retrieve the next timestamp for an event.
    285509 *
    286510 * @since 2.1.0
     511 * @since 5.0.0 {@see pre_next_scheduled} and {@see next_scheduled} filters added.
    287512 *
    288513 * @param string $hook Action hook of the event.
    289514 * @param array  $args Optional. Array containing each separate argument to pass to the hook's callback function.
    function wp_unschedule_hook( $hook ) { 
    292517 * @return false|int The Unix timestamp of the next time the event will occur. False if the event doesn't exist.
    293518 */
    294519function wp_next_scheduled( $hook, $args = array() ) {
     520        /**
     521         * Filter to preflight or hijack retrieving the next scheduled event timestamp.
     522         *
     523         * Passing a non-null value will short-circuit the normal retrieval
     524         * process, returning the passed value instead.
     525         *
     526         * Pass the timestamp of the next event if it exists, false if not.
     527         *
     528         * @since 5.0.0
     529         *
     530         * @param null|bool $pre       Value to return instead. Default null to continue unscheduling the event.
     531         * @param string    $hook      Action hook of the event.
     532         * @param array     $args      Arguments to pass to the hook's callback function.
     533         */
     534        $pre = apply_filters( 'pre_next_scheduled', null, $hook, $args );
     535        if ( null !== $pre ) {
     536                return $pre;
     537        }
     538
    295539        $crons = _get_cron_array();
    296540        $key   = md5( serialize( $args ) );
    297         if ( empty( $crons ) ) {
    298                 return false;
    299         }
    300         foreach ( $crons as $timestamp => $cron ) {
    301                 if ( isset( $cron[ $hook ][ $key ] ) ) {
    302                         return $timestamp;
     541        $next  = false;
     542
     543        if ( ! empty( $crons ) ) {
     544                foreach ( $crons as $timestamp => $cron ) {
     545                        if ( isset( $cron[ $hook ][ $key ] ) ) {
     546                                $next = $timestamp;
     547                                break;
     548                        }
    303549                }
    304550        }
    305         return false;
     551
     552        /**
     553         * Filter the next scheduled event timestamp.
     554         *
     555         * @since 5.0.0
     556         *
     557         * @param int|bool $next The UNIX timestamp when the scheduled event will next occur, or false if not found.
     558         * @param string   $hook Action hook to execute when cron is run.
     559         * @param array    $args Arguments to be passed to the callback function. Used for deduplicating events.
     560         */
     561        return apply_filters( 'next_scheduled', $next, $hook, $args );
    306562}
    307563
    308564/**
    309565 * Sends a request to run cron through HTTP request that doesn't halt page loading.
    310566 *
    311567 * @since 2.1.0
     568 * @since 5.0.0 Return values added.
    312569 *
    313570 * @param int $gmt_time Optional. Unix timestamp (UTC). Default 0 (current time is used).
     571 * @return null|WP_Error|array Null when cron could not be spawned, because it is not needed to run.
     572 *                             When cron runs, return the result of {@see wp_remote_post}
    314573 */
    315574function spawn_cron( $gmt_time = 0 ) {
    316575        if ( ! $gmt_time ) {
    function spawn_cron( $gmt_time = 0 ) { 
    318577        }
    319578
    320579        if ( defined( 'DOING_CRON' ) || isset( $_GET['doing_wp_cron'] ) ) {
    321                 return;
     580                return null;
    322581        }
    323582
    324583        /*
    function spawn_cron( $gmt_time = 0 ) { 
    336595
    337596        // don't run if another process is currently running it or more than once every 60 sec.
    338597        if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) {
    339                 return;
     598                return null;
    340599        }
    341600
    342601        //sanity check
    343602        $crons = _get_cron_array();
    344603        if ( ! is_array( $crons ) ) {
    345                 return;
     604                return null;
    346605        }
    347606
    348607        $keys = array_keys( $crons );
    349608        if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
    350                 return;
     609                return null;
    351610        }
    352611
    353612        if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
    354613                if ( 'GET' !== $_SERVER['REQUEST_METHOD'] || defined( 'DOING_AJAX' ) || defined( 'XMLRPC_REQUEST' ) ) {
    355                         return;
     614                        return null;
    356615                }
    357616
    358617                $doing_wp_cron = sprintf( '%.22F', $gmt_time );
    function spawn_cron( $gmt_time = 0 ) { 
    368627                flush();
    369628
    370629                WP_DEBUG ? include_once( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' );
    371                 return;
     630                return null;
    372631        }
    373632
    374633        // Set the cron lock with the current unix timestamp, when the cron is being spawned.
    function spawn_cron( $gmt_time = 0 ) { 
    409668                ), $doing_wp_cron
    410669        );
    411670
    412         wp_remote_post( $cron_request['url'], $cron_request['args'] );
     671        return wp_remote_post( $cron_request['url'], $cron_request['args'] );
    413672}
    414673
    415674/**
    416675 * Run scheduled callbacks or spawn cron for all scheduled events.
    417676 *
    418677 * @since 2.1.0
     678 * @since 5.0.0 Return values added.
     679 *
     680 * @return array|null Array of {@see spawn_cron} results for any cron jobs that were run, with cron timestamps as keys.
     681 *                    Null if no cron jobs are run.
    419682 */
    420683function wp_cron() {
    421684        // Prevent infinite loops caused by lack of wp-cron.php
    422685        if ( strpos( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) !== false || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ) {
    423                 return;
     686                return null;
    424687        }
    425688
    426         if ( false === $crons = _get_cron_array() ) {
    427                 return;
     689        $crons = _get_cron_array();
     690        if ( false === $crons ) {
     691                return null;
    428692        }
    429693
    430694        $gmt_time = microtime( true );
    431695        $keys     = array_keys( $crons );
    432696        if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
    433                 return;
     697                return null;
    434698        }
    435699
     700        $results   = array();
    436701        $schedules = wp_get_schedules();
    437702        foreach ( $crons as $timestamp => $cronhooks ) {
    438703                if ( $timestamp > $gmt_time ) {
    function wp_cron() { 
    442707                        if ( isset( $schedules[ $hook ]['callback'] ) && ! call_user_func( $schedules[ $hook ]['callback'] ) ) {
    443708                                continue;
    444709                        }
    445                         spawn_cron( $gmt_time );
     710                        $results[ $timestamp ] = spawn_cron( $gmt_time );
    446711                        break 2;
    447712                }
    448713        }
     714
     715        return $results;
    449716}
    450717
    451718/**
    function wp_get_schedules() { 
    508775 * @see wp_get_schedules() for available schedules.
    509776 *
    510777 * @since 2.1.0
     778 * @since 5.0.0 {@see get_schedule} filter added.
    511779 *
    512780 * @param string $hook Action hook to identify the event.
    513781 * @param array $args Optional. Arguments passed to the event's callback function.
    514782 * @return string|false False, if no schedule. Schedule name on success.
    515783 */
    516784function wp_get_schedule( $hook, $args = array() ) {
    517         $crons = _get_cron_array();
    518         $key   = md5( serialize( $args ) );
    519         if ( empty( $crons ) ) {
    520                 return false;
    521         }
    522         foreach ( $crons as $timestamp => $cron ) {
    523                 if ( isset( $cron[ $hook ][ $key ] ) ) {
    524                         return $cron[ $hook ][ $key ]['schedule'];
    525                 }
     785        $schedule = false;
     786        $event    = wp_get_scheduled_event( $hook, $args );
     787
     788        if ( $event ) {
     789                $schedule = $event->schedule;
    526790        }
    527         return false;
     791
     792        /**
     793         * Filter the schedule for a hook.
     794         *
     795         * @since 5.0.0
     796         *
     797         * @param string|bool $schedule Schedule for the hook. False if not found.
     798         * @param string      $hook     Action hook to execute when cron is run.
     799         * @param array       $args     Optional. Arguments to pass to the hook's callback function.
     800         */
     801        return apply_filters( 'get_schedule', $schedule, $hook, $args );
    528802}
    529803
    530804//
    function _get_cron_array() { 
    558832 * Updates the CRON option with the new CRON array.
    559833 *
    560834 * @since 2.1.0
     835 * @since 5.0.0 Return value added.
     836 *
    561837 * @access private
    562838 *
    563839 * @param array $cron Cron info array from _get_cron_array().
     840 * @return bool Whether the update of the cron option succeeded (according to {@see update_option})
    564841 */
    565842function _set_cron_array( $cron ) {
    566843        $cron['version'] = 2;
    567         update_option( 'cron', $cron );
     844        return update_option( 'cron', $cron );
    568845}
    569846
    570847/**