Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 926d228

Browse files
dbufabpot
authored andcommitted
[Serializer] Respect ignored attributes in cache key of normalizer
1 parent b30f57e commit 926d228

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara
397397
}
398398
$parameterClass = $parameter->getClass()->getName();
399399

400-
return $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName));
400+
return $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName, $format));
401401
}
402402

403403
return $parameterData;
@@ -407,14 +407,15 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara
407407
}
408408

409409
/**
410-
* @param array $parentContext
411-
* @param string $attribute
410+
* @param array $parentContext
411+
* @param string $attribute Attribute name
412+
* @param string|null $format
412413
*
413414
* @return array
414415
*
415416
* @internal
416417
*/
417-
protected function createChildContext(array $parentContext, $attribute)
418+
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
418419
{
419420
if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
420421
$parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function normalize($object, $format = null, array $context = [])
9494
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
9595
}
9696

97-
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute)));
97+
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute, $format)));
9898
}
9999

100100
return $data;
@@ -128,15 +128,13 @@ protected function getAttributes($object, $format = null, array $context)
128128
return $allowedAttributes;
129129
}
130130

131-
if (isset($context['attributes'])) {
132-
return $this->extractAttributes($object, $format, $context);
133-
}
131+
$attributes = $this->extractAttributes($object, $format, $context);
134132

135-
if (isset($this->attributesCache[$class])) {
136-
return $this->attributesCache[$class];
133+
if ($context['cache_key']) {
134+
$this->attributesCache[$key] = $attributes;
137135
}
138136

139-
return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context);
137+
return $attributes;
140138
}
141139

142140
/**
@@ -276,7 +274,7 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma
276274
throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class));
277275
}
278276

279-
$childContext = $this->createChildContext($context, $attribute);
277+
$childContext = $this->createChildContext($context, $attribute, $format);
280278
if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) {
281279
return $this->serializer->denormalize($data, $class, $format, $childContext);
282280
}
@@ -373,7 +371,32 @@ private function isMaxDepthReached(array $attributesMetadata, $class, $attribute
373371
}
374372

375373
/**
376-
* Gets the cache key to use.
374+
* Overwritten to update the cache key for the child.
375+
*
376+
* We must not mix up the attribute cache between parent and children.
377+
*
378+
* {@inheritdoc}
379+
*/
380+
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
381+
{
382+
if (\func_num_args() >= 3) {
383+
$format = \func_get_arg(2);
384+
} else {
385+
// will be deprecated in version 4
386+
$format = null;
387+
}
388+
389+
$context = parent::createChildContext($parentContext, $attribute, $format);
390+
// format is already included in the cache_key of the parent.
391+
$context['cache_key'] = $this->getCacheKey($format, $context);
392+
393+
return $context;
394+
}
395+
396+
/**
397+
* Builds the cache key for the attributes cache.
398+
*
399+
* The key must be different for every option in the context that could change which attributes should be handled.
377400
*
378401
* @param string|null $format
379402
* @param array $context
@@ -382,8 +405,13 @@ private function isMaxDepthReached(array $attributesMetadata, $class, $attribute
382405
*/
383406
private function getCacheKey($format, array $context)
384407
{
408+
unset($context['cache_key']); // avoid artificially different keys
385409
try {
386-
return md5($format.serialize($context));
410+
return md5($format.serialize([
411+
'context' => $context,
412+
'ignored' => $this->ignoredAttributes,
413+
'camelized' => $this->camelizedAttributes,
414+
]));
387415
} catch (\Exception $exception) {
388416
// The context cannot be serialized, skip the cache
389417
return false;

src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,16 @@ public function testIgnoredAttributes()
380380
['fooBar' => 'foobar'],
381381
$this->normalizer->normalize($obj, 'any')
382382
);
383+
384+
$this->normalizer->setIgnoredAttributes(['foo', 'baz', 'camelCase', 'object']);
385+
386+
$this->assertEquals(
387+
[
388+
'fooBar' => 'foobar',
389+
'bar' => 'bar',
390+
],
391+
$this->normalizer->normalize($obj, 'any')
392+
);
383393
}
384394

385395
public function testIgnoredAttributesDenormalize()

0 commit comments

Comments
 (0)