From 0ac5346bf56e9300b38e838f47b5e28c5c1fa8df Mon Sep 17 00:00:00 2001 From: Anto Date: Tue, 5 Nov 2019 21:12:31 +0100 Subject: [PATCH] [Serializer] Use context to compute MetadataAwareNameConverter cache --- .../MetadataAwareNameConverter.php | 39 ++++++++++++------- .../MetadataAwareNameConverterTest.php | 23 +++++++++++ 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Serializer/NameConverter/MetadataAwareNameConverter.php b/src/Symfony/Component/Serializer/NameConverter/MetadataAwareNameConverter.php index 9cd20bdefe16..ea69a573632b 100644 --- a/src/Symfony/Component/Serializer/NameConverter/MetadataAwareNameConverter.php +++ b/src/Symfony/Component/Serializer/NameConverter/MetadataAwareNameConverter.php @@ -26,11 +26,11 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface */ private $fallbackNameConverter; - private $normalizeCache = []; + private static $normalizeCache = []; - private $denormalizeCache = []; + private static $denormalizeCache = []; - private $attributesMetadataCache = []; + private static $attributesMetadataCache = []; public function __construct(ClassMetadataFactoryInterface $metadataFactory, NameConverterInterface $fallbackNameConverter = null) { @@ -47,11 +47,11 @@ public function normalize($propertyName, string $class = null, string $format = return $this->normalizeFallback($propertyName, $class, $format, $context); } - if (!isset($this->normalizeCache[$class][$propertyName])) { - $this->normalizeCache[$class][$propertyName] = $this->getCacheValueForNormalization($propertyName, $class); + if (!isset(self::$normalizeCache[$class][$propertyName])) { + self::$normalizeCache[$class][$propertyName] = $this->getCacheValueForNormalization($propertyName, $class); } - return $this->normalizeCache[$class][$propertyName] ?? $this->normalizeFallback($propertyName, $class, $format, $context); + return self::$normalizeCache[$class][$propertyName] ?? $this->normalizeFallback($propertyName, $class, $format, $context); } /** @@ -63,11 +63,12 @@ public function denormalize($propertyName, string $class = null, string $format return $this->denormalizeFallback($propertyName, $class, $format, $context); } - if (!isset($this->denormalizeCache[$class][$propertyName])) { - $this->denormalizeCache[$class][$propertyName] = $this->getCacheValueForDenormalization($propertyName, $class, $context); + $cacheKey = $this->getCacheKey($class, $context); + if (!isset(self::$denormalizeCache[$cacheKey][$propertyName])) { + self::$denormalizeCache[$cacheKey][$propertyName] = $this->getCacheValueForDenormalization($propertyName, $class, $context); } - return $this->denormalizeCache[$class][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context); + return self::$denormalizeCache[$cacheKey][$propertyName] ?? $this->denormalizeFallback($propertyName, $class, $format, $context); } private function getCacheValueForNormalization($propertyName, string $class) @@ -89,13 +90,14 @@ private function normalizeFallback($propertyName, string $class = null, string $ return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName; } - private function getCacheValueForDenormalization($propertyName, string $class, $context) + private function getCacheValueForDenormalization($propertyName, string $class, array $context) { - if (!isset($this->attributesMetadataCache[$class])) { - $this->attributesMetadataCache[$class] = $this->getCacheValueForAttributesMetadata($class, $context); + $cacheKey = $this->getCacheKey($class, $context); + if (!isset(self::$attributesMetadataCache[$cacheKey])) { + self::$attributesMetadataCache[$cacheKey] = $this->getCacheValueForAttributesMetadata($class, $context); } - return $this->attributesMetadataCache[$class][$propertyName] ?? null; + return self::$attributesMetadataCache[$cacheKey][$propertyName] ?? null; } private function denormalizeFallback($propertyName, string $class = null, string $format = null, array $context = []) @@ -103,7 +105,7 @@ private function denormalizeFallback($propertyName, string $class = null, string return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName; } - private function getCacheValueForAttributesMetadata(string $class, $context): array + private function getCacheValueForAttributesMetadata(string $class, array $context): array { if (!$this->metadataFactory->hasMetadataFor($class)) { return []; @@ -130,4 +132,13 @@ private function getCacheValueForAttributesMetadata(string $class, $context): ar return $cache; } + + private function getCacheKey(string $class, array $context): string + { + if (isset($context['cache_key'])) { + return $class.'-'.$context['cache_key']; + } + + return $class.md5(serialize($context[AbstractNormalizer::GROUPS] ?? [])); + } } diff --git a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php index c1c906e6ce98..d95c3ca91d2e 100644 --- a/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php +++ b/src/Symfony/Component/Serializer/Tests/NameConverter/MetadataAwareNameConverterTest.php @@ -117,6 +117,18 @@ public function fallbackAttributeProvider() ]; } + /** + * @dataProvider attributeAndContextProvider + */ + public function testNormalizeWithGroups($propertyName, $expected, $context = []) + { + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + + $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); + + $this->assertEquals($expected, $nameConverter->normalize($propertyName, OtherSerializedNameDummy::class, null, $context)); + } + /** * @dataProvider attributeAndContextProvider */ @@ -138,4 +150,15 @@ public function attributeAndContextProvider() ['buz', 'buz', []], ]; } + + public function testDenormalizeWithCacheContext() + { + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + + $nameConverter = new MetadataAwareNameConverter($classMetadataFactory); + + $this->assertEquals('buz', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class, null, ['groups' => ['a']])); + $this->assertEquals('buzForExport', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class, null, ['groups' => ['b']])); + $this->assertEquals('buz', $nameConverter->denormalize('buz', OtherSerializedNameDummy::class)); + } }