Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9286310

Browse files
committed
minor #19532 [Serializer] Fix recursive custom normalizer (mtarld)
This PR was merged into the 7.0 branch. Discussion ---------- [Serializer] Fix recursive custom normalizer As mentioned in the following issue: symfony/symfony#53708, the example showing how to create a custom normalizer leads to an infinite recursion. I could have been fixed like that: ```diff class TopicNormalizer implements NormalizerInterface, NormalizerAwareInterface { use NormalizerAwareTrait; + private const ALREADY_CALLED = self::class.'_already_called'; + public function __construct( private UrlGeneratorInterface $router, ) { } public function normalize($topic, string $format = null, array $context = []): array { + $context[self::ALREADY_CALLED] = true; + $data = $this->normalizer->normalize($topic, $format, $context); // Here, add, edit, or delete some data: $data['href']['self'] = $this->router->generate('topic_show', [ 'id' => $topic->getId(), ], UrlGeneratorInterface::ABSOLUTE_URL); return $data; } public function supportsNormalization($data, string $format = null, array $context = []): bool { + if ($context[self::ALREADY_CALLED] ?? false) { + return false; + } + return $data instanceof Topic; } public function getSupportedTypes(?string $format): array { return [ - Topic::class => true, + Topic::class => false, ]; } } ``` But this will prevent the normalizer to be cacheable (because it depends on the context). Instead, I dropped the use of `NormalizerAwareInterface` and `NormalizerAwareTrait` and used an explicit constructor injection instead. WDYT? Commits ------- 56c8b4d [Serializer] Fix recursive custom normalizer
2 parents 18434c2 + 56c8b4d commit 9286310

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

serializer/custom_normalizer.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@ Creating a New Normalizer
1212
Imagine you want add, modify, or remove some properties during the serialization
1313
process. For that you'll have to create your own normalizer. But it's usually
1414
preferable to let Symfony normalize the object, then hook into the normalization
15-
to customize the normalized data. To do that, leverage the
16-
``NormalizerAwareInterface`` and the ``NormalizerAwareTrait``. This will give
15+
to customize the normalized data. To do that, you can inject a
16+
``NormalizerInterface`` and wire it to Symfony's object normalizer. This will give
1717
you access to a ``$normalizer`` property which takes care of most of the
1818
normalization process::
1919

2020
// src/Serializer/TopicNormalizer.php
2121
namespace App\Serializer;
2222

2323
use App\Entity\Topic;
24+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
2425
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
25-
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
26-
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
2726
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2827

29-
class TopicNormalizer implements NormalizerInterface, NormalizerAwareInterface
28+
class TopicNormalizer implements NormalizerInterface
3029
{
31-
use NormalizerAwareTrait;
32-
3330
public function __construct(
31+
#[Autowire(service: 'serializer.normalizer.object')]
32+
private readonly NormalizerInterface $normalizer,
33+
3434
private UrlGeneratorInterface $router,
3535
) {
3636
}

0 commit comments

Comments
 (0)