Advertisement
Theme Development

Do-It-Yourself WordPress Scheduling: Mastering WP-Cron

by

As one of the lesser-used WordPress features, WP-Cron often gets overlooked by developers. Its applications, however, are no laughing matter. From caching to notifications to clean up, scheduling cron jobs can work to create a distinct advantage in even the most simple WordPress blog. Join in as we explore important applications of this very system.


Just an Average Cron Job? Think again.

Schedule

WP-Cron is not the same as the Unix cron scheduler...

Immediately upon seeing the word cron, I'm sure you've taken a stab at where we're headed: scheduling perfectly timed events to run at specified intervals. On the contrary, WP-Cron is not the same as the Unix cron scheduler. The key distinction lies in how it is run; unlike a background process, WP-Cron kicks in every time a visitor opens your WordPress-powered site. As such, it retains the vital characteristic of imprecise timing.

Yes, you read right: imprecise timing. Although the words cron and accuracy are like two peas in a pod, they do not harmonize in WordPress' system. But is this really a problem? If considered in the context of the user, this actually becomes an asset.

Let's take the example of a normal cron job running every five minutes to update some database information used on a website. If no visitors visit the site for 40 minutes, what, then, is the point of running this job eight times? All intermediate values would both be obsolete and unused. If, conversely, it were to kick in on the first user visit after a minimum of five minutes, it would not only accomplish the same job, but also prevent unnecessary updates. In other words, because WP-Cron is based on the user, it has the advantage of only running when visitors are present.


Don't Beat Around the Bush. Show Me!

To apply WP-Cron, let's consider the oft-used RSS managing application, FeedBurner. By far, one of the most popular features of this application is its ability to count RSS subscribers. Once indexed, a site's subscriber count can be accessed through a simple API call. It follows, then, that this API call can be done once per page view to deliver the subscriber count to viewers. This, however, leads to a problem.


Enter the World of Caching

If FeedBurner's API is accessed once per page view, it inevitably leads to an extra HTTP request—not to mention one from another domain—for each visitor. This increases the page load time for users.

To counteract this problem, it is important to make one key realization about this delivery method: an RSS subscriber count is unlikely to update on every single view of the page. In fact, FeedBurner only updates its count once per day. Even if it were to change rapidly, is it really necessary to display the latest count for every visitor? Does it matter that the count is slightly outdated, but subsequently refreshed within a day?

For our purposes, it is entirely useless to fetch the RSS subscriber count for each page view. Instead, if it is retrieved for one visitor, it can simply be reused for future ones. Then, after a day has passed, an update to this count can be made. Such a process is known as caching. After being updated, the RSS subscriber count is cached—stored for future use instead of being re-calculated—until a day has passed. And, with that, we enter the world of WP-Cron.


Step 1 Explore the Documentation

Documentation

To understand WP-Cron, it is important to know where documentation is available. WordPress.org provides summaries of each cron function in its Codex. To complete our previously defined task, we will need to look at the wp_schedule_event function, which requires four parameters:

  • Time: a UNIX timestamp specifying when the event should trigger
  • Recurrence: how often the event should be retriggered after the scheduled time
  • Hook: a hook used to add functionality when the event is triggered
  • Args: an array of arguments to pass to all hooked functions (optional)

Our event will trigger when the current time meets or exceeds the time passed to this function, as prescribed by a future visitor to the website. It will then retrigger based on the recurrence parameter, which can be set to hourly, twicedaily, daily, or none. Custom recurrence schedules may also be defined.

In order to deal with the event, a hook is used. In brief, a WordPress hook can be considered a placeholder for an action. Actions may be assigned to hooks via WordPress' add_action function. More specifically, to add a function handler to the given hook, one may call:

add_action( 'hook_name', 'function_name' );

where hook_name and function_name are the name of the hook and handling function, respectively.


Step 2 Calling the Function

Because FeedBurner updates once per day, we will specify a daily schedule, as per the code below:

wp_schedule_event( time(), 'daily', 'feedburner_refresh' );

Note that time() is the current UNIX timestamp in seconds. If run, the 'FeedBurner Update' hook will trigger immediately and then once per day afterward. Note that if we were to just put this in our WordPress functions.php file, it would schedule a new event on every single page load. This is not our desired functionality; rather, we only want to schedule this event once. The easiest way to do this is by simply checking whether the event is already scheduled. This can be done through the wp_next_scheduled function, which will return false if the event is not set to trigger in the future or the time of its next trigger otherwise:

if( !wp_next_scheduled( 'feedburner_refresh' ) ) {
   wp_schedule_event( time(), 'daily', 'feedburner_refresh' );
}

If we ever need to unschedule this event, it's as simple as calling the wp_unschedule_event function, which takes the same parameters—save for the recurrence—as wp_schedule_event. Note that the time passed must be the time of the next trigger, which can be retrieved via wp_next_scheduled:

if( false !== ( $time = wp_next_scheduled( 'feedburner_refresh' ) ) ) {
   wp_unschedule_event( $time, 'feedburner_refresh' );
}

We can also unschedule this event through its hook name using the wp_clear_scheduled_hook function. Be aware that this alternative will also remove all other events that use the same hook.

wp_clear_scheduled_hook( 'feedburner_refresh' );

Step 3 Deploying the Hook

Hook

Now that our event is scheduled, we must add a handler to it:

add_action( 'feedburner_refresh', 'update_rss_subscriber_count' );

This sets the function named update_rss_subscriber_count to be called once the feedburner_refresh hook is triggered. It is now time to write this function.


Step 4 Retrieving the FeedBurner Subscriber Count

