Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ad9e6e

Browse files
committed
[Serializer] Fix deserializing object collection properties
1 parent 6d11c7a commit 7ad9e6e

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

src/Symfony/Component/Serializer/Serializer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,14 @@ private function getDenormalizer(mixed $data, string $class, ?string $format, ar
359359

360360
$supportedTypes = $normalizer->getSupportedTypes($format);
361361

362+
$doesClassRepresentCollection = str_ends_with($class, '[]');
363+
362364
foreach ($supportedTypes as $supportedType => $isCacheable) {
365+
$doesSupportedTypeRepresentCollection = str_ends_with($supportedType, '[]');
366+
363367
if (\in_array($supportedType, ['*', 'object'], true)
364368
|| $class !== $supportedType && ('object' !== $genericType || !is_subclass_of($class, $supportedType))
369+
&& !($doesClassRepresentCollection && $doesSupportedTypeRepresentCollection && is_subclass_of(strstr($class, '[]', true), strstr($supportedType, '[]', true)))
365370
) {
366371
continue;
367372
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
interface FooDummyInterface
15+
{
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
final class FooImplementationDummy implements FooDummyInterface
15+
{
16+
/**
17+
* @var string
18+
*/
19+
public $name;
20+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
15+
16+
final class FooInterfaceDummyDenormalizer implements DenormalizerInterface
17+
{
18+
public function denormalize(mixed $data, string $type, string $format = null, array $context = []): array
19+
{
20+
$result = [];
21+
foreach ($data as $foo) {
22+
$fooDummy = new FooImplementationDummy();
23+
$fooDummy->name = $foo['name'];
24+
$result[] = $fooDummy;
25+
}
26+
27+
return $result;
28+
}
29+
30+
public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool
31+
{
32+
if (str_ends_with($type, '[]')) {
33+
$className = substr($type, 0, -2);
34+
$classImplements = class_implements($className);
35+
\assert(\is_array($classImplements));
36+
37+
return class_exists($className) && \in_array(FooDummyInterface::class, $classImplements, true);
38+
}
39+
40+
return false;
41+
}
42+
43+
/**
44+
* @return array<string, bool>
45+
*/
46+
public function getSupportedTypes(?string $format): array
47+
{
48+
return [FooDummyInterface::class.'[]' => false];
49+
}
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
final class ObjectCollectionPropertyDummy
15+
{
16+
/**
17+
* @var FooImplementationDummy[]
18+
*/
19+
public $foo;
20+
21+
public function getFoo(): array
22+
{
23+
return $this->foo;
24+
}
25+
}

src/Symfony/Component/Serializer/Tests/SerializerTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@
5858
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor;
5959
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty;
6060
use Symfony\Component\Serializer\Tests\Fixtures\FalseBuiltInDummy;
61+
use Symfony\Component\Serializer\Tests\Fixtures\FooImplementationDummy;
62+
use Symfony\Component\Serializer\Tests\Fixtures\FooInterfaceDummyDenormalizer;
6163
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
64+
use Symfony\Component\Serializer\Tests\Fixtures\ObjectCollectionPropertyDummy;
6265
use Symfony\Component\Serializer\Tests\Fixtures\Php74Full;
6366
use Symfony\Component\Serializer\Tests\Fixtures\Php80WithPromotedTypedConstructor;
6467
use Symfony\Component\Serializer\Tests\Fixtures\TraversableDummy;
@@ -711,6 +714,21 @@ public function testDeserializeInconsistentScalarArray()
711714
$serializer->deserialize('["42"]', 'int[]', 'json');
712715
}
713716

717+
public function testDeserializeOnObjectWithObjectCollectionProperty()
718+
{
719+
$serializer = new Serializer([new FooInterfaceDummyDenormalizer(), new ObjectNormalizer(null, null, null, new PhpDocExtractor())], [new JsonEncoder()]);
720+
721+
$obj = $serializer->deserialize('{"foo":[{"name":"bar"}]}', ObjectCollectionPropertyDummy::class, 'json');
722+
$this->assertInstanceOf(ObjectCollectionPropertyDummy::class, $obj);
723+
724+
$fooDummyObjects = $obj->getFoo();
725+
$this->assertCount(1, $fooDummyObjects);
726+
727+
$fooDummyObject = $fooDummyObjects[0];
728+
$this->assertInstanceOf(FooImplementationDummy::class, $fooDummyObject);
729+
$this->assertSame('bar', $fooDummyObject->name);
730+
}
731+
714732
public function testDeserializeWrappedScalar()
715733
{
716734
$serializer = new Serializer([new UnwrappingDenormalizer()], ['json' => new JsonEncoder()]);

0 commit comments

Comments
 (0)