From b8353e4208e9161f34d22c4631c63404b26ba929 Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Tue, 19 Dec 2023 12:58:10 +0100 Subject: [PATCH] [Serializer] Skip uninitialized properties with deep_object_to_populate --- Normalizer/AbstractObjectNormalizer.php | 8 ++++++++ .../Features/SkipUninitializedValuesTestTrait.php | 13 +++++++++++-- Tests/Normalizer/GetSetMethodNormalizerTest.php | 2 +- Tests/Normalizer/PropertyNormalizerTest.php | 3 +-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index 3e1ddc2e2..cd24de584 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -403,6 +403,14 @@ public function denormalize($data, string $type, string $format = null, array $c ? $this->classDiscriminatorResolver->getTypeForMappedObject($object) : $this->getAttributeValue($object, $attribute, $format, $attributeContext); } catch (NoSuchPropertyException $e) { + } catch (UninitializedPropertyException $e) { + if (!($context[self::SKIP_UNINITIALIZED_VALUES] ?? $this->defaultContext[self::SKIP_UNINITIALIZED_VALUES] ?? true)) { + throw $e; + } + } catch (\Error $e) { + if (!(($context[self::SKIP_UNINITIALIZED_VALUES] ?? $this->defaultContext[self::SKIP_UNINITIALIZED_VALUES] ?? true) && $this->isUninitializedValueError($e))) { + throw $e; + } } } diff --git a/Tests/Normalizer/Features/SkipUninitializedValuesTestTrait.php b/Tests/Normalizer/Features/SkipUninitializedValuesTestTrait.php index 0d17ba46d..596b3404b 100644 --- a/Tests/Normalizer/Features/SkipUninitializedValuesTestTrait.php +++ b/Tests/Normalizer/Features/SkipUninitializedValuesTestTrait.php @@ -12,14 +12,14 @@ namespace Symfony\Component\Serializer\Tests\Normalizer\Features; use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; -use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; /** * Test AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES. */ trait SkipUninitializedValuesTestTrait { - abstract protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface; + abstract protected function getNormalizerForSkipUninitializedValues(): AbstractObjectNormalizer; /** * @requires PHP 7.4 @@ -33,6 +33,15 @@ public function testSkipUninitializedValues(array $context) $normalizer = $this->getNormalizerForSkipUninitializedValues(); $result = $normalizer->normalize($object, null, $context); $this->assertSame(['initialized' => 'value'], $result); + + $normalizer->denormalize( + ['unInitialized' => 'value'], + TypedPropertiesObjectWithGetters::class, + null, + ['object_to_populate' => $objectToPopulate = new TypedPropertiesObjectWithGetters(), 'deep_object_to_populate' => true] + $context + ); + + $this->assertSame('value', $objectToPopulate->getUninitialized()); } public function skipUninitializedValuesFlagProvider(): iterable diff --git a/Tests/Normalizer/GetSetMethodNormalizerTest.php b/Tests/Normalizer/GetSetMethodNormalizerTest.php index e90f221eb..f6b2c3e69 100644 --- a/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -496,7 +496,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): GetSetMethod return new GetSetMethodNormalizer(); } - protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface + protected function getNormalizerForSkipUninitializedValues(): GetSetMethodNormalizer { return new GetSetMethodNormalizer(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); } diff --git a/Tests/Normalizer/PropertyNormalizerTest.php b/Tests/Normalizer/PropertyNormalizerTest.php index 1d1de25b4..3257c30fd 100644 --- a/Tests/Normalizer/PropertyNormalizerTest.php +++ b/Tests/Normalizer/PropertyNormalizerTest.php @@ -26,7 +26,6 @@ use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; -use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; @@ -455,7 +454,7 @@ protected function getNormalizerForCacheableObjectAttributesTest(): AbstractObje return new PropertyNormalizer(); } - protected function getNormalizerForSkipUninitializedValues(): NormalizerInterface + protected function getNormalizerForSkipUninitializedValues(): PropertyNormalizer { return new PropertyNormalizer(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); }