Skip to content

Commit 68671b6

Browse files
committed
bug #11428 [Serializer] properly handle null data when denormalizing (xabbuh)
This PR was merged into the 2.3 branch. Discussion ---------- [Serializer] properly handle null data when denormalizing | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #10794 | License | MIT | Doc PR | Commits ------- 123fc62 properly handle null data when denormalizing
2 parents 2c03577 + 2f197e8 commit 68671b6

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

Normalizer/GetSetMethodNormalizer.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ public function normalize($object, $format = null, array $context = array())
114114
*/
115115
public function denormalize($data, $class, $format = null, array $context = array())
116116
{
117+
if (is_array($data) || is_object($data) && $data instanceof \ArrayAccess) {
118+
$normalizedData = $data;
119+
} elseif (is_object($data)) {
120+
$normalizedData = array();
121+
122+
foreach ($data as $attribute => $value) {
123+
$normalizedData[$attribute] = $value;
124+
}
125+
} else {
126+
$normalizedData = array();
127+
}
128+
117129
$reflectionClass = new \ReflectionClass($class);
118130
$constructor = $reflectionClass->getConstructor();
119131

@@ -124,10 +136,10 @@ public function denormalize($data, $class, $format = null, array $context = arra
124136
foreach ($constructorParameters as $constructorParameter) {
125137
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
126138

127-
if (isset($data[$paramName])) {
128-
$params[] = $data[$paramName];
139+
if (isset($normalizedData[$paramName])) {
140+
$params[] = $normalizedData[$paramName];
129141
// don't run set for a parameter passed to the constructor
130-
unset($data[$paramName]);
142+
unset($normalizedData[$paramName]);
131143
} elseif ($constructorParameter->isOptional()) {
132144
$params[] = $constructorParameter->getDefaultValue();
133145
} else {
@@ -144,7 +156,7 @@ public function denormalize($data, $class, $format = null, array $context = arra
144156
$object = new $class();
145157
}
146158

147-
foreach ($data as $attribute => $value) {
159+
foreach ($normalizedData as $attribute => $value) {
148160
$setter = 'set'.$this->formatAttribute($attribute);
149161

150162
if (method_exists($object, $setter)) {

Tests/Normalizer/GetSetMethodNormalizerTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
1717
{
18+
/**
19+
* @var GetSetMethodNormalizer
20+
*/
21+
private $normalizer;
22+
1823
protected function setUp()
1924
{
2025
$this->normalizer = new GetSetMethodNormalizer();
@@ -44,6 +49,17 @@ public function testDenormalize()
4449
$this->assertEquals('bar', $obj->getBar());
4550
}
4651

52+
public function testDenormalizeWithObject()
53+
{
54+
$data = new \stdClass();
55+
$data->foo = 'foo';
56+
$data->bar = 'bar';
57+
$data->fooBar = 'foobar';
58+
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\GetSetDummy', 'any');
59+
$this->assertEquals('foo', $obj->getFoo());
60+
$this->assertEquals('bar', $obj->getBar());
61+
}
62+
4763
public function testDenormalizeOnCamelCaseFormat()
4864
{
4965
$this->normalizer->setCamelizedAttributes(array('camel_case'));
@@ -54,6 +70,11 @@ public function testDenormalizeOnCamelCaseFormat()
5470
$this->assertEquals('camelCase', $obj->getCamelCase());
5571
}
5672

73+
public function testDenormalizeNull()
74+
{
75+
$this->assertEquals(new GetSetDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\GetSetDummy'));
76+
}
77+
5778
/**
5879
* @dataProvider attributeProvider
5980
*/
@@ -96,6 +117,17 @@ public function testConstructorDenormalizeWithMissingOptionalArgument()
96117
$this->assertEquals(array(1, 2, 3), $obj->getBaz());
97118
}
98119

120+
public function testConstructorWithObjectDenormalize()
121+
{
122+
$data = new \stdClass();
123+
$data->foo = 'foo';
124+
$data->bar = 'bar';
125+
$data->fooBar = 'foobar';
126+
$obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\GetConstructorDummy', 'any');
127+
$this->assertEquals('foo', $obj->getFoo());
128+
$this->assertEquals('bar', $obj->getBar());
129+
}
130+
99131
/**
100132
* @dataProvider provideCallbacks
101133
*/

0 commit comments

Comments
 (0)