diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 53abbb23fa31..4eea195b99d2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -731,6 +731,7 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode)
->booleanNode('enable_annotations')->{!class_exists(FullStack::class) && class_exists(Annotation::class) ? 'defaultTrue' : 'defaultFalse'}()->end()
->scalarNode('name_converter')->end()
->scalarNode('circular_reference_handler')->end()
+ ->scalarNode('max_depth_handler')->end()
->arrayNode('mapping')
->addDefaultsIfNotSet()
->fixXmlConfig('path')
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 413d61719384..cd144afdcef9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1273,6 +1273,10 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setCircularReferenceHandler', array(new Reference($config['circular_reference_handler'])));
}
+
+ if ($config['max_depth_handler'] ?? false) {
+ $container->getDefinition('serializer.normalizer.object')->addMethodCall('setMaxDepthHandler', array(new Reference($config['max_depth_handler'])));
+ }
}
private function registerPropertyInfoConfiguration(array $config, 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 653cf52f7c3c..17a09665007a 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
@@ -239,6 +239,7 @@
+
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 a97daeef1d13..3fdd11425595 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php
@@ -68,6 +68,7 @@
'enabled' => true,
'enable_annotations' => true,
'name_converter' => 'serializer.name_converter.camel_case_to_snake_case',
+ 'max_depth_handler' => 'my.max.depth.handler',
),
'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 6920efebed32..779078f9cb66 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml
@@ -41,7 +41,7 @@
-
+
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 3194a0fab2e1..9df691f21ada 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,7 @@ framework:
enabled: true
enable_annotations: true
name_converter: serializer.name_converter.camel_case_to_snake_case
+ max_depth_handler: my.max.depth.handler
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 4269cf131115..80e7a76fa173 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -804,6 +804,7 @@ 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.normalizer.object')->getArgument(1));
$this->assertEquals(new Reference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $container->getDefinition('serializer.normalizer.object')->getArgument(3));
+ $this->assertEquals(array('setMaxDepthHandler', array(new Reference('my.max.depth.handler'))), $container->getDefinition('serializer.normalizer.object')->getMethodCalls()[0]);
}
public function testRegisterSerializerExtractor()
diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md
index c680a19b1657..a4e8bf499f5c 100644
--- a/src/Symfony/Component/Serializer/CHANGELOG.md
+++ b/src/Symfony/Component/Serializer/CHANGELOG.md
@@ -9,6 +9,8 @@ CHANGELOG
* added an optional `default_constructor_arguments` option of context to specify a default data in
case the object is not initializable by its constructor because of data missing
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
+* added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured
+ maximum depth is reached
4.0.0
-----
diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
index bd812d289de3..644985fce727 100644
--- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
@@ -41,6 +41,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
private $attributesCache = array();
private $cache = array();
+ /**
+ * @var callable|null
+ */
+ private $maxDepthHandler;
+
/**
* @var ClassDiscriminatorResolverInterface|null
*/
@@ -86,11 +91,15 @@ public function normalize($object, $format = null, array $context = array())
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
foreach ($attributes as $attribute) {
- if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) {
+ $maxDepthReached = false;
+ if (null !== $attributesMetadata && ($maxDepthReached = $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) && !$this->maxDepthHandler) {
continue;
}
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
+ if ($maxDepthReached) {
+ $attributeValue = \call_user_func($this->maxDepthHandler, $attributeValue);
+ }
if (isset($this->callbacks[$attribute])) {
$attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
@@ -204,6 +213,14 @@ abstract protected function extractAttributes($object, $format = null, array $co
*/
abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = array());
+ /**
+ * Sets an handler function that will be called when the max depth is reached.
+ */
+ public function setMaxDepthHandler(?callable $handler): void
+ {
+ $this->maxDepthHandler = $handler;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
index 333f48779dc2..d5d9885f7f67 100644
--- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php
@@ -613,6 +613,27 @@ public function testMaxDepth()
);
$this->assertEquals($expected, $result);
+
+ $expected = array(
+ 'bar' => null,
+ 'foo' => 'level1',
+ 'child' => array(
+ 'bar' => null,
+ 'foo' => 'level2',
+ 'child' => array(
+ 'bar' => null,
+ 'child' => null,
+ 'foo' => 'handler',
+ ),
+ ),
+ );
+
+ $this->normalizer->setMaxDepthHandler(function ($obj) {
+ return 'handler';
+ });
+
+ $result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true));
+ $this->assertEquals($expected, $result);
}
/**