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

Skip to content

Commit 7a2887a

Browse files
committed
Support multiple types for collection keys & values
1 parent dc0d45d commit 7a2887a

File tree

4 files changed

+134
-4
lines changed

4 files changed

+134
-4
lines changed

UPGRADE-5.3.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
UPGRADE FROM 5.2 to 5.3
2+
=======================
3+
4+
PropertyInfo
5+
------------
6+
7+
* Deprecated the `Type::getCollectionKeyType()` and `Type::getCollectionValueType()` methods, use `Type::getCollectionKeyTypes()` and `Type::getCollectionValueTypes()` instead.

src/Symfony/Component/PropertyInfo/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* Added support for multiple types for collection keys & values
8+
* Deprecated the `Type::getCollectionKeyType()` and `Type::getCollectionValueType()` methods, use `Type::getCollectionKeyTypes()` and `Type::getCollectionValueTypes()` instead.
9+
410
5.2.0
511
-----
612

src/Symfony/Component/PropertyInfo/Tests/TypeTest.php

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,24 @@
1212
namespace Symfony\Component\PropertyInfo\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1516
use Symfony\Component\PropertyInfo\Type;
1617

1718
/**
1819
* @author Kévin Dunglas <[email protected]>
1920
*/
2021
class TypeTest extends TestCase
2122
{
22-
public function testConstruct()
23+
use ExpectDeprecationTrait;
24+
25+
/**
26+
* @group legacy
27+
*/
28+
public function testLegacyConstruct()
2329
{
30+
$this->expectDeprecation('Since symfony/property-info 5.3: The "Symfony\Component\PropertyInfo\Type::getCollectionKeyType()" method is deprecated, use "getCollectionKeyTypes()" instead.');
31+
$this->expectDeprecation('Since symfony/property-info 5.3: The "Symfony\Component\PropertyInfo\Type::getCollectionValueType()" method is deprecated, use "getCollectionValueTypes()" instead.');
32+
2433
$type = new Type('object', true, 'ArrayObject', true, new Type('int'), new Type('string'));
2534

2635
$this->assertEquals(Type::BUILTIN_TYPE_OBJECT, $type->getBuiltinType());
@@ -37,6 +46,26 @@ public function testConstruct()
3746
$this->assertEquals(Type::BUILTIN_TYPE_STRING, $collectionValueType->getBuiltinType());
3847
}
3948

49+
public function testConstruct()
50+
{
51+
$type = new Type('object', true, 'ArrayObject', true, new Type('int'), new Type('string'));
52+
53+
$this->assertEquals(Type::BUILTIN_TYPE_OBJECT, $type->getBuiltinType());
54+
$this->assertTrue($type->isNullable());
55+
$this->assertEquals('ArrayObject', $type->getClassName());
56+
$this->assertTrue($type->isCollection());
57+
58+
$collectionKeyTypes = $type->getCollectionKeyTypes();
59+
$this->assertIsArray($collectionKeyTypes);
60+
$this->assertContainsOnlyInstancesOf('Symfony\Component\PropertyInfo\Type', $collectionKeyTypes);
61+
$this->assertEquals(Type::BUILTIN_TYPE_INT, $collectionKeyTypes[0]->getBuiltinType());
62+
63+
$collectionValueTypes = $type->getCollectionValueTypes();
64+
$this->assertIsArray($collectionValueTypes);
65+
$this->assertContainsOnlyInstancesOf('Symfony\Component\PropertyInfo\Type', $collectionValueTypes);
66+
$this->assertEquals(Type::BUILTIN_TYPE_STRING, $collectionValueTypes[0]->getBuiltinType());
67+
}
68+
4069
public function testIterable()
4170
{
4271
$type = new Type('iterable');
@@ -49,4 +78,30 @@ public function testInvalidType()
4978
$this->expectExceptionMessage('"foo" is not a valid PHP type.');
5079
new Type('foo');
5180
}
81+
82+
public function testArrayCollection()
83+
{
84+
$type = new Type('array', false, null, true, [new Type('int'), new Type('string')], [new Type('object', false, \ArrayObject::class, true), new Type('array', false, null, true)]);
85+
86+
$this->assertEquals(Type::BUILTIN_TYPE_ARRAY, $type->getBuiltinType());
87+
$this->assertFalse($type->isNullable());
88+
$this->assertTrue($type->isCollection());
89+
90+
[$firstKeyType, $secondKeyType] = $type->getCollectionKeyTypes();
91+
$this->assertEquals(Type::BUILTIN_TYPE_INT, $firstKeyType->getBuiltinType());
92+
$this->assertFalse($firstKeyType->isNullable());
93+
$this->assertFalse($firstKeyType->isCollection());
94+
$this->assertEquals(Type::BUILTIN_TYPE_STRING, $secondKeyType->getBuiltinType());
95+
$this->assertFalse($secondKeyType->isNullable());
96+
$this->assertFalse($secondKeyType->isCollection());
97+
98+
[$firstValueType, $secondValueType] = $type->getCollectionValueTypes();
99+
$this->assertEquals(Type::BUILTIN_TYPE_OBJECT, $firstValueType->getBuiltinType());
100+
$this->assertEquals(\ArrayObject::class, $firstValueType->getClassName());
101+
$this->assertFalse($firstValueType->isNullable());
102+
$this->assertTrue($firstValueType->isCollection());
103+
$this->assertEquals(Type::BUILTIN_TYPE_ARRAY, $secondValueType->getBuiltinType());
104+
$this->assertFalse($secondValueType->isNullable());
105+
$this->assertTrue($firstValueType->isCollection());
106+
}
52107
}

