PHP code example of jardissupport / scheduling

1. Go to this page and download the library: Download jardissupport/scheduling library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

jardissupport / scheduling example snippets


use JardisSupport\Scheduling\Schedule;

$schedule = Schedule::create()
    ->task('cleanup:expired')
        ->dailyAt('03:00')
        ->description('Remove expired records')
        ->tag('maintenance')
        ->priority(10)
    ->task('sync:inventory')
        ->everyFiveMinutes()
        ->between('08:00', '18:00')
        ->weekdays()
        ->tag('sync', 'erp')
        ->withoutOverlapping()
    ->task('report:monthly')
        ->monthlyOn(1, '07:00')
        ->timezone('Europe/Berlin')
        ->tag('reports');

$now = new DateTimeImmutable();

// All due tasks (sorted by priority, highest first)
foreach ($schedule->dueNow($now) as $task) {
    echo $task->name();        // 'cleanup:expired'
    echo $task->description(); // 'Remove expired records'
    // Dispatch however you want — command bus, queue, subprocess
}

// Filter by tags
$syncTasks = $schedule->dueNow($now, ['sync']);

use JardisSupport\Scheduling\CronExpression;

$cron = CronExpression::parse('*/5 9-17 * * 1-5');

$cron->isDue($now);              // true/false
$cron->nextRun($now);            // next matching DateTimeInterface
$cron->nextRuns($now, 5);        // next 5 matching times
$cron->previousRun($now);        // last matching DateTimeInterface
$cron->describe();               // 'Every 5 minutes', 'Daily at 09:30', etc.

$cron = CronExpression::parse('0 8 * * *', new DateTimeZone('Europe/Berlin'));

// Evaluates against Berlin time, regardless of server timezone
$cron->isDue(new DateTimeImmutable('now', new DateTimeZone('UTC'))); 

->task('api:sync')
    ->everyFiveMinutes()
    ->between('08:00', '20:00')       // only during this window

->task('db:optimize')
    ->daily()
    ->unlessBetween('09:00', '17:00') // not during business hours

->task('erp:sync')
    ->hourly()
    ->weekdays()                      // Mon-Fri only

->task('backup:full')
    ->dailyAt('01:00')
    ->weekends()                      // Sat-Sun only

->task('supplier:import')
    ->dailyAt('06:00')
    ->days(2, 4)                      // Tue and Thu only (0=Sun, 6=Sat)

->task('beta:sync')
    ->everyFiveMinutes()
    ->when(fn() => $features->isEnabled('new-sync'))   // only if true

->task('cache:warmup')
    ->everyMinute()
    ->skip(fn() => $maintenance->isActive())           // skip if true

$schedule = Schedule::create('production')  // pass current environment
    ->task('monitor:uptime')
        ->everyMinute()
        ->environments('production', 'staging');

->task('email:digest')
    ->dailyAt('08:00')
    ->tag('email', 'notifications')

// Query filtered
$schedule->dueNow($now, ['email']);     // only tasks tagged 'email'
$schedule->allTasks(['notifications']); // only tasks tagged 'notifications'

->task('critical:alerts')
    ->everyMinute()
    ->priority(100)

->task('low:cleanup')
    ->everyMinute()
    ->priority(1)

// dueNow() and allTasks() return tasks sorted by priority (descending)

->task('import:large')
    ->everyFiveMinutes()
    ->withoutOverlapping()

// Check in your runner:
if (!$task->allowsOverlapping()) {
    // Acquire lock before executing
}

CronExpression::parse('* * * * *')->describe();      // 'Every minute'
CronExpression::parse('*/5 * * * *')->describe();     // 'Every 5 minutes'
CronExpression::parse('30 9 * * *')->describe();      // 'Daily at 09:30'
CronExpression::parse('0 9 * * 1')->describe();       // 'Weekly on Monday at 09:00'
CronExpression::parse('0 6 1 * *')->describe();       // 'Monthly on day 1 at 06:00'
CronExpression::parse('0 9-17 * * 1-5')->describe();  // 'Custom schedule'

$cron = CronExpression::parse('0 8 * * *');
$previous = $cron->previousRun(new DateTimeImmutable('2026-04-05 10:00:00'));
// 2026-04-05 08:00:00

$violations = $schedule->validate();

foreach ($violations as $violation) {
    echo $violation->severity;  // 'error' or 'warning'
    echo $violation->taskName;
    echo $violation->message;
}

// All registered tasks (sorted by priority)
foreach ($schedule->allTasks() as $task) {
    echo $task->name();
    echo $task->description();
    echo $task->expression()->describe();
    echo $task->nextRun(new DateTimeImmutable())->format('Y-m-d H:i');
    echo $task->priority();
    echo $task->allowsOverlapping() ? 'yes' : 'no';
    echo implode(', ', $task->tags());
}

// Filter by tags
$emailTasks = $schedule->allTasks(['email']);

use JardisSupport\Scheduling\Exception\InvalidCronExpressionException;

try {
    CronExpression::parse('invalid');
} catch (InvalidCronExpressionException $e) {
    // "Invalid cron expression: "invalid" (Expected 5-7 fields, got 1)"
}

// In your BoundedContext or Application Service:
$schedule = Schedule::create()
    ->task('order:cleanup')->dailyAt('03:00')
    ->task('invoice:generate')->monthlyOn(1, '06:00');

// Runner (CLI Command, Cron Job):
foreach ($schedule->dueNow(new DateTimeImmutable()) as $task) {
    $this->commandBus->dispatch($task->name());
}