A Unix CRON Equivalent in WooCommerce

This question about a WooCommerce cron equivalent is from the WooCommerce Community Slack channel:

I want to loop through all users and their subscriptions, check some custom meta data I added to each subscription on creation and update some of the meta data if needed.

What would be the equivalent of a linux cron job in WooCommerce? Is there something in WooCommerce that triggers daily?

I worked on a client site that day to allow subscription customers to switch from an annual subscription to a monthly subscription. This task involved removing the custom annual subscription scheduled action hook and adding a standard WooCommerce Subscriptions scheduled action. I had the Action Scheduler code fresh in my mind so I replied to the person who asked the question. I messaged that I’d put together some pseudo code to give him a direction to follow to solve his problem. Below is the process I took to answer this question.

Background on the Action Scheduler

If you want an overview of Action Scheduler be sure to checkout the presentation I gave to the West Orlando WordPress Meetup group.

First let’s touch on a quick background on the Action Scheduler library. From the project home page:

The Action Scheduler is a scalable, traceable job queue for background processing large queues of tasks in WordPress.

This library is part of WooCommerce and WooCommerce Subscriptions to handle background processes like database updates and reporting tasks. This code has run on thousands of sites and has handled millions of payment actions so it is very reliable.

A single scheduled action contains three things:

  • A hook to fire. You can think of this as a “do_action() at a specific time.”
  • A schedule. A timestamp of when to run.
  • A list of arguments. Extra data passed to the hook.

It is possible to group actions, but I don’t use that functionality. Actions run once or recur multiple times. The recurring action is the type that fits this use case most closely.

Because the original question referenced WooCommerce and WooCommerce Subscriptions I knew Action Scheduler would be available on the website.

An approach to a CRON Equivalent in WooCommerce

In the Action Scheduler source code there is a functions.php file that contains ten API functions (link). One of these functions is aptly named as_schedule_cron_action(). The definition says it schedules “an action that recurs on a cron-like schedule.” Perfect!

The PHPDoc for the function has a handy reminder on how to setup the cron schedule.

/**
 * Schedule an action that recurs on a cron-like schedule.
 *
 * @param int    $timestamp The first instance of the action will be scheduled
 *           to run at a time calculated after this timestamp matching the cron
 *           expression. This can be used to delay the first instance of the action.
 * @param string $schedule A cron-link schedule string.
 * @see http://en.wikipedia.org/wiki/Cron
 *   *    *    *    *    *    *
 *   ┬    ┬    ┬    ┬    ┬    ┬
 *   |    |    |    |    |    |
 *   |    |    |    |    |    + year [optional]
 *   |    |    |    |    +----- day of week (0 - 7) (Sunday=0 or 7)
 *   |    |    |    +---------- month (1 - 12)
 *   |    |    +--------------- day of month (1 - 31)
 *   |    +-------------------- hour (0 - 23)
 *   +------------------------- min (0 - 59)
 * @param string $hook The hook to trigger.
 * @param array  $args Arguments to pass when the hook triggers.
 * @param string $group The group to assign this job to.
 * @param bool   $unique Whether the action should be unique.
 *
 * @return int The action ID.
 */

Organization of Action Scheduler action and callback

To get this working you can add a plugin file to the wp-content/plugins directory, or add the code to the theme’s functions.php file.

This process needs a call to the schedule function, an add_action() to connect the hook to a callback, and the callback function. You need to make sure that Action Scheduler library is loaded before calling the schedule function so do it after plugins_loaded is called.

A Working Example

Here’s a bit of code to create the action to run “Every Day at 7 AM.”

<?php

add_action( 'plugins_loaded', 'growdev_add_custom_schedule' );

function growdev_add_custom_schedule() {
    $args = '';
    as_schedule_cron_action( time(), '0 7 * * *', 'my-awesome-hook', $args );
}

The first parameter of time() means that this action fires once when it is called, then reschedule itself based on the cron schedule. The hook is called my-awesome-hook. I suggest using something a little more descriptive.

The next piece of code handles the callback.

// Define handler for hook
add_action( 'my-awesome-hook', 'growdev_handle_hook' );

/**
 * Handle the hook to do the check
 */
function growdev_handle_hook(){
	// do things...
}

The add action connects the hook to the callback function. Add code inside the callback to handle the daily task.

Conclusion

Understanding how the Action Scheduler works is a super useful tool to have in your toolbox. The action scheduler is very helpful for spreading out bulk tasks, scheduling tasks to happen at a specific time in the future, or recurring tasks. As I have shown the library can provide a unis cron equivalent in your WooCommerce store.

If you have an understanding of the API functions for using the library it comes in handy when you have scheduled tasks to manage or a large number of updates to separate into smaller blocks.

Happy coding!