1 Feb
Ticking away the moments that make up a dull day. You fritter and waste the hours in an off hand way
WordPress 2.1 brought with it a number of new features, one of which is a pseudo-cron scheduling framework. This has been is the pipes for some time now, Scott Merrill developed a plugin called wp-cron back in 2005. After the 2.0 release of WordPress, there was a discussion on the wp-hackers mailing list about getting a cron-type scheduling feature into the core of WordPress and the functionality that was released with 2.1 started to take shape.
One of the more important points to come out of this discussion was that this was not meant to replace the actual cron feature built into the Linux operating system, it is not meant to be anywhere near that precise
As for the precision, perhaps the minutely thing might be a little much (mostly cause it’s hard to guarantee a hit every single minute of the day.) but I would still leave that in with a warning to authors that a * rules on the minute option is not likely to work — it’d still be handy, though, for every hour, on the hour.
What has been produced is a system that allows plugin developers to schedule events to occur at certain times. It does this by checking the current time against the list of scheduled tasks every time a page is loaded on the site. If the set time has passed the task (a callback function) is done.
Getting the scheduling to do what it should is going to require a working knowledege of how WordPress hooks, actions & filters work. If you don’t here is some recommended reading:
I highly recommend you appraise yourself of this information before proceeding. It’s ok, I’ll wait…
…
…
All back now? Alright, let’s continue.
Before we start it is important to note two things:
The scheduling allows for scheduling two types of events:
To schedule a single event you use the function
wp_schedule_single_event( $timestamp, $hook, $args )
$timestamp is the timestamp of when you want the event to occur$hook is the custom action hook that will call the function you want (more on this in a minute)$args is an optional array of arguments that will be passed to your callback function.
To do this you use the function
wp_schedule_event( $timestamp, $recurrence, $hook, $args )
The same arguments as the single event schedule, with the addition of$recurrence which is a string key for the type of recurrence to schedule. There are two reccurence types built in – hourly & daily. But what if you want others, say, weekly? Well fortunately you can add others. The cron system gets the information on what ‘hourly’ and ‘daily’ mean from the wp_get_schedules() function. Doing a print_r() on the output of this function gives you this:
Array
(
[hourly] => Array
(
[interval] => 3600
[display] => Once Hourly
)
[daily] => Array
(
[interval] => 86400
[display] => Once Daily
)
)
As you can see all it is doing is using an interval value (in seconds) to set how regularly the event should occur. Looking at the source code for the wp_get_schedules() function you can see that it merges the output of the cron_schedule filter with the array containing the two built in ones before returning it. This means that if you implement a filter function that hooks into the cron_schedules hook, you can add to this list.
To add weekly & fortnightly as possible reccurences, use the following code:
function more_reccurences() {
return array(
'weekly' => array('interval' => 604800, 'display' => 'Once Weekly'),
'fortnightly' => array('interval' => 1209600, 'display' => 'Once Fortnightly'),
);
}
add_filter('cron_schedules', 'more_reccurences');
Doing a print_r() on wp_get_schedules() now produces:
Array
(
[weekly] => Array
(
[interval] => 604800
[display] => Once Weekly
)
[fortnightly] => Array
(
[interval] => 1209600
[display] => Once Fortnightly
)
[hourly] => Array
(
[interval] => 3600
[display] => Once Hourly
)
[daily] => Array
(
[interval] => 86400
[display] => Once Daily
)
)
At this point, for the sake of example, lets assume we’re scheduling something that will occur daily & the function we want to call daily is called my_daily_function(). So we will have added this code to our plugin:
if (!wp_next_scheduled('my_daily_function_hook')) {
wp_schedule_event( time(), 'daily', 'my_daily_function_hook' );
}
As mentioned above, what we’ve done here is say that every day the ‘my_daily_function_hook’ will be called. Also it’s important to note again at this point that you only need to call this once, which is the reason for checking that wp_next_scheduled('my_daily_function_hook') is false. That function will return the next scheduled time for a hook, and false if it hasn’t been scheduled. By checking that this is false, we ensure that the event is only scheduled once.
We now need to define this action to call the my_daily_function(). To do this we need to add the custom action
add_action( 'my_daily_function_hook', 'my_daily_function' );
and the function itself
function my_daily_function() { print "I was just called. I'll be called at the same time tomorrow"; }
That’s it. At the same time every day (the time when this plugin is first loaded) the next person who loads a page on the site will see that text printed on the page. For a more complete example of the scheduling in use, have a look at the wp-votd plugin code. In that you’ll see the schedule event call sitting inside _install() method so that it’s only called once.
As mentioned wp_schedule_event can also take an optional fourth parameter of an array of values to pass to the callback function.
This scheduling functionality is a great new feature in WordPress for plugin developers, it’s a lot easier than what we had to do, that is keep a last updated time in the options table and then take the difference between that and the current time & compare it to a pre-defined interval. Major kudos to the developers for including this in the core code, and also to Scott Merrill for developing the original cron plugin.
I hope this tutorial has been helpful to people. Please post any corrections, questions and usage ideas in the comments, share the knowledge!
63 Responses for "Timing is everything: scheduling in WordPress"
[...] to Schedule Events with WordPress Cron Jobs: Glenn Slaven offers “Timing is everything: scheduling in WordPress”, a great step-by-step look at the new pseudo-cron scheduling framework in WordPress 2.1. This is [...]
I’m not a programmer so I have no idea what this means, but I love anyone who quotes Pink Floyd.
Does this mean we don’t need Skippy’s Cron Jobs plugins anymore?
Basically that’s what it means. If you look on the wp-hackers mailing list archive, Scott was involved in the initial discussion, where he basically said take what you want and use it for new built in functions.
[...] Contine to read How to schedule a task [...]
I’m not a programmer so I have no idea what this means, but I love anyone who quotes Pink Floyd.
Does this mean we don’t need Skippy’s Cron Jobs plugins anymore?
Basically that’s what it means. If you look on the wp-hackers mailing list archive, Scott was involved in the initial discussion, where he basically said take what you want and use it for new built in functions.
[...] Slaven has posted a detailed look at scheduling in Wordpress 2.1. This functionallity replaces and builds upon the WP-cron plugin by Skippy – the main application I [...]
[...] Timing is everything: scheduling in WordPress – Development on a Shoestring What has been produced is a system that allows plugin developers to schedule events to occur at certain times. It does this by checking the current time against the list of scheduled tasks every time a page is loaded on the site. If the set time has passed the task (a callback function) is done. [...]
[...] am wondering if Wordpress 2.1 pseudo cron scheduling framework can be used to index the content or maybe integrate an external search solution. This can help in [...]
[...] Timing is everything: scheduling in WordPress – Development on a Shoestring – Ticking away the moments that make up a dull day. You fritter and waste the hours in an off hand way. [...]
[...] to schedule future actions for a variety of purposes, including future posting. Glenn Slaven has a nice article about the WordPress scheduling [...]
Well, that seems pretty easy. I will have to give it a try on one of the plugins I am working on.
Well, that seems pretty easy. I will have to give it a try on one of the plugins I am working on.
Thank you for that explanation! I have tried to write an small test plugin for to test the cron functionality.
This plugin should write every minute the time in to a text file. But it works only one time after i activate this plugin.
I use XAMPP on my computer (Win XP SP2) at home and WP 2.1.3. Can you please help me a little? Thank you very much!!
array('interval' => 180, 'display' => 'timly'),
'timly2' => array('interval' => 60, 'display' => 'timly2'),
);
}
//if (function_exists('more_reccurences') == false){
add_filter('cron_schedules', 'more_reccurences');
//}
function tims_sf2_function() {
$handle = fopen("timtestfile_en.txt", "a");
fputs($handle, date('j. F Y - H:i:s',time())."\n");
fclose($handle);
}
if (!wp_next_scheduled('tim_sf2_function_hook')) {
wp_schedule_event( time(), 'timly2', 'tim_sf2_function_hook' );
}
add_action( 'tim_sf2_function_hook', 'tims_sf2_function' );
?>
array('interval' => 180, 'display' => 'timly'),
'timly2' => array('interval' => 60, 'display' => 'timly2'),
);
}
add_filter('cron_schedules', 'more_reccurences');
function tims_sf2_function() {
$handle = fopen("timtestfile_en.txt", "a");
fputs($handle, date('j. F Y - H:i:s',time())."\n");
fclose($handle);
}
if (!wp_next_scheduled('tim_sf2_function_hook')) {
wp_schedule_event( time(), 'timly2', 'tim_sf2_function_hook' );
}
add_action( 'tim_sf2_function_hook', 'tims_sf2_function' );
?>
I have tried to use <code> to include the source code. But now you can follow this link: http://home.snafu.de/tj.berger/crontest.php
Thank you for that explanation! I have tried to write an small test plugin for to test the cron functionality.
This plugin should write every minute the time in to a text file. But it works only one time after i activate this plugin.
I use XAMPP on my computer (Win XP SP2) at home and WP 2.1.3. Can you please help me a little? Thank you very much!!
array('interval' => 180, 'display' => 'timly'),
'timly2' => array('interval' => 60, 'display' => 'timly2'),
);
}
//if (function_exists('more_reccurences') == false){
add_filter('cron_schedules', 'more_reccurences');
//}
function tims_sf2_function() {
$handle = fopen("timtestfile_en.txt", "a");
fputs($handle, date('j. F Y - H:i:s',time())."n");
fclose($handle);
}
if (!wp_next_scheduled('tim_sf2_function_hook')) {
wp_schedule_event( time(), 'timly2', 'tim_sf2_function_hook' );
}
add_action( 'tim_sf2_function_hook', 'tims_sf2_function' );
?>
array('interval' => 180, 'display' => 'timly'),
'timly2' => array('interval' => 60, 'display' => 'timly2'),
);
}
add_filter('cron_schedules', 'more_reccurences');
function tims_sf2_function() {
$handle = fopen("timtestfile_en.txt", "a");
fputs($handle, date('j. F Y - H:i:s',time())."n");
fclose($handle);
}
if (!wp_next_scheduled('tim_sf2_function_hook')) {
wp_schedule_event( time(), 'timly2', 'tim_sf2_function_hook' );
}
add_action( 'tim_sf2_function_hook', 'tims_sf2_function' );
?>
I have tried to use <code> to include the source code. But now you can follow this link: http://home.snafu.de/tj.berger/crontest.php
Now, I have tried my little plugin on a “real” server of my webhosting provider and it was succesfully. So it seems that my problems is caused by something with test system at home.
Now, I have tried my little plugin on a “real” server of my webhosting provider and it was succesfully. So it seems that my problems is caused by something with test system at home.
[...] Timing is everything: scheduling in WordPress – Development on a Shoestring WordPress 2.1 brought with it a number of new features, one of which is a pseudo-cron scheduling framework. This has been is the pipes for some time now, Scott Merrill developed a plugin called wp-cron back in 2005. After the 2.0 release of WordPress, the (tags: wordpress cron scheduling) [...]
[...] 本文翻译自:Timing is everything: scheduling in WordPressï¼Œç¿»è¯‘çš„ä¸æ˜¯å¾ˆå‡†ç¡®ï¼Œè¯·å¤§å®¶å¸®å¿™ä¿®æ£ã€‚è°¢è°¢ï¼ [...]
[...] WordPress 安排任务,这是一篇Timing is everything: scheduling in WordPress。详述WordPress 2.1的新特性:pseudo-cron – 预定义任务时åºå®‰æŽ’框架。 [...]
Glenn
This method works wonderfully. I had a question though. I would like to run my event at midnight everyday and not at the time I actually enable the script. In the first parameter of the wp_schedul_event I have tried
date('U'), mktime(0,0,0,date('m'),date('d'),date('Y')))
This did not do anything different that time() would have. Do you have any thoughts on how to make this run at a specified time?
Again I have to say this is a very nice tutorial.
Glenn
This method works wonderfully. I had a question though. I would like to run my event at midnight everyday and not at the time I actually enable the script. In the first parameter of the wp_schedul_event I have tried
date('U'), mktime(0,0,0,date('m'),date('d'),date('Y')))
This did not do anything different that time() would have. Do you have any thoughts on how to make this run at a specified time?
Again I have to say this is a very nice tutorial.
Dustin: Sorry for not replying earlier. Actually I haven’t really looked at that, but I assumed that passing the timestamp into the 1st parameter would work.
Dustin: Sorry for not replying earlier. Actually I haven’t really looked at that, but I assumed that passing the timestamp into the 1st parameter would work.
[...] hablar, se trata de wp_schedule_event y wp_schedule_single_event dos funciones que nos permiten programar eventos en nuestro wordpress, recurrentes y una sola vez, [...]
[...] Cron like scheduling. [...]
[...] I have found a very nice description of the new wp-cron.php sheduling functionality at: http://blog.slaven.net.au/archives/2007/02/01/timing-is-everything-scheduling-in-wordpress/ [...]
If you want to write a plugin, which should work with other plugins which add intervals too at one time in a weblog then it could be better if your function more_reccurences looks like this:
function more_reccurences($schedules) {
$schedules['every1800sec'] = array(‘interval’ => 1800, ‘display’ => __(‘every 30 min’));
return $schedules;
}
This will add and not replace other intervals.
If you want to write a plugin, which should work with other plugins which add intervals too at one time in a weblog then it could be better if your function more_reccurences looks like this:
function more_reccurences($schedules) {
$schedules['every1800sec'] = array(‘interval’ => 1800, ‘display’ => __(‘every 30 min’));
return $schedules;
}
This will add and not replace other intervals.
[...] far as I know, the only post on the topic of WorPress scheduling is Timing is everything: scheduling in WordPress by Glenn Slaven. Even though, when I first worked with scheduling, I have to admit that I had quite [...]
[...] programmatic tasks to be run at designated times in the future. Glenn Slaven in his article Timing Is Everything does a great job of describing how this works. (Sadly, Wordpress’s convention is that people [...]
[...] Timing is everything: scheduling in WordPress – Development on a Shoestring (tags: wordpress scheduling cron plugin howto tutorial php) [...]
I’ve written a script that inserts a load of posts from an articles database into a wordpress database. The posts are given a timestamp that is staggered at a rate of approx 4 posts a day.
The posts go in, but don’t publish when the timestamp arrives, they just sit there in limbo.
I know why they don’t publish – THE CRON.
I’m going up the wall trying to figure out what I have to code to tell the cron to deal with the post.
Heres the script, I need to ‘add each post to the cron’.
I’ve been struggling on this for weeks, does anyone know how to add each post to the cron queue?
http://pickledegg.orchardhostings6.co.uk/articletransfer.txt
Thanks
I’ve written a script that inserts a load of posts from an articles database into a wordpress database. The posts are given a timestamp that is staggered at a rate of approx 4 posts a day.
The posts go in, but don’t publish when the timestamp arrives, they just sit there in limbo.
I know why they don’t publish – THE CRON.
I’m going up the wall trying to figure out what I have to code to tell the cron to deal with the post.
Heres the script, I need to ‘add each post to the cron’.
I’ve been struggling on this for weeks, does anyone know how to add each post to the cron queue?
http://pickledegg.orchardhostings6.co.uk/articl...
Thanks
This was very useful for me.
I do not know why, but when I program post in the future, categories are not getting the correct count of posts. I end up with categories which report 1 post, when they have 40. This way, I designed a plugin that recalculate the number of posts of all the categories every day.
So many thanks to you, and others who helped create this plugin. I hope I’ll release it soon and, of course, I’ll let you know.
This was very useful for me.
I do not know why, but when I program post in the future, categories are not getting the correct count of posts. I end up with categories which report 1 post, when they have 40. This way, I designed a plugin that recalculate the number of posts of all the categories every day.
So many thanks to you, and others who helped create this plugin. I hope I’ll release it soon and, of course, I’ll let you know.
I’m having a problem (also described here: http://wordpress.org/support/topic/167846) where wp_schedule_event doesn’t seem to work.
I’m trying to schedule a function to run hourly, and it’s not working, so I decided to call wp_next_scheduled to see what it had for the next scheduled timestamp, but it returns the start timestamp instead (the first parameter of wp_schedule_event).
So that means the next scheduled event is always some time in the past. But even when I set the start timestamp to some time in the future, it doesn’t seem to work.
Can anybody help?
I’m having a problem (also described here: http://wordpress.org/support/topic/167846) where wp_schedule_event doesn’t seem to work.
I’m trying to schedule a function to run hourly, and it’s not working, so I decided to call wp_next_scheduled to see what it had for the next scheduled timestamp, but it returns the start timestamp instead (the first parameter of wp_schedule_event).
So that means the next scheduled event is always some time in the past. But even when I set the start timestamp to some time in the future, it doesn’t seem to work.
Can anybody help?
[...] To add this interval value the implementation of a filter function, as explained in the article Timing is everything: scheduling in WordPress, was needed. The code is shown [...]
[...] ??????Timing is everything: scheduling in WordPress????????????????????? [...]
Don’t we need to also _remove_ our new item from the schedule if the plugin is deactivated?
How would we do that?
Is there an inverse to wp_schedule_event() ?
Don’t we need to also _remove_ our new item from the schedule if the plugin is deactivated?
How would we do that?
Is there an inverse to wp_schedule_event() ?
To answer my own question: wp_unschedule_event() or wp_clear_scheduled_hook()
Another point: to see what is scheduled, you can do a print_r on _get_cron_array()
Nice article. I wish I could get it to work….:-\
To answer my own question: wp_unschedule_event() or wp_clear_scheduled_hook()
Another point: to see what is scheduled, you can do a print_r on _get_cron_array()
Nice article. I wish I could get it to work….:-
My WP-pseudo-cron jobs aren't firing, even though I have what I believe to be sufficient traffic (~1400 hits/day). What can I do to make sure that page loads are indeed forcing the wp-pseudo-cron system to do its thing?
[...] start by saying that the best article I’ve read on the subject of crons is definitely “Timing is everything: scheduling in WordPress,” by Glenn Slaven. I highly recommend that, even before reading this article, you take a [...]
This is a very good point and is so important that it should be added to the main instructions as plugin developers should always keep other plugins in mind while developing.
[...] searched the web high and low for info related to adding your own cron job to Wordpress and this blog post has got to be by far the most [...]
[...] Glenn Slaven’s guide to scheduling events in WordPress. Print addthis_url = ‘http://www.toppa.com/2009/shashin-23-beta-is-here/’; addthis_title = ‘Shashin 2.3 Beta is Here’; addthis_pub = ”; « Christmas in Newport and Philadelphia [...]
Let me know if you find something that works. I need something like this for another project.
As mentioned above, what we’ve done here is say that every day the ‘my_daily_function_hook’ will be called. Also it’s important to note again at this point that you only need to call this once, which is the reason for checking that wp_next_scheduled('my_daily_function_hook') is false. That function will return the next scheduled time for a hook, and false if it hasn’t been scheduled. By checking that this is false, we ensure that the event is only scheduled once.
Nice article, way better than codex.wordpress.org 's .
good work.
you got a new follower.
Thanks
Dennis Wurster, I am having the same problem. I wonder if it worked well if you schedule REAL cronjob to run wp-pseudo-cron (/blog/wp-cron.php as I assume) each minute/hour? So that cron performance doesn't depend on blog traffic.
[...] Timing is everything: scheduling in WordPress [...]
[...] Timing is everything: scheduling in WordPress [...]
[...] Timing is everything: scheduling in WordPress [...]
[...] Timing is everything: scheduling in WordPress [...]
[...] Timing is everything: scheduling in WordPress [...]
[...] Timing is everything: scheduling in WordPress [...]
Leave a reply