8000 [Serializer] Fix `PropertyNormalizer` with named serializers · symfony/symfony@f9a9efd · GitHub
[go: up one dir, main page]

Skip to content

Commit f9a9efd

Browse files
committed
[Serializer] Fix PropertyNormalizer with named serializers
1 parent 282273c commit f9a9efd

File tree

2 files changed

+57
-20
lines changed

2 files changed

+57
-20
lines changed

src/Symfony/Component/Serializer/DependencyInjection/SerializerPass.php

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\DependencyInjection\Reference;
2020
use Symfony\Component\Serializer\Debug\TraceableEncoder;
2121
use Symfony\Component\Serializer\Debug\TraceableNormalizer;
22+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2223
use Symfony\Component\Serializer\Normalizer\ObjectNormal 10000 izer;
2324
use Symfony\Component\Serializer\SerializerInterface;
2425

@@ -204,30 +205,37 @@ private function buildChildNameConverterDefinition(ContainerBuilder $container,
204205
private function buildChildDefinitions(ContainerBuilder $container, string $serializerName, array $services, array $config): array
205206
{
206207
foreach ($services as &$id) {
207-
$childId = $id.'.'.$serializerName;
208-
209-
$definition = $container->registerChild($childId, (string) $id)
210-
->setClass($container->getDefinition((string) $id)->getClass())
211-
;
212-
213-
if (null !== $nameConverterIndex = $this->findNameConverterIndex($container, (string) $id)) {
214-
$definition->replaceArgument($nameConverterIndex, new Reference($config['name_converter']));
215-
}
216-
217-
$id = new Reference($childId);
208+
$id = $this->buildChildDefinition($container, $serializerName, (string) $id, $config);
218209
}
219210

220211
return $services;
221212
}
222213

223-
private function findNameConverterIndex(ContainerBuilder $container, string $id): int|string|null
214+
private function buildChildDefinition(ContainerBuilder $container, string $serializerName, string $id, array $config): Reference
224215
{
225-
foreach ($container->getDefinition($id)->getArguments() as $index => $argument) {
226-
if ($argument instanceof Reference && self::NAME_CONVERTER_METADATA_AWARE_ID === (string) $argument) {
227-
return $index;
216+
$childId = $id.'.'.$serializerName;
217+
218+
$definition = $container->getDefinition($id);
219+
$childDefinition = $container->registerChild($childId, $id)
220+
->setClass($definition->getClass())
221+
;
222+
223+
foreach ($definition->getArguments() as $index => $argument) {
224+
if (!$argument instanceof Reference) {
225+
continue;
226+
}
227+
228+
if (self::NAME_CONVERTER_METADATA_AWARE_ID === (string) $argument) {
229+
$childDefinition->replaceArgument($index, new Reference($config['name_converter']));
230+
} elseif (
231+
$container->hasDefinition($argument)
232+
&& is_a(($argDefinition = $container->getDefinition($argument))->getClass(), NormalizerInterface::class, true)
233+
&& !$argDefinition->hasTag('serializer.normalizer')
234+
) {
235+
$childDefinition->replaceArgument($index, $this->buildChildDefinition($container, $serializerName, (string) $argument, $config));
228236
}
229237
}
230238

231-
return null;
239+
return new Reference($childId);
232240
}
233241
}

src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Serializer\Debug\TraceableSerializer;
2121
use Symfony\Component\Serializer\DependencyInjection\SerializerPass;
2222
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
23+
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
2324
use Symfony\Component\Serializer\SerializerInterface;
2425

2526
/**
@@ -113,8 +114,7 @@ public function testBindObjectNormalizerDefaultContext(array $parameters, array
113114
$container->setParameter('kernel.debug', false);
114115
$container->register('serializer')->setArguments([null, null, []]);
115116
$container->getParameterBag()->add($parameters);
116-
$definition = $container->register('serializer.normalizer.object')
117-
->setClass(ObjectNormalizer::class)
117+
$definition = $container->register('serializer.normalizer.object', ObjectNormalizer::class)
118118
->addTag('serializer.normalizer')
119119
->addTag('serializer.encoder')
120120
;
@@ -620,8 +620,7 @@ public function testBindNamedSerializerObjectNormalizerDefaultContext(array $def
620620

621621
$container->register('serializer')->setArguments([null, null, []]);
622622
$container->getParameterBag()->add($parameters);
623-
$container->register('serializer.normalizer.object')
624-
->setClass(ObjectNormalizer::class)
623+
$container->register('serializer.normalizer.object', ObjectNormalizer::class)
625624
->addTag('serializer.normalizer', ['serializer' => '*'])
626625
->addTag('serializer.encoder', ['serializer' => '*'])
627626
;
@@ -702,4 +701,34 @@ public function testNormalizersAndEncodersAreDecoratedAndOrderedWhenCollectingDa
702701
$this->assertEquals(new Reference('serializer.data_collector'), $traceableEncoderDefinition->getArgument(1));
703702
$this->assertSame('api', $traceableEncoderDefinition->getArgument(2));
704703
}
704+
705+
public function testMimeMessageNormalizerGetsUniquePropertyNormalizerWhenUsingNamedSerializer()
706+
{
707+
$container = new ContainerBuilder();
708+
709+
$container->setParameter('kernel.debug', false);
710+
$container->setParameter('.serializer.named_serializers', [
711+
'api' => ['name_converter' => 'my.name_converter'],
712+
]);
713+
714+
$container->register('serializer')->setArguments([null, null]);
715+
$container->register('serializer.normalizer.property', PropertyNormalizer::class)
716+
->setArguments([null, new Reference('serializer.name_converter.metadata_aware')])
717+
;
718+
$container->register('n1')
719+
->addArgument(new Reference('serializer.normalizer.property'))
720+
->addTag('serializer.normalizer', ['serializer' => '*'])
721+
->addTag('serializer.encoder', ['serializer' => '*'])
722+
;
723+
724+
$serializerPass = new SerializerPass();
725+
$serializerPass->process($container);
726+
727+
$this->assertEquals(new Reference('serializer.normalizer.property'), $container->getDefinition('n1')->getArgument(0));
728+
$this->assertEquals(new Reference('serializer.normalizer.property.api'), $container->getDefinition('n1.api')->getArgument(0));
729+
730+
$nameConverter = (string) $container->getDefinition('serializer.normalizer.property.api')->getArgument(1);
731+
$this->assertStringStartsWith('serializer.name_converter.metadata_aware.', $nameConverter);
732+
$this->assertEquals(new Reference('my.name_converter'), $container->getDefinition($nameConverter)->getArgument(0));
733+
}
705734
}

0 commit comments

Comments
 (0)
0