Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 006fd51

Browse files
Merge branch '6.4' into 7.4
* 6.4: [DependencyInjection] Fix rejecting inline services in parameters section [Serializer] Fix denormalization of nested array with key types [VarDumper] Ensure that tests are resilient when the Xdebug file link format is defined
2 parents 714e9d2 + 90e4e01 commit 006fd51

3 files changed

Lines changed: 66 additions & 3 deletions

File tree

Normalizer/AbstractObjectNormalizer.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,18 +542,18 @@ private function validateAndDenormalizeLegacy(array $types, string $currentClass
542542
$builtinType = LegacyType::BUILTIN_TYPE_OBJECT;
543543
$class = $collectionValueType->getClassName().'[]';
544544

545-
if (\count($collectionKeyType = $type->getCollectionKeyTypes()) > 0) {
545+
if ($collectionKeyType = $type->getCollectionKeyTypes()) {
546546
$context['key_type'] = \count($collectionKeyType) > 1 ? $collectionKeyType : $collectionKeyType[0];
547547
}
548548

549549
$context['value_type'] = $collectionValueType;
550-
} elseif ($type->isCollection() && \count($collectionValueType = $type->getCollectionValueTypes()) > 0 && LegacyType::BUILTIN_TYPE_ARRAY === $collectionValueType[0]->getBuiltinType()) {
550+
} elseif ($type->isCollection() && ($collectionValueType = $type->getCollectionValueTypes()) && LegacyType::BUILTIN_TYPE_ARRAY === $collectionValueType[0]->getBuiltinType()) {
551551
// get inner type for any nested array
552552
[$innerType] = $collectionValueType;
553553

554554
// note that it will break for any other builtinType
555555
$dimensions = '[]';
556-
while (\count($innerType->getCollectionValueTypes()) > 0 && LegacyType::BUILTIN_TYPE_ARRAY === $innerType->getBuiltinType()) {
556+
while ($innerType->getCollectionValueTypes() && LegacyType::BUILTIN_TYPE_ARRAY === $innerType->getBuiltinType()) {
557557
$dimensions .= '[]';
558558
[$innerType] = $innerType->getCollectionValueTypes();
559559
}
@@ -562,6 +562,12 @@ private function validateAndDenormalizeLegacy(array $types, string $currentClass
562562
// the builtinType is the inner one and the class is the class followed by []...[]
563563
$builtinType = $innerType->getBuiltinType();
564564
$class = $innerType->getClassName().$dimensions;
565+
566+
if ($collectionKeyType = $type->getCollectionKeyTypes()) {
567+
$context['key_type'] = \count($collectionKeyType) > 1 ? $collectionKeyType : $collectionKeyType[0];
568+
}
569+
570+
$context['value_type'] = $collectionValueType[0];
565571
} else {
566572
// default fallback (keep it as array)
567573
$builtinType = $type->getBuiltinType();
@@ -838,6 +844,8 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
838844
// the builtinType is the inner one and the class is the class followed by []...[]
839845
$typeIdentifier = TypeIdentifier::OBJECT;
840846
$class = $innerType->getClassName().$dimensions;
847+
$context['key_type'] = $collectionKeyType;
848+
$context['value_type'] = $collectionValueType;
841849
} else {
842850
// default fallback (keep it as array)
843851
if ($t instanceof ObjectType) {

Normalizer/ArrayDenormalizer.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
1818
use Symfony\Component\TypeInfo\Type;
1919
use Symfony\Component\TypeInfo\Type\BuiltinType;
20+
use Symfony\Component\TypeInfo\Type\CollectionType;
2021
use Symfony\Component\TypeInfo\Type\UnionType;
2122
use Symfony\Component\TypeInfo\TypeIdentifier;
2223

@@ -70,6 +71,20 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a
7071
}
7172
}
7273

74+
$valueType = $context['value_type'] ?? null;
75+
if ($valueType instanceof CollectionType) {
76+
$context['key_type'] = $valueType->getCollectionKeyType();
77+
$context['value_type'] = $valueType->getCollectionValueType();
78+
} elseif ($valueType instanceof LegacyType && $valueType->isCollection()) {
79+
if ($collectionKeyTypes = $valueType->getCollectionKeyTypes()) {
80+
$context['key_type'] = \count($collectionKeyTypes) > 1 ? $collectionKeyTypes : $collectionKeyTypes[0];
81+
}
82+
83+
if ($collectionValueTypes = $valueType->getCollectionValueTypes()) {
84+
$context['value_type'] = $collectionValueTypes[0];
85+
}
86+
}
87+
7388
foreach ($data as $key => $value) {
7489
$subContext = $context;
7590
$subContext['deserialization_path'] = ($context['deserialization_path'] ?? false) ? \sprintf('%s[%s]', $context['deserialization_path'], $key) : "[$key]";

Tests/DeserializeNestedArrayOfObjectsTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,30 @@ public function testPropertyPhpDocWithKeyTypes()
101101
self::assertArrayHasKey(3, $zoo->animalsGenerics);
102102
self::assertInstanceOf(Animal::class, $zoo->animalsGenerics[3]);
103103
}
104+
105+
public function testNestedArrayWithStringKeyUnderList()
106+
{
107+
$json = <<<EOF
108+
{
109+
"foos": [{"operators": {"something": [{"name": "Bug"}]}}]
110+
}
111+
EOF;
112+
$serializer = new Serializer([
113+
new ObjectNormalizer(null, null, null, new PhpDocExtractor()),
114+
new ArrayDenormalizer(),
115+
], ['json' => new JsonEncoder()]);
116+
117+
/** @var BarWithNestedKeyTypes $bar */
118+
$bar = $serializer->deserialize($json, BarWithNestedKeyTypes::class, 'json');
119+
120+
self::assertCount(1, $bar->foos);
121+
self::assertInstanceOf(FooWithStringKeyedList::class, $bar->foos[0]);
122+
self::assertCount(1, $bar->foos[0]->operators);
123+
self::assertArrayHasKey('something', $bar->foos[0]->operators);
124+
self::assertCount(1, $bar->foos[0]->operators['something']);
125+
self::assertInstanceOf(Animal::class, $bar->foos[0]->operators['something'][0]);
126+
self::assertSame('Bug', $bar->foos[0]->operators['something'][0]->getName());
127+
}
104128
}
105129

106130
class Zoo
@@ -177,3 +201,19 @@ public function setName($name)
177201
$this->name = $name;
178202
}
179203
}
204+
205+
class FooWithStringKeyedList
206+
{
207+
/** @param array<string, list<Animal>> $operators */
208+
public function __construct(public array $operators = [])
209+
{
210+
}
211+
}
212+
213+
class BarWithNestedKeyTypes
214+
{
215+
/** @param list<FooWithStringKeyedList> $foos */
216+
public function __construct(public array $foos = [])
217+
{
218+
}
219+
}

0 commit comments

Comments
 (0)