Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions example/01-run-due-jobs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
use Gt\Cron\CrontabParser;
use Gt\Cron\ExpressionFactory;
use Gt\Cron\JobRepository;
use Gt\Cron\Queue;
use Gt\Cron\ScriptOutputMode;

chdir(dirname(__DIR__));
require "vendor/autoload.php";

$now = new DateTime("2026-03-11 12:25:00");
$crontab = <<<'CRON'
10 * * * * printf 'This is not due at 12:25.\n'
25 * * * * printf 'This runs at 25 past the hour.\n'
*/5 * * * * printf 'This runs every five minutes.\n'
CRON;

echo "Current time: " . $now->format("Y-m-d H:i:s") . PHP_EOL;
echo "Crontab:" . PHP_EOL;
echo $crontab . PHP_EOL . PHP_EOL;

$queue = new Queue($now);
$crontabParser = new CrontabParser(new ExpressionFactory());
$jobRepository = new JobRepository(ScriptOutputMode::INHERIT);
$crontabParser->parseIntoQueue($crontab, $queue, $jobRepository);

echo "Command output:" . PHP_EOL;
$runCommandList = $queue->runDueJobsAndGetCommands();
echo "Jobs ran: " . count($runCommandList) . PHP_EOL;
31 changes: 31 additions & 0 deletions example/02-next-job.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
use Gt\Cron\CrontabParser;
use Gt\Cron\ExpressionFactory;
use Gt\Cron\JobRepository;
use Gt\Cron\Queue;
use Gt\Cron\ScriptOutputMode;

chdir(dirname(__DIR__));
require "vendor/autoload.php";

$now = new DateTime("2026-03-11 12:25:00");
$crontab = <<<'CRON'
25 * * * * printf 'Generate report.\n'
30 * * * * printf 'Warm cache.\n'
0 13 * * * printf 'Send lunchtime digest.\n'
CRON;

$queue = new Queue($now);
$crontabParser = new CrontabParser(new ExpressionFactory());
$jobRepository = new JobRepository(ScriptOutputMode::INHERIT);
$crontabParser->parseIntoQueue($crontab, $queue, $jobRepository);

echo "Current time: " . $now->format("Y-m-d H:i:s") . PHP_EOL;
echo "Crontab:" . PHP_EOL;
echo $crontab . PHP_EOL . PHP_EOL;

echo "Command output:" . PHP_EOL;
$queue->runDueJobsAndGetCommands();

echo "Next job: " . $queue->timeOfNextJob()?->format("Y-m-d H:i:s") . PHP_EOL;
echo "Next command: " . $queue->commandOfNextJob() . PHP_EOL;
31 changes: 31 additions & 0 deletions example/03-nickname-expressions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
use Gt\Cron\CrontabParser;
use Gt\Cron\ExpressionFactory;
use Gt\Cron\JobRepository;
use Gt\Cron\Queue;
use Gt\Cron\ScriptOutputMode;

chdir(dirname(__DIR__));
require "vendor/autoload.php";

$now = new DateTime("2026-03-11 13:00:00");
$crontab = <<<'CRON'
# Nicknames are accepted as a single schedule token.
@hourly printf 'Hourly job fired.\n'
@daily printf 'Daily job is not due yet.\n'
CRON;

$queue = new Queue($now);
$crontabParser = new CrontabParser(new ExpressionFactory());
$jobRepository = new JobRepository(ScriptOutputMode::INHERIT);
$crontabParser->parseIntoQueue($crontab, $queue, $jobRepository);

echo "Current time: " . $now->format("Y-m-d H:i:s") . PHP_EOL;
echo "Crontab:" . PHP_EOL;
echo $crontab . PHP_EOL . PHP_EOL;

echo "Command output:" . PHP_EOL;
$runCommandList = $queue->runDueJobsAndGetCommands();
echo "Commands due right now: " . implode(", ", $runCommandList) . PHP_EOL;
echo "Next job: " . $queue->timeOfNextJob()?->format("Y-m-d H:i:s") . PHP_EOL;
echo "Next command: " . $queue->commandOfNextJob() . PHP_EOL;
49 changes: 49 additions & 0 deletions example/04-custom-expression-factory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
use Gt\Cron\CrontabParser;
use Gt\Cron\CronExpression;
use Gt\Cron\Expression;
use Gt\Cron\ExpressionFactory;
use Gt\Cron\JobRepository;
use Gt\Cron\Queue;
use Gt\Cron\ScriptOutputMode;

chdir(dirname(__DIR__));
require "vendor/autoload.php";

$customExpressionFactory = new class extends ExpressionFactory {
public function create(string $expression):Expression {
if($expression === "@start") {
return new class implements Expression {
public function isDue(DateTime $now):bool {
return true;
}

public function getNextRunDate(?DateTime $now = null):DateTime {
return clone ($now ?? new DateTime());
}
};
}

return new CronExpression($expression);
}
};

$now = new DateTime("2026-03-11 12:25:00");
$crontab = <<<'CRON'
@start printf 'This runs once when the runner starts.\n'
30 * * * * printf 'This is a normal cron schedule.\n'
CRON;

echo "Current time: " . $now->format("Y-m-d H:i:s") . PHP_EOL;
echo "Crontab:" . PHP_EOL;
echo $crontab . PHP_EOL . PHP_EOL;
echo "This example injects a custom ExpressionFactory to handle @start." . PHP_EOL;
echo "Command output:" . PHP_EOL;

$queue = new Queue($now);
$jobRepository = new JobRepository(ScriptOutputMode::INHERIT);
(new CrontabParser($customExpressionFactory))
->parseIntoQueue($crontab, $queue, $jobRepository);

$runCommandList = $queue->runDueJobsAndGetCommands();
echo "Jobs ran: " . count($runCommandList) . PHP_EOL;
12 changes: 12 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Examples

Run each example from the project root with `php`:

```bash
php example/01-run-due-jobs.php
php example/02-next-job.php
php example/03-nickname-expressions.php
php example/04-custom-expression-factory.php
```

Each script embeds its own crontab string so you can read the schedule and the code together.
40 changes: 40 additions & 0 deletions src/FunctionCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
namespace Gt\Cron;

class FunctionCommand {
public function isCallable(string $command):bool {
$callable = $this->callableName($command);
return str_contains($callable, "::") || is_callable($callable);
}

public function execute(string $command):void {
$callableName = $this->callableName($command);
$callable = explode("::", $callableName);
if(!is_callable($callable)) {
throw new FunctionExecutionException($callableName);
}

call_user_func_array($callable, $this->arguments($command));
}

protected function callableName(string $command):string {
$bracketPos = strpos($command, "(");
if($bracketPos === false) {
return trim($command);
}

return trim(substr($command, 0, $bracketPos));
}

/** @return array<int, string> */
protected function arguments(string $command):array {
$bracketPos = strpos($command, "(");
if($bracketPos === false) {
return [];
}

$argsString = substr($command, $bracketPos);
$argsString = trim($argsString, " ();");
return str_getcsv($argsString, ",", "\"", "\\");
}
}
Loading
Loading