Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define a different timezone for scheduled tasks #98

Merged
merged 2 commits into from
Mar 22, 2025
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ Execute scheduled commands.

**Run a specific scheduled command :** php bin/console synolia:scheduler-run --id=5

Is it possible to choose the timezone of the command execution by setting the `SYNOLIA_SCHEDULER_PLUGIN_TIMEZONE` environment variable, example:

```
SYNOLIA_SCHEDULER_PLUGIN_TIMEZONE=Europe/Paris
```

### synolia:scheduler:purge-history

Purge scheduled command history greater than {X} days old.
Expand Down
11 changes: 11 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,14 @@
* `logFile` field must be renamed to `logFilePrefix` and must not end with the file extension

Also, for old existing schedules in your database, please remove the log file extension in column `logFilePrefix`.

## from 3.8 to 3.9

* The constructors of `Synolia\SyliusSchedulerCommandPlugin\Checker\EveryMinuteIsDueChecker` and `Synolia\SyliusSchedulerCommandPlugin\Checker\SoftLimitThresholdIsDueChecker` has been modified, a new argument has been added :

```php
public function __construct(
// ...
private ?DateTimeProviderInterface $dateTimeProvider = null,
)
```
17 changes: 16 additions & 1 deletion src/Checker/EveryMinuteIsDueChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Synolia\SyliusSchedulerCommandPlugin\Checker;

use Cron\CronExpression;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Synolia\SyliusSchedulerCommandPlugin\Components\Exceptions\Checker\IsNotDueException;
use Synolia\SyliusSchedulerCommandPlugin\Entity\CommandInterface;
Expand All @@ -17,6 +18,20 @@ class EveryMinuteIsDueChecker implements IsDueCheckerInterface
{
private const PRIORITY = 0;

public function __construct(
private readonly ?DateTimeProviderInterface $dateTimeProvider = null,
) {
if (!$dateTimeProvider instanceof DateTimeProviderInterface) {
trigger_deprecation(
'synolia/sylius-scheduler-command-plugin',
'3.9',
'Not passing a service that implements "%s" as a 1st argument of "%s" constructor is deprecated and will be prohibited in 4.0.',
DateTimeProviderInterface::class,
self::class,
);
}
}

public static function getDefaultPriority(): int
{
return self::PRIORITY;
Expand All @@ -28,7 +43,7 @@ public static function getDefaultPriority(): int
public function isDue(CommandInterface $command, ?\DateTimeInterface $dateTime = null): bool
{
if (!$dateTime instanceof \DateTimeInterface) {
$dateTime = new \DateTime();
$dateTime = $this->dateTimeProvider?->now() ?? new \DateTime();
}

$cron = new CronExpression($command->getCronExpression());
Expand Down
13 changes: 12 additions & 1 deletion src/Checker/SoftLimitThresholdIsDueChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Synolia\SyliusSchedulerCommandPlugin\Checker;

use Cron\CronExpression;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Synolia\SyliusSchedulerCommandPlugin\Components\Exceptions\Checker\IsNotDueException;
use Synolia\SyliusSchedulerCommandPlugin\Entity\CommandInterface;
Expand All @@ -22,11 +23,21 @@ public static function getDefaultPriority(): int

public function __construct(
private readonly ScheduledCommandRepositoryInterface $scheduledCommandRepository,
private readonly ?DateTimeProviderInterface $dateTimeProvider = null,
/**
* Threshold in minutes
*/
private readonly int $threshold = 5,
) {
if (!$dateTimeProvider instanceof DateTimeProviderInterface) {
trigger_deprecation(
'synolia/sylius-scheduler-command-plugin',
'3.9',
'Not passing a service that implements "%s" as a 1st argument of "%s" constructor is deprecated and will be prohibited in 4.0.',
DateTimeProviderInterface::class,
self::class,
);
}
}

/**
Expand All @@ -35,7 +46,7 @@ public function __construct(
public function isDue(CommandInterface $command, ?\DateTimeInterface $dateTime = null): bool
{
if (!$dateTime instanceof \DateTimeInterface) {
$dateTime = new \DateTime();
$dateTime = $this->dateTimeProvider?->now() ?? new \DateTime();
}

$cron = new CronExpression($command->getCronExpression());
Expand Down
32 changes: 32 additions & 0 deletions src/Provider/CalendarWithTimezone.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Synolia\SyliusSchedulerCommandPlugin\Provider;

use DateTimeImmutable;
use DateTimeZone;
use Exception;
use Sylius\Calendar\Provider\DateTimeProviderInterface;
use Symfony\Component\DependencyInjection\Attribute\AsAlias;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

#[AsAlias(DateTimeProviderInterface::class)]
final class CalendarWithTimezone implements DateTimeProviderInterface
{
public function __construct(
#[Autowire(param: 'env(SYNOLIA_SCHEDULER_PLUGIN_TIMEZONE)')]
private ?string $timezone = null,
) {
}

/**
* @throws Exception
*/
public function now(): \DateTimeInterface
{
$timezone = $this->timezone ?? date_default_timezone_get();

return new DateTimeImmutable(timezone: new DateTimeZone($timezone));
}
}
1 change: 1 addition & 0 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ parameters:
env(SYNOLIA_SCHEDULER_PLUGIN_KEEP_ALIVE): true
env(SYNOLIA_SCHEDULER_PLUGIN_LOGS_DIR): '%kernel.logs_dir%'
env(SYNOLIA_SCHEDULER_PLUGIN_TIMEFORMAT_24H): false
env(SYNOLIA_SCHEDULER_PLUGIN_TIMEZONE): ~

services:
_defaults:
Expand Down
11 changes: 9 additions & 2 deletions tests/PHPUnit/Checker/EveryMinuteIsDueCheckerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@

class EveryMinuteIsDueCheckerTest extends AbstractIsDueTestCase
{
private EveryMinuteIsDueChecker $everyMinuteIsDueChecker;

public function setUp(): void
{
parent::setUp();
$this->everyMinuteIsDueChecker = static::getContainer()->get(EveryMinuteIsDueChecker::class);
}

/**
* @dataProvider isDueUsingCronExpressionDataProvider
*/
Expand All @@ -18,13 +26,12 @@ public function testIsDue(
\DateTimeInterface $currentDateTime,
bool $expectedResult,
): void {
$checker = new EveryMinuteIsDueChecker();
$command = $this->setupCommand($cronExpression);

if ($expectedResult === false) {
$this->expectException(IsNotDueException::class);
}

$this->assertEquals($expectedResult, $checker->isDue($command, $currentDateTime));
$this->assertEquals($expectedResult, $this->everyMinuteIsDueChecker->isDue($command, $currentDateTime));
}
}
Loading