Monday, March 21, 2011

WordPress cron explained

cron is a job scheduler in the unix-like operating systems that can be very helpful to automate tasks. . Webhosts provide cron service to execute scripts periodically.

 It is encouraged to use the webhost cron service in most of the cases because WordPress cron is actually a psudo cron service. You might want to use the functions of WordPress in your script. In that Case  you will have to load the wp-load.php file and the core WordPress functions, database classes will be available for your script.

require_once('wp-load.php');

If your host doesn't support cron, WordPress cron will be handy. You will need the WordPress cron functionalities for your plugins or for automating other tasks like auto-generating posts, sending mails, messages to users. So let's digg into the WordPress cron.

I mentioned before that WordPress cron is a "psudo cron", that means that it won't always execute the script at the real time you want. The cron job is triggered when somebody visits your website. That means if you have scheduled a function to be executed at 8am and if nobody visits your website at 8am the execution will be triggered suppost at 8:10 am when somebody has hit your site.

WordPress cron doesn't make your website slow!

May be you are thinking what if the cron-script takes a long time to be executed, will the visitors have to wait until the script is  executed. Nope! How can that be possible? If you look at the wp-cron.php file you will find a line

ignore_user_abort(true);

It's a php.ini configuration that sets that if you stop loading the site/script the script won't stop executing.

If you look at the wp-includes/cron.php file you'll find a line like this

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
 

That means WordPress will wait only 0.01 second for triggering the execution then it will abort but as you have set ignore_user_abort to true the script will be executing.This functionality is a huge advantage to execute large scripts in the WordPress cron.

Now we know the basics of WordPress cron but how will we implement this  beast?

Let's point out the most used cron WordPress functions:



wp_schedule_event($timestamp, $recurrence, $hook, $args);

Here $timestamp indicates the first time we want to execute the script. 

$recurrence is the interval between the two execution.
$hook is the hook or tag with with we attach our cron functions, $args are some optional parameters 

Let's make a plugin using the function.

<?php
/*
Plugin Name: cron-robot
Plugin URI: http://sabirul-mostofa.blogspot.com
Author: Sabirul Mostofa
Version: 0.1
*/


//adding the function to our  hook 'practice_cron_job'

add_action('practice_cron_jobs','practice_cron_func');

//calling the cron function 

if(!wp_next_scheduled('practice_cron_jobs'))
wp_schedule_event(time(),'hourly','practice_cron_jobs');


 // a function to add a option in the options table

function practice_cron_func(){
if($a=get_option('practice_cron'))
update_option('practice_cron',$a.'+');
else
add_option('practice_cron','init_value');

}

//for clearing the sceduled tasks

register_deactivation_hook(__FILE__,'deactivate_cron_hook');

function deactivate_cron_hook(){
wp_clear_scheduled_hook('practice_cron_jobs');
}
?>


what this plugin does
This plugin runs the function 'practice_cron_func' once in a hour. you
can make your own time intervals. see below in the 'what is hourly?' section.

what does the wp_next_scheduled() do?
It will take a hook as a parameter and will return the timestamp of the cron hook's next execution time 

you can add these lines in the above plugin to test:

echo wp_next_scheduled('practice_cron_jobs');
exit;

remove these lines after testing!



Why I am adding

if(!wp_next_scheduled('practice_cron_jobs'))
This is just to make sure that you are not making the same cron job again because when you are scheduling a event by
wp_schedule_event(time(),'hourly','practice_cron_jobs');
it will  schedule another event attached to the hook.


what is 'hourly'?

If you look at the function the second parameter is the time intervalbetween the executions. 'hourly' is the WordPress defined time interval. WordPress has three defined values that you can use they are
  • hourly
  • daily
  • twicedaily

You can add your defined values like 'every_minute', 'twice_a_hour' etc. This can be done by hooking a function to 'cron_schedules'. Follow the following procedure.

add_filter('cron_schedules','cron_minute');

function cron_minute($cron_schedules){
   
     $cron_schedules['every_minute'] = array(
      'interval'=> 60,
      'display'=>  __('every minute')
  );

    return $cron_schedules;
   
    } 
    
    

# Take a note that WordPress won't run cron jobs more than once a minute. see here for further details.

if we want to clear all the schedueled hooked with 'practice_cron_jobs'
use this code
wp_clear_scheduled_hook('practice_cron_jobs') ;
It will delete the cron tasks from the wp_options table

you can view the scheduled tasks attached to our defined hook by


wp_get_schedule('practice_cron_jobs');

When you deactivate plugin clear the scheduled hook which will free many scheduled events.

Use this code:


register_deactivation_hook(__FILE__,'deactivate_cron_hook');

function deactivate_cron_hook(){
wp_clear_scheduled_hook('practice_cron_jobs');

}


Recently I have been working on iappsy.com I have used cron to autogenerate the posts and it's working perfectly.

Limitations: It won't execute more than once if time limit is exceeded. For example if you have scheduled a task to do every hour and if a visior comes after 10 hours you can expect there will be 10 executions but actually it doesn't happen It'll execute only once.

WordPress won't execute cron jobs more than once a minute. see here for more details.

3 comments:

  1. Nice guide! Is there no need for a register_activation_hook ?

    ReplyDelete
  2. I guess its ok for what it is, but its really not what is needed.

    ReplyDelete
  3. Thanks for the article.
    If your hosting doesn't provide cronjobs, you may try www.easycron.com some of wordpress users i know are using it, works quite well.

    ReplyDelete

About Me

Web Developer From Dhaka, Bangladesh.