Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit02161b7

Browse files
committed
bug#60026 [Serializer] Fix ObjectNormalizer default context with named serializers (HypeMC)
This PR was merged into the 7.2 branch.Discussion----------[Serializer] Fix ObjectNormalizer default context with named serializers| Q | A| ------------- | ---| Branch? | 7.2| Bug fix? | yes| New feature? | no| Deprecations? | no| Issues |Fix#59639| License | MITAs mentioned in#59639, the main problem is that arguments have precedence over bindings, and children inherit arguments from their parents.This PR moves the logic for setting the default context of `ObjectNormalizer` from the extension to the `SerializerPass`, where only bindings are used.Commits-------80d993f [Serializer] Fix ObjectNormalizer default context with named serializers
2 parents2f6b2e6 +80d993f commit02161b7

File tree

6 files changed

+110
-28
lines changed

6 files changed

+110
-28
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,24 +1946,14 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
19461946
$container->setParameter('serializer.default_context',$defaultContext);
19471947
}
19481948

1949-
if (!$container->hasDefinition('serializer.normalizer.object')) {
1950-
return;
1951-
}
1952-
1953-
$arguments =$container->getDefinition('serializer.normalizer.object')->getArguments();
1954-
$context =$arguments[6] ??$defaultContext;
1955-
1956-
if (isset($config['circular_reference_handler']) &&$config['circular_reference_handler']) {
1957-
$context += ['circular_reference_handler' =>newReference($config['circular_reference_handler'])];
1958-
$container->getDefinition('serializer.normalizer.object')->setArgument(5,null);
1949+
if ($config['circular_reference_handler'] ??false) {
1950+
$container->setParameter('.serializer.circular_reference_handler',$config['circular_reference_handler']);
19591951
}
19601952

19611953
if ($config['max_depth_handler'] ??false) {
1962-
$context += ['max_depth_handler' =>newReference($config['max_depth_handler'])];
1954+
$container->setParameter('.serializer.max_depth_handler',$config['max_depth_handler']);
19631955
}
19641956

1965-
$container->getDefinition('serializer.normalizer.object')->setArgument(6,$context);
1966-
19671957
$container->getDefinition('serializer.normalizer.property')->setArgument(5,$defaultContext);
19681958

19691959
$container->setParameter('.serializer.named_serializers',$config['named_serializers'] ?? []);

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129
service('property_info')->ignoreOnInvalid(),
130130
service('serializer.mapping.class_discriminator_resolver')->ignoreOnInvalid(),
131131
null,
132-
null,
132+
abstract_arg('default context, set in the SerializerPass'),
133133
service('property_info')->ignoreOnInvalid(),
134134
])
135135
->tag('serializer.normalizer', ['built_in' =>true,'priority' => -1000])

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
useSymfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
3434
useSymfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
3535
useSymfony\Component\DependencyInjection\ChildDefinition;
36+
useSymfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
3637
useSymfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
3738
useSymfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
3839
useSymfony\Component\DependencyInjection\Compiler\ResolveTaggedIteratorArgumentPass;
@@ -67,6 +68,7 @@
6768
useSymfony\Component\Notifier\TexterInterface;
6869
useSymfony\Component\PropertyAccess\PropertyAccessor;
6970
useSymfony\Component\Security\Core\AuthenticationEvents;
71+
useSymfony\Component\Serializer\DependencyInjection\SerializerPass;
7072
useSymfony\Component\Serializer\Mapping\Loader\AttributeLoader;
7173
useSymfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
7274
useSymfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
@@ -1447,9 +1449,6 @@ public function testSerializerEnabled()
14471449
$this->assertEquals(AttributeLoader::class,$argument[0]->getClass());
14481450
$this->assertEquals(newReference('serializer.name_converter.camel_case_to_snake_case'),$container->getDefinition('serializer.name_converter.metadata_aware')->getArgument(1));
14491451
$this->assertEquals(newReference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE),$container->getDefinition('serializer.normalizer.object')->getArgument(3));
1450-
$this->assertArrayHasKey('circular_reference_handler',$container->getDefinition('serializer.normalizer.object')->getArgument(6));
1451-
$this->assertArrayHasKey('max_depth_handler',$container->getDefinition('serializer.normalizer.object')->getArgument(6));
1452-
$this->assertEquals($container->getDefinition('serializer.normalizer.object')->getArgument(6)['max_depth_handler'],newReference('my.max.depth.handler'));
14531452
}
14541453

