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 a2cd56c

Browse filesBrowse files
bug #33733 [Serializer] fix denormalization of string-arrays with only one element (mkrauser)
This PR was merged into the 3.4 branch. Discussion ---------- [Serializer] fix denormalization of string-arrays with only one element | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? |no | Deprecations? |no | Tickets | Fix #33731 | License | MIT | Doc PR | This PR does almost the same as ac70edf, just not only for arrays of objects. Commits ------- 8814751 [Serializer] fix denormalization of string-arrays with only one element #33731
2 parents 03f2adc + 8814751 commit a2cd56c
Copy full SHA for a2cd56c

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.