From 90c3483727c58f8820368bcc57ec966cd319c38d Mon Sep 17 00:00:00 2001 From: idsulik Date: Tue, 3 Nov 2020 15:00:04 +0300 Subject: [PATCH 1/4] [Serializer] Add SKIP_UNINITIALIZED_PROPERTIES context property to AbstractObjectNormalizer to skip uninitialized properties when normalizing object. --- .../Normalizer/AbstractObjectNormalizer.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index aa1be48cfbaf5..866d3f72c9962 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -13,6 +13,7 @@ use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException; use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; +use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; use Symfony\Component\PropertyInfo\Type; use Symfony\Component\Serializer\Encoder\CsvEncoder; @@ -58,6 +59,12 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer */ public const SKIP_NULL_VALUES = 'skip_null_values'; + /** + * Flag to control whether uninitialized fields should be skipped + * when normalizing. + */ + public const SKIP_UNINITIALIZED_PROPERTIES = 'skip_uninitialized_properties'; + /** * Callback to allow to set a value for an attribute when the max depth has * been reached. @@ -175,7 +182,17 @@ public function normalize($object, string $format = null, array $context = []) continue; } - $attributeValue = $this->getAttributeValue($object, $attribute, $format, $context); + $attributeValue = null; + try { + $attributeValue = $this->getAttributeValue($object, $attribute, $format, $context); + } catch (UninitializedPropertyException $e) { + if (isset($context[self::SKIP_UNINITIALIZED_PROPERTIES])) { + continue; + } + + throw $e; + } + if ($maxDepthReached) { $attributeValue = $maxDepthHandler($attributeValue, $object, $attribute, $format, $context); } From c4d4a83b52be5afa37deb9d18eadeb2bc82b7795 Mon Sep 17 00:00:00 2001 From: idsulik Date: Tue, 3 Nov 2020 15:40:08 +0300 Subject: [PATCH 2/4] Add test SKIP_UNINITIALIZED_PROPERTIES --- .../Normalizer/Features/ObjectDummy2.php | 16 ++++++++++ .../SkipUninitializedPropertiesTestTrait.php | 32 +++++++++++++++++++ .../Tests/Normalizer/ObjectNormalizerTest.php | 9 ++++++ 3 files changed, 57 insertions(+) create mode 100644 src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy2.php create mode 100644 src/Symfony/Component/Serializer/Tests/Normalizer/Features/SkipUninitializedPropertiesTestTrait.php diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy2.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy2.php new file mode 100644 index 0000000000000..2abf7a4b1cc58 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ObjectDummy2.php @@ -0,0 +1,16 @@ +bar = 'present'; + + $normalizer = $this->getNormalizerForSkipUninitializedProperties(); + $result = $normalizer->normalize($dummy, null, ['skip_uninitialized_properties' => true]); + $this->assertSame(['bar' => 'present'], $result); + } + + public function testWithoutSkipUninitializedProperties() + { + $this->expectException(UninitializedPropertyException::class); + + $normalizer = $this->getNormalizerForSkipUninitializedProperties(); + $normalizer->normalize(new ObjectDummy2(), null); + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 66d578f1ebf85..8ddeba21f7ae5 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -43,6 +43,7 @@ use Symfony\Component\Serializer\Tests\Normalizer\Features\ObjectDummy; use Symfony\Component\Serializer\Tests\Normalizer\Features\ObjectToPopulateTestTrait; use Symfony\Component\Serializer\Tests\Normalizer\Features\SkipNullValuesTestTrait; +use Symfony\Component\Serializer\Tests\Normalizer\Features\SkipUninitializedPropertiesTestTrait; use Symfony\Component\Serializer\Tests\Normalizer\Features\TypeEnforcementTestTrait; /** @@ -59,6 +60,7 @@ class ObjectNormalizerTest extends TestCase use MaxDepthTestTrait; use ObjectToPopulateTestTrait; use SkipNullValuesTestTrait; + use SkipUninitializedPropertiesTestTrait; use TypeEnforcementTestTrait; /** @@ -506,6 +508,13 @@ protected function getNormalizerForSkipNullValues(): ObjectNormalizer return new ObjectNormalizer(); } + // skip uninitialized + + protected function getNormalizerForSkipUninitializedProperties(): ObjectNormalizer + { + return new ObjectNormalizer(); + } + // type enforcement protected function getDenormalizerForTypeEnforcement(): ObjectNormalizer From aceaaf57b4b18efa271955759a6398bf81afe718 Mon Sep 17 00:00:00 2001 From: idsulik Date: Tue, 3 Nov 2020 15:44:35 +0300 Subject: [PATCH 3/4] Fix ObjectNormalizerTest.php cs --- .../Serializer/Tests/Normalizer/ObjectNormalizerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 8ddeba21f7ae5..5094e01e0bfbd 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -28,8 +28,8 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; use Symfony\Component\Serializer\Tests\Fixtures\Annotations\GroupDummy; +use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; use Symfony\Component\Serializer\Tests\Fixtures\OtherSerializedNameDummy; use Symfony\Component\Serializer\Tests\Fixtures\Php74Dummy; use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder; From 6b4f043d8e5fceea645f13ccf381e23d30f77c9b Mon Sep 17 00:00:00 2001 From: idsulik Date: Tue, 3 Nov 2020 15:50:02 +0300 Subject: [PATCH 4/4] Update Serializer CHANGELOG.md --- src/Symfony/Component/Serializer/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 97ae3fd62fdab..e652194340038 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -9,6 +9,7 @@ CHANGELOG * added `FormErrorNormalizer` * added `MimeMessageNormalizer` * serializer mapping can be configured using php attributes + * added `skip_uninitialized_properties` context option to not serialize uninitialized properties 5.1.0 -----