8000 Normalize `TriggerInterface` as `string` · symfony/symfony@20f676a · GitHub
[go: up one dir, main page]

Skip to content

Commit 20f676a

Browse files
committed
Normalize TriggerInterface as string
1 parent 54b61d4 commit 20f676a

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/scheduler.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Scheduler\EventListener\DispatchSchedulerEventListener;
1515
use Symfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
16+
use Symfony\Component\Scheduler\Messenger\Serializer\Normalizer\SchedulerTriggerNormalizer;
1617
use Symfony\Component\Scheduler\Messenger\ServiceCallMessageHandler;
1718

1819
return static function (ContainerConfigurator $container) {
@@ -34,5 +35,7 @@
3435
service('event_dispatcher'),
3536
])
3637
->tag('kernel.event_subscriber')
38+
->set('serializer.normalizer.scheduler_trigger', SchedulerTriggerNormalizer::class)
39+
->tag('serializer.normalizer', ['built_in' => true, 'priority' => -880])
3740
;
3841
};
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Scheduler\Messenger\Serializer\Normalizer;
13+
14+
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
15+
use Symfony\Component\Scheduler\Trigger\TriggerInterface;
16+
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
17+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
18+
19+
final class SchedulerTriggerNormalizer implements DenormalizerInterface, NormalizerInterface
20+
{
21+
public function getSupportedTypes(?string $format): array
22+
{
23+
return [
24+
TriggerInterface::class => false,
25+
];
26+
}
27+
28+
/**
29+
* @param TriggerInterface $data
30+
*/
31+
public function normalize(mixed $data, ?string $format = null, array $context = []): string
32+
{
33+
return (string) $data;
34+
}
35+
36+
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
37+
{
38+
return $data instanceof TriggerInterface && ($context[Serializer::MESSENGER_SERIALIZATION_CONTEXT] ?? false);
39+
}
40+
41+
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): TriggerInterface
42+
{
43+
return new class($data) implements TriggerInterface {
44+
public function __construct(private readonly string $description)
45+
{
46+
}
47+
48+
public function __toString(): string
49+
{
50+
return $this->description;
51+
}
52+
53+
public function getNextRunDate(\DateTimeImmutable $run): ?\DateTimeImmutable
54+
{
55+
throw new \LogicException('Not possible to get next run date from a deserialized trigger.');
56+
}
57+
};
58+
}
59+
60+
public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
61+
{
62+
return TriggerInterface::class === $type && ($context[Serializer::MESSENGER_SERIALIZATION_CONTEXT] ?? false) && \is_string($data);
63+
}
64+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Scheduler\Tests\Messenger;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Scheduler\Messenger\Serializer\Normalizer\SchedulerTriggerNormalizer;
16+
use Symfony\Component\Scheduler\Trigger\CallbackTrigger;
17+
use Symfony\Component\Scheduler\Trigger\PeriodicalTrigger;
18+
use Symfony\Component\Scheduler\Trigger\TriggerInterface;
19+
20+
class SchedulerTriggerNormalizerTest extends TestCase
21+
{
22+
private SchedulerTriggerNormalizer $normalizer;
23+
24+
/**
25+
* @before
26+
*/
27+
protected function setUpNormalizer(): void
28+
{
29+
$this->normalizer = new SchedulerTriggerNormalizer();
30+
}
31+
32+
/**
33+
* @dataProvider normalizeProvider
34+
*/
35+
public function testNormalize(mixed $data, mixed $expected)
36+
{
37+
self::assertSame($expected, $this->normalizer->normalize($data));
38+
}
39+
40+
public static function normalizeProvider(): iterable
41+
{
42+
yield 'CallbackTrigger' => [new CallbackTrigger(fn () => null, 'test1'), 'test1'];
43+
yield 'PeriodicalTrigger' => [new PeriodicalTrigger(5), 'every 5 seconds'];
44+
}
45+
46+
/**
47+
* @dataProvider supportsNormalizationProvider
48+
*/
49+
public function testSupportsNormalization(mixed $data, array $context, bool $expected)
50+
{
51+
self::assertSame($expected, $this->normalizer->supportsNormalization($data, 'json', $context));
52+
}
53+
54+
public static function supportsNormalizationProvider(): iterable
55+
{
56+
yield 'CallbackTrigger, messenger context' => [new CallbackTrigger(fn () => null, 'test1'), ['messenger_serialization' => true], true];
57+
yield 'CallbackTrigger, normal context' => [new CallbackTrigger(fn () => null, 'test1'), [], false];
58+
yield 'PeriodicalTrigger, messenger context' => [new PeriodicalTrigger(5), ['messenger_serialization' => true], true];
59+
yield 'PeriodicalTrigger, normal context' => [new PeriodicalTrigger(5), [], false];
60+
yield 'stdClass, messenger context' => [new \stdClass(), ['messenger_serialization' => true], false];
61+
yield 'stdClass, normal context' => [new \stdClass(), [], false];
62+
}
63+
64+
/**
65+
* @dataProvider supportsDenormalizationProvider
66+
*/
67+
public function testSupportsDenormalization(mixed $data, string $type, array $context, bool $expected)
68+
{
69+
self::assertSame($expected, $this->normalizer->supportsDenormalization($data, $type, 'json', $context));
70+
}
71+
72+
public static function supportsDenormalizationProvider(): iterable
73+
{
74+
yield 'unknown type' => ['test', \stdClass::class, ['messenger_serialization' => true], false];
75+
yield 'string, messenger context' => ['test', TriggerInterface::class, ['messenger_serialization' => true], true];
76+
yield 'string, normal context' => ['test', TriggerInterface::class, [], false];
77+
yield 'array, messenger context' => [['a' => 'b'], TriggerInterface::class, ['messenger_serialization' => true], false];
78+
yield 'array, normal context' => [['a' => 'b'], TriggerInterface::class, [], false];
79+
}
80+
81+
public function testDenormalize()
82+
{
83+
$trigger = $this->normalizer->denormalize('every 5 seconds', TriggerInterface::class);
84+
self::assertSame('every 5 seconds', (string) $trigger);
85+
}
86+
}

0 commit comments

Comments
 (0)
0