Skip to content

Commit

Permalink
[Serializer] Fix denormalizing a collection of union types
Browse files Browse the repository at this point in the history
  • Loading branch information
HypeMC committed May 29, 2024
1 parent 972eb05 commit d7e6907
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
7 changes: 6 additions & 1 deletion Normalizer/AbstractObjectNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Symfony\Component\Serializer\Mapping\ClassMetadataInterface;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
use Symfony\Component\TypeInfo\Exception\LogicException as TypeInfoLogicException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\CollectionType;
use Symfony\Component\TypeInfo\Type\IntersectionType;
Expand Down Expand Up @@ -702,7 +703,11 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
}

if ($collectionValueType) {
$collectionValueBaseType = $collectionValueType instanceof UnionType ? $collectionValueType->asNonNullable()->getBaseType() : $collectionValueType->getBaseType();
try {
$collectionValueBaseType = $collectionValueType->getBaseType();
} catch (TypeInfoLogicException) {
$collectionValueBaseType = Type::mixed();
}

if ($collectionValueBaseType instanceof ObjectType) {
$typeIdentifier = TypeIdentifier::OBJECT;
Expand Down
38 changes: 38 additions & 0 deletions Tests/Normalizer/AbstractObjectNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,25 @@ public function testDenormalizeCollectionOfScalarTypesPropertyWithPhpDocExtracto

$this->assertEquals($expected, $normalizer->denormalize($data, ScalarCollectionDocBlockDummy::class));
}

public function testDenormalizeCollectionOfUnionTypesPropertyWithPhpDocExtractor()
{
$normalizer = new AbstractObjectNormalizerWithMetadataAndPhpDocExtractor();
$data = [
'values1' => [
'foo' => 'foo',
'bar' => 222,
],
'values2' => [
'baz' => 'baz',
'qux' => 333,
],
];
$expected = new UnionCollectionDocBlockDummy($data['values1']);
$expected->values2 = $data['values2'];

$this->assertEquals($expected, $normalizer->denormalize($data, UnionCollectionDocBlockDummy::class));
}
}

class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer
Expand Down Expand Up @@ -1577,6 +1596,22 @@ public function getValues(): ?array
}
}

class UnionCollectionDocBlockDummy
{
/**
* @param array<string, string|int> $values1
*/
public function __construct(
public array $values1,
) {
}

/**
* @var array<string, string|int>
*/
public array $values2;
}

class AbstractObjectNormalizerWithMetadataAndPhpDocExtractor extends AbstractObjectNormalizer
{
public function __construct()
Expand All @@ -1596,6 +1631,9 @@ protected function getAttributeValue(object $object, string $attribute, ?string

protected function setAttributeValue(object $object, string $attribute, mixed $value, ?string $format = null, array $context = []): void
{
if (property_exists($object, $attribute)) {
$object->$attribute = $value;
}
}

public function getSupportedTypes(?string $format): array
Expand Down

0 comments on commit d7e6907

Please sign in to comment.