14551454
publicfunctiontestSerializerWithoutTranslator()
@@ -1547,13 +1546,22 @@ public function testJsonSerializableNormalizerRegistered()
15471546

15481547
publicfunctiontestObjectNormalizerRegistered()
15491548
{
1550-
$container =$this->createContainerFromFile('full');
1549+
$container =$this->createContainerFromFile('full', compile:false);
1550+
$container->addCompilerPass(newSerializerPass());
1551+
$container->addCompilerPass(newResolveBindingsPass());
1552+
$container->compile();
15511553

15521554
$definition =$container->getDefinition('serializer.normalizer.object');
15531555
$tag =$definition->getTag('serializer.normalizer');
15541556

15551557
$this->assertEquals(ObjectNormalizer::class,$definition->getClass());
15561558
$this->assertEquals(-1000,$tag[0]['priority']);
1559+
1560+
$this->assertEquals([
1561+
'enable_max_depth' =>true,
1562+
'circular_reference_handler' =>newReference('my.circular.reference.handler'),
1563+
'max_depth_handler' =>newReference('my.max.depth.handler'),
1564+
],$definition->getArgument(6));
15571565
}
15581566

15591567
publicfunctiontestConstraintViolationListNormalizerRegistered()

‎src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"symfony/scheduler":"^6.4.4|^7.0.4",
6060
"symfony/security-bundle":"^6.4|^7.0",
6161
"symfony/semaphore":"^6.4|^7.0",
62-
"symfony/serializer":"^7.1",
62+
"symfony/serializer":"^7.2.5",
6363
"symfony/stopwatch":"^6.4|^7.0",
6464
"symfony/string":"^6.4|^7.0",
6565
"symfony/translation":"^6.4|^7.0",
@@ -97,7 +97,7 @@
9797
"symfony/scheduler":"<6.4.4|>=7.0.0,<7.0.4",
9898
"symfony/security-csrf":"<7.2",
9999
"symfony/security-core":"<6.4",
100-
"symfony/serializer":"<7.1",
100+
"symfony/serializer":"<7.2.5",
101101
"symfony/stopwatch":"<6.4",
102102
"symfony/translation":"<6.4",
103103
"symfony/twig-bridge":"<6.4",

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

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
useSymfony\Component\DependencyInjection\Reference;
2020
useSymfony\Component\Serializer\Debug\TraceableEncoder;
2121
useSymfony\Component\Serializer\Debug\TraceableNormalizer;
22+
useSymfony\Component\Serializer\Normalizer\ObjectNormalizer;
2223
useSymfony\Component\Serializer\SerializerInterface;
2324

2425
/**
@@ -54,17 +55,27 @@ public function process(ContainerBuilder $container): void
5455
thrownewRuntimeException('You must tag at least one service as "serializer.encoder" to use the "serializer" service.');
5556
}
5657

58+
$defaultContext = [];
5759
if ($container->hasParameter('serializer.default_context')) {
5860
$defaultContext =$container->getParameter('serializer.default_context');
59-
$this->bindDefaultContext($container,array_merge($normalizers,$encoders),$defaultContext);
6061
$container->getParameterBag()->remove('serializer.default_context');
6162
$container->getDefinition('serializer')->setArgument('$defaultContext',$defaultContext);
6263
}
6364

65+
/** @var ?string $circularReferenceHandler */
66+
$circularReferenceHandler =$container->hasParameter('.serializer.circular_reference_handler')
67+
?$container->getParameter('.serializer.circular_reference_handler') :null;
68+
69+
/** @var ?string $maxDepthHandler */
70+
$maxDepthHandler =$container->hasParameter('.serializer.max_depth_handler')
71+
?$container->getParameter('.serializer.max_depth_handler') :null;
72+
73+
$this->bindDefaultContext($container,array_merge($normalizers,$encoders),$defaultContext,$circularReferenceHandler,$maxDepthHandler);
74+
6475
$this->configureSerializer($container,'serializer',$normalizers,$encoders,'default');
6576

