WordPress.org

Make WordPress Core

Ticket #39052: 39052.diff

File 39052.diff, 2.7 KB (added by ebinnion, 4 years ago)

Return false if attempting to unschedule non-existent event

  • src/wp-includes/cron.php

     
    165165 * identified.
    166166 *
    167167 * @since 2.1.0
     168 * @since 4.7.1 A condition was added to ensure function returns false when the event does not exist.
    168169 *
    169170 * @param int $timestamp Unix timestamp (UTC) for when to run the event.
    170171 * @param string $hook Action hook, the execution of which will be unscheduled.
     
    172173 * Although not passed to a callback function, these arguments are used
    173174 * to uniquely identify the scheduled event, so they should be the same
    174175 * as those used when originally scheduling the event.
    175  * @return false|void False if the event does not get unscheduled.
     176 *
     177 * @return false|void False if the event does not exist.
    176178 */
    177179function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
    178180        // Make sure timestamp is a positive integer
     
    181183        }
    182184
    183185        $crons = _get_cron_array();
    184         $key = md5(serialize($args));
    185         unset( $crons[$timestamp][$hook][$key] );
    186         if ( empty($crons[$timestamp][$hook]) )
    187                 unset( $crons[$timestamp][$hook] );
    188         if ( empty($crons[$timestamp]) )
    189                 unset( $crons[$timestamp] );
     186        $key = md5( serialize( $args ) );
     187
     188        // If the event does not exist, we can't unschedule the event, so return false.
     189        if ( ! isset(
     190                $crons,
     191                $crons[ $timestamp ],
     192                $crons[ $timestamp ][ $hook ],
     193                $crons[ $timestamp ][ $hook ][ $key ] )
     194        ) {
     195                return false;
     196        }
     197
     198        // Now, remove the event, do cleanup, and update the cron option.
     199        unset( $crons[ $timestamp ][ $hook ][ $key ] );
     200        if ( empty( $crons[ $timestamp ][ $hook ] ) ) {
     201                unset( $crons[ $timestamp ][ $hook ] );
     202        }
     203        if ( empty( $crons[ $timestamp ] ) ) {
     204                unset( $crons[ $timestamp ] );
     205        }
    190206        _set_cron_array( $crons );
    191207}
    192208
  • tests/phpunit/tests/cron.php

     
    9898                $this->assertEquals( false, wp_next_scheduled($hook) );
    9999        }
    100100
     101        function test_unschedule_event_returns_false_when_event_not_unscheduled() {
     102                $hook = __FUNCTION__;
     103                $timestamp = strtotime( '+1 hour' );
     104
     105                $this->assertFalse( wp_unschedule_event( 'hello', $hook ) );
     106                $this->assertFalse( wp_unschedule_event( -1, $hook ) );
     107                $this->assertFalse( wp_unschedule_event( 123456, $hook ) );
     108
     109                // now unschedule it and make sure it's gone
     110                wp_unschedule_event( $timestamp, $hook );
     111                $this->assertEquals( false, wp_next_scheduled($hook) );
     112        }
     113
    101114        function test_clear_schedule() {
    102115                $hook = __FUNCTION__;
    103116                $args = array( 'arg1' );