8000 feature #32832 [Serializer] Allow multi-dimenstion object array in Ab… · symfony/symfony@6916822 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6916822

Browse files
committed
feature #32832 [Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer (alediator)
This PR was submitted for the 4.3 branch but it was squashed and merged into the 4.4 branch instead (closes #32832). Discussion ---------- [Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer Modify ´AbstractObjectNormalizer´ adding the capability of parsing nested arrays of objects instead of parsing them into arrays | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #31175 | License | MIT I was trying to parse a nested array of objects and I'd find out with this #31175 behavior. After trying to solve in different ways, I was able to do it adding the fix that allows the `AbstractObjectNormalizer` to parse more than one dimension array of objects. I would like to add some tests to assure it works and doesn't generate any side effects, but I'd prefer to open the PR to link it to the existing issue #31175. On the other hand, if you think it is not applicable or you want me to change anything, please let me know. Commits ------- ea03f6d [Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer
2 parents dc75ae2 + ea03f6d commit 6916822

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,26 @@ private function validateAndDenormalize(string $currentClass, string $attribute,
415415
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
416416
$context['key_type'] = $collectionKeyType;
417417
}
418+
} elseif ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_ARRAY === $collectionValueType->getBuiltinType()) {
419+
// get inner type for any nested array
420+
$innerType = $collectionValueType;
421+
422+
// note that it will break for any other builtinType
423+
$dimensions = '[]';
424+
while (null !== $innerType->getCollectionValueType() && Type::BUILTIN_TYPE_ARRAY === $innerType->getBuiltinType()) {
425+
$dimensions .= '[]';
426+
$innerType = $innerType->getCollectionValueType();
427+
}
428+
429+
if (null !== $innerType->getClassName()) {
430+
// the builtinType is the inner one and the class is the class followed by []...[]
431+
$builtinType = $innerType->getBuiltinType();
432+
$class = $innerType->getClassName().$dimensions;
433+
} else {
434+
// default fallback (keep it as array)
435+
$builtinType = $type->getBuiltinType();
436+
$class = $type->getClassName();
437+
}
418438
} else {
419439
$builtinType = $type->getBuiltinType();
420440
$class = $type->getClassName();

src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
2828
use Symfony\Component\Serializer\Serializer;
2929
use Symfony\Component\Serializer\SerializerInterface;
30+
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
3031
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
3132
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
3233
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
@@ -407,6 +408,52 @@ public function testInheritedPropertiesSupport()
407408
{
408409
$this->assertTrue($this->normalizer->supportsNormalization(new PropertyChildDummy()));
409410
}
411+
412+
public function testMultiDimensionObject()
413+
{
414+
$normalizer = $this->getDenormalizerForTypeEnforcement();
415+
$root = $normalizer->denormalize([
416+
'children' => [[
417+
['foo' => 'one', 'bar' => 'two'],
418+
['foo' => 'three', 'bar' => 'four'],
419+
]],
420+
'grandChildren' => [[[
421+
['foo' => 'five', 'bar' => 'six'],
422+
['foo' => 'seven', 'bar' => 'eight'],
423+
]]],
424+
'intMatrix' => [
425+
[0, 1, 2],
426+
[3, 4, 5],
427+
],
428+
],
429+
RootDummy::class,
430+
'any'
431+
);
432+
$this->assertEquals(\get_class($root), RootDummy::class);
433+
434+
// children (two dimension array)
435+
$this->assertCount(1, $root->children);
436+
$this->assertCount(2, $root->children[0]);
437+
$firstChild = $root->children[0][0];
438+
$this->assertInstanceOf(Dummy::class, $firstChild);
439+
$this->assertSame('one', $firstChild->foo);
440+
$this->assertSame('two', < 8000 span class=pl-s1>$firstChild->bar);
441+
442+
// grand children (three dimension array)
443+
$this->assertCount(1, $root->grandChildren);
444+
$this->assertCount(1, $root->grandChildren[0]);
445+
$this->assertCount(2, $root->grandChildren[0][0]);
446+
$firstGrandChild = $root->grandChildren[0][0][0];
447+
$this->assertInstanceOf(Dummy::class, $firstGrandChild);
448+
$this->assertSame('five', $firstGrandChild->foo);
449+
$this->assertSame('six', $firstGrandChild->bar);
450+
451+
// int matrix
452+
$this->assertSame([
453+
[0, 1, 2],
454+
[3, 4, 5],
455+
], $root->intMatrix);
456+
}
410457
}
411458

412459
class PropertyDummy
@@ -472,3 +519,34 @@ class PropertyParentDummy
472519
class PropertyChildDummy extends PropertyParentDummy
473520
{
474521
}
522+
523+
class RootDummy
524+
{
525+
public $children;
526+
public $grandChildren;
527+
public $intMatrix;
528+
529+
/**
530+
* @return Dummy[][]
531+
*/
532+
public function getChildren(): array
533+
{
534+
return $this->children;
535+
}
536+
537+
/**
538+
* @return Dummy[][][]
539+
*/
540+
public function getGrandChildren()
541+
{
542+
return $this->grandChildren;
543+
}
544+
545+
/**
546+
* @return array
547+
*/
548+
public function getIntMatrix()
549+
{
550+
return $this->intMatrix;
551+
}
552+
}

0 commit comments

Comments
 (0)
0