Projects : mp-wp : mp-wp_genesis
1 | <?php |
2 | /** |
3 | * WordPress CRON API |
4 | * |
5 | * @package WordPress |
6 | */ |
7 | |
8 | /** |
9 | * Schedules a hook to run only once. |
10 | * |
11 | * Schedules a hook which will be executed once by the Wordpress actions core at |
12 | * a time which you specify. The action will fire off when someone visits your |
13 | * WordPress site, if the schedule time has passed. |
14 | * |
15 | * @since 2.1.0 |
16 | * @link http://codex.wordpress.org/Function_Reference/wp_schedule_single_event |
17 | * |
18 | * @param int $timestamp Timestamp for when to run the event. |
19 | * @param callback $hook Function or method to call, when cron is run. |
20 | * @param array $args Optional. Arguments to pass to the hook function. |
21 | */ |
22 | function wp_schedule_single_event( $timestamp, $hook, $args = array()) { |
23 | // don't schedule a duplicate if there's already an identical event due in the next 10 minutes |
24 | $next = wp_next_scheduled($hook, $args); |
25 | if ( $next && $next <= $timestamp + 600 ) |
26 | return; |
27 | |
28 | $crons = _get_cron_array(); |
29 | $key = md5(serialize($args)); |
30 | $crons[$timestamp][$hook][$key] = array( 'schedule' => false, 'args' => $args ); |
31 | uksort( $crons, "strnatcasecmp" ); |
32 | _set_cron_array( $crons ); |
33 | } |
34 | |
35 | /** |
36 | * Schedule a periodic event. |
37 | * |
38 | * Schedules a hook which will be executed by the WordPress actions core on a |
39 | * specific interval, specified by you. The action will trigger when someone |
40 | * visits your WordPress site, if the scheduled time has passed. |
41 | * |
42 | * @since 2.1.0 |
43 | * |
44 | * @param int $timestamp Timestamp for when to run the event. |
45 | * @param string $recurrence How often the event should recur. |
46 | * @param callback $hook Function or method to call, when cron is run. |
47 | * @param array $args Optional. Arguments to pass to the hook function. |
48 | * @return bool|null False on failure, null when complete with scheduling event. |
49 | */ |
50 | function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) { |
51 | $crons = _get_cron_array(); |
52 | $schedules = wp_get_schedules(); |
53 | $key = md5(serialize($args)); |
54 | if ( !isset( $schedules[$recurrence] ) ) |
55 | return false; |
56 | $crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] ); |
57 | uksort( $crons, "strnatcasecmp" ); |
58 | _set_cron_array( $crons ); |
59 | } |
60 | |
61 | /** |
62 | * Reschedule a recurring event. |
63 | * |
64 | * @since 2.1.0 |
65 | * |
66 | * @param int $timestamp Timestamp for when to run the event. |
67 | * @param string $recurrence How often the event should recur. |
68 | * @param callback $hook Function or method to call, when cron is run. |
69 | * @param array $args Optional. Arguments to pass to the hook function. |
70 | * @return bool|null False on failure. Null when event is rescheduled. |
71 | */ |
72 | function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) { |
73 | $crons = _get_cron_array(); |
74 | $schedules = wp_get_schedules(); |
75 | $key = md5(serialize($args)); |
76 | $interval = 0; |
77 | |
78 | // First we try to get it from the schedule |
79 | if ( 0 == $interval ) |
80 | $interval = $schedules[$recurrence]['interval']; |
81 | // Now we try to get it from the saved interval in case the schedule disappears |
82 | if ( 0 == $interval ) |
83 | $interval = $crons[$timestamp][$hook][$key]['interval']; |
84 | // Now we assume something is wrong and fail to schedule |
85 | if ( 0 == $interval ) |
86 | return false; |
87 | |
88 | while ( $timestamp < time() + 1 ) |
89 | $timestamp += $interval; |
90 | |
91 | wp_schedule_event( $timestamp, $recurrence, $hook, $args ); |
92 | } |
93 | |
94 | /** |
95 | * Unschedule a previously scheduled cron job. |
96 | * |
97 | * The $timestamp and $hook parameters are required, so that the event can be |
98 | * identified. |
99 | * |
100 | * @since 2.1.0 |
101 | * |
102 | * @param int $timestamp Timestamp for when to run the event. |
103 | * @param callback $hook Function or method to call, when cron is run. |
104 | * @param array $args Optional. Arguments to pass to the hook function. |
105 | */ |
106 | function wp_unschedule_event( $timestamp, $hook, $args = array() ) { |
107 | $crons = _get_cron_array(); |
108 | $key = md5(serialize($args)); |
109 | unset( $crons[$timestamp][$hook][$key] ); |
110 | if ( empty($crons[$timestamp][$hook]) ) |
111 | unset( $crons[$timestamp][$hook] ); |
112 | if ( empty($crons[$timestamp]) ) |
113 | unset( $crons[$timestamp] ); |
114 | _set_cron_array( $crons ); |
115 | } |
116 | |
117 | /** |
118 | * Unschedule all cron jobs attached to a specific hook. |
119 | * |
120 | * @since 2.1.0 |
121 | * |
122 | * @param callback $hook Function or method to call, when cron is run. |
123 | * @param mixed $args,... Optional. Event arguments. |
124 | */ |
125 | function wp_clear_scheduled_hook( $hook ) { |
126 | $args = array_slice( func_get_args(), 1 ); |
127 | |
128 | while ( $timestamp = wp_next_scheduled( $hook, $args ) ) |
129 | wp_unschedule_event( $timestamp, $hook, $args ); |
130 | } |
131 | |
132 | /** |
133 | * Retrieve the next timestamp for a cron event. |
134 | * |
135 | * @since 2.1.0 |
136 | * |
137 | * @param callback $hook Function or method to call, when cron is run. |
138 | * @param array $args Optional. Arguments to pass to the hook function. |
139 | * @return bool|int The UNIX timestamp of the next time the scheduled event will occur. |
140 | */ |
141 | function wp_next_scheduled( $hook, $args = array() ) { |
142 | $crons = _get_cron_array(); |
143 | $key = md5(serialize($args)); |
144 | if ( empty($crons) ) |
145 | return false; |
146 | foreach ( $crons as $timestamp => $cron ) { |
147 | if ( isset( $cron[$hook][$key] ) ) |
148 | return $timestamp; |
149 | } |
150 | return false; |
151 | } |
152 | |
153 | /** |
154 | * Send request to run cron through HTTP request that doesn't halt page loading. |
155 | * |
156 | * @since 2.1.0 |
157 | * |
158 | * @return null Cron could not be spawned, because it is not needed to run. |
159 | */ |
160 | function spawn_cron( $local_time ) { |
161 | |
162 | /* |
163 | * do not even start the cron if local server timer has drifted |
164 | * such as due to power failure, or misconfiguration |
165 | */ |
166 | $timer_accurate = check_server_timer( $local_time ); |
167 | if ( !$timer_accurate ) |
168 | return; |
169 | |
170 | //sanity check |
171 | $crons = _get_cron_array(); |
172 | if ( !is_array($crons) ) |
173 | return; |
174 | |
175 | $keys = array_keys( $crons ); |
176 | $timestamp = $keys[0]; |
177 | if ( $timestamp > $local_time ) |
178 | return; |
179 | |
180 | $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?check=' . wp_hash('187425'); |
181 | /* |
182 | * multiple processes on multiple web servers can run this code concurrently |
183 | * try to make this as atomic as possible by setting doing_cron switch |
184 | */ |
185 | $flag = get_option('doing_cron'); |
186 | |
187 | // clean up potential invalid value resulted from various system chaos |
188 | if ( $flag != 0 ) { |
189 | if ( $flag > $local_time + 10*60 || $flag < $local_time - 10*60 ) { |
190 | update_option('doing_cron', 0); |
191 | $flag = 0; |
192 | } |
193 | } |
194 | |
195 | //don't run if another process is currently running it |
196 | if ( $flag > $local_time ) |
197 | return; |
198 | |
199 | update_option( 'doing_cron', $local_time + 30 ); |
200 | |
201 | wp_remote_post($cron_url, array('timeout' => 0.01, 'blocking' => false)); |
202 | } |
203 | |
204 | /** |
205 | * Run scheduled callbacks or spawn cron for all scheduled events. |
206 | * |
207 | * @since 2.1.0 |
208 | * |
209 | * @return null When doesn't need to run Cron. |
210 | */ |
211 | function wp_cron() { |
212 | |
213 | // Prevent infinite loops caused by lack of wp-cron.php |
214 | if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false ) |
215 | return; |
216 | |
217 | $crons = _get_cron_array(); |
218 | |
219 | if ( !is_array($crons) ) |
220 | return; |
221 | |
222 | $keys = array_keys( $crons ); |
223 | if ( isset($keys[0]) && $keys[0] > time() ) |
224 | return; |
225 | |
226 | $local_time = time(); |
227 | $schedules = wp_get_schedules(); |
228 | foreach ( $crons as $timestamp => $cronhooks ) { |
229 | if ( $timestamp > $local_time ) break; |
230 | foreach ( (array) $cronhooks as $hook => $args ) { |
231 | if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) ) |
232 | continue; |
233 | spawn_cron( $local_time ); |
234 | break 2; |
235 | } |
236 | } |
237 | } |
238 | |
239 | /** |
240 | * Retrieve supported and filtered Cron recurrences. |
241 | * |
242 | * The supported recurrences are 'hourly' and 'daily'. A plugin may add more by |
243 | * hooking into the 'cron_schedules' filter. The filter accepts an array of |
244 | * arrays. The outer array has a key that is the name of the schedule or for |
245 | * example 'weekly'. The value is an array with two keys, one is 'interval' and |
246 | * the other is 'display'. |
247 | * |
248 | * The 'interval' is a number in seconds of when the cron job should run. So for |
249 | * 'hourly', the time is 3600 or 60*60. For weekly, the value would be |
250 | * 60*60*24*7 or 604800. The value of 'interval' would then be 604800. |
251 | * |
252 | * The 'display' is the description. For the 'weekly' key, the 'display' would |
253 | * be <code>__('Once Weekly')</code>. |
254 | * |
255 | * For your plugin, you will be passed an array. you can easily add your |
256 | * schedule by doing the following. |
257 | * <code> |
258 | * // filter parameter variable name is 'array' |
259 | * $array['weekly'] = array( |
260 | * 'interval' => 604800, |
261 | * 'display' => __('Once Weekly') |
262 | * ); |
263 | * </code> |
264 | * |
265 | * @since 2.1.0 |
266 | * |
267 | * @return array |
268 | */ |
269 | function wp_get_schedules() { |
270 | $schedules = array( |
271 | 'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ), |
272 | 'twicedaily' => array( 'interval' => 43200, 'display' => __('Twice Daily') ), |
273 | 'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ), |
274 | ); |
275 | return array_merge( apply_filters( 'cron_schedules', array() ), $schedules ); |
276 | } |
277 | |
278 | /** |
279 | * Retrieve Cron schedule for hook with arguments. |
280 | * |
281 | * @since 2.1.0 |
282 | * |
283 | * @param callback $hook Function or method to call, when cron is run. |
284 | * @param array $args Optional. Arguments to pass to the hook function. |
285 | * @return string|bool False, if no schedule. Schedule on success. |
286 | */ |
287 | function wp_get_schedule($hook, $args = array()) { |
288 | $crons = _get_cron_array(); |
289 | $key = md5(serialize($args)); |
290 | if ( empty($crons) ) |
291 | return false; |
292 | foreach ( $crons as $timestamp => $cron ) { |
293 | if ( isset( $cron[$hook][$key] ) ) |
294 | return $cron[$hook][$key]['schedule']; |
295 | } |
296 | return false; |
297 | } |
298 | |
299 | // |
300 | // Private functions |
301 | // |
302 | |
303 | /** |
304 | * Retrieve cron info array option. |
305 | * |
306 | * @since 2.1.0 |
307 | * @access private |
308 | * |
309 | * @return array CRON info array. |
310 | */ |
311 | function _get_cron_array() { |
312 | $cron = get_option('cron'); |
313 | if ( ! is_array($cron) ) |
314 | return false; |
315 | |
316 | if ( !isset($cron['version']) ) |
317 | $cron = _upgrade_cron_array($cron); |
318 | |
319 | unset($cron['version']); |
320 | |
321 | return $cron; |
322 | } |
323 | |
324 | /** |
325 | * Updates the CRON option with the new CRON array. |
326 | * |
327 | * @since 2.1.0 |
328 | * @access private |
329 | * |
330 | * @param array $cron Cron info array from {@link _get_cron_array()}. |
331 | */ |
332 | function _set_cron_array($cron) { |
333 | $cron['version'] = 2; |
334 | update_option( 'cron', $cron ); |
335 | } |
336 | |
337 | /** |
338 | * Upgrade a Cron info array. |
339 | * |
340 | * This function upgrades the Cron info array to version 2. |
341 | * |
342 | * @since 2.1.0 |
343 | * @access private |
344 | * |
345 | * @param array $cron Cron info array from {@link _get_cron_array()}. |
346 | * @return array An upgraded Cron info array. |
347 | */ |
348 | function _upgrade_cron_array($cron) { |
349 | if ( isset($cron['version']) && 2 == $cron['version']) |
350 | return $cron; |
351 | |
352 | $new_cron = array(); |
353 | |
354 | foreach ( (array) $cron as $timestamp => $hooks) { |
355 | foreach ( (array) $hooks as $hook => $args ) { |
356 | $key = md5(serialize($args['args'])); |
357 | $new_cron[$timestamp][$hook][$key] = $args; |
358 | } |
359 | } |
360 | |
361 | $new_cron['version'] = 2; |
362 | update_option( 'cron', $new_cron ); |
363 | return $new_cron; |
364 | } |
365 | |
366 | // stub for checking server timer accuracy, using outside standard time sources |
367 | function check_server_timer( $local_time ) { |
368 | return true; |
369 | } |
370 | |
371 | ?> |