74 * Return true if the event was scheduled, false or a WP_Error if not. |
74 * Return true if the event was scheduled, false or a WP_Error if not. |
75 * |
75 * |
76 * @since 5.1.0 |
76 * @since 5.1.0 |
77 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
77 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
78 * |
78 * |
79 * @param null|bool|WP_Error $pre Value to return instead. Default null to continue adding the event. |
79 * @param null|bool|WP_Error $result The value to return instead. Default null to continue adding the event. |
80 * @param stdClass $event { |
80 * @param object $event { |
81 * An object containing an event's data. |
81 * An object containing an event's data. |
82 * |
82 * |
83 * @type string $hook Action hook to execute when the event is run. |
83 * @type string $hook Action hook to execute when the event is run. |
84 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
84 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
85 * @type string|false $schedule How often the event should subsequently recur. |
85 * @type string|false $schedule How often the event should subsequently recur. |
86 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
86 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
87 * @type int $interval The interval time in seconds for the schedule. Only present for recurring events. |
87 * @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events. |
88 * } |
88 * } |
89 * @param bool $wp_error Whether to return a WP_Error on failure. |
89 * @param bool $wp_error Whether to return a WP_Error on failure. |
90 */ |
90 */ |
91 $pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error ); |
91 $pre = apply_filters( 'pre_schedule_event', null, $event, $wp_error ); |
92 |
92 |
165 /** |
164 /** |
166 * Modify an event before it is scheduled. |
165 * Modify an event before it is scheduled. |
167 * |
166 * |
168 * @since 3.1.0 |
167 * @since 3.1.0 |
169 * |
168 * |
170 * @param stdClass|false $event { |
169 * @param object|false $event { |
171 * An object containing an event's data, or boolean false to prevent the event from being scheduled. |
170 * An object containing an event's data, or boolean false to prevent the event from being scheduled. |
172 * |
171 * |
173 * @type string $hook Action hook to execute when the event is run. |
172 * @type string $hook Action hook to execute when the event is run. |
174 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
173 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
175 * @type string|false $schedule How often the event should subsequently recur. |
174 * @type string|false $schedule How often the event should subsequently recur. |
176 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
175 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
177 * @type int $interval The interval time in seconds for the schedule. Only present for recurring events. |
176 * @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events. |
178 * } |
177 * } |
179 */ |
178 */ |
180 $event = apply_filters( 'schedule_event', $event ); |
179 $event = apply_filters( 'schedule_event', $event ); |
181 |
180 |
182 // A plugin disallowed this event. |
181 // A plugin disallowed this event. |
205 * |
204 * |
206 * Schedules a hook which will be triggered by WordPress at the specified interval. |
205 * Schedules a hook which will be triggered by WordPress at the specified interval. |
207 * The action will trigger when someone visits your WordPress site if the scheduled |
206 * The action will trigger when someone visits your WordPress site if the scheduled |
208 * time has passed. |
207 * time has passed. |
209 * |
208 * |
210 * Valid values for the recurrence are 'hourly', 'daily', and 'twicedaily'. These can |
209 * Valid values for the recurrence are 'hourly', 'twicedaily', 'daily', and 'weekly'. |
211 * be extended using the {@see 'cron_schedules'} filter in wp_get_schedules(). |
210 * These can be extended using the {@see 'cron_schedules'} filter in wp_get_schedules(). |
212 * |
|
213 * Note that scheduling an event to occur within 10 minutes of an existing event |
|
214 * with the same action hook will be ignored unless you pass unique `$args` values |
|
215 * for each scheduled event. |
|
216 * |
211 * |
217 * Use wp_next_scheduled() to prevent duplicate events. |
212 * Use wp_next_scheduled() to prevent duplicate events. |
218 * |
213 * |
219 * Use wp_schedule_single_event() to schedule a non-recurring event. |
214 * Use wp_schedule_single_event() to schedule a non-recurring event. |
220 * |
215 * |
304 } |
299 } |
305 |
300 |
306 $key = md5( serialize( $event->args ) ); |
301 $key = md5( serialize( $event->args ) ); |
307 |
302 |
308 $crons = _get_cron_array(); |
303 $crons = _get_cron_array(); |
309 if ( ! is_array( $crons ) ) { |
|
310 $crons = array(); |
|
311 } |
|
312 |
304 |
313 $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( |
305 $crons[ $event->timestamp ][ $event->hook ][ $key ] = array( |
314 'schedule' => $event->schedule, |
306 'schedule' => $event->schedule, |
315 'args' => $event->args, |
307 'args' => $event->args, |
316 'interval' => $event->interval, |
308 'interval' => $event->interval, |
381 'args' => $args, |
374 'args' => $args, |
382 'interval' => $interval, |
375 'interval' => $interval, |
383 ); |
376 ); |
384 |
377 |
385 /** |
378 /** |
386 * Filter to preflight or hijack rescheduling of events. |
379 * Filter to override rescheduling of a recurring event. |
387 * |
380 * |
388 * Returning a non-null value will short-circuit the normal rescheduling |
381 * Returning a non-null value will short-circuit the normal rescheduling |
389 * process, causing the function to return the filtered value instead. |
382 * process, causing the function to return the filtered value instead. |
390 * |
383 * |
391 * For plugins replacing wp-cron, return true if the event was successfully |
384 * For plugins replacing wp-cron, return true if the event was successfully |
392 * rescheduled, false if not. |
385 * rescheduled, false or a WP_Error if not. |
393 * |
386 * |
394 * @since 5.1.0 |
387 * @since 5.1.0 |
395 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
388 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
396 * |
389 * |
397 * @param null|bool|WP_Error $pre Value to return instead. Default null to continue adding the event. |
390 * @param null|bool|WP_Error $pre Value to return instead. Default null to continue adding the event. |
398 * @param stdClass $event { |
391 * @param object $event { |
399 * An object containing an event's data. |
392 * An object containing an event's data. |
400 * |
393 * |
401 * @type string $hook Action hook to execute when the event is run. |
394 * @type string $hook Action hook to execute when the event is run. |
402 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
395 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
403 * @type string|false $schedule How often the event should subsequently recur. |
396 * @type string $schedule How often the event should subsequently recur. |
404 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
397 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
405 * @type int $interval The interval time in seconds for the schedule. Only present for recurring events. |
398 * @type int $interval The interval time in seconds for the schedule. |
406 * } |
399 * } |
407 * @param bool $wp_error Whether to return a WP_Error on failure. |
400 * @param bool $wp_error Whether to return a WP_Error on failure. |
408 */ |
401 */ |
409 $pre = apply_filters( 'pre_reschedule_event', null, $event, $wp_error ); |
402 $pre = apply_filters( 'pre_reschedule_event', null, $event, $wp_error ); |
410 |
403 |
445 |
438 |
446 return wp_schedule_event( $timestamp, $recurrence, $hook, $args, $wp_error ); |
439 return wp_schedule_event( $timestamp, $recurrence, $hook, $args, $wp_error ); |
447 } |
440 } |
448 |
441 |
449 /** |
442 /** |
450 * Unschedule a previously scheduled event. |
443 * Unschedules a previously scheduled event. |
451 * |
444 * |
452 * The $timestamp and $hook parameters are required so that the event can be |
445 * The `$timestamp` and `$hook` parameters are required so that the event can be |
453 * identified. |
446 * identified. |
454 * |
447 * |
455 * @since 2.1.0 |
448 * @since 2.1.0 |
456 * @since 5.1.0 Return value modified to boolean indicating success or failure, |
449 * @since 5.1.0 Return value modified to boolean indicating success or failure, |
457 * {@see 'pre_unschedule_event'} filter added to short-circuit the function. |
450 * {@see 'pre_unschedule_event'} filter added to short-circuit the function. |
478 |
471 |
479 return false; |
472 return false; |
480 } |
473 } |
481 |
474 |
482 /** |
475 /** |
483 * Filter to preflight or hijack unscheduling of events. |
476 * Filter to override unscheduling of events. |
484 * |
477 * |
485 * Returning a non-null value will short-circuit the normal unscheduling |
478 * Returning a non-null value will short-circuit the normal unscheduling |
486 * process, causing the function to return the filtered value instead. |
479 * process, causing the function to return the filtered value instead. |
487 * |
480 * |
488 * For plugins replacing wp-cron, return true if the event was successfully |
481 * For plugins replacing wp-cron, return true if the event was successfully |
489 * unscheduled, false if not. |
482 * unscheduled, false or a WP_Error if not. |
490 * |
483 * |
491 * @since 5.1.0 |
484 * @since 5.1.0 |
492 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
485 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
493 * |
486 * |
494 * @param null|bool|WP_Error $pre Value to return instead. Default null to continue unscheduling the event. |
487 * @param null|bool|WP_Error $pre Value to return instead. Default null to continue unscheduling the event. |
514 return $pre; |
507 return $pre; |
515 } |
508 } |
516 |
509 |
517 $crons = _get_cron_array(); |
510 $crons = _get_cron_array(); |
518 $key = md5( serialize( $args ) ); |
511 $key = md5( serialize( $args ) ); |
|
512 |
519 unset( $crons[ $timestamp ][ $hook ][ $key ] ); |
513 unset( $crons[ $timestamp ][ $hook ][ $key ] ); |
|
514 |
520 if ( empty( $crons[ $timestamp ][ $hook ] ) ) { |
515 if ( empty( $crons[ $timestamp ][ $hook ] ) ) { |
521 unset( $crons[ $timestamp ][ $hook ] ); |
516 unset( $crons[ $timestamp ][ $hook ] ); |
522 } |
517 } |
|
518 |
523 if ( empty( $crons[ $timestamp ] ) ) { |
519 if ( empty( $crons[ $timestamp ] ) ) { |
524 unset( $crons[ $timestamp ] ); |
520 unset( $crons[ $timestamp ] ); |
525 } |
521 } |
526 |
522 |
527 return _set_cron_array( $crons, $wp_error ); |
523 return _set_cron_array( $crons, $wp_error ); |
528 } |
524 } |
529 |
525 |
530 /** |
526 /** |
531 * Unschedules all events attached to the hook with the specified arguments. |
527 * Unschedules all events attached to the hook with the specified arguments. |
532 * |
528 * |
533 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
529 * Warning: This function may return boolean false, but may also return a non-boolean |
534 * value which evaluates to FALSE. For information about casting to booleans see the |
530 * value which evaluates to false. For information about casting to booleans see the |
535 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
531 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
536 * the `===` operator for testing the return value of this function. |
532 * the `===` operator for testing the return value of this function. |
537 * |
533 * |
538 * @since 2.1.0 |
534 * @since 2.1.0 |
539 * @since 5.1.0 Return value modified to indicate success or failure, |
535 * @since 5.1.0 Return value modified to indicate success or failure, |
549 * @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no |
545 * @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no |
550 * events were registered with the hook and arguments combination), false or WP_Error |
546 * events were registered with the hook and arguments combination), false or WP_Error |
551 * if unscheduling one or more events fail. |
547 * if unscheduling one or more events fail. |
552 */ |
548 */ |
553 function wp_clear_scheduled_hook( $hook, $args = array(), $wp_error = false ) { |
549 function wp_clear_scheduled_hook( $hook, $args = array(), $wp_error = false ) { |
554 // Backward compatibility. |
550 /* |
555 // Previously, this function took the arguments as discrete vars rather than an array like the rest of the API. |
551 * Backward compatibility. |
|
552 * Previously, this function took the arguments as discrete vars rather than an array like the rest of the API. |
|
553 */ |
556 if ( ! is_array( $args ) ) { |
554 if ( ! is_array( $args ) ) { |
557 _deprecated_argument( __FUNCTION__, '3.0.0', __( 'This argument has changed to an array to match the behavior of the other cron functions.' ) ); |
555 _deprecated_argument( |
|
556 __FUNCTION__, |
|
557 '3.0.0', |
|
558 __( 'This argument has changed to an array to match the behavior of the other cron functions.' ) |
|
559 ); |
|
560 |
558 $args = array_slice( func_get_args(), 1 ); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection |
561 $args = array_slice( func_get_args(), 1 ); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection |
559 $wp_error = false; |
562 $wp_error = false; |
560 } |
563 } |
561 |
564 |
562 /** |
565 /** |
563 * Filter to preflight or hijack clearing a scheduled hook. |
566 * Filter to override clearing a scheduled hook. |
564 * |
567 * |
565 * Returning a non-null value will short-circuit the normal unscheduling |
568 * Returning a non-null value will short-circuit the normal unscheduling |
566 * process, causing the function to return the filtered value instead. |
569 * process, causing the function to return the filtered value instead. |
567 * |
570 * |
568 * For plugins replacing wp-cron, return the number of events successfully |
571 * For plugins replacing wp-cron, return the number of events successfully |
569 * unscheduled (zero if no events were registered with the hook) or false |
572 * unscheduled (zero if no events were registered with the hook) or false |
570 * if unscheduling one or more events fails. |
573 * or a WP_Error if unscheduling one or more events fails. |
571 * |
574 * |
572 * @since 5.1.0 |
575 * @since 5.1.0 |
573 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
576 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
574 * |
577 * |
575 * @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the event. |
578 * @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the event. |
632 /** |
635 /** |
633 * Unschedules all events attached to the hook. |
636 * Unschedules all events attached to the hook. |
634 * |
637 * |
635 * Can be useful for plugins when deactivating to clean up the cron queue. |
638 * Can be useful for plugins when deactivating to clean up the cron queue. |
636 * |
639 * |
637 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
640 * Warning: This function may return boolean false, but may also return a non-boolean |
638 * value which evaluates to FALSE. For information about casting to booleans see the |
641 * value which evaluates to false. For information about casting to booleans see the |
639 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
642 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
640 * the `===` operator for testing the return value of this function. |
643 * the `===` operator for testing the return value of this function. |
641 * |
644 * |
642 * @since 4.9.0 |
645 * @since 4.9.0 |
643 * @since 5.1.0 Return value added to indicate success or failure. |
646 * @since 5.1.0 Return value added to indicate success or failure. |
648 * @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no |
651 * @return int|false|WP_Error On success an integer indicating number of events unscheduled (0 indicates no |
649 * events were registered on the hook), false or WP_Error if unscheduling fails. |
652 * events were registered on the hook), false or WP_Error if unscheduling fails. |
650 */ |
653 */ |
651 function wp_unschedule_hook( $hook, $wp_error = false ) { |
654 function wp_unschedule_hook( $hook, $wp_error = false ) { |
652 /** |
655 /** |
653 * Filter to preflight or hijack clearing all events attached to the hook. |
656 * Filter to override clearing all events attached to the hook. |
654 * |
657 * |
655 * Returning a non-null value will short-circuit the normal unscheduling |
658 * Returning a non-null value will short-circuit the normal unscheduling |
656 * process, causing the function to return the filtered value instead. |
659 * process, causing the function to return the filtered value instead. |
657 * |
660 * |
658 * For plugins replacing wp-cron, return the number of events successfully |
661 * For plugins replacing wp-cron, return the number of events successfully |
659 * unscheduled (zero if no events were registered with the hook) or false |
662 * unscheduled (zero if no events were registered with the hook). If unscheduling |
660 * if unscheduling one or more events fails. |
663 * one or more events fails then return either a WP_Error object or false depending |
|
664 * on the value of the `$wp_error` parameter. |
661 * |
665 * |
662 * @since 5.1.0 |
666 * @since 5.1.0 |
663 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
667 * @since 5.7.0 The `$wp_error` parameter was added, and a `WP_Error` object can now be returned. |
664 * |
668 * |
665 * @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the hook. |
669 * @param null|int|false|WP_Error $pre Value to return instead. Default null to continue unscheduling the hook. |
730 * Although not passed to a callback, these arguments are used to uniquely identify the |
736 * Although not passed to a callback, these arguments are used to uniquely identify the |
731 * event, so they should be the same as those used when originally scheduling the event. |
737 * event, so they should be the same as those used when originally scheduling the event. |
732 * Default empty array. |
738 * Default empty array. |
733 * @param int|null $timestamp Optional. Unix timestamp (UTC) of the event. If not specified, the next scheduled event |
739 * @param int|null $timestamp Optional. Unix timestamp (UTC) of the event. If not specified, the next scheduled event |
734 * is returned. Default null. |
740 * is returned. Default null. |
735 * @return object|false The event object. False if the event does not exist. |
741 * @return object|false { |
|
742 * The event object. False if the event does not exist. |
|
743 * |
|
744 * @type string $hook Action hook to execute when the event is run. |
|
745 * @type int $timestamp Unix timestamp (UTC) for when to next run the event. |
|
746 * @type string|false $schedule How often the event should subsequently recur. |
|
747 * @type array $args Array containing each separate argument to pass to the hook's callback function. |
|
748 * @type int $interval Optional. The interval time in seconds for the schedule. Only present for recurring events. |
|
749 * } |
736 */ |
750 */ |
737 function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) { |
751 function wp_get_scheduled_event( $hook, $args = array(), $timestamp = null ) { |
738 /** |
752 /** |
739 * Filter to preflight or hijack retrieving a scheduled event. |
753 * Filter to override retrieving a scheduled event. |
740 * |
754 * |
741 * Returning a non-null value will short-circuit the normal process, |
755 * Returning a non-null value will short-circuit the normal process, |
742 * returning the filtered value instead. |
756 * returning the filtered value instead. |
743 * |
757 * |
744 * Return false if the event does not exist, otherwise an event object |
758 * Return false if the event does not exist, otherwise an event object |
752 * Although not passed to a callback, these arguments are used to uniquely identify |
766 * Although not passed to a callback, these arguments are used to uniquely identify |
753 * the event. |
767 * the event. |
754 * @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event. |
768 * @param int|null $timestamp Unix timestamp (UTC) of the event. Null to retrieve next scheduled event. |
755 */ |
769 */ |
756 $pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp ); |
770 $pre = apply_filters( 'pre_get_scheduled_event', null, $hook, $args, $timestamp ); |
|
771 |
757 if ( null !== $pre ) { |
772 if ( null !== $pre ) { |
758 return $pre; |
773 return $pre; |
759 } |
774 } |
760 |
775 |
761 if ( null !== $timestamp && ! is_numeric( $timestamp ) ) { |
776 if ( null !== $timestamp && ! is_numeric( $timestamp ) ) { |
845 * and has not finished running. |
862 * and has not finished running. |
846 * |
863 * |
847 * Multiple processes on multiple web servers can run this code concurrently, |
864 * Multiple processes on multiple web servers can run this code concurrently, |
848 * this lock attempts to make spawning as atomic as possible. |
865 * this lock attempts to make spawning as atomic as possible. |
849 */ |
866 */ |
850 $lock = get_transient( 'doing_cron' ); |
867 $lock = (float) get_transient( 'doing_cron' ); |
851 |
868 |
852 if ( $lock > $gmt_time + 10 * MINUTE_IN_SECONDS ) { |
869 if ( $lock > $gmt_time + 10 * MINUTE_IN_SECONDS ) { |
853 $lock = 0; |
870 $lock = 0; |
854 } |
871 } |
855 |
872 |
856 // Don't run if another process is currently running it or more than once every 60 sec. |
873 // Don't run if another process is currently running it or more than once every 60 sec. |
857 if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) { |
874 if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time ) { |
858 return false; |
875 return false; |
859 } |
876 } |
860 |
877 |
861 // Sanity check. |
878 // Confidence check. |
862 $crons = wp_get_ready_cron_jobs(); |
879 $crons = wp_get_ready_cron_jobs(); |
863 if ( empty( $crons ) ) { |
880 if ( empty( $crons ) ) { |
864 return false; |
881 return false; |
865 } |
882 } |
866 |
883 |
928 ), |
945 ), |
929 $doing_wp_cron |
946 $doing_wp_cron |
930 ); |
947 ); |
931 |
948 |
932 $result = wp_remote_post( $cron_request['url'], $cron_request['args'] ); |
949 $result = wp_remote_post( $cron_request['url'], $cron_request['args'] ); |
|
950 |
933 return ! is_wp_error( $result ); |
951 return ! is_wp_error( $result ); |
934 } |
952 } |
935 |
953 |
936 /** |
954 /** |
937 * Register _wp_cron() to run on the {@see 'wp_loaded'} action. |
955 * Registers _wp_cron() to run on the {@see 'wp_loaded'} action. |
938 * |
956 * |
939 * If the {@see 'wp_loaded'} action has already fired, this function calls |
957 * If the {@see 'wp_loaded'} action has already fired, this function calls |
940 * _wp_cron() directly. |
958 * _wp_cron() directly. |
941 * |
959 * |
942 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
960 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
946 * |
964 * |
947 * @since 2.1.0 |
965 * @since 2.1.0 |
948 * @since 5.1.0 Return value added to indicate success or failure. |
966 * @since 5.1.0 Return value added to indicate success or failure. |
949 * @since 5.7.0 Functionality moved to _wp_cron() to which this becomes a wrapper. |
967 * @since 5.7.0 Functionality moved to _wp_cron() to which this becomes a wrapper. |
950 * |
968 * |
951 * @return bool|int|void On success an integer indicating number of events spawned (0 indicates no |
969 * @return false|int|void On success an integer indicating number of events spawned (0 indicates no |
952 * events needed to be spawned), false if spawning fails for one or more events or |
970 * events needed to be spawned), false if spawning fails for one or more events or |
953 * void if the function registered _wp_cron() to run on the action. |
971 * void if the function registered _wp_cron() to run on the action. |
954 */ |
972 */ |
955 function wp_cron() { |
973 function wp_cron() { |
956 if ( did_action( 'wp_loaded' ) ) { |
974 if ( did_action( 'wp_loaded' ) ) { |
957 return _wp_cron(); |
975 return _wp_cron(); |
958 } |
976 } |
959 |
977 |
960 add_action( 'wp_loaded', '_wp_cron', 20 ); |
978 add_action( 'wp_loaded', '_wp_cron', 20 ); |
961 } |
979 } |
962 |
980 |
963 /** |
981 /** |
964 * Run scheduled callbacks or spawn cron for all scheduled events. |
982 * Runs scheduled callbacks or spawns cron for all scheduled events. |
965 * |
983 * |
966 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
984 * Warning: This function may return Boolean FALSE, but may also return a non-Boolean |
967 * value which evaluates to FALSE. For information about casting to booleans see the |
985 * value which evaluates to FALSE. For information about casting to booleans see the |
968 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
986 * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. Use |
969 * the `===` operator for testing the return value of this function. |
987 * the `===` operator for testing the return value of this function. |
974 * @return int|false On success an integer indicating number of events spawned (0 indicates no |
992 * @return int|false On success an integer indicating number of events spawned (0 indicates no |
975 * events needed to be spawned), false if spawning fails for one or more events. |
993 * events needed to be spawned), false if spawning fails for one or more events. |
976 */ |
994 */ |
977 function _wp_cron() { |
995 function _wp_cron() { |
978 // Prevent infinite loops caused by lack of wp-cron.php. |
996 // Prevent infinite loops caused by lack of wp-cron.php. |
979 if ( strpos( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) !== false || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ) { |
997 if ( str_contains( $_SERVER['REQUEST_URI'], '/wp-cron.php' ) |
|
998 || ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) |
|
999 ) { |
980 return 0; |
1000 return 0; |
981 } |
1001 } |
982 |
1002 |
983 $crons = wp_get_ready_cron_jobs(); |
1003 $crons = wp_get_ready_cron_jobs(); |
984 if ( empty( $crons ) ) { |
1004 if ( empty( $crons ) ) { |
991 return 0; |
1011 return 0; |
992 } |
1012 } |
993 |
1013 |
994 $schedules = wp_get_schedules(); |
1014 $schedules = wp_get_schedules(); |
995 $results = array(); |
1015 $results = array(); |
|
1016 |
996 foreach ( $crons as $timestamp => $cronhooks ) { |
1017 foreach ( $crons as $timestamp => $cronhooks ) { |
997 if ( $timestamp > $gmt_time ) { |
1018 if ( $timestamp > $gmt_time ) { |
998 break; |
1019 break; |
999 } |
1020 } |
|
1021 |
1000 foreach ( (array) $cronhooks as $hook => $args ) { |
1022 foreach ( (array) $cronhooks as $hook => $args ) { |
1001 if ( isset( $schedules[ $hook ]['callback'] ) && ! call_user_func( $schedules[ $hook ]['callback'] ) ) { |
1023 if ( isset( $schedules[ $hook ]['callback'] ) |
|
1024 && ! call_user_func( $schedules[ $hook ]['callback'] ) |
|
1025 ) { |
1002 continue; |
1026 continue; |
1003 } |
1027 } |
|
1028 |
1004 $results[] = spawn_cron( $gmt_time ); |
1029 $results[] = spawn_cron( $gmt_time ); |
1005 break 2; |
1030 break 2; |
1006 } |
1031 } |
1007 } |
1032 } |
1008 |
1033 |
1009 if ( in_array( false, $results, true ) ) { |
1034 if ( in_array( false, $results, true ) ) { |
1010 return false; |
1035 return false; |
1011 } |
1036 } |
|
1037 |
1012 return count( $results ); |
1038 return count( $results ); |
1013 } |
1039 } |
1014 |
1040 |
1015 /** |
1041 /** |
1016 * Retrieve supported event recurrence schedules. |
1042 * Retrieves supported event recurrence schedules. |
1017 * |
1043 * |
1018 * The default supported recurrences are 'hourly', 'twicedaily', 'daily', and 'weekly'. |
1044 * The default supported recurrences are 'hourly', 'twicedaily', 'daily', and 'weekly'. |
1019 * A plugin may add more by hooking into the {@see 'cron_schedules'} filter. |
1045 * A plugin may add more by hooking into the {@see 'cron_schedules'} filter. |
1020 * The filter accepts an array of arrays. The outer array has a key that is the name |
1046 * The filter accepts an array of arrays. The outer array has a key that is the name |
1021 * of the schedule, for example 'monthly'. The value is an array with two keys, |
1047 * of the schedule, for example 'monthly'. The value is an array with two keys, |
1022 * one is 'interval' and the other is 'display'. |
1048 * one is 'interval' and the other is 'display'. |
1023 * |
1049 * |
1024 * The 'interval' is a number in seconds of when the cron job should run. |
1050 * The 'interval' is a number in seconds of when the cron job should run. |
1025 * So for 'hourly' the time is `HOUR_IN_SECONDS` (60 * 60 or 3600). For 'monthly', |
1051 * So for 'hourly' the time is `HOUR_IN_SECONDS` (`60 * 60` or `3600`). For 'monthly', |
1026 * the value would be `MONTH_IN_SECONDS` (30 * 24 * 60 * 60 or 2592000). |
1052 * the value would be `MONTH_IN_SECONDS` (`30 * 24 * 60 * 60` or `2592000`). |
1027 * |
1053 * |
1028 * The 'display' is the description. For the 'monthly' key, the 'display' |
1054 * The 'display' is the description. For the 'monthly' key, the 'display' |
1029 * would be `__( 'Once Monthly' )`. |
1055 * would be `__( 'Once Monthly' )`. |
1030 * |
1056 * |
1031 * For your plugin, you will be passed an array. You can easily add your |
1057 * For your plugin, you will be passed an array. You can add your |
1032 * schedule by doing the following. |
1058 * schedule by doing the following: |
1033 * |
1059 * |
1034 * // Filter parameter variable name is 'array'. |
1060 * // Filter parameter variable name is 'array'. |
1035 * $array['monthly'] = array( |
1061 * $array['monthly'] = array( |
1036 * 'interval' => MONTH_IN_SECONDS, |
1062 * 'interval' => MONTH_IN_SECONDS, |
1037 * 'display' => __( 'Once Monthly' ) |
1063 * 'display' => __( 'Once Monthly' ) |
1038 * ); |
1064 * ); |
1039 * |
1065 * |
1040 * @since 2.1.0 |
1066 * @since 2.1.0 |
1041 * @since 5.4.0 The 'weekly' schedule was added. |
1067 * @since 5.4.0 The 'weekly' schedule was added. |
1042 * |
1068 * |
1043 * @return array[] |
1069 * @return array { |
|
1070 * The array of cron schedules keyed by the schedule name. |
|
1071 * |
|
1072 * @type array ...$0 { |
|
1073 * Cron schedule information. |
|
1074 * |
|
1075 * @type int $interval The schedule interval in seconds. |
|
1076 * @type string $display The schedule display name. |
|
1077 * } |
|
1078 * } |
1044 */ |
1079 */ |
1045 function wp_get_schedules() { |
1080 function wp_get_schedules() { |
1046 $schedules = array( |
1081 $schedules = array( |
1047 'hourly' => array( |
1082 'hourly' => array( |
1048 'interval' => HOUR_IN_SECONDS, |
1083 'interval' => HOUR_IN_SECONDS, |
1065 /** |
1100 /** |
1066 * Filters the non-default cron schedules. |
1101 * Filters the non-default cron schedules. |
1067 * |
1102 * |
1068 * @since 2.1.0 |
1103 * @since 2.1.0 |
1069 * |
1104 * |
1070 * @param array[] $new_schedules An array of non-default cron schedule arrays. Default empty. |
1105 * @param array $new_schedules { |
|
1106 * An array of non-default cron schedules keyed by the schedule name. Default empty array. |
|
1107 * |
|
1108 * @type array ...$0 { |
|
1109 * Cron schedule information. |
|
1110 * |
|
1111 * @type int $interval The schedule interval in seconds. |
|
1112 * @type string $display The schedule display name. |
|
1113 * } |
|
1114 * } |
1071 */ |
1115 */ |
1072 return array_merge( apply_filters( 'cron_schedules', array() ), $schedules ); |
1116 return array_merge( apply_filters( 'cron_schedules', array() ), $schedules ); |
1073 } |
1117 } |
1074 |
1118 |
1075 /** |
1119 /** |
1076 * Retrieve the recurrence schedule for an event. |
1120 * Retrieves the name of the recurrence schedule for an event. |
1077 * |
1121 * |
1078 * @see wp_get_schedules() for available schedules. |
1122 * @see wp_get_schedules() for available schedules. |
1079 * |
1123 * |
1080 * @since 2.1.0 |
1124 * @since 2.1.0 |
1081 * @since 5.1.0 {@see 'get_schedule'} filter added. |
1125 * @since 5.1.0 {@see 'get_schedule'} filter added. |
1104 */ |
1148 */ |
1105 return apply_filters( 'get_schedule', $schedule, $hook, $args ); |
1149 return apply_filters( 'get_schedule', $schedule, $hook, $args ); |
1106 } |
1150 } |
1107 |
1151 |
1108 /** |
1152 /** |
1109 * Retrieve cron jobs ready to be run. |
1153 * Retrieves cron jobs ready to be run. |
1110 * |
1154 * |
1111 * Returns the results of _get_cron_array() limited to events ready to be run, |
1155 * Returns the results of _get_cron_array() limited to events ready to be run, |
1112 * ie, with a timestamp in the past. |
1156 * ie, with a timestamp in the past. |
1113 * |
1157 * |
1114 * @since 5.1.0 |
1158 * @since 5.1.0 |
1115 * |
1159 * |
1116 * @return array[] Array of cron job arrays ready to be run. |
1160 * @return array[] Array of cron job arrays ready to be run. |
1117 */ |
1161 */ |
1118 function wp_get_ready_cron_jobs() { |
1162 function wp_get_ready_cron_jobs() { |
1119 /** |
1163 /** |
1120 * Filter to preflight or hijack retrieving ready cron jobs. |
1164 * Filter to override retrieving ready cron jobs. |
1121 * |
1165 * |
1122 * Returning an array will short-circuit the normal retrieval of ready |
1166 * Returning an array will short-circuit the normal retrieval of ready |
1123 * cron jobs, causing the function to return the filtered value instead. |
1167 * cron jobs, causing the function to return the filtered value instead. |
1124 * |
1168 * |
1125 * @since 5.1.0 |
1169 * @since 5.1.0 |
1126 * |
1170 * |
1127 * @param null|array[] $pre Array of ready cron tasks to return instead. Default null |
1171 * @param null|array[] $pre Array of ready cron tasks to return instead. Default null |
1128 * to continue using results from _get_cron_array(). |
1172 * to continue using results from _get_cron_array(). |
1129 */ |
1173 */ |
1130 $pre = apply_filters( 'pre_get_ready_cron_jobs', null ); |
1174 $pre = apply_filters( 'pre_get_ready_cron_jobs', null ); |
|
1175 |
1131 if ( null !== $pre ) { |
1176 if ( null !== $pre ) { |
1132 return $pre; |
1177 return $pre; |
1133 } |
1178 } |
1134 |
1179 |
1135 $crons = _get_cron_array(); |
1180 $crons = _get_cron_array(); |
1136 if ( ! is_array( $crons ) ) { |
|
1137 return array(); |
|
1138 } |
|
1139 |
|
1140 $gmt_time = microtime( true ); |
1181 $gmt_time = microtime( true ); |
1141 $keys = array_keys( $crons ); |
1182 $results = array(); |
1142 if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) { |
1183 |
1143 return array(); |
|
1144 } |
|
1145 |
|
1146 $results = array(); |
|
1147 foreach ( $crons as $timestamp => $cronhooks ) { |
1184 foreach ( $crons as $timestamp => $cronhooks ) { |
1148 if ( $timestamp > $gmt_time ) { |
1185 if ( $timestamp > $gmt_time ) { |
1149 break; |
1186 break; |
1150 } |
1187 } |
|
1188 |
1151 $results[ $timestamp ] = $cronhooks; |
1189 $results[ $timestamp ] = $cronhooks; |
1152 } |
1190 } |
1153 |
1191 |
1154 return $results; |
1192 return $results; |
1155 } |
1193 } |
1157 // |
1195 // |
1158 // Private functions. |
1196 // Private functions. |
1159 // |
1197 // |
1160 |
1198 |
1161 /** |
1199 /** |
1162 * Retrieve cron info array option. |
1200 * Retrieves cron info array option. |
1163 * |
1201 * |
1164 * @since 2.1.0 |
1202 * @since 2.1.0 |
|
1203 * @since 6.1.0 Return type modified to consistently return an array. |
1165 * @access private |
1204 * @access private |
1166 * |
1205 * |
1167 * @return array[]|false Array of cron info arrays on success, false on failure. |
1206 * @return array[] Array of cron events. |
1168 */ |
1207 */ |
1169 function _get_cron_array() { |
1208 function _get_cron_array() { |
1170 $cron = get_option( 'cron' ); |
1209 $cron = get_option( 'cron' ); |
1171 if ( ! is_array( $cron ) ) { |
1210 if ( ! is_array( $cron ) ) { |
1172 return false; |
1211 return array(); |
1173 } |
1212 } |
1174 |
1213 |
1175 if ( ! isset( $cron['version'] ) ) { |
1214 if ( ! isset( $cron['version'] ) ) { |
1176 $cron = _upgrade_cron_array( $cron ); |
1215 $cron = _upgrade_cron_array( $cron ); |
1177 } |
1216 } |
1211 |
1251 |
1212 return $result; |
1252 return $result; |
1213 } |
1253 } |
1214 |
1254 |
1215 /** |
1255 /** |
1216 * Upgrade a Cron info array. |
1256 * Upgrades a cron info array. |
1217 * |
1257 * |
1218 * This function upgrades the Cron info array to version 2. |
1258 * This function upgrades the cron info array to version 2. |
1219 * |
1259 * |
1220 * @since 2.1.0 |
1260 * @since 2.1.0 |
1221 * @access private |
1261 * @access private |
1222 * |
1262 * |
1223 * @param array $cron Cron info array from _get_cron_array(). |
1263 * @param array $cron Cron info array from _get_cron_array(). |
1224 * @return array An upgraded Cron info array. |
1264 * @return array An upgraded cron info array. |
1225 */ |
1265 */ |
1226 function _upgrade_cron_array( $cron ) { |
1266 function _upgrade_cron_array( $cron ) { |
1227 if ( isset( $cron['version'] ) && 2 == $cron['version'] ) { |
1267 if ( isset( $cron['version'] ) && 2 === $cron['version'] ) { |
1228 return $cron; |
1268 return $cron; |
1229 } |
1269 } |
1230 |
1270 |
1231 $new_cron = array(); |
1271 $new_cron = array(); |
1232 |
1272 |
1233 foreach ( (array) $cron as $timestamp => $hooks ) { |
1273 foreach ( (array) $cron as $timestamp => $hooks ) { |
1234 foreach ( (array) $hooks as $hook => $args ) { |
1274 foreach ( (array) $hooks as $hook => $args ) { |
1235 $key = md5( serialize( $args['args'] ) ); |
1275 $key = md5( serialize( $args['args'] ) ); |
|
1276 |
1236 $new_cron[ $timestamp ][ $hook ][ $key ] = $args; |
1277 $new_cron[ $timestamp ][ $hook ][ $key ] = $args; |
1237 } |
1278 } |
1238 } |
1279 } |
1239 |
1280 |
1240 $new_cron['version'] = 2; |
1281 $new_cron['version'] = 2; |
|
1282 |
1241 update_option( 'cron', $new_cron ); |
1283 update_option( 'cron', $new_cron ); |
|
1284 |
1242 return $new_cron; |
1285 return $new_cron; |
1243 } |
1286 } |