Skip to content

Commit d69fa8f

Browse files
pounardnicolas-grekas
authored andcommitted
[Serializer] AbstractNormalizer force null for non-optional nullable constructor parameter denormalization when not present in input
1 parent 9fa3632 commit d69fa8f

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

Normalizer/AbstractNormalizer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref
501501
$params[] = $this->defaultContext[self::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key];
502502
} elseif ($constructorParameter->isDefaultValueAvailable()) {
503503
$params[] = $constructorParameter->getDefaultValue();
504+
} elseif ($constructorParameter->hasType() && $constructorParameter->getType()->allowsNull()) {
505+
$params[] = null;
504506
} else {
505507
throw new MissingConstructorArgumentsException(sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires parameter "%s" to be present.', $class, $constructorParameter->name));
506508
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
class NullableOptionalConstructorArgumentDummy
15+
{
16+
private $foo;
17+
18+
public function __construct(?\stdClass $foo)
19+
{
20+
$this->foo = $foo;
21+
}
22+
23+
public function setFoo($foo)
24+
{
25+
$this->foo = 'this setter should not be called when using the constructor argument';
26+
}
27+
28+
public function getFoo()
29+
{
30+
return $this->foo;
31+
}
32+
}

Tests/Normalizer/AbstractNormalizerTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
1919
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
2020
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
21+
use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy;
2122
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
2223
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer;
2324
use Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorTypedArgsDummy;
@@ -118,13 +119,37 @@ public function testObjectWithStaticConstructor()
118119
}
119120

120121
public function testObjectWithNullableConstructorArgument()
122+
{
123+
$normalizer = new ObjectNormalizer();
124+
$dummy = $normalizer->denormalize(['foo' => null], NullableOptionalConstructorArgumentDummy::class);
125+
126+
$this->assertNull($dummy->getFoo());
127+
}
128+
129+
public function testObjectWithNullableConstructorArgumentWithoutInput()
130+
{
131+
$normalizer = new ObjectNormalizer();
132+
$dummy = $normalizer->denormalize([], NullableOptionalConstructorArgumentDummy::class);
133+
134+
$this->assertNull($dummy->getFoo());
135+
}
136+
137+
public function testObjectWithNullableNonOptionalConstructorArgument()
121138
{
122139
$normalizer = new ObjectNormalizer();
123140
$dummy = $normalizer->denormalize(['foo' => null], NullableConstructorArgumentDummy::class);
124141

125142
$this->assertNull($dummy->getFoo());
126143
}
127144

145+
public function testObjectWithNullableNonOptionalConstructorArgumentWithoutInput()
146+
{
147+
$normalizer = new ObjectNormalizer();
148+
$dummy = $normalizer->denormalize([], NullableConstructorArgumentDummy::class);
149+
150+
$this->assertNull($dummy->getFoo());
151+
}
152+
128153
/**
129154
* @dataProvider getNormalizer
130155
*/

0 commit comments

Comments
 (0)