Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1b2ab75

Browse filesBrowse files
bug #46765 [Serializer] Fix denormalization union types with constructor (Gwemox)
This PR was merged into the 4.4 branch. Discussion ---------- [Serializer] Fix denormalization union types with constructor | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #46396 | License | MIT Fix bug when deserialize union types with constructor. Before that, `MissingConstructorArgumentsException` was thrown even if another type matched. Is similar to #45861 Commits ------- 33fb153 [Serializer] Fix denormalization union types with constructor
2 parents 45db39c + 33fb153 commit 1b2ab75
Copy full SHA for 1b2ab75

File tree

Expand file treeCollapse file tree

2 files changed

+40
-8
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+40
-8
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2121
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2222
use Symfony\Component\Serializer\Exception\LogicException;
23+
use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException;
2324
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2425
use Symfony\Component\Serializer\Exception\RuntimeException;
2526
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
@@ -395,6 +396,8 @@ abstract protected function setAttributeValue($object, $attribute, $value, $form
395396
* @return mixed
396397
*
397398
* @throws NotNormalizableValueException
399+
* @throws ExtraAttributesException
400+
* @throws MissingConstructorArgumentsException
398401
* @throws LogicException
399402
*/
400403
private function validateAndDenormalize(string $currentClass, string $attribute, $data, ?string $format, array $context)
@@ -406,6 +409,7 @@ private function validateAndDenormalize(string $currentClass, string $attribute,
406409
$expectedTypes = [];
407410
$isUnionType = \count($types) > 1;
408411
$extraAttributesException = null;
412+
$missingConstructorArgumentException = null;
409413
foreach ($types as $type) {
410414
if (null === $data && $type->isNullable()) {
411415
return null;
@@ -503,13 +507,25 @@ private function validateAndDenormalize(string $currentClass, string $attribute,
503507
if (!$extraAttributesException) {
504508
$extraAttributesException = $e;
505509
}
510+
} catch (MissingConstructorArgumentsException $e) {
511+
if (!$isUnionType) {
512+
throw $e;
513+
}
514+
515+
if (!$missingConstructorArgumentException) {
516+
$missingConstructorArgumentException = $e;
517+
}
506518
}
507519
}
508520

509521
if ($extraAttributesException) {
510522
throw $extraAttributesException;
511523
}
512524

525+
if ($missingConstructorArgumentException) {
526+
throw $missingConstructorArgumentException;
527+
}
528+
513529
if ($context[self::DISABLE_TYPE_ENFORCEMENT] ?? $this->defaultContext[self::DISABLE_TYPE_ENFORCEMENT] ?? false) {
514530
return $data;
515531
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/SerializerTest.php
+24-8Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -586,20 +586,26 @@ public function testUnionTypeDeserializableWithoutAllowedExtraAttributes()
586586
['json' => new JsonEncoder()]
587587
);
588588

589-
$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndB::class, 'json', [
589+
$actual = $serializer->deserialize('{ "v": { "a": 0 }}', DummyUnionWithAAndCAndB::class, 'json', [
590590
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
591591
]);
592592

593-
$this->assertEquals(new DummyUnionWithAAndB(new DummyATypeForUnion()), $actual);
593+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyATypeForUnion()), $actual);
594594

595-
$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndB::class, 'json', [
595+
$actual = $serializer->deserialize('{ "v": { "b": 1 }}', DummyUnionWithAAndCAndB::class, 'json', [
596596
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
597597
]);
598598

599-
$this->assertEquals(new DummyUnionWithAAndB(new DummyBTypeForUnion()), $actual);
599+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyBTypeForUnion()), $actual);
600+
601+
$actual = $serializer->deserialize('{ "v": { "c": 3 }}', DummyUnionWithAAndCAndB::class, 'json', [
602+
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
603+
]);
604+
605+
$this->assertEquals(new DummyUnionWithAAndCAndB(new DummyCTypeForUnion(3)), $actual);
600606

601607
$this->expectException(ExtraAttributesException::class);
602-
$serializer->deserialize('{ "v": { "b": 1, "c": "i am not allowed" }}', DummyUnionWithAAndB::class, 'json', [
608+
$serializer->deserialize('{ "v": { "b": 1, "d": "i am not allowed" }}', DummyUnionWithAAndCAndB::class, 'json', [
603609
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
604610
]);
605611
}
@@ -719,13 +725,23 @@ class DummyBTypeForUnion
719725
public $b = 1;
720726
}
721727

722-
class DummyUnionWithAAndB
728+
class DummyCTypeForUnion
729+
{
730+
public $c = 2;
731+
732+
public function __construct($c)
733+
{
734+
$this->c = $c;
735+
}
736+
}
737+
738+
class DummyUnionWithAAndCAndB
723739
{
724-
/** @var DummyATypeForUnion|DummyBTypeForUnion */
740+
/** @var DummyATypeForUnion|DummyCTypeForUnion|DummyBTypeForUnion */
725741
public $v;
726742

727743
/**
728-
* @param DummyATypeForUnion|DummyBTypeForUnion $v
744+
* @param DummyATypeForUnion|DummyCTypeForUnion|DummyBTypeForUnion $v
729745
*/
730746
public function __construct($v)
731747
{

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.