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 8814751

Browse filesBrowse files
mkrausernicolas-grekas
authored andcommitted
[Serializer] fix denormalization of string-arrays with only one element #33731
1 parent fda5b20 commit 8814751
Copy full SHA for 8814751

File tree

2 files changed

+63
-17
lines changed
Filter options

2 files changed

+63
-17
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
+9-7Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,18 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma
244244
return null;
245245
}
246246

247-
if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) {
247+
$collectionValueType = $type->isCollection() ? $type->getCollectionValueType() : null;
248+
249+
// Fix a collection that contains the only one element
250+
// This is special to xml format only
251+
if ('xml' === $format && null !== $collectionValueType && (!\is_array($data) || !\is_int(key($data)))) {
252+
$data = [$data];
253+
}
254+
255+
if (null !== $collectionValueType && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) {
248256
$builtinType = Type::BUILTIN_TYPE_OBJECT;
249257
$class = $collectionValueType->getClassName().'[]';
250258

251-
// Fix a collection that contains the only one element
252-
// This is special to xml format only
253-
if ('xml' === $format && !\is_int(key($data))) {
254-
$data = [$data];
255-
}
256-
257259
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
258260
$context['key_type'] = $collectionKeyType;
259261
}

‎src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php
+54-10Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,54 @@ private function getDenormalizerForDummyCollection()
121121
$extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock();
122122
$extractor->method('getTypes')
123123
->will($this->onConsecutiveCalls(
124-
[
125-
new Type(
126-
'array',
127-
false,
128-
null,
129-
true,
130-
new Type('int'),
131-
new Type('object', false, DummyChild::class)
132-
),
133-
],
124+
[new Type('array', false, null, true, new Type('int'), new Type('object', false, DummyChild::class))],
125+
null
126+
));
127+
128+
$denormalizer = new AbstractObjectNormalizerCollectionDummy(null, null, $extractor);
129+
$arrayDenormalizer = new ArrayDenormalizerDummy();
130+
$serializer = new SerializerCollectionDummy([$arrayDenormalizer, $denormalizer]);
131+
$arrayDenormalizer->setSerializer($serializer);
132+
$denormalizer->setSerializer($serializer);
133+
134+
return $denormalizer;
135+
}
136+
137+
public function testDenormalizeStringCollectionDecodedFromXmlWithOneChild()
138+
{
139+
$denormalizer = $this->getDenormalizerForStringCollection();
140+
141+
// if an xml-node can have children which should be deserialized as string[]
142+
// and only one child exists
143+
$stringCollection = $denormalizer->denormalize(['children' => 'foo'], StringCollection::class, 'xml');
144+
145+
$this->assertInstanceOf(StringCollection::class, $stringCollection);
146+
$this->assertIsArray($stringCollection->children);
147+
$this->assertCount(1, $stringCollection->children);
148+
$this->assertEquals('foo', $stringCollection->children[0]);
149+
}
150+
151+
public function testDenormalizeStringCollectionDecodedFromXmlWithTwoChildren()
152+
{
153+
$denormalizer = $this->getDenormalizerForStringCollection();
154+
155+
// if an xml-node can have children which should be deserialized as string[]
156+
// and only one child exists
157+
$stringCollection = $denormalizer->denormalize(['children' => ['foo', 'bar']], StringCollection::class, 'xml');
158+
159+
$this->assertInstanceOf(StringCollection::class, $stringCollection);
160+
$this->assertIsArray($stringCollection->children);
161+
$this->assertCount(2, $stringCollection->children);
162+
$this->assertEquals('foo', $stringCollection->children[0]);
163+
$this->assertEquals('bar', $stringCollection->children[1]);
164+
}
165+
166+
private function getDenormalizerForStringCollection()
167+
{
168+
$extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock();
169+
$extractor->method('getTypes')
170+
->will($this->onConsecutiveCalls(
171+
[new Type('array', false, null, true, new Type('int'), new Type('string'))],
134172
null
135173
));
136174

@@ -212,6 +250,12 @@ protected function setAttributeValue($object, $attribute, $value, $format = null
212250
}
213251
}
214252

253+
class StringCollection
254+
{
255+
/** @var string[] */
256+
public $children;
257+
}
258+
215259
class DummyCollection
216260
{
217261
/** @var DummyChild[] */

0 commit comments

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