6677
if ($namedSerializers) {
67-
$this->configureNamedSerializers($container);
78+
$this->configureNamedSerializers($container,$circularReferenceHandler,$maxDepthHandler);
6879
}
6980
}
7081

@@ -98,11 +109,22 @@ private function createNamedSerializerTags(ContainerBuilder $container, string $
98109
}
99110
}
100111

101-
privatefunctionbindDefaultContext(ContainerBuilder$container,array$services,array$defaultContext):void
112+
privatefunctionbindDefaultContext(ContainerBuilder$container,array$services,array$defaultContext, ?string$circularReferenceHandler, ?string$maxDepthHandler):void
102113
{
103114
foreach ($servicesas$id) {
104115
$definition =$container->getDefinition((string)$id);
105-
$definition->setBindings(['array $defaultContext' =>newBoundArgument($defaultContext,false)] +$definition->getBindings());
116+
117+
$context =$defaultContext;
118+
if (is_a($definition->getClass(), ObjectNormalizer::class,true)) {
119+
if (null !==$circularReferenceHandler) {
120+
$context += ['circular_reference_handler' =>newReference($circularReferenceHandler)];
121+
}
122+
if (null !==$maxDepthHandler) {
123+
$context += ['max_depth_handler' =>newReference($maxDepthHandler)];
124+
}
125+
}
126+
127+
$definition->setBindings(['array $defaultContext' =>newBoundArgument($context,false)] +$definition->getBindings());
106128
}
107129
}
108130

@@ -125,7 +147,7 @@ private function configureSerializer(ContainerBuilder $container, string $id, ar
125147
$serializerDefinition->replaceArgument(1,$encoders);
126148
}
127149

