diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index a04da80f7d94c..d58cc7fda831d 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -415,6 +415,26 @@ private function validateAndDenormalize(string $currentClass, string $attribute, if (null !== $collectionKeyType = $type->getCollectionKeyType()) { $context['key_type'] = $collectionKeyType; } + } elseif ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_ARRAY === $collectionValueType->getBuiltinType()) { + // get inner type for any nested array + $innerType = $collectionValueType; + + // note that it will break for any other builtinType + $dimensions = '[]'; + while (null !== $innerType->getCollectionValueType() && Type::BUILTIN_TYPE_ARRAY === $innerType->getBuiltinType()) { + $dimensions .= '[]'; + $innerType = $innerType->getCollectionValueType(); + } + + if (null !== $innerType->getClassName()) { + // the builtinType is the inner one and the class is the class followed by []...[] + $builtinType = $innerType->getBuiltinType(); + $class = $innerType->getClassName().$dimensions; + } else { + // default fallback (keep it as array) + $builtinType = $type->getBuiltinType(); + $class = $type->getClassName(); + } } else { $builtinType = $type->getBuiltinType(); $class = $type->getClassName(); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php index 9a8eb3fb38c09..2b1d7769393a7 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php @@ -27,6 +27,7 @@ use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Serializer\Tests\Fixtures\Dummy; use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy; use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild; use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy; @@ -407,6 +408,52 @@ public function testInheritedPropertiesSupport() { $this->assertTrue($this->normalizer->supportsNormalization(new PropertyChildDummy())); } + + public function testMultiDimensionObject() + { + $normalizer = $this->getDenormalizerForTypeEnforcement(); + $root = $normalizer->denormalize([ + 'children' => [[ + ['foo' => 'one', 'bar' => 'two'], + ['foo' => 'three', 'bar' => 'four'], + ]], + 'grandChildren' => [[[ + ['foo' => 'five', 'bar' => 'six'], + ['foo' => 'seven', 'bar' => 'eight'], + ]]], + 'intMatrix' => [ + [0, 1, 2], + [3, 4, 5], + ], + ], + RootDummy::class, + 'any' + ); + $this->assertEquals(\get_class($root), RootDummy::class); + + // children (two dimension array) + $this->assertCount(1, $root->children); + $this->assertCount(2, $root->children[0]); + $firstChild = $root->children[0][0]; + $this->assertInstanceOf(Dummy::class, $firstChild); + $this->assertSame('one', $firstChild->foo); + $this->assertSame('two', $firstChild->bar); + + // grand children (three dimension array) + $this->assertCount(1, $root->grandChildren); + $this->assertCount(1, $root->grandChildren[0]); + $this->assertCount(2, $root->grandChildren[0][0]); + $firstGrandChild = $root->grandChildren[0][0][0]; + $this->assertInstanceOf(Dummy::class, $firstGrandChild); + $this->assertSame('five', $firstGrandChild->foo); + $this->assertSame('six', $firstGrandChild->bar); + + // int matrix + $this->assertSame([ + [0, 1, 2], + [3, 4, 5], + ], $root->intMatrix); + } } class PropertyDummy @@ -472,3 +519,34 @@ class PropertyParentDummy class PropertyChildDummy extends PropertyParentDummy { } + +class RootDummy +{ + public $children; + public $grandChildren; + public $intMatrix; + + /** + * @return Dummy[][] + */ + public function getChildren(): array + { + return $this->children; + } + + /** + * @return Dummy[][][] + */ + public function getGrandChildren() + { + return $this->grandChildren; + } + + /** + * @return array + */ + public function getIntMatrix() + { + return $this->intMatrix; + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy