08/11/2017 / Samuel

In this tutorial on automated tasks using WP-Cron, we’ll build a plugin for fetching popular tweets from a certain hashtag and e-mail them hourly. We’ll use WP-Cron as well as the Twitter API.

Intro to Cron in WordPress

If the word “cron” comes from Greek origins and meant “time” (χρόνος) , it is frequently used in Unix-like systems when referring to task that are scheduled to be executed sometime in the future. Generally, a cron task runs periodically and comes in handy for automated operations.

In WordPress, cron jobs or tasks are used for various purposes including:

  • Checking for theme & plugin updates
  • Publish scheduled posts
  • Sending pingbacks

Under the hood, cron tasks use the WordPress Cron functions, a set of functions that are located in wp-includes/cron.php. To run cron tasks repetitively, WordPress has its own mechanism to mimic the native Unix cron system.

  • A visitor requests a page on your website
  • /wp-settings.php triggers the wp_cron() function and ensures that WordPress Cron is not disabled.
  • If WordPress Cron is enabled, the wp-cron.php file loops through each one of the scheduled cron tasks and compare its next execution time with the current time.
  • If the next execution time is matched or has passed, the task is triggered.

As you have probably noticed, WP-Cron relies on page visits and is then prone to inaccuracy issues if your interval is too short. However, there are many workarounds such as Cavalcade and we’ll get to that later.

Now that you roughly understand how cron works in WordPress, let’s start building our plugin.

Create a the plugin

For the skeleton of our plugin, create a folder within the /wp-content/plugins directory and add a php file. It is required to name the folder in lowercase and without special characters. In our case, the plugin is Tweety Mail, the folder will be tweety-mail with an index.php file inside:


--/wp-content
------/plugins
----------/tweety-mail
-----------------/index.php

Insert the comments below at the top of the php file. In short, this comment part will be the “ID card” of the plugin, and will register the folder as a WordPress plugin.

<?php
/**
 * Plugin Name: Tweety Mail
 * Plugin URI: https://github.com/samuelguebo/tweety-mail
 * Description: Fetch popular tweets from a hashtag and send them via e-mail
 * Version: 0.0.1
 * Author: Samuel Guebo
 * Author URI: https://github.com/samuelguebo
 * Text Domain: no
 * License: GPL3
 */
 ?>

 
If you correctly followed the steps above, your plugin should appear in the plugins in your WordPress dashboard.

Set up a basic cron

First, we’ll register a new WordPress action. In fact for triggering our function and sending e-mail periodically, we need to create a new WordPress action first, and hook our function into that action. If you need a refreshing on action_hooks, check my previous post Action hooks in WordPress.

We’ll create the new action and add our function as a callback in a single move as shown below:


// Create a new action with the tml_task() function as callback
add_action('tml_action', 'tml_task') ;

 
Now let’s add the tml_task() function. It basically sends the current time by e-mail to the administrator with a simple objet and message. We’ll use this as a placeholder for the next part and substitute it with the popular tweets.


// The call back for sending e-mail
function tml_task (){
        
       // Preparing the e-mail
        $object   = "Current time: " . date("h:i:s") ;
        $to  = get_bloginfo('admin_email');
        $headers[] = "From: " .get_bloginfo('title'). " <$to>";

        $message = "It's exactly : " . date("h:i:s");

        // Send the e-mail
        wp_mail( $to, $object, $message, $headers );

        
}

 
Let’s do the schedulling now.


// Check if the tml_action is not already scheduled
if( !wp_next_scheduled( 'tml_action' ) ) {

	// Schedule the tml_action to repeat hourly
	wp_schedule_event( time(), 'hourly', 'tml_action' );
}

 

We used the wp_next_scheduled() to avoid scheduling again our action. When we made sure that the scheduling is hapenning for the first time, we do the scheduling with the wp_schedule_event() function. wp_schedule_event() takes some parameters:

  • int $timestamp: when the task will run for the first time. We used time() which is the current timestamp.
  • string $recurrence: the interval before next run. By default WordPress offers the following: hourly, twicedaily and daily.
  • string $hook: the action hook to run. We put the tml_action defined previously

 

Refine the code

    For now, our codebase is functional but not optimal. Some issues might arise:

  • If the plugin is removed, the cron task will still be registered. It won’t fire our function but it will waste resources
  • As you might have noticed, on every page load, our plugin will check wether it can schedule the task. This is also a waste of ressources.

We can add few improvements:

  • Automatically delete the scheduled tasks when you deactivate the plugin in order to avoid wasting resources
  • Set up the scheduling only once, during activation, instead of trying to do it on every page load as we are doing it now.

We need to create two functions tml_activation() and tml_deactivation(). As they name suggest, they will be called respectively when the plugin is activated and when it gets deactivated. Next we’ll hook these two functions into to WordPress process using register_action_hook() and register_deactivation_hook().


// Activation and deactivation hooks
register_activation_hook( __FILE__ , 'tml_activation' );
register_deactivation_hook( __FILE__ , 'tml_deactivation' );

// The callbacks
function tml_activation() {
	// Action when the plugin activated
    if( !wp_next_scheduled( 'tml_task' ) ) {
    	wp_schedule_event( time(), 'hourly', 'tml_task' );
	}
}


function tml_deactivation() {
	// Action when the plugin deactivated
    wp_clear_scheduled_hook( 'tml_task');
}

 

The full code

 

<?php
/**
 * Plugin Name: Tweety Mail
 * Plugin URI: https://github.com/samuelguebo/tweety-mail
 * Description: Fetch popular tweets from a hashtag and send them via e-mail
 * Version: 0.0.1
 * Author: Samuel Guebo
 * Author URI: https://github.com/samuelguebo
 * Text Domain: no
 * License: GPL3
 */
 
// Activation and deactivation hooks
register_activation_hook( __FILE__ , 'tml_activation' );
register_deactivation_hook( __FILE__ , 'tml_deactivation' );

// Activation and deactivation callbacks
function tml_activation() {
	// Check if the tml_action is not already scheduled
	if( !wp_next_scheduled( 'tml_action' ) ) {

		// Schedule the tml_action to repeat hourly
		wp_schedule_event( time(), 'hourly', 'tml_action' );
	}
}

function tml_deactivation() {
	// Action when the plugin is deactivated
    wp_clear_scheduled_hook( 'tml_task');
}

// The call back for sending e-mail
function tml_task (){
        
        // Preparing the e-mail
        $object   = "Current time: " . date("h:i:s") ;
        $to  = get_bloginfo('admin_email');
        $headers[] = "From: " .get_bloginfo('title'). " <$to>";

        $message = "It's exactly : " . date("h:i:s");

        // Send the e-mail
        wp_mail( $to, $object, $message, $headers );

        
}
?>

 
We are all set for this first part. You can activate your plugin now.
 

Monitor the cron tasks

A convenient way to check wether the task has been successfully scheduled is by installing the WP-Control plugin. This handy plugin gives you an overview of all scheduled tasks. You can easily add, edit, delete whichever task you wish.

 

Conclusion

By now you should know how to set up a simple automated task in WordPress using WP-Cron. In the next part of this tutorial we’ll expand our codebase and take advantage of the Twitter API to fetch popular tweets from a hashtag. For the purpose of this tutorial, the plugin code is available on Github.

Facebook Comments