]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/cron.php
Wordpress 2.8-scripts
[autoinstalls/wordpress.git] / wp-includes / cron.php
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 string $hook Action hook to execute when cron is run.
20  * @param array $args Optional. Arguments to pass to the hook's callback 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  * Valid values for the recurrence are hourly, daily and twicedaily.  These can
43  * be extended using the cron_schedules filter in wp_get_schedules().
44  *
45  * @since 2.1.0
46  *
47  * @param int $timestamp Timestamp for when to run the event.
48  * @param string $recurrence How often the event should recur.
49  * @param string $hook Action hook to execute when cron is run.
50  * @param array $args Optional. Arguments to pass to the hook's callback function.
51  * @return bool|null False on failure, null when complete with scheduling event.
52  */
53 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
54         $crons = _get_cron_array();
55         $schedules = wp_get_schedules();
56         $key = md5(serialize($args));
57         if ( !isset( $schedules[$recurrence] ) )
58                 return false;
59         $crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
60         uksort( $crons, "strnatcasecmp" );
61         _set_cron_array( $crons );
62 }
63
64 /**
65  * Reschedule a recurring event.
66  *
67  * @since 2.1.0
68  *
69  * @param int $timestamp Timestamp for when to run the event.
70  * @param string $recurrence How often the event should recur.
71  * @param string $hook Action hook to execute when cron is run.
72  * @param array $args Optional. Arguments to pass to the hook's callback function.
73  * @return bool|null False on failure. Null when event is rescheduled.
74  */
75 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
76         $crons = _get_cron_array();
77         $schedules = wp_get_schedules();
78         $key = md5(serialize($args));
79         $interval = 0;
80
81         // First we try to get it from the schedule
82         if ( 0 == $interval )
83                 $interval = $schedules[$recurrence]['interval'];
84         // Now we try to get it from the saved interval in case the schedule disappears
85         if ( 0 == $interval )
86                 $interval = $crons[$timestamp][$hook][$key]['interval'];
87         // Now we assume something is wrong and fail to schedule
88         if ( 0 == $interval )
89                 return false;
90
91         $now = time();
92
93     if ( $timestamp >= $now )
94         $timestamp = $now + $interval;
95     else
96         $timestamp = $now + ($interval - (($now - $timestamp) % $interval));
97
98         wp_schedule_event( $timestamp, $recurrence, $hook, $args );
99 }
100
101 /**
102  * Unschedule a previously scheduled cron job.
103  *
104  * The $timestamp and $hook parameters are required, so that the event can be
105  * identified.
106  *
107  * @since 2.1.0
108  *
109  * @param int $timestamp Timestamp for when to run the event.
110  * @param string $hook Action hook, the execution of which will be unscheduled.
111  * @param array $args Arguments to pass to the hook's callback function.
112  * Although not passed to a callback function, these arguments are used
113  * to uniquely identify the scheduled event, so they should be the same
114  * as those used when originally scheduling the event.
115  */
116 function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
117         $crons = _get_cron_array();
118         $key = md5(serialize($args));
119         unset( $crons[$timestamp][$hook][$key] );
120         if ( empty($crons[$timestamp][$hook]) )
121                 unset( $crons[$timestamp][$hook] );
122         if ( empty($crons[$timestamp]) )
123                 unset( $crons[$timestamp] );
124         _set_cron_array( $crons );
125 }
126
127 /**
128  * Unschedule all cron jobs attached to a specific hook.
129  *
130  * @since 2.1.0
131  *
132  * @param string $hook Action hook, the execution of which will be unscheduled.
133  * @param mixed $args,... Optional. Event arguments.
134  */
135 function wp_clear_scheduled_hook( $hook ) {
136         $args = array_slice( func_get_args(), 1 );
137
138         while ( $timestamp = wp_next_scheduled( $hook, $args ) )
139                 wp_unschedule_event( $timestamp, $hook, $args );
140 }
141
142 /**
143  * Retrieve the next timestamp for a cron event.
144  *
145  * @since 2.1.0
146  *
147  * @param string $hook Action hook to execute when cron is run.
148  * @param array $args Optional. Arguments to pass to the hook's callback function.
149  * @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
150  */
151 function wp_next_scheduled( $hook, $args = array() ) {
152         $crons = _get_cron_array();
153         $key = md5(serialize($args));
154         if ( empty($crons) )
155                 return false;
156         foreach ( $crons as $timestamp => $cron ) {
157                 if ( isset( $cron[$hook][$key] ) )
158                         return $timestamp;
159         }
160         return false;
161 }
162
163 /**
164  * Send request to run cron through HTTP request that doesn't halt page loading.
165  *
166  * @since 2.1.0
167  *
168  * @return null Cron could not be spawned, because it is not needed to run.
169  */
170 function spawn_cron( $local_time = 0 ) {
171
172         if ( !$local_time )
173                 $local_time = time();
174
175         if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
176                 return;
177
178         /*
179          * do not even start the cron if local server timer has drifted
180          * such as due to power failure, or misconfiguration
181          */
182         $timer_accurate = check_server_timer( $local_time );
183         if ( !$timer_accurate )
184                 return;
185
186         /*
187         * multiple processes on multiple web servers can run this code concurrently
188         * try to make this as atomic as possible by setting doing_cron switch
189         */
190         $flag = get_transient('doing_cron');
191
192         if ( $flag > $local_time + 10*60 )
193                 $flag = 0;
194
195         // don't run if another process is currently running it or more than once every 60 sec.
196         if ( $flag + 60 > $local_time )
197                 return;
198
199         //sanity check
200         $crons = _get_cron_array();
201         if ( !is_array($crons) )
202                 return;
203
204         $keys = array_keys( $crons );
205         if ( isset($keys[0]) && $keys[0] > $local_time )
206                 return;
207
208         if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
209                 if ( !empty($_POST) || defined('DOING_AJAX') )
210                         return;
211
212                 set_transient( 'doing_cron', $local_time );
213
214                 ob_start();
215                 wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) );
216                 echo ' ';
217
218                 // flush any buffers and send the headers
219                 while ( @ob_end_flush() );
220                 flush();
221
222                 @include_once(ABSPATH . 'wp-cron.php');
223                 return;
224         }
225
226         set_transient( 'doing_cron', $local_time );
227
228         $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron';
229         wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
230 }
231
232 /**
233  * Run scheduled callbacks or spawn cron for all scheduled events.
234  *
235  * @since 2.1.0
236  *
237  * @return null When doesn't need to run Cron.
238  */
239 function wp_cron() {
240
241         // Prevent infinite loops caused by lack of wp-cron.php
242         if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
243                 return;
244
245         if ( false === $crons = _get_cron_array() )
246                 return;
247
248         $local_time = time();
249         $keys = array_keys( $crons );
250         if ( isset($keys[0]) && $keys[0] > $local_time )
251                 return;
252
253         $schedules = wp_get_schedules();
254         foreach ( $crons as $timestamp => $cronhooks ) {
255                 if ( $timestamp > $local_time ) break;
256                 foreach ( (array) $cronhooks as $hook => $args ) {
257                         if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
258                                 continue;
259                         spawn_cron( $local_time );
260                         break 2;
261                 }
262         }
263 }
264
265 /**
266  * Retrieve supported and filtered Cron recurrences.
267  *
268  * The supported recurrences are 'hourly' and 'daily'. A plugin may add more by
269  * hooking into the 'cron_schedules' filter. The filter accepts an array of
270  * arrays. The outer array has a key that is the name of the schedule or for
271  * example 'weekly'. The value is an array with two keys, one is 'interval' and
272  * the other is 'display'.
273  *
274  * The 'interval' is a number in seconds of when the cron job should run. So for
275  * 'hourly', the time is 3600 or 60*60. For weekly, the value would be
276  * 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
277  *
278  * The 'display' is the description. For the 'weekly' key, the 'display' would
279  * be <code>__('Once Weekly')</code>.
280  *
281  * For your plugin, you will be passed an array. you can easily add your
282  * schedule by doing the following.
283  * <code>
284  * // filter parameter variable name is 'array'
285  *      $array['weekly'] = array(
286  *              'interval' => 604800,
287  *              'display' => __('Once Weekly')
288  *      );
289  * </code>
290  *
291  * @since 2.1.0
292  *
293  * @return array
294  */
295 function wp_get_schedules() {
296         $schedules = array(
297                 'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ),
298                 'twicedaily' => array( 'interval' => 43200, 'display' => __('Twice Daily') ),
299                 'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ),
300         );
301         return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
302 }
303
304 /**
305  * Retrieve Cron schedule for hook with arguments.
306  *
307  * @since 2.1.0
308  *
309  * @param string $hook Action hook to execute when cron is run.
310  * @param array $args Optional. Arguments to pass to the hook's callback function.
311  * @return string|bool False, if no schedule. Schedule on success.
312  */
313 function wp_get_schedule($hook, $args = array()) {
314         $crons = _get_cron_array();
315         $key = md5(serialize($args));
316         if ( empty($crons) )
317                 return false;
318         foreach ( $crons as $timestamp => $cron ) {
319                 if ( isset( $cron[$hook][$key] ) )
320                         return $cron[$hook][$key]['schedule'];
321         }
322         return false;
323 }
324
325 //
326 // Private functions
327 //
328
329 /**
330  * Retrieve cron info array option.
331  *
332  * @since 2.1.0
333  * @access private
334  *
335  * @return array CRON info array.
336  */
337 function _get_cron_array()  {
338         $cron = get_option('cron');
339         if ( ! is_array($cron) )
340                 return false;
341
342         if ( !isset($cron['version']) )
343                 $cron = _upgrade_cron_array($cron);
344
345         unset($cron['version']);
346
347         return $cron;
348 }
349
350 /**
351  * Updates the CRON option with the new CRON array.
352  *
353  * @since 2.1.0
354  * @access private
355  *
356  * @param array $cron Cron info array from {@link _get_cron_array()}.
357  */
358 function _set_cron_array($cron) {
359         $cron['version'] = 2;
360         update_option( 'cron', $cron );
361 }
362
363 /**
364  * Upgrade a Cron info array.
365  *
366  * This function upgrades the Cron info array to version 2.
367  *
368  * @since 2.1.0
369  * @access private
370  *
371  * @param array $cron Cron info array from {@link _get_cron_array()}.
372  * @return array An upgraded Cron info array.
373  */
374 function _upgrade_cron_array($cron) {
375         if ( isset($cron['version']) && 2 == $cron['version'])
376                 return $cron;
377
378         $new_cron = array();
379
380         foreach ( (array) $cron as $timestamp => $hooks) {
381                 foreach ( (array) $hooks as $hook => $args ) {
382                         $key = md5(serialize($args['args']));
383                         $new_cron[$timestamp][$hook][$key] = $args;
384                 }
385         }
386
387         $new_cron['version'] = 2;
388         update_option( 'cron', $new_cron );
389         return $new_cron;
390 }
391
392 // stub for checking server timer accuracy, using outside standard time sources
393 function check_server_timer( $local_time ) {
394         return true;
395 }
396
397 ?>