Skip to content

Commit ed975c7

Browse files
dunglasfabpot
authored andcommitted
[Serializer] Add a MaxDepth handler
1 parent 1364089 commit ed975c7

File tree

10 files changed

+51
-2
lines changed

10 files changed

+51
-2
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode)
731731
->booleanNode('enable_annotations')->{!class_exists(FullStack::class) && class_exists(Annotation::class) ? 'defaultTrue' : 'defaultFalse'}()->end()
732732
->scalarNode('name_converter')->end()
733733
->scalarNode('circular_reference_handler')->end()
734+
->scalarNode('max_depth_handler')->end()
734735
->arrayNode('mapping')
735736
->addDefaultsIfNotSet()
736737
->fixXmlConfig('path')

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,10 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
12731273
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
12741274
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setCircularReferenceHandler', array(new Reference($config['circular_reference_handler'])));
12751275
}
1276+
1277+
if ($config['max_depth_handler'] ?? false) {
1278+
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setMaxDepthHandler', array(new Reference($config['max_depth_handler'])));
1279+
}
12761280
}
12771281

12781282
private function registerPropertyInfoConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
<xsd:attribute name="cache" type="xsd:string" />
240240
<xsd:attribute name="enable-annotations" type="xsd:boolean" />
241241
<xsd:attribute name="name-converter" type="xsd:string" />
242+
<xsd:attribute name="max-depth-handler" type="xsd:string" />
242243
</xsd:complexType>
243244

244245
<xsd:complexType name="property_info">

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
'enabled' => true,
6969
'enable_annotations' => true,
7070
'name_converter' => 'serializer.name_converter.camel_case_to_snake_case',
71+
'max_depth_handler' => 'my.max.depth.handler',
7172
),
7273
'property_info' => true,
7374
'ide' => 'file%%link%%format',

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
</framework:translator>
4242
<framework:validation enabled="true" />
4343
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />
44-
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" />
44+
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" max-depth-handler="my.max.depth.handler" />
4545
<framework:property-info />
4646
</framework:config>
4747
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ framework:
5454
enabled: true
5555
enable_annotations: true
5656
name_converter: serializer.name_converter.camel_case_to_snake_case
57+
max_depth_handler: my.max.depth.handler
5758
property_info: ~
5859
ide: file%%link%%format
5960
request:

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ public function testSerializerEnabled()
804804
$this->assertNull($container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1));
805805
$this->assertEquals(new Reference('serializer.name_converter.camel_case_to_snake_case'), $container->getDefinition('serializer.normalizer.object')->getArgument(1));
806806
$this->assertEquals(new Reference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $container->getDefinition('serializer.normalizer.object')->getArgument(3));
807+
$this->assertEquals(array('setMaxDepthHandler', array(new Reference('my.max.depth.handler'))), $container->getDefinition('serializer.normalizer.object')->getMethodCalls()[0]);
807808
}
808809

809810
public function testRegisterSerializerExtractor()

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ CHANGELOG
99
* added an optional `default_constructor_arguments` option of context to specify a default data in
1010
case the object is not initializable by its constructor because of data missing
1111
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
12+
* added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured
13+
maximum depth is reached
1214

1315
4.0.0
1416
-----

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
4141
private $attributesCache = array();
4242
private $cache = array();
4343

44+
/**
45+
* @var callable|null
46+
*/
47+
private $maxDepthHandler;
48+
4449
/**
4550
* @var ClassDiscriminatorResolverInterface|null
4651
*/
@@ -86,11 +91,15 @@ public function normalize($object, $format = null, array $context = array())
8691
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
8792

8893
foreach ($attributes as $attribute) {
89-
if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) {
94+
$maxDepthReached = false;
95+
if (null !== $attributesMetadata && ($maxDepthReached = $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) && !$this->maxDepthHandler) {
9096
continue;
9197
}
9298

9399
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
100+
if ($maxDepthReached) {
101+
$attributeValue = \call_user_func($this->maxDepthHandler, $attributeValue);
102+
}
94103

95104
if (isset($this->callbacks[$attribute])) {
96105
$attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
@@ -204,6 +213,14 @@ abstract protected function extractAttributes($object, $format = null, array $co
204213
*/
205214
abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = array());
206215

216+
/**
217+
* Sets an handler function that will be called when the max depth is reached.
218+
*/
219+
public function setMaxDepthHandler(?callable $handler): void
220+
{
221+
$this->maxDepthHandler = $handler;
222+
}
223+
207224
/**
208225
* {@inheritdoc}
209226
*/

src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,27 @@ public function testMaxDepth()
613613
);
614614

615615
$this->assertEquals($expected, $result);
616+
617+
$expected = array(
618+
'bar' => null,
619+
'foo' => 'level1',
620+
'child' => array(
621+
'bar' => null,
622+
'foo' => 'level2',
623+
'child' => array(
624+
'bar' => null,
625+
'child' => null,
626+
'foo' => 'handler',
627+
),
628+
),
629+
);
630+
631+
$this->normalizer->setMaxDepthHandler(function ($obj) {
632+
return 'handler';
633+
});
634+
635+
$result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true));
636+
$this->assertEquals($expected, $result);
616637
}
617638

618639
/**

0 commit comments

Comments
 (0)