[Serializer] Respect ignored attributes in cache key of normalizer
This commit is contained in:
parent
b30f57e14b
commit
926d228877
@ -397,7 +397,7 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
|
|||||||
}
|
}
|
||||||
$parameterClass = $parameter->getClass()->getName();
|
$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;
|
return $parameterData;
|
||||||
@ -407,14 +407,15 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $parentContext
|
* @param array $parentContext
|
||||||
* @param string $attribute
|
* @param string $attribute Attribute name
|
||||||
|
* @param string|null $format
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected function createChildContext(array $parentContext, $attribute)
|
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
|
||||||
{
|
{
|
||||||
if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
|
if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
|
||||||
$parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];
|
$parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];
|
||||||
|
@ -94,7 +94,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
|
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;
|
return $data;
|
||||||
@ -128,15 +128,13 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
return $allowedAttributes;
|
return $allowedAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($context['attributes'])) {
|
$attributes = $this->extractAttributes($object, $format, $context);
|
||||||
return $this->extractAttributes($object, $format, $context);
|
|
||||||
|
if ($context['cache_key']) {
|
||||||
|
$this->attributesCache[$key] = $attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->attributesCache[$class])) {
|
return $attributes;
|
||||||
return $this->attributesCache[$class];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,7 +274,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class));
|
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)) {
|
if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) {
|
||||||
return $this->serializer->denormalize($data, $class, $format, $childContext);
|
return $this->serializer->denormalize($data, $class, $format, $childContext);
|
||||||
}
|
}
|
||||||
@ -373,7 +371,32 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 string|null $format
|
||||||
* @param array $context
|
* @param array $context
|
||||||
@ -382,8 +405,13 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
*/
|
*/
|
||||||
private function getCacheKey($format, array $context)
|
private function getCacheKey($format, array $context)
|
||||||
{
|
{
|
||||||
|
unset($context['cache_key']); // avoid artificially different keys
|
||||||
try {
|
try {
|
||||||
return md5($format.serialize($context));
|
return md5($format.serialize([
|
||||||
|
'context' => $context,
|
||||||
|
'ignored' => $this->ignoredAttributes,
|
||||||
|
'camelized' => $this->camelizedAttributes,
|
||||||
|
]));
|
||||||
} catch (\Exception $exception) {
|
} catch (\Exception $exception) {
|
||||||
// The context cannot be serialized, skip the cache
|
// The context cannot be serialized, skip the cache
|
||||||
return false;
|
return false;
|
||||||
|
@ -380,6 +380,16 @@ class ObjectNormalizerTest extends TestCase
|
|||||||
['fooBar' => 'foobar'],
|
['fooBar' => 'foobar'],
|
||||||
$this->normalizer->normalize($obj, 'any')
|
$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()
|
public function testIgnoredAttributesDenormalize()
|
||||||
|
Reference in New Issue
Block a user