8000 Merge branch '6.2' into 6.3 · symfony/symfony@4c1d953 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4c1d953

Browse files
Merge branch '6.2' into 6.3
* 6.2: [Cache] Fix generating proxies when ext-redis v6 is installed [Serializer] Fix deserializing nested arrays of objects with mixed keys
2 parents 7a46e34 + 49ab4ab commit 4c1d953

File tree

5 files changed

+104
-25
lines changed

5 files changed

+104
-25
lines changed

src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
class RedisProxiesTest extends TestCase
2020
{
2121
/**
22-
* @requires extension redis
22+
* @requires extension redis < 6
2323
*
2424
* @testWith ["Redis"]
2525
* ["RedisCluster"]
@@ -86,19 +86,24 @@ public function testRelayProxy()
8686
*/
8787
public function testRedis6Proxy($class, $stub)
8888
{
89-
$this->markTestIncomplete('To be re-enabled when phpredis v6 becomes stable');
90-
91-
$stub = file_get_contents("https://raw.githubusercontent.com/phpredis/phpredis/develop/{$stub}.stub.php");
92-
$stub = preg_replace('/^class /m', 'return; \0', $stub);
93-
$stub = preg_replace('/^return; class ([a-zA-Z]++)/m', 'interface \1StubInterface', $stub, 1);
94-
$stub = preg_replace('/^ public const .*/m', '', $stub);
95-
eval(substr($stub, 5));
89+
if (version_compare(phpversion('redis'), '6.0.0', '<')) {
90+
$this->markTestIncomplete('To be re-enabled when phpredis v6 becomes stable');
91+
92+
$stub = file_get_contents("https://raw.githubusercontent.com/phpredis/phpredis/develop/{$stub}.stub.php");
93+
$stub = preg_replace('/^class /m', 'return; \0', $stub);
94+
$stub = preg_replace('/^return; class ([a-zA-Z]++)/m', 'interface \1StubInterface', $stub, 1);
95+
$stub = preg_replace('/^ public const .*/m', '', $stub);
96+
eval(substr($stub, 5));
97+
$r = new \ReflectionClass($class.'StubInterface');
98+
} else {
99+
$r = new \ReflectionClass($class);
100+
}
96101

97102
$proxy = file_get_contents(\dirname(__DIR__, 2)."/Traits/{$class}6Proxy.php");
98103
$proxy = substr($proxy, 0, 4 + strpos($proxy, '[];'));
99104
$methods = [];
100105

101-
foreach ((new \ReflectionClass($class.'StubInterface'))->getMethods() as $method) {
106+
foreach ($r->getMethods() as $method) {
102107
if ('reset' === $method->name || method_exists(LazyProxyTrait::class, $method->name)) {
103108
continue;
104109
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri
501501
$class = $collectionValueType->getClassName().'[]';
502502

503503
if (\count($collectionKeyType = $type->getCollectionKeyTypes()) > 0) {
504-
[$context['key_type']] = $collectionKeyType;
504+
$context['key_type'] = \count($collectionKeyType) > 1 ? $collectionKeyType : $collectionKeyType[0];
505505
}
506506

507507
$context['value_type'] = $collectionValueType;

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,15 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
5858

5959
$type = substr($type, 0, -2);
6060

61-
$builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
61+
$builtinTypes = array_map(static function (Type $keyType) {
62+
return $keyType->getBuiltinType();
63+
}, \is_array($keyType = $context['key_type'] ?? []) ? $keyType : [$keyType]);
64+
6265
foreach ($data as $key => $value) {
6366
$subContext = $context;
6467
$subContext['deserialization_path'] = ($context['deserialization_path'] ?? false) ? sprintf('%s[%s]', $context['deserialization_path'], $key) : "[$key]";
6568

66-
if (null !== $builtinType && !('is_'.$builtinType)($key)) {
67-
throw NotNormalizableValueException::createForUnexpectedDataType(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, get_debug_type($key)), $key, [$builtinType], $subContext['deserialization_path'] ?? null, true);
68-
}
69+
$this->validateKeyType($builtinTypes, $key, $subContext['deserialization_path']);
6970

7071
$data[$key] = $this->denormalizer->denormalize($value, $type, $format, $subContext);
7172
}
@@ -92,4 +93,22 @@ public function hasCacheableSupportsMethod(): bool
9293

9394
return $this->denormalizer instanceof CacheableSupportsMethodInterface && $this->denormalizer->hasCacheableSupportsMethod();
9495
}
96+
97+
/**
98+
* @param mixed $key
99+
*/
100+
private function validateKeyType(array $builtinTypes, $key, string $path): void
101+
{
102+
if (!$builtinTypes) {
103+
return;
104+
}
105+
106+
foreach ($builtinTypes as $builtinType) {
107+
if (('is_'.$builtinType)($key)) {
108+
return;
109+
}
110+
}
111+
112+
throw NotNormalizableValueException::createForUnexpectedDataType(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, implode('", "', $builtinTypes), get_debug_type($key)), $key, $builtinTypes, $path, true);
113+
}
95114
}

src/Symfony/Component/Serializer/Tests/DeserializeNestedArrayOfObjectsTest.php

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public static function provider()
3535
*/
3636
public function testPropertyPhpDoc($class)
3737
{
38-
// GIVEN
3938
$json = <<<EOF
4039
{
4140
"animals": [
@@ -47,13 +46,62 @@ public function testPropertyPhpDoc($class)
4746
new ObjectNormalizer(null, null, null, new PhpDocExtractor()),
4847
new ArrayDenormalizer(),
4948
], ['json' => new JsonEncoder()]);
50-
// WHEN
51-
/** @var Zoo $zoo */
49+
50+
/** @var Zoo|ZooImmutable $zoo */
5251
$zoo = $serializer->deserialize($json, $class, 'json');
53-
// THEN
52+
5453
self::assertCount(1, $zoo->getAnimals());
5554
self::assertInstanceOf(Animal::class, $zoo->getAnimals()[0]);
5655
}
56+
57+
public function testPropertyPhpDocWithKeyTypes()
58+
{
59+
$json = <<<EOF
60+
{
61+
"animalsInt": [
62+
{"name": "Bug"}
63+
],
64+
"animalsString": {
65+
"animal1": {"name": "Bug"}
66+
},
67+
"animalsUnion": {
68+
"animal2": {"name": "Bug"},
69+
"2": {"name": "Dog"}
70+
},
71+
"animalsGenerics": {
72+
"animal3": {"name": "Bug"},
73+
"3": {"name": "Dog"}
74+
}
75+
}
76+
EOF;
77+
$serializer = new Serializer([
78+
new ObjectNormalizer(null, null, null, new PhpDocExtractor()),
79+
new ArrayDenormalizer(),
80+
], ['json' => new JsonEncoder()]);
81+
82+
/** @var ZooWithKeyTypes $zoo */
83+
$zoo = $serializer->deserialize($json, ZooWithKeyTypes::class, 'json');
84+
85+
self::assertCount(1, $zoo->animalsInt);
86+
self::assertArrayHasKey(0, $zoo->animalsInt);
87+
self::assertInstanceOf(Animal::class, $zoo->animalsInt[0]);
88+
89+
self::assertCount(1, $zoo->animalsString);
90+
self::assertArrayHasKey('animal1', $zoo->animalsString);
91+
self::assertInstanceOf(Animal::class, $zoo->animalsString['animal1']);
92+
93+
self::assertCount(2, $zoo->animalsUnion);
94+
self::assertArrayHasKey('animal2', $zoo->animalsUnion);
95+
self::assertInstanceOf(Animal::class, $zoo->animalsUnion['animal2']);
96+
self::assertArrayHasKey(2, $zoo->animalsUnion);
97+
self::assertInstanceOf(Animal::class, $zoo->animalsUnion[2]);
98+
99+
self::assertCount(2, $zoo->animalsGenerics);
100+
self::assertArrayHasKey('animal3', $zoo->animalsGenerics);
101+
self::assertInstanceOf(Animal::class, $zoo->animalsGenerics['animal3']);
102+
self::assertArrayHasKey(3, $zoo->animalsGenerics);
103+
self::assertInstanceOf(Animal::class, $zoo->animalsGenerics[3]);
104+
}
57105
}
58106

