Overview
Architecture
WPZylos Scheduler provides a fluent task scheduling layer on top of WordPress's WP-Cron system. It follows a registry pattern where a central Schedule object manages a collection of ScheduledTask instances.
Component Diagram
┌──────────────────────────────────────────────────────────┐
| SchedulerServiceProvider |
| - Registers Schedule singleton |
| - Hooks into WP-Cron (every-minute interval) |
| - Runs due tasks on cron trigger |
+--──────────────────────┬─────────────────────────────────┘
|
▼
┌──────────────────────────────────────────────────────────┐
| Schedule |
| - call(callable): ScheduledTask |
| - command(string): ScheduledTask |
| - job(string): ScheduledTask |
| - getTasks(): ScheduledTask[] |
| - getDueTasks(): ScheduledTask[] |
| - run(): int |
+--──────────────────────┬─────────────────────────────────┘
| manages
▼
┌──────────────────────────────────────────────────────────┐
| ScheduledTask |
| uses: Frequencies, ManagesLocks |
| - name(), when(), skip(), between(), onOneServer() |
| - isDue(): bool |
| - run(): void |
+--────────┬───────────────────────────────┬───────────────┘
| |
▼ ▼
┌─────────────────────┐ ┌──────────────────────────────┐
| Frequencies | | ManagesLocks |
| everyMinute() | | withoutOverlapping() |
| everyFiveMinutes() | | acquireLock() / releaseLock |
| hourly() / daily() | | (uses WP transients) |
| weekly() / monthly() | +--────────────────────────────┘
+--───────────────────┘
Design Patterns
Registry Pattern
The Schedule class acts as a registry, collecting all task definitions. Tasks are registered via call(), command(), and job() methods, each returning a ScheduledTask for fluent configuration.
Fluent Interface
Every configuration method on ScheduledTask returns static, enabling natural chaining:
$schedule->call($callback)
->everyFiveMinutes()
->name('my-task')
->withoutOverlapping()
->between('09:00', '17:00')
->when(fn() => is_main_site());
Trait Composition
Scheduling concerns are split into focused traits:
- Frequencies — All time-based frequency methods and interval tracking
- ManagesLocks — Transient-based overlap prevention logic
Strategy Pattern
The ScheduledTask::run() method uses a match expression to execute the appropriate strategy based on task type (callback, command, job).
How It Works
- Registration — The
SchedulerServiceProviderregisters aSchedulesingleton in the container - Cron Hook — A custom
every_minutecron schedule is added viacron_schedulesfilter - Execution — On each WP-Cron tick, the provider resolves the
Scheduleand callsrun() - Due Check —
run()iterates all tasks, callingisDue()on each to check time/condition constraints - Lock Check — If
withoutOverlapping()is enabled, a transient lock is checked before execution - Task Run — The task executes based on its type: closure call, WP-CLI command, or job dispatch
Integration with WP-Cron
The scheduler hooks into WordPress's native cron system:
// 1. Register a custom every-minute interval
add_filter('cron_schedules', function ($schedules) {
$schedules['wpzylos_every_minute'] = [
'interval' => 60,
'display' => 'Every Minute',
];
return $schedules;
});
// 2. Schedule the recurring event
wp_schedule_event(time(), 'wpzylos_every_minute', 'wpzylos_run_scheduler');
// 3. Run due tasks on the cron action
add_action('wpzylos_run_scheduler', function () use ($app) {
$app->make(Schedule::class)->run();
});
Note: For production reliability, configure a system-level cron job to hit
wp-cron.phpevery minute and disable WordPress's default "on-request" cron withdefine('DISABLE_WP_CRON', true);.