8000 bug #15426 [Serializer] Add support for variadic arguments in the Get… · symfony/symfony@620a3d4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 620a3d4

Browse files
committed
bug #15426 [Serializer] Add support for variadic arguments in the GetSetNormalizer (stof)
This PR was merged into the 2.3 branch. Discussion ---------- [Serializer] Add support for variadic arguments in the GetSetNormalizer | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a There were 2 broken cases: - when the value was passed, the array was passed as argument, becoming the first value of the variadic array. The array needs to be spread into multiple arguments when calling the method - when the value was missing, the code would throw a ReflectionException, similar to the issue reported in #13690, because a variadic argument is optional but does not have a default value Commits ------- 704760b Add support for variadic arguments in the GetSetNormalizer
2 parents 0f56497 + 704760b commit 620a3d4

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,19 @@ public function denormalize($data, $class, $format = null, array $context = arra
136136
foreach ($constructorParameters as $constructorParameter) {
137137
$paramName = lcfirst($this->formatAttribute($constructorParameter->name));
138138

139-
if (isset($normalizedData[$paramName])) {
139+
if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) {
140+
if (isset($normalizedData[$paramName])) {
141+
if (!is_array($normalizedData[$paramName])) {
142+
throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name));
143+
}
144+
145+
$params = array_merge($params, $normalizedData[$paramName]);
146+
}
147+
} elseif (isset($normalizedData[$paramName])) {
140148
$params[] = $normalizedData[$paramName];
141149
// don't run set for a parameter passed to the constructor
142150
unset($normalizedData[$paramName]);
143-
} elseif ($constructorParameter->isOptional()) {
151+
} elseif ($constructorParameter->isDefaultValueAvailable()) {
144152
$params[] = $constructorParameter->getDefaultValue();
145153
} else {
146154
throw new RuntimeException(
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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 VariadicConstructorArgsDummy
15+
{
16+
private $foo;
17+
18+
public function __construct(...$foo)
19+
{
20+
$this->foo = $foo;
21+
}
22+
23+
public function getFoo()
24+
{
25+
return $this->foo;
26+
}
27+
}

src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,28 @@ public function testConstructorDenormalizeWithMissingOptionalArgument()
117117
$this->assertEquals(array(1, 2, 3), $obj->getBaz());
118118
}
119119

120+
/**
121+
* @requires PHP 5.6
122+
*/
123+
public function testConstructorDenormalizeWithVariadicArgument()
124+
{
125+
$obj = $this->normalizer->denormalize(
126+
array('foo' => array(1, 2, 3)),
127+
'Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorArgsDummy', 'any');
128+
$this->assertEquals(array(1, 2, 3), $obj->getFoo());
129+
}
130+
131+
/**
132+
* @requires PHP 5.6
133+
*/
134+
public function testConstructorDenormalizeWithMissingVariadicArgument()
135+
{
136+
$obj = $this->normalizer->denormalize(
137+
array(),
138+
'Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorArgsDummy', 'any');
139+
$this->assertEquals(array(), $obj->getFoo());
140+
}
141+
120142
public function testConstructorWithObjectDenormalize()
121143
{
122144
$data = new \stdClass();

0 commit comments

Comments
 (0)
0