128-
privatefunctionconfigureNamedSerializers(ContainerBuilder$container):void
150+
privatefunctionconfigureNamedSerializers(ContainerBuilder$container, ?string$circularReferenceHandler, ?string$maxDepthHandler):void
129151
{
130152
$defaultSerializerNameConverter =$container->hasParameter('.serializer.name_converter')
131153
?$container->getParameter('.serializer.name_converter') :null;
@@ -149,7 +171,7 @@ private function configureNamedSerializers(ContainerBuilder $container): void
149171
$normalizers =$this->buildChildDefinitions($container,$serializerName,$normalizers,$config);
150172
$encoders =$this->buildChildDefinitions($container,$serializerName,$encoders,$config);
151173

152-
$this->bindDefaultContext($container,array_merge($normalizers,$encoders),$config['default_context']);
174+
$this->bindDefaultContext($container,array_merge($normalizers,$encoders),$config['default_context'],$circularReferenceHandler,$maxDepthHandler);
153175

154176
$container->registerChild($serializerId,'serializer')->setArgument('$defaultContext',$config['default_context']);
155177
$container->registerAliasForArgument($serializerId, SerializerInterface::class,$serializerName.'.serializer');
@@ -184,7 +206,9 @@ private function buildChildDefinitions(ContainerBuilder $container, string $seri
184206
foreach ($servicesas &$id) {
185207
$childId =$id.'.'.$serializerName;
186208

187-
$definition =$container->registerChild($childId, (string)$id);
209+
$definition =$container->registerChild($childId, (string)$id)
210+
->setClass($container->getDefinition((string)$id)->getClass())
211+
;
188212

189213
if (null !==$nameConverterIndex =$this->findNameConverterIndex($container, (string)$id)) {
190214
$definition->replaceArgument($nameConverterIndex,newReference($config['name_converter']));

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

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
useSymfony\Component\Serializer\Debug\TraceableNormalizer;
2020
useSymfony\Component\Serializer\Debug\TraceableSerializer;
2121
useSymfony\Component\Serializer\DependencyInjection\SerializerPass;
22+
useSymfony\Component\Serializer\Normalizer\ObjectNormalizer;
2223
useSymfony\Component\Serializer\SerializerInterface;
2324

2425
/**
@@ -99,6 +100,32 @@ public function testBindSerializerDefaultContext()
99100
$this->assertEquals($context,$container->getDefinition('serializer')->getArgument('$defaultContext'));
100101
}
101102

103+
/**
104+
* @testWith [{}, {}]
105+
* [{"serializer.default_context": {"enable_max_depth": true}}, {"enable_max_depth": true}]
106+
* [{".serializer.circular_reference_handler": "foo"}, {"circular_reference_handler": "foo"}]
107+
* [{".serializer.max_depth_handler": "bar"}, {"max_depth_handler": "bar"}]
108+
* [{"serializer.default_context": {"enable_max_depth": true}, ".serializer.circular_reference_handler": "foo", ".serializer.max_depth_handler": "bar"}, {"enable_max_depth": true, "circular_reference_handler": "foo", "max_depth_handler": "bar"}]
109+
*/
110+
publicfunctiontestBindObjectNormalizerDefaultContext(array$parameters,array$context)
111+
{
112+
$container =newContainerBuilder();
113+
$container->setParameter('kernel.debug',false);
114+
$container->register('serializer')->setArguments([null,null, []]);
115+
$container->getParameterBag()->add($parameters);
116+
$definition =$container->register('serializer.normalizer.object')
117+
->setClass(ObjectNormalizer::class)
118+
->addTag('serializer.normalizer')
119+
->addTag('serializer.encoder')
120+
;
121+
122+
$serializerPass =newSerializerPass();
123+
$serializerPass->process($container);
124+
125+
$bindings =$definition->getBindings();
126+
$this->assertEquals($bindings['array $defaultContext'],newBoundArgument($context,false));
127+
}
128+
102129
publicfunctiontestNormalizersAndEncodersAreDecoratedAndOrderedWhenCollectingData()
103130
{
104131
$container =newContainerBuilder();
@@ -565,7 +592,9 @@ public function testBindSerializerDefaultContextToNamedSerializers()
565592
$serializerPass =newSerializerPass();
566593
$serializerPass->process($container);
567594

568-
$this->assertEmpty($definition->getBindings());
595+
$bindings =$definition->getBindings();
596+
$this->assertArrayHasKey('array $defaultContext',$bindings);
597+
$this->assertEquals($bindings['array $defaultContext'],newBoundArgument([],false));
569598

570599
$bindings =$container->getDefinition('n1.api')->getBindings();
571600
$this->assertArrayHasKey('array $defaultContext',$bindings);
@@ -574,6 +603,37 @@ public function testBindSerializerDefaultContextToNamedSerializers()
574603
$this->assertEquals($defaultContext,$container->getDefinition('serializer.api')->getArgument('$defaultContext'));
575604
}
576605

606+
/**
607+
* @testWith [{}, {}, {}]
608+
* [{"enable_max_depth": true}, {}, {"enable_max_depth": true}]
609+
* [{}, {".serializer.circular_reference_handler": "foo"}, {"circular_reference_handler": "foo"}]
610+
* [{}, {".serializer.max_depth_handler": "bar"}, {"max_depth_handler": "bar"}]
611+
* [{"enable_max_depth": true}, {".serializer.circular_reference_handler": "foo", ".serializer.max_depth_handler": "bar"}, {"enable_max_depth": true, "circular_reference_handler": "foo", "max_depth_handler": "bar"}]
612+
*/
613+
publicfunctiontestBindNamedSerializerObjectNormalizerDefaultContext(array$defaultContext,array$parameters,array$context)
614+
{
615+
$container =newContainerBuilder();
616+
$container->setParameter('kernel.debug',false);
617+
$container->setParameter('.serializer.named_serializers', [
618+
'api' => ['default_context' =>$defaultContext],
619+
]);
620+
621+
$container->register('serializer')->setArguments([null,null, []]);
622+
$container->getParameterBag()->add($parameters);
623+
$container->register('serializer.normalizer.object')
624+
->setClass(ObjectNormalizer::class)
625+
->addTag('serializer.normalizer', ['serializer' =>'*'])
626+
->addTag('serializer.encoder', ['serializer' =>'*'])
627+
;
628+
629+
$serializerPass =newSerializerPass();
630+
$serializerPass->process($container);
631+
632+
$bindings =$container->getDefinition('serializer.normalizer.object.api')->getBindings();
633+
$this->assertArrayHasKey('array $defaultContext',$bindings);
634+
$this->assertEquals($bindings['array $defaultContext'],newBoundArgument($context,false));
635+
}
636+
577637
publicfunctiontestNamedSerializersAreRegistered()
578638
{
579639
$container =newContainerBuilder();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp