Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
minor #20529 [Serializer] Optimize max depth checking (dunglas)
This PR was merged into the 3.1 branch.

Discussion
----------

[Serializer] Optimize max depth checking

| Q             | A
| ------------- | ---
| Branch?       | 3.1
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes/no
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Avoid to call the metadata factory for each attribute when max depth checking is enabled.
Prepare the code for the "serialized name" feature (that also requires metadata) in Symfony 3.3.

Commits
-------

bb3ee76 [Serializer] Optimize max depth checking
  • Loading branch information
fabpot committed Dec 13, 2016
2 parents 0a6f127 + bb3ee76 commit e55f79b
Showing 1 changed file with 18 additions and 23 deletions.
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

Expand Down Expand Up @@ -67,9 +68,10 @@ public function normalize($object, $format = null, array $context = array())
$stack = array();
$attributes = $this->getAttributes($object, $format, $context);
$class = get_class($object);
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;

foreach ($attributes as $attribute) {
if ($this->isMaxDepthReached($class, $attribute, $context)) {
if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) {
continue;
}

Expand Down Expand Up @@ -289,42 +291,35 @@ private function updateData(array $data, $attribute, $attributeValue)
/**
* Is the max depth reached for the given attribute?
*
* @param string $class
* @param string $attribute
* @param array $context
* @param AttributeMetadataInterface[] $attributesMetadata
* @param string $class
* @param string $attribute
* @param array $context
*
* @return bool
*/
private function isMaxDepthReached($class, $attribute, array &$context)
private function isMaxDepthReached(array $attributesMetadata, $class, $attribute, array &$context)
{
if (!$this->classMetadataFactory || !isset($context[static::ENABLE_MAX_DEPTH])) {
if (
!isset($context[static::ENABLE_MAX_DEPTH]) ||
!isset($attributesMetadata[$attribute]) ||
null === $maxDepth = $attributesMetadata[$attribute]->getMaxDepth()
) {
return false;
}

$classMetadata = $this->classMetadataFactory->getMetadataFor($class);
$attributesMetadata = $classMetadata->getAttributesMetadata();

if (!isset($attributesMetadata[$attribute])) {
return false;
}
$key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute);
if (!isset($context[$key])) {
$context[$key] = 1;

$maxDepth = $attributesMetadata[$attribute]->getMaxDepth();
if (null === $maxDepth) {
return false;
}

$key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute);
$keyExist = isset($context[$key]);

if ($keyExist && $context[$key] === $maxDepth) {
if ($context[$key] === $maxDepth) {
return true;
}

if ($keyExist) {
++$context[$key];
} else {
$context[$key] = 1;
}
++$context[$key];

return false;
}
Expand Down

0 comments on commit e55f79b

Please sign in to comment.