59107
class Zoo
@@ -100,16 +148,23 @@ public function getAnimals(): array
100148
}
101149
}
102150

151+
class ZooWithKeyTypes
152+
{
153+
/** @var array<int, Animal> */
154+
public $animalsInt = [];
155+
/** @var array<string, Animal> */
156+
public $animalsString = [];
157+
/** @var array<int|string, Animal> */
158+
public $animalsUnion = [];
159+
/** @var \stdClass<Animal> */
160+
public $animalsGenerics = [];
161+
}
162+
103163
class Animal
104164
{
105165
/** @var string */
106166
private $name;
107167

108-
public function __construct()
109-
{
110-
echo '';
111-
}
112-
113168
public function getName(): ?string
114169
{
115170
return $this->name;

src/Symfony/Component/Serializer/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"symfony/http-kernel": "^5.4|^6.0",
3434
"symfony/mime": "^5.4|^6.0",
3535
"symfony/property-access": "^5.4|^6.0",
36-
"symfony/property-info": "^5.4|^6.0",
36+
"symfony/property-info": "^5.4.24|^6.2.11",
3737
"symfony/uid": "^5.4|^6.0",
3838
"symfony/validator": "^5.4|^6.0",
3939
"symfony/var-dumper": "^5.4|^6.0",
@@ -46,7 +46,7 @@
4646
"phpdocumentor/type-resolver": "<1.4.0",
4747
"symfony/dependency-injection": "<5.4",
4848
"symfony/property-access": "<5.4",
49-
"symfony/property-info": "<5.4",
49+
"symfony/property-info": "<5.4.24|>=6,<6.2.11",
5050
"symfony/uid": "<5.4",
5151
"symfony/yaml": "<5.4"
5252
},

0 commit comments

Comments
 (0)
0