294 lines
7.7 KiB
PHP
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;
|
|
}
|
|
}
|