From b0a7d0ea73e90cf8b442166591225f77b2ed112e Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 5 Mar 2020 10:18:51 +0100 Subject: [PATCH] Allow serializer default context configuration --- .../DependencyInjection/Configuration.php | 6 ++++ .../FrameworkExtension.php | 2 ++ .../Resources/config/schema/symfony-1.0.xsd | 1 + .../Resources/config/serializer.xml | 15 ++++++++-- .../DependencyInjection/ConfigurationTest.php | 1 + .../DependencyInjection/Fixtures/php/full.php | 1 + .../DependencyInjection/Fixtures/xml/full.xml | 6 +++- .../DependencyInjection/Fixtures/yml/full.yml | 2 ++ .../FrameworkExtensionTest.php | 5 ++-- .../DependencyInjection/SerializerPass.php | 28 +++++++++++++++++++ .../SerializerPassTest.php | 14 ++++++++++ 11 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 1632956f7e408..24f583662cfab 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -825,6 +825,12 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode) ->end() ->end() ->end() + ->arrayNode('default_context') + ->normalizeKeys(false) + ->useAttributeAsKey('name') + ->defaultValue([]) + ->prototype('variable')->end() + ->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index a82aad5d6d41d..9a27c879f8f12 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1527,6 +1527,8 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $defaultContext += ['max_depth_handler' => new Reference($config['max_depth_handler'])]; $container->getDefinition('serializer.normalizer.object')->replaceArgument(6, $defaultContext); } + + $container->setParameter('serializer.default_context', $config['default_context'] ?? []); } private function registerPropertyInfoConfiguration(ContainerBuilder $container, XmlFileLoader $loader) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 99ffbabb82cdc..efd0f2432d270 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -231,6 +231,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml index 0dbc388ddffcb..20dba3b18a3c8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml @@ -32,8 +32,7 @@ - - + %serializer.default_context% @@ -44,6 +43,7 @@ + %serializer.default_context% @@ -55,11 +55,15 @@ + %serializer.default_context% + null + null + %serializer.default_context% @@ -77,7 +81,7 @@ null - + %serializer.default_context% @@ -122,6 +126,7 @@ + %serializer.default_context% @@ -130,10 +135,14 @@ + null + null + %serializer.default_context% + %serializer.default_context% diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index fad9b09a049fa..9d9f22b3c0431 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -396,6 +396,7 @@ protected static function getBundleDefaultConfig() 'enabled' => true, ], 'serializer' => [ + 'default_context' => [], 'enabled' => !class_exists(FullStack::class), 'enable_annotations' => !class_exists(FullStack::class), 'mapping' => ['paths' => []], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php index b11b5e08dcb96..cb4df4222bb4f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -66,6 +66,7 @@ 'name_converter' => 'serializer.name_converter.camel_case_to_snake_case', 'circular_reference_handler' => 'my.circular.reference.handler', 'max_depth_handler' => 'my.max.depth.handler', + 'default_context' => ['enable_max_depth' => true], ], 'property_info' => true, 'ide' => 'file%%link%%format', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index 10a646049d766..d5e2270ea0b91 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -33,7 +33,11 @@ - + + + true + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 5ad80a2da4db2..29fe3ab327156 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -54,6 +54,8 @@ framework: name_converter: serializer.name_converter.camel_case_to_snake_case circular_reference_handler: my.circular.reference.handler max_depth_handler: my.max.depth.handler + default_context: + enable_max_depth: true property_info: ~ ide: file%%link%%format request: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 9588b90c4e57b..7b2ada43a4ddd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -1047,9 +1047,8 @@ public function testSerializerEnabled() $this->assertNull($container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1)); $this->assertEquals(new Reference('serializer.name_converter.camel_case_to_snake_case'), $container->getDefinition('serializer.name_converter.metadata_aware')->getArgument(1)); $this->assertEquals(new Reference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $container->getDefinition('serializer.normalizer.object')->getArgument(3)); - $this->assertArrayHasKey('circular_reference_handler', $container->getDefinition('serializer.normalizer.object')->getArgument(6)); - $this->assertArrayHasKey('max_depth_handler', $container->getDefinition('serializer.normalizer.object')->getArgument(6)); - $this->assertEquals($container->getDefinition('serializer.normalizer.object')->getArgument(6)['max_depth_handler'], new Reference('my.max.depth.handler')); + $this->assertEquals(['setCircularReferenceHandler', [new Reference('my.circular.reference.handler')]], $container->getDefinition('serializer.normalizer.object')->getMethodCalls()[0]); + $this->assertEquals(['setMaxDepthHandler', [new Reference('my.max.depth.handler')]], $container->getDefinition('serializer.normalizer.object')->getMethodCalls()[1]); } public function testRegisterSerializerExtractor() diff --git a/src/Symfony/Component/Serializer/DependencyInjection/SerializerPass.php b/src/Symfony/Component/Serializer/DependencyInjection/SerializerPass.php index 155a6f00ecb4e..c6e224a084993 100644 --- a/src/Symfony/Component/Serializer/DependencyInjection/SerializerPass.php +++ b/src/Symfony/Component/Serializer/DependencyInjection/SerializerPass.php @@ -50,11 +50,39 @@ public function process(ContainerBuilder $container) $serializerDefinition = $container->getDefinition($this->serializerService); $serializerDefinition->replaceArgument(0, $normalizers); + $this->addDefaultContextParameter($normalizers, $container); if (!$encoders = $this->findAndSortTaggedServices($this->encoderTag, $container)) { throw new RuntimeException(sprintf('You must tag at least one service as "%s" to use the "%s" service.', $this->encoderTag, $this->serializerService)); } $serializerDefinition->replaceArgument(1, $encoders); + $this->addDefaultContextParameter($encoders, $container); + } + + private function addDefaultContextParameter($services, $container) + { + foreach ($services as $service) { + $definition = $container->getDefinition($service); + if (!$definition->isAutowired()) { + continue; + } + + if (null === $class = $definition->getClass()) { + continue; + } + + $reflection = new \ReflectionClass($class); + + if (null === $constructor = $reflection->getConstructor()) { + continue; + } + + foreach ($constructor->getParameters() as $arg) { + if ('defaultContext' === $arg->name) { + $definition->setArgument('$defaultContext', '%serializer.default_context%'); + } + } + } } } diff --git a/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php b/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php index 65d7a65f5acdb..148ee569344bb 100644 --- a/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php +++ b/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php @@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Serializer\DependencyInjection\SerializerPass; +use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; /** * Tests for the SerializerPass class. @@ -68,4 +69,17 @@ public function testServicesAreOrderedAccordingToPriority() $this->assertEquals($expected, $definition->getArgument(0)); $this->assertEquals($expected, $definition->getArgument(1)); } + + public function testServiceHasDefaultContextParameterArgument() + { + $container = new ContainerBuilder(); + + $definition = $container->register('serializer')->setClass(ObjectNormalizer::class)->setArguments([null, null, null, null, null, null, null])->addTag('serializer.normalizer')->addTag('serializer.encoder'); + $definition->setAutowired(true); + + $serializerPass = new SerializerPass(); + $serializerPass->process($container); + + $this->assertEquals('%serializer.default_context%', $definition->getArgument('$defaultContext')); + } }