Skip to content

Cron Jobs

Miguel Muscat edited this page Nov 30, 2022 · 1 revision

Cron jobs are scheduled events that trigger actions at a specific time.

Creating a Cron Job

Cron jobs can be created using the constructor. The only required argument is the name of the action hook to trigger.

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook');

You can optionally provide a list of arguments, that will be passed to the action hook handlers:

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook', ['arg1', 'arg2']);

add_action('my_action_hook', function ($arg1, $arg2) {
    // Do something
}, 10, 2);

A recurrence schedule can be provided to create a repeating cron job. This must be the name of a registered WordPress cron schedule. Refer to the WordPress Codex pages on the wp_get_schedules() function and the cron_schedules filter for more information.

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook', [], 'hourly');

Lastly, you may provide a list of handlers to be attached to the action hook. These handlers can be automatically registered to the cron job's action hook. The next section will explain this in greater detail.

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook', ['arg'], null, [
    function ($arg) {
        // Do something
    },
    function ($arg) {
        // Do something else
    },
]);

Scheduling a Cron Job

You can schedule cron jobs in two ways, depending on your requirements.

Fire and forget

If your cron job is scheduled only under certain conditions, you can simply use the schedule() method:

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook', ['arg1'], 'hourly');

// Schedule to run as soon as possible
$job->schedule();

// Schedule to run in an hour
$job->schedule(time() + 3600);

// Schedule to run ASAP, and add more args
$job->schedule(null, ['arg2']);

You will also need to register the cron job's handlers, if it has any. This can be done using the registerHandlers().

$job->registerHandlers();

Note: If the cron job is registered to the WordPress module's cron_jobs list, then the handlers will be automatically registered for you. You only need to call registerHandlers() if you are not using the WordPress module.

Ensure it is always scheduled

If your cron job needs to always be scheduled, rather than being scheduled under certain conditions, you can use the CronJob::ensureScheduled() method.

use RebelCode\WpSdk\Wp\CronJob;

$job = new CronJob('my_action_hook', [], 'hourly');
$job->ensureScheduled();

This will also automatically register the cron job's handlers, if it has any. You should not call registerHandlers() yourself when using this method.

Un-scheduling a Cron Job

To remove a cron job's scheduled event, simply call the unschedule() method:

$didUnschedule = $job->unschedule();

It is safe to call this method when the cron job is not scheduled yet. The method will return a boolean that indicates if the cron job was unscheduled or not. If it was not already scheduled, the method will return false.

Alternatively, you can use the isScheduled() method to determine if the cron job is scheduled beforehand.

Getting the scheduled event

You can obtain the cron job's currently scheduled event using the getScheduledEvent() method:

$event = $job->getScheduledEvent();
// {
//   hook: "my_action_hook",
//   timestamp: 1234567890,
//   schedule: "hourly",
//   args: ["arg"],
// }

This will return an object with information about the scheduled event, or null if the cron job is not scheduled.

For more information about the returned object, refer to the WordPress Codex page for the wp_get_scheduled_event function.

Services

Cron job services can be easily created using the CronJob::factory() static method:

use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Wp\CronJob;
use Dhii\Services\Factories\FuncService;

class MyModule extends Module
{
    public function getFactories() : array
    {
        return [
            'my_cron_job' => CronJob::factory('my_action_hook', [], 'hourly', [
                'my_cron_job/handler_1',
                'my_cron_job/handler_2',
            ]),
            'my_cron_job/handler_1' => new FuncService([], function () {}),
            'my_cron_job/handler_1' => new FuncService([], function () {}),
        ];
    }
}

Note that the CronJob::factory() static method takes similar arguments to the CronJob constructor, except that the handlers are specified as service IDs, rather than callback functions.

Examples

Example 1 - Schedule a cron job on user action

In this example, we create and schedule a fire-and-forget cron job when a post is deleted.

use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Wp\CronJob;
use Dhii\Services\Factories\FuncService;
use RebelCode\WpSdk\Handler;
use Dhii\Services\Extensions\ArrayExtension;

class MyModule extends Module
{
    public function getHooks(): array
    {
        return [
            'delete_post' => [
                // Add a handler to schedule our cron job when a post is deleted
                new Handler(['my_cron'], function (int $id, \WP_Post $post, CronJob $job) {
                    $job->schedule();
                }),
            ],
        ];
    }

    public function getFactories() : array
    {
        return [
            'my_cron' => CronJob::factory('my_action', [], 'hourly', [
                'my_handler',
            ]),

            'my_handler' => new FuncService([], function () {}),
        ];
    }
    
    public function getExtensions() : array
    {
        return [
            // Add our cron job to the WordPress module to automatically register its handlers
            'wp/cron_jobs' => new ArrayExtension(['my_cron']),
        ];
    }
}

Example 2 - Ensure a cron job always exists

In this example, we create a cron job that must always be scheduled.

use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Wp\CronJob;
use Dhii\Services\Factories\FuncService;
use RebelCode\WpSdk\Handler;
use Dhii\Services\Extensions\ArrayExtension;
use Psr\Container\ContainerInterface;

class MyModule extends Module
{
    public function run(ContainerInterface $c) : void
    {
        // We run this on every request, so that the cron job is always scheduled
        $c->get('my_cron')->ensureScheduled();
    }

    public function getFactories() : array
    {
        return [
            'my_cron' => CronJob::factory('my_action', [], 'hourly', [
                'my_handler',
            ]),

            'my_handler' => new FuncService([], function () {}),
        ];
    }
    
    public function getExtensions() : array
    {
        return [
            // Add our cron job to the WordPress module to automatically register its handlers
            'wp/cron_jobs' => new ArrayExtension(['my_cron']),
        ];
    }
}

Clone this wiki locally