[Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer
This commit is contained in:
parent
dc75ae2614
commit
ea03f6d664
@ -415,6 +415,26 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
|
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
|
||||||
$context['key_type'] = $collectionKeyType;
|
$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 {
|
} else {
|
||||||
$builtinType = $type->getBuiltinType();
|
$builtinType = $type->getBuiltinType();
|
||||||
$class = $type->getClassName();
|
$class = $type->getClassName();
|
||||||
|
@ -27,6 +27,7 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
|||||||
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
|
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
|
||||||
use Symfony\Component\Serializer\Serializer;
|
use Symfony\Component\Serializer\Serializer;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
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\GroupDummy;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
|
use Symfony\Component\Serializer\Tests\Fixtures\GroupDummyChild;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
|
use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
|
||||||
@ -407,6 +408,52 @@ class PropertyNormalizerTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->assertTrue($this->normalizer->supportsNormalization(new PropertyChildDummy()));
|
$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
|
class PropertyDummy
|
||||||
@ -472,3 +519,34 @@ class PropertyParentDummy
|
|||||||
class PropertyChildDummy extends 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user