From 1c979c01729672b13c44637f2cc55484dfc1fb33 Mon Sep 17 00:00:00 2001 From: soyuka Date: Mon, 27 Apr 2020 15:09:19 +0200 Subject: [PATCH] Fix serializer do not transform empty \Traversable to Array --- .../Component/Serializer/Serializer.php | 6 +++++- .../Serializer/Tests/SerializerTest.php | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 94770484738f0..c166e1263040b 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -157,6 +157,10 @@ public function normalize($data, $format = null, array $context = []) } if (\is_array($data) || $data instanceof \Traversable) { + if ($data instanceof \Countable && 0 === $data->count()) { + return $data; + } + $normalized = []; foreach ($data as $key => $val) { $normalized[$key] = $this->normalize($val, $format, $context); @@ -173,7 +177,7 @@ public function normalize($data, $format = null, array $context = []) throw new NotNormalizableValueException(sprintf('Could not normalize object of type "%s", no supporting normalizer found.', \get_class($data))); } - throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s.', !\is_resource($data) ? var_export($data, true) : sprintf('%s resource', get_resource_type($data)))); + throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: "%s".', !\is_resource($data) ? var_export($data, true) : sprintf('"%s" resource', get_resource_type($data)))); } /** diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 9864c4e940360..fe8f8de929692 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -25,6 +25,7 @@ use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\CustomNormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; @@ -490,6 +491,26 @@ public function testNotNormalizableValueExceptionMessageForAResource() (new Serializer())->normalize(tmpfile()); } + public function testNormalizePreserveEmptyArrayObject() + { + $serializer = new Serializer( + [ + new PropertyNormalizer(), + new ObjectNormalizer(), + new ArrayDenormalizer(), + ], + [ + 'json' => new JsonEncoder(), + ] + ); + + $object = []; + $object['foo'] = new \ArrayObject(); + $object['bar'] = new \ArrayObject(['notempty']); + $object['baz'] = new \ArrayObject(['nested' => new \ArrayObject()]); + $this->assertEquals('{"foo":{},"bar":["notempty"],"baz":{"nested":{}}}', $serializer->serialize($object, 'json', [AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS => true])); + } + private function serializerWithClassDiscriminator() { $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));