Skip to content

Commit dc554d7

Browse files
Merge branch '4.4' into 5.4
* 4.4: [HttpKernel] Fix a PHP 8.1 deprecation notice in HttpCache [Serializer] Fix denormalization union types with constructor
2 parents e9c80ee + bd020a5 commit dc554d7

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

Normalizer/AbstractObjectNormalizer.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2222
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2323
use Symfony\Component\Serializer\Exception\LogicException;
24+
use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException;
2425
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2526
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
2627
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
@@ -437,13 +438,16 @@ abstract protected function setAttributeValue(object $object, string $attribute,
437438
* @return mixed
438439
*
439440
* @throws NotNormalizableValueException
441+
* @throws ExtraAttributesException
442+
* @throws MissingConstructorArgumentsException
440443
* @throws LogicException
441444
*/
442445
private function validateAndDenormalize(array $types, string $currentClass, string $attribute, $data, ?string $format, array $context)
443446
{
444447
$expectedTypes = [];
445448
$isUnionType = \count($types) > 1;
446449
$extraAttributesException = null;
450+
$missingConstructorArgumentException = null;
447451
foreach ($types as $type) {
448452
if (null === $data && $type->isNullable()) {
449453
return null;
@@ -587,13 +591,25 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
587591
if (!$extraAttributesException) {
588592
$extraAttributesException = $e;
589593
}
594+
} catch (MissingConstructorArgumentsException $e) {
595+
if (!$isUnionType) {
596+
throw $e;
597+
}
598+
599+
if (!$missingConstructorArgumentException) {
600+
$missingConstructorArgumentException = $e;
601+
}
590602
}
591603
}
592604

593605
if ($extraAttributesException) {
594606
throw $extraAttributesException;
595607
}
596608

609+
if ($missingConstructorArgumentException) {
610+
throw $missingConstructorArgumentException;
611+
}
612+
597613
if ($context[self::DISABLE_TYPE_ENFORCEMENT] ?? $this->defaultContext[self::DISABLE_TYPE_ENFORCEMENT] ?? false) {
598614
return $data;
599615
}

Tests/SerializerTest.php

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -764,20 +764,26 @@ public function testUnionTypeDeserializableWithoutAllowedExtraAttributes()
764764
['json' => new JsonEncoder()]
765765
);
766766

767-
$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndB::class, 'json', [
767+
$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndCAndB::class, 'json', [
768768
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
769769
]);
770770

771-
$this->assertEquals(new DummyUnionWithAAndB(new DummyATypeForUnion()), $actual);
771+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyATypeForUnion()), $actual);
772772

773-
$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndB::class, 'json', [
773+
$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndCAndB::class, 'json', [
774774
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
775775
]);
776776

777-
$this->assertEquals(new DummyUnionWithAAndB(new DummyBTypeForUnion()), $actual);
777+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyBTypeForUnion()), $actual);
778+
779+
$actual = $serializer->deserialize('{ "v": { "c": 3 }}', DummyUnionWithAAndCAndB::class, 'json', [
780+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
781+
]);
782+
783+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyCTypeForUnion(3)), $actual);
778784

779785
$this->expectException(ExtraAttributesException::class);
780-
$serializer->deserialize('{ "v": { "b": 1, "c": "i am not allowed" }}', DummyUnionWithAAndB::class, 'json', [
786+
$serializer->deserialize('{ "v": { "b": 1, "d": "i am not allowed" }}', DummyUnionWithAAndCAndB::class, 'json', [
781787
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
782788
]);
783789
}
@@ -1262,13 +1268,23 @@ class DummyBTypeForUnion
12621268
public $b = 1;
12631269
}
12641270

1265-
class DummyUnionWithAAndB
1271+
class DummyCTypeForUnion
1272+
{
1273+
public $c = 2;
1274+
1275+
public function __construct($c)
1276+
{
1277+
$this->c = $c;
1278+
}
1279+
}
1280+
1281+
class DummyUnionWithAAndCAndB
12661282
{
1267-
/** @var DummyATypeForUnion|DummyBTypeForUnion */
1283+
/** @var DummyATypeForUnion|DummyCTypeForUnion|DummyBTypeForUnion */
12681284
public $v;
12691285

12701286
/**
1271-
* @param DummyATypeForUnion|DummyBTypeForUnion $v
1287+
* @param DummyATypeForUnion|DummyCTypeForUnion|DummyBTypeForUnion $v
12721288
*/
12731289
public function __construct($v)
12741290
{

0 commit comments

Comments
 (0)