From 926d228877deb81c6edf86d3802894c4877b9e92 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Sat, 6 Apr 2019 16:28:08 +0200 Subject: [PATCH] [Serializer] Respect ignored attributes in cache key of normalizer --- .../Normalizer/AbstractNormalizer.php | 9 ++-- .../Normalizer/AbstractObjectNormalizer.php | 48 +++++++++++++++---- .../Tests/Normalizer/ObjectNormalizerTest.php | 10 ++++ 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index ef1166a493497..c5bd3ffd97202 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -397,7 +397,7 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara } $parameterClass = $parameter->getClass()->getName(); - return $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName)); + return $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName, $format)); } return $parameterData; @@ -407,14 +407,15 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara } /** - * @param array $parentContext - * @param string $attribute + * @param array $parentContext + * @param string $attribute Attribute name + * @param string|null $format * * @return array * * @internal */ - protected function createChildContext(array $parentContext, $attribute) + protected function createChildContext(array $parentContext, $attribute/*, string $format = null */) { if (isset($parentContext[self::ATTRIBUTES][$attribute])) { $parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute]; diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 17c31b132b29c..38908a9323ba1 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -94,7 +94,7 @@ public function normalize($object, $format = null, array $context = []) throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute)); } - $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute))); + $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute, $format))); } return $data; @@ -128,15 +128,13 @@ protected function getAttributes($object, $format = null, array $context) return $allowedAttributes; } - if (isset($context['attributes'])) { - return $this->extractAttributes($object, $format, $context); - } + $attributes = $this->extractAttributes($object, $format, $context); - if (isset($this->attributesCache[$class])) { - return $this->attributesCache[$class]; + if ($context['cache_key']) { + $this->attributesCache[$key] = $attributes; } - return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context); + return $attributes; } /** @@ -276,7 +274,7 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class)); } - $childContext = $this->createChildContext($context, $attribute); + $childContext = $this->createChildContext($context, $attribute, $format); if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) { return $this->serializer->denormalize($data, $class, $format, $childContext); } @@ -373,7 +371,32 @@ private function isMaxDepthReached(array $attributesMetadata, $class, $attribute } /** - * Gets the cache key to use. + * Overwritten to update the cache key for the child. + * + * We must not mix up the attribute cache between parent and children. + * + * {@inheritdoc} + */ + protected function createChildContext(array $parentContext, $attribute/*, string $format = null */) + { + if (\func_num_args() >= 3) { + $format = \func_get_arg(2); + } else { + // will be deprecated in version 4 + $format = null; + } + + $context = parent::createChildContext($parentContext, $attribute, $format); + // format is already included in the cache_key of the parent. + $context['cache_key'] = $this->getCacheKey($format, $context); + + return $context; + } + + /** + * Builds the cache key for the attributes cache. + * + * The key must be different for every option in the context that could change which attributes should be handled. * * @param string|null $format * @param array $context @@ -382,8 +405,13 @@ private function isMaxDepthReached(array $attributesMetadata, $class, $attribute */ private function getCacheKey($format, array $context) { + unset($context['cache_key']); // avoid artificially different keys try { - return md5($format.serialize($context)); + return md5($format.serialize([ + 'context' => $context, + 'ignored' => $this->ignoredAttributes, + 'camelized' => $this->camelizedAttributes, + ])); } catch (\Exception $exception) { // The context cannot be serialized, skip the cache return false; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 4b72e2a4b5032..b30739714b663 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -380,6 +380,16 @@ public function testIgnoredAttributes() ['fooBar' => 'foobar'], $this->normalizer->normalize($obj, 'any') ); + + $this->normalizer->setIgnoredAttributes(['foo', 'baz', 'camelCase', 'object']); + + $this->assertEquals( + [ + 'fooBar' => 'foobar', + 'bar' => 'bar', + ], + $this->normalizer->normalize($obj, 'any') + ); } public function testIgnoredAttributesDenormalize() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy