Skip to content

Commit b552837

Browse files
committed
feature #26108 [Serializer] Add a MaxDepth handler (dunglas)
This PR was squashed before being merged into the 4.1-dev branch (closes #26108). Discussion ---------- [Serializer] Add a MaxDepth handler | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | no <!-- don't forget to update UPGRADE-*.md files --> | Tests pass? | yes | Fixed tickets | api-platform/core#1130, api-platform/core#1528, api-platform/core#1528 <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | todo <!--highly recommended for new features--> Sometimes, instead of just stopping the serialization process when the configured max depth is reached, it can be interesting to let the user return something (like returning the identifier of the entity to stop manually the serialization process). This PR also makes the max depth handling more similar to circular references handling (that already has the possibility to set a handler). Commits ------- ed975c764b [Serializer] Add a MaxDepth handler
2 parents 3e93cd9 + 35d7386 commit b552837

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

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
-----

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
*/

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)