[Serializer] fix denormalization of string-arrays with only one element #33731
This commit is contained in:
parent
fda5b20c39
commit
8814751b96
|
@ -244,16 +244,18 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($type->isCollection() && null !== ($collectionValueType = $type->getCollectionValueType()) && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) {
|
||||
$collectionValueType = $type->isCollection() ? $type->getCollectionValueType() : null;
|
||||
|
||||
// Fix a collection that contains the only one element
|
||||
// This is special to xml format only
|
||||
if ('xml' === $format && null !== $collectionValueType && (!\is_array($data) || !\is_int(key($data)))) {
|
||||
$data = [$data];
|
||||
}
|
||||
|
||||
if (null !== $collectionValueType && Type::BUILTIN_TYPE_OBJECT === $collectionValueType->getBuiltinType()) {
|
||||
$builtinType = Type::BUILTIN_TYPE_OBJECT;
|
||||
$class = $collectionValueType->getClassName().'[]';
|
||||
|
||||
// Fix a collection that contains the only one element
|
||||
// This is special to xml format only
|
||||
if ('xml' === $format && !\is_int(key($data))) {
|
||||
$data = [$data];
|
||||
}
|
||||
|
||||
if (null !== $collectionKeyType = $type->getCollectionKeyType()) {
|
||||
$context['key_type'] = $collectionKeyType;
|
||||
}
|
||||
|
|
|
@ -121,16 +121,54 @@ class AbstractObjectNormalizerTest extends TestCase
|
|||
$extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock();
|
||||
$extractor->method('getTypes')
|
||||
->will($this->onConsecutiveCalls(
|
||||
[
|
||||
new Type(
|
||||
'array',
|
||||
false,
|
||||
null,
|
||||
true,
|
||||
new Type('int'),
|
||||
new Type('object', false, DummyChild::class)
|
||||
),
|
||||
],
|
||||
[new Type('array', false, null, true, new Type('int'), new Type('object', false, DummyChild::class))],
|
||||
null
|
||||
));
|
||||
|
||||
$denormalizer = new AbstractObjectNormalizerCollectionDummy(null, null, $extractor);
|
||||
$arrayDenormalizer = new ArrayDenormalizerDummy();
|
||||
$serializer = new SerializerCollectionDummy([$arrayDenormalizer, $denormalizer]);
|
||||
$arrayDenormalizer->setSerializer($serializer);
|
||||
$denormalizer->setSerializer($serializer);
|
||||
|
||||
return $denormalizer;
|
||||
}
|
||||
|
||||
public function testDenormalizeStringCollectionDecodedFromXmlWithOneChild()
|
||||
{
|
||||
$denormalizer = $this->getDenormalizerForStringCollection();
|
||||
|
||||
// if an xml-node can have children which should be deserialized as string[]
|
||||
// and only one child exists
|
||||
$stringCollection = $denormalizer->denormalize(['children' => 'foo'], StringCollection::class, 'xml');
|
||||
|
||||
$this->assertInstanceOf(StringCollection::class, $stringCollection);
|
||||
$this->assertIsArray($stringCollection->children);
|
||||
$this->assertCount(1, $stringCollection->children);
|
||||
$this->assertEquals('foo', $stringCollection->children[0]);
|
||||
}
|
||||
|
||||
public function testDenormalizeStringCollectionDecodedFromXmlWithTwoChildren()
|
||||
{
|
||||
$denormalizer = $this->getDenormalizerForStringCollection();
|
||||
|
||||
// if an xml-node can have children which should be deserialized as string[]
|
||||
// and only one child exists
|
||||
$stringCollection = $denormalizer->denormalize(['children' => ['foo', 'bar']], StringCollection::class, 'xml');
|
||||
|
||||
$this->assertInstanceOf(StringCollection::class, $stringCollection);
|
||||
$this->assertIsArray($stringCollection->children);
|
||||
$this->assertCount(2, $stringCollection->children);
|
||||
$this->assertEquals('foo', $stringCollection->children[0]);
|
||||
$this->assertEquals('bar', $stringCollection->children[1]);
|
||||
}
|
||||
|
||||
private function getDenormalizerForStringCollection()
|
||||
{
|
||||
$extractor = $this->getMockBuilder(PhpDocExtractor::class)->getMock();
|
||||
$extractor->method('getTypes')
|
||||
->will($this->onConsecutiveCalls(
|
||||
[new Type('array', false, null, true, new Type('int'), new Type('string'))],
|
||||
null
|
||||
));
|
||||
|
||||
|
@ -212,6 +250,12 @@ class AbstractObjectNormalizerWithMetadata extends AbstractObjectNormalizer
|
|||
}
|
||||
}
|
||||
|
||||
class StringCollection
|
||||
{
|
||||
/** @var string[] */
|
||||
public $children;
|
||||
}
|
||||
|
||||
class DummyCollection
|
||||
{
|
||||
/** @var DummyChild[] */
|
||||
|
|
Reference in New Issue