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 ----- 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); } 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..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; @@ -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
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: