From c87ac90c42c10895bdebe195f8b2963fddde5284 Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Thu, 15 Dec 2022 13:11:53 +0100 Subject: [PATCH] [Serializer] fix context attribute with serializedName --- .../Normalizer/AbstractNormalizer.php | 2 +- .../AbstractObjectNormalizerTest.php | 17 +++++++++++ .../ObjectDummyWithContextAttribute.php | 29 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummyWithContextAttribute.php diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 12c778cb803af..829e178407bd2 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -331,8 +331,8 @@ protected function instantiateObject(array &$data, string $class, array &$contex $params = []; foreach ($constructorParameters as $constructorParameter) { $paramName = $constructorParameter->name; + $attributeContext = $this->getAttributeDenormalizationContext($class, $paramName, $context); $key = $this->nameConverter ? $this->nameConverter->normalize($paramName, $class, $format, $context) : $paramName; - $attributeContext = $this->getAttributeDenormalizationContext($class, $key, $context); $allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes); $ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php index 9c8ba3ffcf4e2..4cc6686586e89 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; +use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\PropertyInfo\Type; use Symfony\Component\Serializer\Annotation\SerializedName; use Symfony\Component\Serializer\Annotation\SerializedPath; @@ -32,6 +33,7 @@ use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; @@ -41,6 +43,7 @@ use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummyFirstChild; use Symfony\Component\Serializer\Tests\Fixtures\Annotations\AbstractDummySecondChild; use Symfony\Component\Serializer\Tests\Fixtures\DummySecondChildQuux; +use Symfony\Component\Serializer\Tests\Normalizer\Features\ObjectDummyWithContextAttribute; class AbstractObjectNormalizerTest extends TestCase { @@ -525,6 +528,20 @@ public function testDenormalizeRecursiveWithObjectAttributeWithStringValue() $this->assertInstanceOf(ObjectInner::class, $obj->getInner()); } + + public function testDenormalizeUsesContextAttributeForPropertiesInConstructorWithSeralizedName() + { + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + + $extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]); + $normalizer = new ObjectNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, $extractor); + $serializer = new Serializer([new DateTimeNormalizer([DateTimeNormalizer::FORMAT_KEY => 'd-m-Y']), $normalizer]); + + /** @var ObjectDummyWithContextAttribute $obj */ + $obj = $serializer->denormalize(['property_with_serialized_name' => '01-02-2022', 'propertyWithoutSerializedName' => '01-02-2022'], ObjectDummyWithContextAttribute::class); + + $this->assertSame($obj->propertyWithSerializedName->format('Y-m-d'), $obj->propertyWithoutSerializedName->format('Y-m-d')); + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummyWithContextAttribute.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummyWithContextAttribute.php new file mode 100644 index 0000000000000..b846f042fe620 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummyWithContextAttribute.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Normalizer\Features; + +use Symfony\Component\Serializer\Annotation\Context; +use Symfony\Component\Serializer\Annotation\SerializedName; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; + +final class ObjectDummyWithContextAttribute +{ + public function __construct( + #[Context([DateTimeNormalizer::FORMAT_KEY => 'm-d-Y'])] + #[SerializedName('property_with_serialized_name')] + public \DateTimeImmutable $propertyWithSerializedName, + + #[Context([DateTimeNormalizer::FORMAT_KEY => 'm-d-Y'])] + public \DateTimeImmutable $propertyWithoutSerializedName, + ) { + } +}