[Serializer] Add a MaxDepth handler
This commit is contained in:
parent
136408937b
commit
ed975c764b
@ -731,6 +731,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
->booleanNode('enable_annotations')->{!class_exists(FullStack::class) && class_exists(Annotation::class) ? 'defaultTrue' : 'defaultFalse'}()->end()
|
->booleanNode('enable_annotations')->{!class_exists(FullStack::class) && class_exists(Annotation::class) ? 'defaultTrue' : 'defaultFalse'}()->end()
|
||||||
->scalarNode('name_converter')->end()
|
->scalarNode('name_converter')->end()
|
||||||
->scalarNode('circular_reference_handler')->end()
|
->scalarNode('circular_reference_handler')->end()
|
||||||
|
->scalarNode('max_depth_handler')->end()
|
||||||
->arrayNode('mapping')
|
->arrayNode('mapping')
|
||||||
->addDefaultsIfNotSet()
|
->addDefaultsIfNotSet()
|
||||||
->fixXmlConfig('path')
|
->fixXmlConfig('path')
|
||||||
|
@ -1273,6 +1273,10 @@ class FrameworkExtension extends Extension
|
|||||||
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
|
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
|
||||||
$container->getDefinition('serializer.normalizer.object')->addMethodCall('setCircularReferenceHandler', array(new Reference($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)
|
private function registerPropertyInfoConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
|
||||||
|
@ -239,6 +239,7 @@
|
|||||||
<xsd:attribute name="cache" type="xsd:string" />
|
<xsd:attribute name="cache" type="xsd:string" />
|
||||||
<xsd:attribute name="enable-annotations" type="xsd:boolean" />
|
<xsd:attribute name="enable-annotations" type="xsd:boolean" />
|
||||||
<xsd:attribute name="name-converter" type="xsd:string" />
|
<xsd:attribute name="name-converter" type="xsd:string" />
|
||||||
|
<xsd:attribute name="max-depth-handler" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="property_info">
|
<xsd:complexType name="property_info">
|
||||||
|
@ -68,6 +68,7 @@ $container->loadFromExtension('framework', array(
|
|||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
'enable_annotations' => true,
|
'enable_annotations' => true,
|
||||||
'name_converter' => 'serializer.name_converter.camel_case_to_snake_case',
|
'name_converter' => 'serializer.name_converter.camel_case_to_snake_case',
|
||||||
|
'max_depth_handler' => 'my.max.depth.handler',
|
||||||
),
|
),
|
||||||
'property_info' => true,
|
'property_info' => true,
|
||||||
'ide' => 'file%%link%%format',
|
'ide' => 'file%%link%%format',
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
</framework:translator>
|
</framework:translator>
|
||||||
<framework:validation enabled="true" />
|
<framework:validation enabled="true" />
|
||||||
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />
|
<framework:annotations cache="file" debug="true" file-cache-dir="%kernel.cache_dir%/annotations" />
|
||||||
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" />
|
<framework:serializer enabled="true" enable-annotations="true" name-converter="serializer.name_converter.camel_case_to_snake_case" max-depth-handler="my.max.depth.handler" />
|
||||||
<framework:property-info />
|
<framework:property-info />
|
||||||
</framework:config>
|
</framework:config>
|
||||||
</container>
|
</container>
|
||||||
|
@ -54,6 +54,7 @@ framework:
|
|||||||
enabled: true
|
enabled: true
|
||||||
enable_annotations: true
|
enable_annotations: true
|
||||||
name_converter: serializer.name_converter.camel_case_to_snake_case
|
name_converter: serializer.name_converter.camel_case_to_snake_case
|
||||||
|
max_depth_handler: my.max.depth.handler
|
||||||
property_info: ~
|
property_info: ~
|
||||||
ide: file%%link%%format
|
ide: file%%link%%format
|
||||||
request:
|
request:
|
||||||
|
@ -804,6 +804,7 @@ abstract class FrameworkExtensionTest extends TestCase
|
|||||||
$this->assertNull($container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1));
|
$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('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(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()
|
public function testRegisterSerializerExtractor()
|
||||||
|
@ -9,6 +9,8 @@ CHANGELOG
|
|||||||
* added an optional `default_constructor_arguments` option of context to specify a default data in
|
* 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
|
case the object is not initializable by its constructor because of data missing
|
||||||
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
|
* 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
|
4.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -41,6 +41,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
private $attributesCache = array();
|
private $attributesCache = array();
|
||||||
private $cache = array();
|
private $cache = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var callable|null
|
||||||
|
*/
|
||||||
|
private $maxDepthHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ClassDiscriminatorResolverInterface|null
|
* @var ClassDiscriminatorResolverInterface|null
|
||||||
*/
|
*/
|
||||||
@ -86,11 +91,15 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
||||||
|
|
||||||
foreach ($attributes as $attribute) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
|
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
|
||||||
|
if ($maxDepthReached) {
|
||||||
|
$attributeValue = \call_user_func($this->maxDepthHandler, $attributeValue);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($this->callbacks[$attribute])) {
|
if (isset($this->callbacks[$attribute])) {
|
||||||
$attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
|
$attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
|
||||||
@ -204,6 +213,14 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
*/
|
*/
|
||||||
abstract protected function getAttributeValue($object, $attribute, $format = null, array $context = array());
|
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}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -613,6 +613,27 @@ class ObjectNormalizerTest extends TestCase
|
|||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals($expected, $result);
|
$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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user