src/Symfony/Component/PropertyInfo/Type.php

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ class Type
5757
private $collectionValueType;
5858

5959
/**
60+
* @param array|Type|null $collectionKeyType
61+
* @param array|Type|null $collectionValueType
6062
* @throws \InvalidArgumentException
6163
*/
62-
public function __construct(string $builtinType, bool $nullable = false, string $class = null, bool $collection = false, self $collectionKeyType = null, self $collectionValueType = null)
64+
public function __construct(string $builtinType, bool $nullable = false, string $class = null, bool $collection = false, $collectionKeyType = null, $collectionValueType = null)
6365
{
6466
if (!\in_array($builtinType, self::$builtinTypes)) {
6567
throw new \InvalidArgumentException(sprintf('"%s" is not a valid PHP type.', $builtinType));
@@ -69,8 +71,30 @@ public function __construct(string $builtinType, bool $nullable = false, string
6971
$this->nullable = $nullable;
7072
$this->class = $class;
7173
$this->collection = $collection;
72-
$this->collectionKeyType = $collectionKeyType;
73-
$this->collectionValueType = $collectionValueType;
74+
$this->collectionKeyType = $this->validateCollectionArgument($collectionKeyType, 5, '$collectionKeyType');
75+
$this->collectionValueType = $this->validateCollectionArgument($collectionValueType, 6, '$collectionValueType');
76+
}
77+
78+
private function validateCollectionArgument($collectionArgument, int $argumentIndex, string $argumentName): ?array
79+
{
80+
if (null === $collectionArgument) {
81+
return null;
82+
}
83+
84+
if (!is_null($collectionArgument) && !is_array($collectionArgument) && !$collectionArgument instanceof Type) {
85+
throw new \TypeError(sprintf('"%s()": Argument #%d (%s) must be of type "array", "%s" or "null", "%s" given.', __METHOD__, $argumentIndex, $argumentName, Type::class, get_debug_type($collectionArgument)));
86+
}
87+
88+
if (is_array($collectionArgument)) {
89+
foreach ($collectionArgument as $type) {
90+
if (!$type instanceof Type) {
91+
throw new \TypeError(sprintf('"%s()": Argument #%d (%s) must be an array with items of type "%s", "%s" given.', __METHOD__, $argumentIndex, $argumentName, Type::class, get_debug_type($collectionArgument)));
92+
}
93+
}
94+
return $collectionArgument;
95+
}
96+
97+
return [$collectionArgument];
7498
}
7599

76100
/**
@@ -107,8 +131,27 @@ public function isCollection(): bool
107131
* Gets collection key type.
108132
*
109133
* Only applicable for a collection type.
134+
*
135+
* @deprecated since Symfony 5.3, use "getCollectionKeyTypes()" instead
110136
*/
111137
public function getCollectionKeyType(): ?self
138+
{
139+
trigger_deprecation('symfony/property-info', '5.3', 'The "%s()" method is deprecated, use "getCollectionKeyTypes()" instead.', __METHOD__);
140+
141+
$type = $this->getCollectionKeyTypes();
142+
if (is_array($type)) {
143+
[$type] = $type;
144+
}
145+
146+
return $type;
147+
}
148+
149+
/**
150+
* Gets collection key types.
151+
*
152+
* Only applicable for a collection type.
153+
*/
154+
public function getCollectionKeyTypes(): ?array
112155
{
113156
return $this->collectionKeyType;
114157
}
@@ -117,8 +160,27 @@ public function getCollectionKeyType(): ?self
117160
* Gets collection value type.
118161
*
119162
* Only applicable for a collection type.
163+
*
164+
* @deprecated since Symfony 5.3, use "getCollectionValueTypes()" instead
120165
*/
121166
public function getCollectionValueType(): ?self
167+
{
168+
trigger_deprecation('symfony/property-info', '5.3', 'The "%s()" method is deprecated, use "getCollectionValueTypes()" instead.', __METHOD__);
169+
170+
$type = $this->getCollectionValueTypes();
171+
if (is_array($type)) {
172+
[$type] = $type;
173+
}
174+
175+
return $type;
176+
}
177+
178+
/**
179+
* Gets collection value types.
180+
*
181+
* Only applicable for a collection type.
182+
*/
183+
public function getCollectionValueTypes(): ?array
122184
{
123185
return $this->collectionValueType;
124186
}

0 commit comments

Comments
 (0)