14 * visit when the cron job is needed to run. |
14 * visit when the cron job is needed to run. |
15 * |
15 * |
16 * @package WordPress |
16 * @package WordPress |
17 */ |
17 */ |
18 |
18 |
19 ignore_user_abort(true); |
19 ignore_user_abort( true ); |
20 |
20 |
21 if ( !empty($_POST) || defined('DOING_AJAX') || defined('DOING_CRON') ) |
21 /* Don't make the request block till we finish, if possible. */ |
|
22 if ( function_exists( 'fastcgi_finish_request' ) && version_compare( phpversion(), '7.0.16', '>=' ) ) { |
|
23 fastcgi_finish_request(); |
|
24 } |
|
25 |
|
26 if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) || defined( 'DOING_CRON' ) ) { |
22 die(); |
27 die(); |
|
28 } |
23 |
29 |
24 /** |
30 /** |
25 * Tell WordPress we are doing the CRON task. |
31 * Tell WordPress we are doing the CRON task. |
26 * |
32 * |
27 * @var bool |
33 * @var bool |
28 */ |
34 */ |
29 define('DOING_CRON', true); |
35 define( 'DOING_CRON', true ); |
30 |
36 |
31 if ( !defined('ABSPATH') ) { |
37 if ( ! defined( 'ABSPATH' ) ) { |
32 /** Set up WordPress environment */ |
38 /** Set up WordPress environment */ |
33 require_once( dirname( __FILE__ ) . '/wp-load.php' ); |
39 require_once( dirname( __FILE__ ) . '/wp-load.php' ); |
34 } |
40 } |
35 |
41 |
36 /** |
42 /** |
55 * in case another process updated the cache. |
61 * in case another process updated the cache. |
56 */ |
62 */ |
57 $value = wp_cache_get( 'doing_cron', 'transient', true ); |
63 $value = wp_cache_get( 'doing_cron', 'transient', true ); |
58 } else { |
64 } else { |
59 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) ); |
65 $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) ); |
60 if ( is_object( $row ) ) |
66 if ( is_object( $row ) ) { |
61 $value = $row->option_value; |
67 $value = $row->option_value; |
|
68 } |
62 } |
69 } |
63 |
70 |
64 return $value; |
71 return $value; |
65 } |
72 } |
66 |
73 |
67 if ( false === $crons = _get_cron_array() ) |
74 $crons = wp_get_ready_cron_jobs(); |
|
75 if ( empty( $crons ) ) { |
68 die(); |
76 die(); |
|
77 } |
69 |
78 |
70 $keys = array_keys( $crons ); |
|
71 $gmt_time = microtime( true ); |
79 $gmt_time = microtime( true ); |
72 |
|
73 if ( isset($keys[0]) && $keys[0] > $gmt_time ) |
|
74 die(); |
|
75 |
|
76 |
80 |
77 // The cron lock: a unix timestamp from when the cron was spawned. |
81 // The cron lock: a unix timestamp from when the cron was spawned. |
78 $doing_cron_transient = get_transient( 'doing_cron' ); |
82 $doing_cron_transient = get_transient( 'doing_cron' ); |
79 |
83 |
80 // Use global $doing_wp_cron lock otherwise use the GET lock. If no lock, trying grabbing a new lock. |
84 // Use global $doing_wp_cron lock otherwise use the GET lock. If no lock, trying grabbing a new lock. |
81 if ( empty( $doing_wp_cron ) ) { |
85 if ( empty( $doing_wp_cron ) ) { |
82 if ( empty( $_GET[ 'doing_wp_cron' ] ) ) { |
86 if ( empty( $_GET['doing_wp_cron'] ) ) { |
83 // Called from external script/job. Try setting a lock. |
87 // Called from external script/job. Try setting a lock. |
84 if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) |
88 if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) { |
85 return; |
89 return; |
|
90 } |
86 $doing_cron_transient = $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); |
91 $doing_cron_transient = $doing_wp_cron = sprintf( '%.22F', microtime( true ) ); |
87 set_transient( 'doing_cron', $doing_wp_cron ); |
92 set_transient( 'doing_cron', $doing_wp_cron ); |
88 } else { |
93 } else { |
89 $doing_wp_cron = $_GET[ 'doing_wp_cron' ]; |
94 $doing_wp_cron = $_GET['doing_wp_cron']; |
90 } |
95 } |
91 } |
96 } |
92 |
97 |
93 /* |
98 /* |
94 * The cron lock (a unix timestamp set when the cron was spawned), |
99 * The cron lock (a unix timestamp set when the cron was spawned), |
95 * must match $doing_wp_cron (the "key"). |
100 * must match $doing_wp_cron (the "key"). |
96 */ |
101 */ |
97 if ( $doing_cron_transient != $doing_wp_cron ) |
102 if ( $doing_cron_transient != $doing_wp_cron ) { |
98 return; |
103 return; |
|
104 } |
99 |
105 |
100 foreach ( $crons as $timestamp => $cronhooks ) { |
106 foreach ( $crons as $timestamp => $cronhooks ) { |
101 if ( $timestamp > $gmt_time ) |
107 if ( $timestamp > $gmt_time ) { |
102 break; |
108 break; |
|
109 } |
103 |
110 |
104 foreach ( $cronhooks as $hook => $keys ) { |
111 foreach ( $cronhooks as $hook => $keys ) { |
105 |
112 |
106 foreach ( $keys as $k => $v ) { |
113 foreach ( $keys as $k => $v ) { |
107 |
114 |
108 $schedule = $v['schedule']; |
115 $schedule = $v['schedule']; |
109 |
116 |
110 if ( $schedule != false ) { |
117 if ( $schedule != false ) { |
111 $new_args = array($timestamp, $schedule, $hook, $v['args']); |
118 $new_args = array( $timestamp, $schedule, $hook, $v['args'] ); |
112 call_user_func_array('wp_reschedule_event', $new_args); |
119 call_user_func_array( 'wp_reschedule_event', $new_args ); |
113 } |
120 } |
114 |
121 |
115 wp_unschedule_event( $timestamp, $hook, $v['args'] ); |
122 wp_unschedule_event( $timestamp, $hook, $v['args'] ); |
116 |
123 |
117 /** |
124 /** |
121 * @since 2.1.0 |
128 * @since 2.1.0 |
122 * |
129 * |
123 * @param string $hook Name of the hook that was scheduled to be fired. |
130 * @param string $hook Name of the hook that was scheduled to be fired. |
124 * @param array $args The arguments to be passed to the hook. |
131 * @param array $args The arguments to be passed to the hook. |
125 */ |
132 */ |
126 do_action_ref_array( $hook, $v['args'] ); |
133 do_action_ref_array( $hook, $v['args'] ); |
127 |
134 |
128 // If the hook ran too long and another cron process stole the lock, quit. |
135 // If the hook ran too long and another cron process stole the lock, quit. |
129 if ( _get_cron_lock() != $doing_wp_cron ) |
136 if ( _get_cron_lock() != $doing_wp_cron ) { |
130 return; |
137 return; |
|
138 } |
131 } |
139 } |
132 } |
140 } |
133 } |
141 } |
134 |
142 |
135 if ( _get_cron_lock() == $doing_wp_cron ) |
143 if ( _get_cron_lock() == $doing_wp_cron ) { |
136 delete_transient( 'doing_cron' ); |
144 delete_transient( 'doing_cron' ); |
|
145 } |
137 |
146 |
138 die(); |
147 die(); |