Ticket #34913: 0002-b-Fix-issue-34913-with-doing-it-wrong-refreshed.patch
File 0002-b-Fix-issue-34913-with-doing-it-wrong-refreshed.patch, 12.3 KB (added by , 9 years ago) |
---|
-
src/wp-admin/includes/upgrade.php
--- src/wp-admin/includes/upgrade.php | 3 ++ src/wp-includes/cron.php | 108 ++++++++++++++++++++++++++++---------- tests/phpunit/tests/cron.php | 100 +++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 27 deletions(-) diff --git a/src/wp-admin/includes/upgrade.php b/src/wp-admin/includes/upgrade.php index e09d42a..649847c 100644
a b function upgrade_450() { 1682 1682 if ( $wp_current_db_version < 36679 && is_multisite() ) { 1683 1683 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name REGEXP '^[0-9]+_new_email$'" ); 1684 1684 } 1685 1686 // Getting the cron array will automatically update it to version 3. 1687 _get_cron_array(); 1685 1688 } 1686 1689 1687 1690 /** -
src/wp-includes/cron.php
diff --git a/src/wp-includes/cron.php b/src/wp-includes/cron.php index 493e0ec..e823026 100644
a b 21 21 * @return false|void False when an event is not scheduled. 22 22 */ 23 23 function wp_schedule_single_event( $timestamp, $hook, $args = array()) { 24 if ( ! is_array( $args ) ) { 25 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 26 } 27 24 28 // Make sure timestamp is a positive integer 25 29 if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { 26 30 return false; … … function wp_schedule_single_event( $timestamp, $hook, $args = array()) { 47 51 if ( ! $event ) 48 52 return false; 49 53 54 $event->args = _cron_cast_to_array_helper( $event->args ); 50 55 $key = md5(serialize($event->args)); 51 56 52 57 $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args ); … … function wp_schedule_single_event( $timestamp, $hook, $args = array()) { 75 80 * @return false|void False when an event is not scheduled. 76 81 */ 77 82 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) { 83 if ( ! is_array( $args ) ) { 84 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 85 } 86 78 87 // Make sure timestamp is a positive integer 79 88 if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { 80 89 return false; … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) { 94 103 if ( ! $event ) 95 104 return false; 96 105 106 $event->args = _cron_cast_to_array_helper( $event->args ); 97 107 $key = md5(serialize($event->args)); 98 108 99 109 $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval ); … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) { 113 123 * @return false|void False when an event is not scheduled. 114 124 */ 115 125 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 126 if ( ! is_array( $args ) ) { 127 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 128 } 129 116 130 // Make sure timestamp is a positive integer 117 131 if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { 118 132 return false; … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 120 134 121 135 $crons = _get_cron_array(); 122 136 $schedules = wp_get_schedules(); 123 $key = md5( serialize( $args ) );124 137 $interval = 0; 125 138 126 139 // First we try to get it from the schedule … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 129 142 } 130 143 // Now we try to get it from the saved interval in case the schedule disappears 131 144 if ( 0 == $interval ) { 145 $key = md5( serialize( _cron_cast_to_array_helper( $args ) ) ); 132 146 $interval = $crons[ $timestamp ][ $hook ][ $key ]['interval']; 133 147 } 134 148 // Now we assume something is wrong and fail to schedule … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 164 178 * @return false|void False when an event is not unscheduled. 165 179 */ 166 180 function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 181 if ( ! is_array( $args ) ) { 182 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 183 } 184 167 185 // Make sure timestamp is a positive integer 168 186 if ( ! is_numeric( $timestamp ) || $timestamp <= 0 ) { 169 187 return false; 170 188 } 171 189 172 190 $crons = _get_cron_array(); 173 $key = md5(serialize($args)); 174 unset( $crons[$timestamp][$hook][$key] ); 175 if ( empty($crons[$timestamp][$hook]) ) 176 unset( $crons[$timestamp][$hook] ); 177 if ( empty($crons[$timestamp]) ) 178 unset( $crons[$timestamp] ); 191 $key = md5( serialize( _cron_cast_to_array_helper( $args ) ) ); 192 unset( $crons[ $timestamp ][ $hook ][ $key ] ); 193 if ( empty( $crons[ $timestamp ][ $hook ] ) ) { 194 unset( $crons[ $timestamp ][ $hook ] ); 195 } 196 if ( empty( $crons[ $timestamp ] ) ) { 197 unset( $crons[ $timestamp ] ); 198 } 179 199 _set_cron_array( $crons ); 180 200 } 181 201 … … function wp_clear_scheduled_hook( $hook, $args = array() ) { 220 240 * @return false|int The UNIX timestamp of the next time the scheduled event will occur. 221 241 */ 222 242 function wp_next_scheduled( $hook, $args = array() ) { 243 if ( ! is_array( $args ) ) { 244 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 245 } 246 223 247 $crons = _get_cron_array(); 224 $key = md5(serialize($args)); 225 if ( empty($crons) ) 248 if ( empty( $crons ) ) { 226 249 return false; 250 } 251 252 $key = md5( serialize( _cron_cast_to_array_helper( $args ) ) ); 227 253 foreach ( $crons as $timestamp => $cron ) { 228 if ( isset( $cron[ $hook][$key] ) )254 if ( isset( $cron[ $hook ][ $key ] ) ) { 229 255 return $timestamp; 256 } 230 257 } 231 258 return false; 232 259 } … … function wp_get_schedules() { 415 442 * @return string|false False, if no schedule. Schedule on success. 416 443 */ 417 444 function wp_get_schedule($hook, $args = array()) { 445 if ( ! is_array( $args ) ) { 446 _doing_it_wrong( __FUNCTION__, __( 'Cron arguments are expected to be an array. Please update your function call.' ), '2.1.0' ); 447 } 448 418 449 $crons = _get_cron_array(); 419 $key = md5(serialize($args)); 420 if ( empty($crons) ) 450 if ( empty( $crons ) ) { 421 451 return false; 452 } 453 454 $key = md5( serialize( _cron_cast_to_array_helper( $args ) ) ); 422 455 foreach ( $crons as $timestamp => $cron ) { 423 if ( isset( $cron[$hook][$key] ) ) 424 return $cron[$hook][$key]['schedule']; 456 if ( isset( $cron[ $hook ][ $key ] ) ) { 457 return $cron[ $hook ][ $key ]['schedule']; 458 } 425 459 } 426 460 return false; 427 461 } … … function wp_get_schedule($hook, $args = array()) { 439 473 * @return false|array CRON info array. 440 474 */ 441 475 function _get_cron_array() { 442 $cron = get_option( 'cron');443 if ( ! is_array( $cron) )476 $cron = get_option( 'cron' ); 477 if ( ! is_array( $cron ) ) { 444 478 return false; 479 } 445 480 446 if ( !isset($cron['version']) ) 447 $cron = _upgrade_cron_array($cron); 481 if ( ! isset( $cron['version'] ) || 3 > $cron['version'] ) { 482 $cron = _upgrade_cron_array( $cron ); 483 } 448 484 449 unset( $cron['version']);485 unset( $cron['version'] ); 450 486 451 487 return $cron; 452 488 } … … function _get_cron_array() { 460 496 * @param array $cron Cron info array from {@link _get_cron_array()}. 461 497 */ 462 498 function _set_cron_array($cron) { 463 $cron['version'] = 2;499 $cron['version'] = 3; 464 500 update_option( 'cron', $cron ); 465 501 } 466 502 467 503 /** 468 504 * Upgrade a Cron info array. 469 505 * 470 * This function upgrades the Cron info array to version 2.506 * This function upgrades the Cron info array to version 3. 471 507 * 472 508 * @since 2.1.0 473 509 * @access private … … function _set_cron_array($cron) { 476 512 * @return array An upgraded Cron info array. 477 513 */ 478 514 function _upgrade_cron_array($cron) { 479 if ( isset( $cron['version']) && 2 == $cron['version'])515 if ( isset( $cron['version'] ) && 3 === $cron['version'] ) { 480 516 return $cron; 517 } 481 518 482 519 $new_cron = array(); 483 520 484 foreach ( (array) $cron as $timestamp => $hooks) { 485 foreach ( (array) $hooks as $hook => $args ) { 486 $key = md5(serialize($args['args'])); 487 $new_cron[$timestamp][$hook][$key] = $args; 521 foreach ( (array) $cron as $timestamp => $hooks ) { 522 foreach ( (array) $hooks as $hook => $event ) { 523 foreach( (array) $event as $args ) { 524 $key = md5( serialize( _cron_cast_to_array_helper( $args['args'] ) ) ); 525 $new_cron[ $timestamp ][ $hook ][ $key ] = $args; 526 } 488 527 } 489 528 } 490 529 491 $new_cron['version'] = 2;530 $new_cron['version'] = 3; 492 531 update_option( 'cron', $new_cron ); 493 532 return $new_cron; 494 533 } 534 535 /** 536 * Compatibility function for consistent casting to array of cron arguments. 537 * 538 * @since 4.5.0 539 * 540 * @param mixed $args Cron arguments. 541 * @return array 542 */ 543 function _cron_cast_to_array_helper( $args ) { 544 if ( is_object( $args ) ) { 545 return array( $args ); 546 } 547 return (array) $args; 548 } 549 No newline at end of file -
tests/phpunit/tests/cron.php
diff --git a/tests/phpunit/tests/cron.php b/tests/phpunit/tests/cron.php index b411a5b..390f00c 100644
a b class Tests_Cron extends WP_UnitTestCase { 189 189 190 190 } 191 191 192 193 /** 194 * @ticket 34913 195 * 196 * @expectedDeprecated wp_clear_scheduled_hook 197 * @expectedIncorrectUsage wp_schedule_single_event 198 * @expectedIncorrectUsage wp_next_scheduled 199 */ 200 function test_clear_schedule_non_array_args() { 201 $hook = rand_str(); 202 $bool_arg = true; 203 $int_arg = mt_rand(); 204 $float_arg = mt_rand() / mt_getrandmax(); 205 $string_arg = rand_str(); 206 $obj_arg = new cronTestClass(); 207 208 // Schedule several events with non-array arguments. 209 wp_schedule_single_event( strtotime('+1 hour'), $hook, $bool_arg ); 210 wp_schedule_single_event( strtotime('+2 hour'), $hook, $int_arg ); 211 wp_schedule_single_event( strtotime('+3 hour'), $hook, $float_arg ); 212 wp_schedule_single_event( strtotime('+4 hour'), $hook, $string_arg ); 213 wp_schedule_single_event( strtotime('+5 hour'), $hook, $obj_arg ); 214 215 // Make sure they're returned by wp_next_scheduled(). 216 $this->assertTrue( wp_next_scheduled($hook, $bool_arg) > 0 ); 217 $this->assertTrue( wp_next_scheduled($hook, $int_arg) > 0 ); 218 $this->assertTrue( wp_next_scheduled($hook, $float_arg) > 0 ); 219 $this->assertTrue( wp_next_scheduled($hook, $string_arg) > 0 ); 220 $this->assertTrue( wp_next_scheduled($hook, $obj_arg) > 0 ); 221 222 // Clear the schedule for the bool_arg event and make sure it's gone. 223 wp_clear_scheduled_hook($hook, $bool_arg ); 224 $this->assertFalse( wp_next_scheduled($hook, $bool_arg) ); 225 226 // Clear the schedule for the int_arg event and make sure it's gone. 227 wp_clear_scheduled_hook($hook, $int_arg ); 228 $this->assertFalse( wp_next_scheduled($hook, $int_arg) ); 229 230 // Clear the schedule for the float_arg event and make sure it's gone. 231 wp_clear_scheduled_hook($hook, $float_arg ); 232 $this->assertFalse( wp_next_scheduled($hook, $float_arg) ); 233 234 // Clear the schedule for the string_arg event and make sure it's gone. 235 wp_clear_scheduled_hook($hook, $string_arg ); 236 $this->assertFalse( wp_next_scheduled($hook, $string_arg) ); 237 238 // Clear the schedule for the object_arg event and make sure it's gone. 239 wp_clear_scheduled_hook($hook, $obj_arg ); 240 $this->assertFalse( wp_next_scheduled($hook, $obj_arg) ); 241 242 } 243 244 /** 245 * @ticket 34913 246 * 247 * {@internal Separate test for resources as this one can easily fail to create 248 * the necessary resource and we don't want to skip the other wp_clear_scheduled_hook() 249 * tests if it does.}} 250 * 251 * @expectedDeprecated wp_clear_scheduled_hook 252 * @expectedIncorrectUsage wp_schedule_single_event 253 * @expectedIncorrectUsage wp_next_scheduled 254 */ 255 function test_clear_schedule_resource_arg() { 256 $hook = rand_str(); 257 $arg = tmpfile(); 258 259 if ( $arg === false ) { 260 $this->markTestSkipped( 'Could not create resource.' ); 261 return; 262 } 263 264 // Schedule event with resource argument. 265 wp_schedule_single_event( strtotime('+1 hour'), $hook, $arg ); 266 267 // Make sure they're returned by wp_next_scheduled(). 268 $this->assertTrue( wp_next_scheduled($hook, $arg) > 0 ); 269 270 // Clear the schedule for the event and make sure it's gone. 271 wp_clear_scheduled_hook($hook, $arg ); 272 $this->assertFalse( wp_next_scheduled($hook, $arg) ); 273 274 fclose( $arg ); 275 276 } 277 278 192 279 /** 193 280 * @ticket 6966 194 281 */ … … class WPTestCronRunning extends _WPEmptyBlog { 327 414 } 328 415 } 329 416 */ 417 418 /** 419 * Test class belonging to the `test_clear_schedule_non_array_arg()` test. 420 */ 421 class cronTestClass { 422 public $property_a = 'something'; 423 public $property_b = 123; 424 private $property_c = false; 425 426 public function some_function() { 427 return true; 428 } 429 }