Paulund
2012-05-25 #wordpress

Create Cron Jobs In Wordpress

A cron job allows you to automatically set a function to run at a set time or interval. Wordpress comes with an in-built function wp_schedule_event(). ## Wordpress Schedule Event

The function wp_schedule_event() allows you schedule a hook to run an action to schedule a function to run at a set interval.


<?php wp_schedule_event($timestamp, $recurrence, $hook, $args); ?>

Schedule An Hourly Event In Plugin

To schedule an hourly event within a plugin you will schedule a function on activation of the plugin.

register_activation_hook(__FILE__, 'my_activation');
add_action('my_hourly_event', 'do_this_hourly');

function my_activation() {
	wp_schedule_event( current_time( 'timestamp' ), 'hourly', 'my_hourly_event');
}

function do_this_hourly() {
	// do something every hour
}

If you want to deactivate the schedule event then use this.


register_deactivation_hook(__FILE__, 'my_deactivation');

function my_deactivation() {
	wp_clear_scheduled_hook('my_hourly_event');
}

Schedule hourly Event In Functions.php

This doesn't rely on activation of the plugin as it will run inside the functions.php file.


add_action('my_hourly_event', 'do_this_hourly');

function my_activation() {
	if ( !wp_next_scheduled( 'my_hourly_event' ) ) {
		wp_schedule_event( current_time( 'timestamp' ), 'hourly', 'my_hourly_event');
	}
}
add_action('wp', 'my_activation');

function do_this_hourly() {
	// do something every hour
}

Add New Cron Intervals

WordPress cron doesn't work like normal apache cron as in it doesn't run at a certain time and day, WordPress cron works by running in intervals of time. Therefore it will run a task when it is hit and then for daily tasks will run this in 24 hours. If you want to add new time intervals that you can use in your WordPress cron you can use WordPress filter called cron_schedules, by adding new elements to this array will allow you to have new intervals.


function add_new_intervals($schedules) 
{
	// add weekly and monthly intervals
	$schedules['weekly'] = array(
		'interval' => 604800,
		'display' => __('Once Weekly')
	);

	$schedules['monthly'] = array(
		'interval' => 2635200,
		'display' => __('Once a month')
	);

	return $schedules;
}
add_filter( 'cron_schedules', 'add_new_intervals'); 

Cron At Certain Day's And Time

The way the Cron works on WordPress is not the same as it works on normal apache cron, WordPress cron works in time intervals from when it was first ran which can be at any time. Therefore if you want the script to run weekly on every monday then you can not setup a weekly cron.


wp_schedule_event( current_time( 'timestamp' ), 'weekly', 'my_weekly_event');

This is because you don't know what day this will run on, you can upload the script on a Monday and then make sure it run on that day and it will repeat on every Monday. The problem is there are a lot of this that can go wrong with this, what if the database is updated and the time intervals change you can not guarantee that it will run on the correct day. So what can we do if we want the script to run on a certain date say every Monday? We can setup a wp-cron job that runs daily, then all we have to do is check what the current day is before we continue with the script.


add_action('new_daily_event', 'monday_event');

function monday_event_activation() 
{
    if ( !wp_next_scheduled( 'new_daily_event' ) ) {
        wp_schedule_event( current_time( 'timestamp' ), 'daily', 'new_daily_event');
    }
}
add_action('wp', 'monday_event_activation');

function monday_event()
{
    // Get the current date time
    $dateTime = new DateTime();

    // Check that the day is Monday
    if($dateTime->format('N') == 1)
    {
        // run script
    }
}

This script will run once a day which isn't a big hit to the server as all it will do is check the current day before deciding to run the script, but now we can have a script that runs every Monday. If you want to run this script at a certain time then you need to change this wp-cron to run hourly and check both the day and the time is what you want it to be.