To retrieve the subscriber count in the update_rss_subscriber_count function, we can make a call to FeedBurner's API via the URL <https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]>, where [NAME] is the name of our feed.

This will return XML data in the following form:

<rsp stat="ok">
   <!--
      This information is part of the FeedBurner Awareness API. If you want to hide this information, you may do so via your FeedBurner Account.
   -->
   <feed id="8olmjno1k05rb1som1frr6u854" uri="nettuts">
      <entry date="2011-06-22" circulation="84673" hits="152325" reach="25865"/>
   </feed>
</rsp>

The information we are looking for is in the circulation attribute. The following regular expression can easily parse through the data for this value: circulation="(.*?)".

Put in English, our regular expression matches the following:

  • circulation= – The word circulation followed by an equals sign
  • "(.*?)" – Quotes and everything inside

Running this using the preg_match function will retrieve an array of matches which will contain the number of subscribers in the first index position. Putting this information together yields the following code:

// find the FeedBurner url and get the data from it
// change [NAME] to the name of your FeedBurner feed
$url = 'https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]';
$data = @file_get_contents( $url ); // @ will surpress errors

// use a regular expression to parse the data
$regex = '%circulation="(.*?)"%';
preg_match( $regex, $data, $matches );

// get the resultant count if available
$count = false;
if( $matches && $matches[1] )
   $count = (int) $matches[1];

Step 5 Storing the Subscriber Count

Save

Now that we have retrieved the subscriber count, we'll need to store it for accessibility; instead of revisiting the API XML data, visitors will merely access this stored value.

Rather than creating a database or file for storage purposes, we can employ yet another WordPress feature: options. WordPress options are simple ways to store bits of data along with identifying names. Adding, deleting, and accessing options are as simple as the following functions:

  • update_option( $name, $value ) - Adds or updates an option with name $name and value $value.
  • delete_option( $name ) - Delete an option with name $name.
  • get_option( $name ) - Get the option value associated with name $name.

Although our subscriber count is not technically a configuration value, using WordPress options is one of the most convenient ways—if not the most convenient—for storing such simple data. Consequently, to store our subscriber count, we'll use the update_option method, which will not only override previous values, but also create the option in the first place:

// if a count could not be found, do not update
// instead, stick with the previous count
if( $count !== false )
   update_option( 'subscriber_count', $count );

Our function is complete! After setting up the event, retreiving the data via the FeedBurner API, and storing the desired value, all that's left to do is output! The full code for the scheduling and retrieval function—which you can place in functions.php—may be found below:

// schedule the feedburner_refresh event only once
if( !wp_next_scheduled( 'feedburner_refresh' ) ) {
   wp_schedule_event( time(), 'daily', 'feedburner_refresh' );
}

add_action( 'feedburner_refresh', 'update_rss_subscriber_count' );
function update_rss_subscriber_count() {
   // find the FeedBurner url and get the data from it
   // change [NAME] to the name of your FeedBurner feed
   $url = 'https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=[NAME]';
   $data = @file_get_contents( $url ); // @ will surpress errors

   // use a regular expression to parse the data
   $regex = '%circulation="(.*?)"%';
   preg_match( $regex, $data, $matches );

   // get the resultant count if available
   $count = false;
   if( $matches && $matches[1] )
      $count = (int) $matches[1];

   // if a count could not be found, do not update
   // instead, stick with the previous count
   if( $count !== false )
      update_option( 'subscriber_count', $count );
}

Step 6 Output

The subscriber count is now just a mere function call away in any template file:

echo get_option( 'subscriber_count' );

Conclusion

Finish

Our RSS subscriber count is now optimized; rather than being retrieved for each request, it is cached with the help of WP-Cron, saving our users time and reducing bandwidth usage. Because it only activates when our site actually receives a visitor, our function is lazy—a term that can certainly be considered good in this context. But alas, we have only uncovered one application of WP-Cron here; the rest is up to you.

Have your own innovative application of WP-Cron? Share it with us in the comments!

Related Posts
  • Code
    WordPress
    A Guide to Using FeedPress with WordPressA guide to using feedpress with wordpress
    FeedBurner still works great, but it hasn't been updated much in the last few years, and people are worried that Google, owner of FeedBurner, may close it down especially with the track record they've had over the past few years. So for those of us who want to continue tracking statistics about our subscribers, what options do we have available?Read More…
  • Code
    Plugins
    Distributing Your Plugins in GitHub with Automatic UpdatesSensorsthumbnail
    This article will teach you that, with a little creative coding, you can host your own WordPress plugins in GitHub while still retaining the automatic update feature.Read More…
  • Code
    Creative Coding
    Using WordPress for Web Application Development: A ReviewApplication foundation 400
    Over the past few months, we've been taking a look at all of the features and aspects that make WordPress a potential foundation for application development. In fact, we've spent roughly 15 articles talking about all that WordPress offers. And though we'll be reviewing each of the points in this email, perhaps the biggest thing to take away that building web applications using WordPress is different than using many of the popular frameworks that are currently available namely because WordPress isn't a framework.Read More…
  • Code
    Creative Coding
    Using WordPress For Web Application Development: Available Features, Part 6: URL Rewriting (or Routes)Application foundation 400
    One of the nicest things about modern web application development frameworks is that they provide a way to generate really clean routes—or URL schemes—that map to the conceptual model of how the application is structured.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    Plugins
    Displaying Information of a WordPress.org Plugin on Your WebsiteWordpressdotorg plugin api border 400
    In the first part of this article, we discussed how to use built-in functions to communicate with WordPress.org and retrieve plugin details. In this tutorial we will put the theory in action to create a simple plugin which will allow us to display details of any plugin hosted on WordPress.org on our WordPress website using shortcodes.Read More…