diff --git a/src/Symfony/Component/Scheduler/CHANGELOG.md b/src/Symfony/Component/Scheduler/CHANGELOG.md index a2b7fd057ed1d..982658a2bfafa 100644 --- a/src/Symfony/Component/Scheduler/CHANGELOG.md +++ b/src/Symfony/Component/Scheduler/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Allow setting timezone of next run date in CronExpressionTrigger + * Add `AbstractTriggerDecorator` 6.3 --- diff --git a/src/Symfony/Component/Scheduler/Tests/Trigger/AbstractDecoratedTriggerTest.php b/src/Symfony/Component/Scheduler/Tests/Trigger/AbstractDecoratedTriggerTest.php new file mode 100644 index 0000000000000..331b43be845a2 --- /dev/null +++ b/src/Symfony/Component/Scheduler/Tests/Trigger/AbstractDecoratedTriggerTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Scheduler\Tests\Trigger; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Scheduler\Trigger\ExcludeTimeTrigger; +use Symfony\Component\Scheduler\Trigger\JitterTrigger; +use Symfony\Component\Scheduler\Trigger\TriggerInterface; + +class AbstractDecoratedTriggerTest extends TestCase +{ + public function testCanGetInnerTrigger() + { + $trigger = new JitterTrigger($inner = $this->createMock(TriggerInterface::class)); + + $this->assertSame($inner, $trigger->inner()); + $this->assertSame([$trigger], iterator_to_array($trigger->decorators())); + } + + public function testCanGetNestedInnerTrigger() + { + $trigger = new ExcludeTimeTrigger( + $jitter = new JitterTrigger($inner = $this->createMock(TriggerInterface::class)), + new \DateTimeImmutable(), + new \DateTimeImmutable(), + ); + + $this->assertSame($inner, $trigger->inner()); + $this->assertSame([$trigger, $jitter], iterator_to_array($trigger->decorators())); + } +} diff --git a/src/Symfony/Component/Scheduler/Trigger/AbstractDecoratedTrigger.php b/src/Symfony/Component/Scheduler/Trigger/AbstractDecoratedTrigger.php new file mode 100644 index 0000000000000..8ba5047a664d3 --- /dev/null +++ b/src/Symfony/Component/Scheduler/Trigger/AbstractDecoratedTrigger.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Scheduler\Trigger; + +/** + * @author Kevin Bond + */ +abstract class AbstractDecoratedTrigger implements TriggerInterface +{ + public function __construct(private TriggerInterface $inner) + { + } + + final public function inner(): TriggerInterface + { + $inner = $this->inner; + + while ($inner instanceof self) { + $inner = $inner->inner; + } + + return $inner; + } + + /** + * @return \Traversable + */ + final public function decorators(): \Traversable + { + yield $this; + + $inner = $this->inner; + + while ($inner instanceof self) { + yield $inner; + + $inner = $inner->inner; + } + } +} diff --git a/src/Symfony/Component/Scheduler/Trigger/ExcludeTimeTrigger.php b/src/Symfony/Component/Scheduler/Trigger/ExcludeTimeTrigger.php index 619d3dccb9618..f76275ab01dcf 100644 --- a/src/Symfony/Component/Scheduler/Trigger/ExcludeTimeTrigger.php +++ b/src/Symfony/Component/Scheduler/Trigger/ExcludeTimeTrigger.php @@ -14,13 +14,14 @@ /** * @experimental */ -final class ExcludeTimeTrigger implements TriggerInterface +final class ExcludeTimeTrigger extends AbstractDecoratedTrigger { public function __construct( private readonly TriggerInterface $inner, private readonly \DateTimeImmutable $from, private readonly \DateTimeImmutable $until, ) { + parent::__construct($inner); } public function __toString(): string diff --git a/src/Symfony/Component/Scheduler/Trigger/JitterTrigger.php b/src/Symfony/Component/Scheduler/Trigger/JitterTrigger.php index 639c490c12070..a63c026fbc0cd 100644 --- a/src/Symfony/Component/Scheduler/Trigger/JitterTrigger.php +++ b/src/Symfony/Component/Scheduler/Trigger/JitterTrigger.php @@ -14,13 +14,14 @@ /** * @author Kevin Bond */ -final class JitterTrigger implements TriggerInterface +final class JitterTrigger extends AbstractDecoratedTrigger { /** * @param positive-int $maxSeconds */ public function __construct(private readonly TriggerInterface $trigger, private readonly int $maxSeconds = 60) { + parent::__construct($trigger); } public function __toString(): string diff --git a/src/Symfony/Component/Scheduler/Trigger/PeriodicalTrigger.php b/src/Symfony/Component/Scheduler/Trigger/PeriodicalTrigger.php index b7241c5c35be8..c02315bed1a55 100644 --- a/src/Symfony/Component/Scheduler/Trigger/PeriodicalTrigger.php +++ b/src/Symfony/Component/Scheduler/Trigger/PeriodicalTrigger.php @@ -16,7 +16,7 @@ /** * @experimental */ -class PeriodicalTrigger implements TriggerInterface, \Stringable +class PeriodicalTrigger implements TriggerInterface { private float $intervalInSeconds = 0.0; private \DateTimeImmutable $from;