Ticket #32656: 32656.3.diff
File 32656.3.diff, 19.0 KB (added by , 6 years ago) |
---|
-
src/wp-includes/cron.php
diff --git src/wp-includes/cron.php src/wp-includes/cron.php index fbf5a629af..3c0a0fdff7 100644
26 26 * @param int $timestamp Unix timestamp (UTC) for when to next run the event. 27 27 * @param string $hook Action hook to execute when the event is run. 28 28 * @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 getscheduled.29 * @return bool Whether or not the requested event has been scheduled. 30 30 */ 31 31 function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 32 32 // Make sure timestamp is a positive integer … … function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 34 34 return false; 35 35 } 36 36 37 // Don't schedule a duplicate if there's already an identical event due within 10 minutes of it38 $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();44 37 $event = (object) array( 45 38 'hook' => $hook, 46 39 'timestamp' => $timestamp, … … function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 48 41 'args' => $args, 49 42 ); 50 43 44 /** 45 * Filter to preflight or hijack scheduling an event. 46 * 47 * Passing a non-null value will short-circuit adding the event to the cron 48 * array, returning the passed value instead. 49 * 50 * Both single events and recurring events are passed through this filter; 51 * single events have `$event->schedule` as false, whereas recurring events 52 * have this set to a recurrence from {@see wp_get_schedules}. Recurring 53 * events also have the integer recurrence interval set as `$event->interval` 54 * 55 * @param null|bool $pre Value to return instead. Default null to continue adding the event. 56 * @param stdClass $event { 57 * An object containing an event's data. 58 * 59 * @type string $hook Action hook to execute when the event is run. 60 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. 61 * @type string|false $schedule How often the event should subsequently recur. 62 * @type array $args Array containing each separate argument to pass to the hook's callback function. 63 * @type int $interval The interval time in seconds for the schedule. Only present for recurring events. 64 * } 65 */ 66 $pre = apply_filters( 'pre_schedule_event', null, $event ); 67 if ( null !== $pre ) { 68 return $pre; 69 } 70 71 // Don't schedule a duplicate if there's already an identical event due within 10 minutes of it 72 $next = wp_next_scheduled( $hook, $args ); 73 if ( $next && abs( $next - $timestamp ) <= 10 * MINUTE_IN_SECONDS ) { 74 return false; 75 } 76 51 77 /** 52 78 * Filters a single event before it is scheduled. 53 79 * … … function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 72 98 73 99 $key = md5( serialize( $event->args ) ); 74 100 101 $crons = _get_cron_array(); 75 102 $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( 76 103 'schedule' => $event->schedule, 77 104 'args' => $event->args, 78 105 ); 79 106 uksort( $crons, 'strnatcasecmp' ); 80 _set_cron_array( $crons );107 return _set_cron_array( $crons ); 81 108 } 82 109 83 110 /** … … function wp_schedule_single_event( $timestamp, $hook, $args = array() ) { 105 132 * @param string $recurrence How often the event should subsequently recur. See wp_get_schedules() for accepted values. 106 133 * @param string $hook Action hook to execute when the event is run. 107 134 * @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 getscheduled.135 * @return bool Whether or not the requested event has been scheduled. 109 136 */ 110 137 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 111 138 // Make sure timestamp is a positive integer … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 113 140 return false; 114 141 } 115 142 116 $crons = _get_cron_array();117 143 $schedules = wp_get_schedules(); 118 144 119 145 if ( ! isset( $schedules[ $recurrence ] ) ) { … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 127 153 'args' => $args, 128 154 'interval' => $schedules[ $recurrence ]['interval'], 129 155 ); 156 157 /** This filter is documented in wp-includes/cron.php */ 158 $pre = apply_filters( 'pre_schedule_event', null, $event ); 159 if ( null !== $pre ) { 160 return $pre; 161 } 162 130 163 /** This filter is documented in wp-includes/cron.php */ 131 164 $event = apply_filters( 'schedule_event', $event ); 132 165 … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 137 170 138 171 $key = md5( serialize( $event->args ) ); 139 172 173 $crons = _get_cron_array(); 140 174 $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( 141 175 'schedule' => $event->schedule, 142 176 'args' => $event->args, 143 177 'interval' => $event->interval, 144 178 ); 145 179 uksort( $crons, 'strnatcasecmp' ); 146 _set_cron_array( $crons );180 return _set_cron_array( $crons ); 147 181 } 148 182 149 183 /** … … function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 155 189 * @param string $recurrence How often the event should subsequently recur. See wp_get_schedules() for accepted values. 156 190 * @param string $hook Action hook to execute when the event is run. 157 191 * @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 getrescheduled.192 * @return bool Whether or not the requested event has been rescheduled. 159 193 */ 160 194 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) { 161 195 // Make sure timestamp is a positive integer … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 163 197 return false; 164 198 } 165 199 166 $crons = _get_cron_array();167 200 $schedules = wp_get_schedules(); 168 $key = md5( serialize( $args ) );169 201 $interval = 0; 170 202 171 // First we try to get it from the schedule203 // First we try to get the interval from the schedule. 172 204 if ( isset( $schedules[ $recurrence ] ) ) { 173 205 $interval = $schedules[ $recurrence ]['interval']; 174 206 } 175 // Now we try to get it from the saved interval in case the schedule disappears 207 208 // Now we try to get it from the saved interval in case the schedule disappears. 176 209 if ( 0 == $interval ) { 177 $interval = $crons[ $timestamp ][ $hook ][ $key ]['interval']; 210 $crons = _get_cron_array(); 211 $key = md5( serialize( $args ) ); 212 $interval = $crons[ $timestamp ][ $hook ][ $key ][ 'interval' ]; 213 } 214 215 $event = (object) array( 216 'hook' => $hook, 217 'timestamp' => $timestamp, 218 'schedule' => $recurrence, 219 'args' => $args, 220 'interval' => $schedules[ $recurrence ]['interval'], 221 ); 222 223 /** 224 * Filter to preflight or hijack rescheduling of events. 225 * 226 * Passing a non-null value will short-circuit the normal rescheduling 227 * process, returning the passed value instead. 228 * 229 * @param null|bool $pre Value to return instead. Default null to continue adding the event. 230 * @param stdClass $event { 231 * An object containing an event's data. 232 * 233 * @type string $hook Action hook to execute when the event is run. 234 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. 235 * @type string|false $schedule How often the event should subsequently recur. 236 * @type array $args Array containing each separate argument to pass to the hook's callback function. 237 * @type int $interval The interval time in seconds for the schedule. Only present for recurring events. 238 * } 239 */ 240 $pre = apply_filters( 'pre_reschedule_event', null, $event ); 241 if ( null !== $pre ) { 242 return $pre; 178 243 } 244 179 245 // Now we assume something is wrong and fail to schedule 180 246 if ( 0 == $interval ) { 181 247 return false; … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 189 255 $timestamp = $now + ( $interval - ( ( $now - $timestamp ) % $interval ) ); 190 256 } 191 257 192 wp_schedule_event( $timestamp, $recurrence, $hook, $args );258 return wp_schedule_event( $timestamp, $recurrence, $hook, $args ); 193 259 } 194 260 195 261 /** … … function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) 205 271 * @param array $args Optional. Array containing each separate argument to pass to the hook's callback function. 206 272 * Although not passed to a callback, these arguments are used to uniquely identify the 207 273 * 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 getunscheduled.274 * @return bool Whether or not the requested event has been unscheduled. 209 275 */ 210 276 function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 211 277 // Make sure timestamp is a positive integer … … function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 213 279 return false; 214 280 } 215 281 282 /** 283 * Filter to preflight or hijack unscheduling of events. 284 * 285 * Passing a non-null value will short-circuit the normal unscheduling 286 * process, returning the passed value instead. 287 * 288 * @param null|bool $pre Value to return instead. Default null to continue unscheduling the event. 289 * @param int $timestamp Timestamp for when to run the event. 290 * @param string $hook Action hook, the execution of which will be unscheduled. 291 * @param array $args Arguments to pass to the hook's callback function. 292 */ 293 $pre = apply_filters( 'pre_unschedule_event', null, $timestamp, $hook, $args ); 294 if ( null !== $pre ) { 295 return $pre; 296 } 297 216 298 $crons = _get_cron_array(); 217 299 $key = md5( serialize( $args ) ); 218 300 unset( $crons[ $timestamp ][ $hook ][ $key ] ); … … function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 222 304 if ( empty( $crons[ $timestamp ] ) ) { 223 305 unset( $crons[ $timestamp ] ); 224 306 } 225 _set_cron_array( $crons );307 return _set_cron_array( $crons ); 226 308 } 227 309 228 310 /** … … function wp_unschedule_event( $timestamp, $hook, $args = array() ) { 232 314 * 233 315 * @param string $hook Action hook, the execution of which will be unscheduled. 234 316 * @param array $args Optional. Arguments that were to be passed to the hook's callback function. 317 * @return array Boolean values, indicating the result of attempting to unschedule each indicated event, with timestamps as keys. 235 318 */ 236 319 function wp_clear_scheduled_hook( $hook, $args = array() ) { 237 320 // Backward compatibility … … function wp_clear_scheduled_hook( $hook, $args = array() ) { 241 324 $args = array_slice( func_get_args(), 1 ); 242 325 } 243 326 327 /** 328 * Filter to preflight or hijack clearing a scheduled hook. 329 * 330 * Passing a non-null value will short-circuit the normal unscheduling 331 * process, returning the passed value instead. 332 * 333 * @param null|array $pre Value to return instead. Default null to continue unscheduling the event. 334 * @param string $hook Action hook, the execution of which will be unscheduled. 335 * @param array $args Arguments to pass to the hook's callback function. 336 */ 337 $pre = apply_filters( 'pre_clear_scheduled_hook', null, $hook, $args ); 338 if ( null !== $pre ) { 339 return $pre; 340 } 341 244 342 // This logic duplicates wp_next_scheduled() 245 343 // It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing, 246 344 // and, wp_next_scheduled() returns the same schedule in an infinite loop. 247 345 $crons = _get_cron_array(); 248 346 if ( empty( $crons ) ) { 249 return ;347 return array(); 250 348 } 251 349 252 $key = md5( serialize( $args ) ); 350 $results = array(); 351 $key = md5( serialize( $args ) ); 253 352 foreach ( $crons as $timestamp => $cron ) { 254 353 if ( isset( $cron[ $hook ][ $key ] ) ) { 255 wp_unschedule_event( $timestamp, $hook, $args );354 $results[ $timestamp ] = wp_unschedule_event( $timestamp, $hook, $args ); 256 355 } 257 356 } 357 return $results; 258 358 } 259 359 260 360 /** … … function wp_clear_scheduled_hook( $hook, $args = array() ) { 265 365 * @since 4.9.0 266 366 * 267 367 * @param string $hook Action hook, the execution of which will be unscheduled. 368 * @return bool Whether or not the requested events have been unscheduled. 268 369 */ 269 370 function wp_unschedule_hook( $hook ) { 371 /** 372 * Filter to preflight or hijack clearing all events attached to the hook. 373 * 374 * Passing a non-null value will short-circuit the normal unscheduling 375 * process, returning the passed value instead. 376 * 377 * @param null|array $pre Value to return instead. Default null to continue unscheduling the hook. 378 * @param string $hook Action hook, the execution of which will be unscheduled. 379 */ 380 $pre = apply_filters( 'pre_unschedule_hook', null, $hook ); 381 if ( null !== $pre ) { 382 return $pre; 383 } 384 270 385 $crons = _get_cron_array(); 271 386 272 387 foreach ( $crons as $timestamp => $args ) { … … function wp_unschedule_hook( $hook ) { 277 392 } 278 393 } 279 394 280 _set_cron_array( $crons );395 return _set_cron_array( $crons ); 281 396 } 282 397 283 398 /** … … function wp_unschedule_hook( $hook ) { 292 407 * @return false|int The Unix timestamp of the next time the event will occur. False if the event doesn't exist. 293 408 */ 294 409 function wp_next_scheduled( $hook, $args = array() ) { 410 /** 411 * Filter to preflight or hijack unscheduling of events. 412 * 413 * Passing a non-null value will short-circuit the normal unscheduling 414 * process, returning the passed value instead. 415 * 416 * @param null|bool $pre Value to return instead. Default null to continue unscheduling the event. 417 * @param string $hook Action hook of the event. 418 * @param array $args Arguments to pass to the hook's callback function. 419 */ 420 $pre = apply_filters( 'pre_next_scheduled', null, $hook, $args ); 421 if ( null !== $pre ) { 422 return $pre; 423 } 424 295 425 $crons = _get_cron_array(); 296 426 $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; 427 $next = false; 428 429 if ( ! empty( $crons ) ) { 430 foreach ( $crons as $timestamp => $cron ) { 431 if ( isset( $cron[ $hook ][ $key ] ) ) { 432 $next = $timestamp; 433 break; 434 } 303 435 } 304 436 } 305 return false; 437 438 /** 439 * Filter the next scheduled event timestamp. 440 * 441 * @param int|bool $next The UNIX timestamp when the scheduled event will next occur, or false if not found. 442 * @param string $hook Action hook to execute when cron is run. 443 * @param array $args Arguments to be passed to the callback function. Used for deduplicating events. 444 */ 445 return apply_filters( 'next_scheduled', $next, $hook, $args ); 306 446 } 307 447 308 448 /** … … function wp_next_scheduled( $hook, $args = array() ) { 311 451 * @since 2.1.0 312 452 * 313 453 * @param int $gmt_time Optional. Unix timestamp (UTC). Default 0 (current time is used). 454 * @return null|WP_Error|array Null when cron could not be spawned, because it is not needed to run. 455 * When cron runs, return the result of {@see wp_remote_post} 314 456 */ 315 457 function spawn_cron( $gmt_time = 0 ) { 316 458 if ( ! $gmt_time ) { … … function spawn_cron( $gmt_time = 0 ) { 318 460 } 319 461 320 462 if ( defined( 'DOING_CRON' ) || isset( $_GET['doing_wp_cron'] ) ) { 321 return ;463 return null; 322 464 } 323 465 324 466 /* … … function spawn_cron( $gmt_time = 0 ) { 336 478 337 479 // don't run if another process is currently running it or more than once every 60 sec. 338 480 if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) { 339 return ;481 return null; 340 482 } 341 483 342 484 //sanity check 343 485 $crons = _get_cron_array(); 344 486 if ( ! is_array( $crons ) ) { 345 return ;487 return null; 346 488 } 347 489 348 490 $keys = array_keys( $crons ); 349 491 if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { 350 return ;492 return null; 351 493 } 352 494 353 495 if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) { 354 496 if ( 'GET' !== $_SERVER['REQUEST_METHOD'] || defined( 'DOING_AJAX' ) || defined( 'XMLRPC_REQUEST' ) ) { 355 return ;497 return null; 356 498 } 357 499 358 500 $doing_wp_cron = sprintf( '%.22F', $gmt_time ); … … function spawn_cron( $gmt_time = 0 ) { 368 510 flush(); 369 511 370 512 WP_DEBUG ? include_once( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' ); 371 return ;513 return null; 372 514 } 373 515 374 516 // Set the cron lock with the current unix timestamp, when the cron is being spawned. … … function spawn_cron( $gmt_time = 0 ) { 409 551 ), $doing_wp_cron 410 552 ); 411 553 412 wp_remote_post( $cron_request['url'], $cron_request['args'] );554 return wp_remote_post( $cron_request['url'], $cron_request['args'] ); 413 555 } 414 556 415 557 /** 416 558 * Run scheduled callbacks or spawn cron for all scheduled events. 417 559 * 418 560 * @since 2.1.0 561 * 562 * @return array Array of spawn_cron() results for any cron jobs that were run, with cron timestamps as keys. 419 563 */ 420 564 function wp_cron() { 421 565 // Prevent infinite loops caused by lack of wp-cron.php 422 566 if ( strpos( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) !== false || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ) { 423 return ;567 return array(); 424 568 } 425 569 426 if ( false === $crons = _get_cron_array() ) { 427 return; 570 $crons = _get_cron_array(); 571 if ( false === $crons ) { 572 return array(); 428 573 } 429 574 430 575 $gmt_time = microtime( true ); 431 576 $keys = array_keys( $crons ); 432 577 if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { 433 return ;578 return array(); 434 579 } 435 580 581 $results = array(); 436 582 $schedules = wp_get_schedules(); 437 583 foreach ( $crons as $timestamp => $cronhooks ) { 438 584 if ( $timestamp > $gmt_time ) { … … function wp_cron() { 442 588 if ( isset( $schedules[ $hook ]['callback'] ) && ! call_user_func( $schedules[ $hook ]['callback'] ) ) { 443 589 continue; 444 590 } 445 spawn_cron( $gmt_time );591 $results[ $timestamp ] = spawn_cron( $gmt_time ); 446 592 break 2; 447 593 } 448 594 } 595 596 return $results; 449 597 } 450 598 451 599 /** … … function wp_get_schedules() { 514 662 * @return string|false False, if no schedule. Schedule name on success. 515 663 */ 516 664 function 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']; 665 $crons = _get_cron_array(); 666 $key = md5( serialize( $args ) ); 667 $schedule = false; 668 669 if ( ! empty( $crons ) ) { 670 foreach ( $crons as $timestamp => $cron ) { 671 if ( isset( $cron[ $hook ][ $key ] ) ) { 672 $schedule = $cron[ $hook ][ $key ]['schedule']; 673 break; 674 } 525 675 } 526 676 } 527 return false; 677 678 /** 679 * Filter the schedule for a hook. 680 * 681 * @param string|bool $schedule Schedule for the hook. False if not found. 682 * @param string $hook Action hook to execute when cron is run. 683 * @param array $args Optional. Arguments to pass to the hook's callback function. 684 */ 685 return apply_filters( 'get_schedule', $schedule, $hook, $args ); 528 686 } 529 687 530 688 // … … function _get_cron_array() { 561 719 * @access private 562 720 * 563 721 * @param array $cron Cron info array from _get_cron_array(). 722 * @return bool Whether the update of the cron option succeeded (according to {@see update_option}) 564 723 */ 565 724 function _set_cron_array( $cron ) { 566 725 $cron['version'] = 2; 567 update_option( 'cron', $cron );726 return update_option( 'cron', $cron ); 568 727 } 569 728 570 729 /**