Files
2025-08-02 16:30:27 +02:00

294 lines
7.7 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\SynchronizationBundle\Synchronization;
class Job
{
public string $id;
public string $cronExpression = '*/20 * * * *';
/** Max execution time in minutes. Defaults to 30 minutes. */
public ?int $maxExecutionTime = 30;
public function __construct(
public string $name,
public \Closure $fn,
public int $priority = 0,
public ?\Closure $truthTest = null,
public ?string $description = null,
public readonly bool $enableManualRun = true,
) {
$this->id = md5($this->name);
}
public static function create(string $name, callable $fn, int $priority = 0, ?string $description = null, bool $enableManualRun = true): self
{
return new static($name, $fn, $priority, description: $description, enableManualRun: $enableManualRun);
}
/**
* Sets max execution time of job in minutes.
*/
public function setMaxExecutionTime(?int $maxExecutionTime): self
{
$this->maxExecutionTime = $maxExecutionTime;
return $this;
}
public function when(callable $fn): self
{
$this->truthTest = $fn;
return $this;
}
public function at($expression)
{
$this->cronExpression = $expression;
return $this;
}
/**
* Set the execution time to every minute.
*/
public function everyMinute(?int $minute = null): self
{
$minuteExpression = '*';
if ($minute !== null) {
$c = $this->validateCronSequence($minute);
$minuteExpression = '*/'.$c['minute'];
}
return $this->at($minuteExpression.' * * * *');
}
/**
* Set the execution time to every hour.
*/
public function hourly(int $minute = 0): self
{
$c = $this->validateCronSequence($minute);
return $this->at("{$c['minute']} * * * *");
}
/**
* Set the execution time to once a day.
*/
public function daily(int $hour = 0, int $minute = 0): self
{
$c = $this->validateCronSequence($minute, $hour);
return $this->at("{$c['minute']} {$c['hour']} * * *");
}
/**
* Set the execution time to once a week.
*/
public function weekly(int $weekday = 0, int $hour = 0, int $minute = 0): self
{
$c = $this->validateCronSequence($minute, $hour, null, null, $weekday);
return $this->at("{$c['minute']} {$c['hour']} * * {$c['weekday']}");
}
/**
* Set the execution time to once a month.
*/
public function monthly(int|string $month = '*', int $day = 1, int $hour = 0, int $minute = 0): self
{
$c = $this->validateCronSequence($minute, $hour, $day, $month);
return $this->at("{$c['minute']} {$c['hour']} {$c['day']} {$c['month']} *");
}
/**
* Set the execution time to every Sunday.
*/
public function sunday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(0, $hour, $minute);
}
/**
* Set the execution time to every Monday.
*/
public function monday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(1, $hour, $minute);
}
/**
* Set the execution time to every Tuesday.
*/
public function tuesday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(2, $hour, $minute);
}
/**
* Set the execution time to every Wednesday.
*/
public function wednesday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(3, $hour, $minute);
}
/**
* Set the execution time to every Thursday.
*/
public function thursday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(4, $hour, $minute);
}
/**
* Set the execution time to every Friday.
*/
public function friday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(5, $hour, $minute);
}
/**
* Set the execution time to every Saturday.
*/
public function saturday(int $hour = 0, int $minute = 0): self
{
return $this->weekly(6, $hour, $minute);
}
/**
* Set the execution time to every January.
*/
public function january(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(1, $day, $hour, $minute);
}
/**
* Set the execution time to every February.
*/
public function february(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(2, $day, $hour, $minute);
}
/**
* Set the execution time to every March.
*/
public function march(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(3, $day, $hour, $minute);
}
/**
* Set the execution time to every April.
*/
public function april(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(4, $day, $hour, $minute);
}
/**
* Set the execution time to every May.
*/
public function may(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(5, $day, $hour, $minute);
}
/**
* Set the execution time to every June.
*/
public function june(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(6, $day, $hour, $minute);
}
/**
* Set the execution time to every July.
*/
public function july(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(7, $day, $hour, $minute);
}
/**
* Set the execution time to every August.
*/
public function august(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(8, $day, $hour, $minute);
}
/**
* Set the execution time to every September.
*/
public function september(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(9, $day, $hour, $minute);
}
/**
* Set the execution time to every October.
*/
public function october(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(10, $day, $hour, $minute);
}
/**
* Set the execution time to every November.
*/
public function november(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(11, $day, $hour, $minute);
}
/**
* Set the execution time to every December.
*/
public function december(int $day = 1, int $hour = 0, int $minute = 0): self
{
return $this->monthly(12, $day, $hour, $minute);
}
/**
* Validate sequence of cron expression.
*/
private function validateCronSequence(?int $minute = null, ?int $hour = null, ?int $day = null, int|string|null $month = null, ?int $weekday = null): array
{
return [
'minute' => $this->validateCronRange($minute, 0, 59),
'hour' => $this->validateCronRange($hour, 0, 23),
'day' => $this->validateCronRange($day, 1, 31),
'month' => $this->validateCronRange($month, 1, 12),
'weekday' => $this->validateCronRange($weekday, 0, 6),
];
}
/**
* Validate sequence of cron expression.
*/
private function validateCronRange(int|string|null $value, int $min, int $max): int|string
{
if ($value === null || $value === '*') {
return '*';
}
if (!is_numeric($value)
|| !($value >= $min && $value <= $max)
) {
throw new \InvalidArgumentException(
"Invalid value: it should be '*' or between {$min} and {$max}."
);
}
return (int) $value;
}
}