Skip to content

Commit 6edee23

Browse files
mtarldKorbeil
andcommitted
[PropertyInfo] Deprecate PropertyInfo Type
Co-authored-by: Baptiste Leduc <[email protected]>
1 parent 5efdeb3 commit 6edee23

File tree

51 files changed

+3322
-1819
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3322
-1819
lines changed

src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
2222
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
2323
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
24-
use Symfony\Component\PropertyInfo\Type;
24+
use Symfony\Component\PropertyInfo\Util\BackwardCompatibilityHelper;
25+
use Symfony\Component\TypeInfo\BuiltinType;
26+
use Symfony\Component\TypeInfo\Type;
2527

2628
/**
2729
* Extracts data using Doctrine ORM and ODM metadata.
@@ -52,7 +54,7 @@ public function getProperties(string $class, array $context = []): ?array
5254
return $properties;
5355
}
5456

55-
public function getTypes(string $class, string $property, array $context = []): ?array
57+
public function getType(string $class, string $property, array $context = []): ?Type
5658
{
5759
if (null === $metadata = $this->getMetadata($class)) {
5860
return null;
@@ -64,16 +66,17 @@ public function getTypes(string $class, string $property, array $context = []):
6466
if ($metadata->isSingleValuedAssociation($property)) {
6567
if ($metadata instanceof ClassMetadata) {
6668
$associationMapping = $metadata->getAssociationMapping($property);
67-
6869
$nullable = $this->isAssociationNullable($associationMapping);
6970
} else {
7071
$nullable = false;
7172
}
7273

73-
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $class)];
74+
$t = Type::object($class);
75+
76+
return $nullable ? Type::nullable($t) : $t;
7477
}
7578

76-
$collectionKeyType = Type::BUILTIN_TYPE_INT;
79+
$collectionKeyType = BuiltinType::INT;
7780

7881
if ($metadata instanceof ClassMetadata) {
7982
$associationMapping = $metadata->getAssociationMapping($property);
@@ -107,18 +110,11 @@ public function getTypes(string $class, string $property, array $context = []):
107110
}
108111
}
109112

110-
return [new Type(
111-
Type::BUILTIN_TYPE_OBJECT,
112-
false,
113-
Collection::class,
114-
true,
115-
new Type($collectionKeyType),
116-
new Type(Type::BUILTIN_TYPE_OBJECT, false, $class)
117-
)];
113+
return Type::collection(Type::object(Collection::class), Type::object($class), Type::builtin($collectionKeyType));
118114
}
119115

120116
if ($metadata instanceof ClassMetadata && isset($metadata->embeddedClasses[$property])) {
121-
return [new Type(Type::BUILTIN_TYPE_OBJECT, false, $metadata->embeddedClasses[$property]['class'])];
117+
return Type::object($metadata->embeddedClasses[$property]['class']);
122118
}
123119

124120
if ($metadata->hasField($property)) {
@@ -130,32 +126,40 @@ public function getTypes(string $class, string $property, array $context = []):
130126

131127
$nullable = $metadata instanceof ClassMetadata && $metadata->isNullable($property);
132128
$enumType = null;
129+
133130
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
134-
$enumType = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass);
131+
$enumType = Type::enum($enumClass);
132+
$enumType = $nullable ? Type::nullable($enumType) : $enumType;
135133
}
136134

137135
switch ($builtinType) {
138-
case Type::BUILTIN_TYPE_OBJECT:
136+
case BuiltinType::OBJECT:
139137
switch ($typeOfField) {
140138
case Types::DATE_MUTABLE:
141139
case Types::DATETIME_MUTABLE:
142140
case Types::DATETIMETZ_MUTABLE:
143141
case 'vardatetime':
144142
case Types::TIME_MUTABLE:
145-
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')];
143+
$t = Type::object(\DateTime::class);
144+
145+
return $nullable ? Type::nullable($t) : $t;
146146

147147
case Types::DATE_IMMUTABLE:
148148
case Types::DATETIME_IMMUTABLE:
149149
case Types::DATETIMETZ_IMMUTABLE:
150150
case Types::TIME_IMMUTABLE:
151-
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTimeImmutable')];
151+
$t = Type::object(\DateTimeImmutable::class);
152+
153+
return $nullable ? Type::nullable($t) : $t;
152154

153155
case Types::DATEINTERVAL:
154-
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateInterval')];
156+
$t = Type::object(\DateInterval::class);
157+
158+
return $nullable ? Type::nullable($t) : $t;
155159
}
156160

157161
break;
158-
case Type::BUILTIN_TYPE_ARRAY:
162+
case BuiltinType::ARRAY:
159163
switch ($typeOfField) {
160164
case 'array': // DBAL < 4
161165
case 'json_array': // DBAL < 3
@@ -164,26 +168,39 @@ public function getTypes(string $class, string $property, array $context = []):
164168
return null;
165169
}
166170

167-
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];
171+
$t = Type::array();
172+
173+
return $nullable ? Type::nullable($t) : $t;
168174

169175
case Types::SIMPLE_ARRAY:
170-
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), $enumType ?? new Type(Type::BUILTIN_TYPE_STRING))];
176+
$t = Type::list($enumType ?? Type::string());
177+
178+
return $nullable ? Type::nullable($t) : $t;
171179
}
172180
break;
173-
case Type::BUILTIN_TYPE_INT:
174-
case Type::BUILTIN_TYPE_STRING:
181+
case BuiltinType::INT:
182+
case BuiltinType::STRING:
175183
if ($enumType) {
176-
return [$enumType];
184+
return $enumType;
177185
}
178186
break;
179187
}
180188

181-
return [new Type($builtinType, $nullable)];
189+
$t = Type::builtin($builtinType);
190+
191+
return $nullable ? Type::nullable($t) : $t;
182192
}
183193

184194
return null;
185195
}
186196

197+
public function getTypes(string $class, string $property, array $context = []): ?array
198+
{
199+
trigger_deprecation('symfony/doctrine-bridge', '7.1', 'The "%s()" method is deprecated. Use "%s::getType()" instead.', __METHOD__, self::class);
200+
201+
return BackwardCompatibilityHelper::convertTypeToLegacyTypes($this->getType($class, $property, $context, true));
202+
}
203+
187204
public function isReadable(string $class, string $property, array $context = []): ?bool
188205
{
189206
return null;
@@ -241,21 +258,21 @@ private function isAssociationNullable(array|AssociationMapping $associationMapp
241258
/**
242259
* Gets the corresponding built-in PHP type.
243260
*/
244-
private function getPhpType(string $doctrineType): ?string
261+
private function getPhpType(string $doctrineType): ?BuiltinType
245262
{
246263
return match ($doctrineType) {
247264
Types::SMALLINT,
248-
Types::INTEGER => Type::BUILTIN_TYPE_INT,
249-
Types::FLOAT => Type::BUILTIN_TYPE_FLOAT,
265+
Types::INTEGER => BuiltinType::INT,
266+
Types::FLOAT => BuiltinType::FLOAT,
250267
Types::BIGINT,
251268
Types::STRING,
252269
Types::TEXT,
253270
Types::GUID,
254-
Types::DECIMAL => Type::BUILTIN_TYPE_STRING,
255-
Types::BOOLEAN => Type::BUILTIN_TYPE_BOOL,
271+
Types::DECIMAL => BuiltinType::STRING,
272+
Types::BOOLEAN => BuiltinType::BOOL,
256273
Types::BLOB,
257-
Types::BINARY => Type::BUILTIN_TYPE_RESOURCE,
258-
'object', // DBAL < 4
274+
Types::BINARY => BuiltinType::RESOURCE,
275+
BuiltinType::OBJECT, // DBAL < 4
259276
Types::DATE_MUTABLE,
260277
Types::DATETIME_MUTABLE,
261278
Types::DATETIMETZ_MUTABLE,
@@ -265,10 +282,10 @@ private function getPhpType(string $doctrineType): ?string
265282
Types::DATETIME_IMMUTABLE,
266283
Types::DATETIMETZ_IMMUTABLE,
267284
Types::TIME_IMMUTABLE,
268-
Types::DATEINTERVAL => Type::BUILTIN_TYPE_OBJECT,
285+
Types::DATEINTERVAL => BuiltinType::OBJECT,
269286
'array', // DBAL < 4
270287
'json_array', // DBAL < 3
271-
Types::SIMPLE_ARRAY => Type::BUILTIN_TYPE_ARRAY,
288+
Types::SIMPLE_ARRAY => BuiltinType::ARRAY,
272289
default => null,
273290
};
274291
}

src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php

Lines changed: 43 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded;
3030
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt;
3131
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString;
32-
use Symfony\Component\PropertyInfo\Type;
32+
use Symfony\Component\TypeInfo\Type;
3333

3434
/**
3535
* @author Kévin Dunglas <[email protected]>
@@ -106,134 +106,70 @@ public function testTestGetPropertiesWithEmbedded()
106106
}
107107

108108
/**
109-
* @dataProvider typesProvider
109+
* @dataProvider typeProvider
110110
*/
111-
public function testExtract(string $property, array $type = null)
111+
public function testExtract(string $property, ?Type $type)
112112
{
113-
$this->assertEquals($type, $this->createExtractor()->getTypes(DoctrineDummy::class, $property, []));
113+
$this->assertEquals($type, $this->createExtractor()->getType(DoctrineDummy::class, $property, []));
114114
}
115115

116116
public function testExtractWithEmbedded()
117117
{
118-
$expectedTypes = [new Type(
119-
Type::BUILTIN_TYPE_OBJECT,
120-
false,
121-
DoctrineEmbeddable::class
122-
)];
123-
124-
$actualTypes = $this->createExtractor()->getTypes(
125-
DoctrineWithEmbedded::class,
126-
'embedded',
127-
[]
118+
$this->assertEquals(
119+
Type::object(DoctrineEmbeddable::class),
120+
$this->createExtractor()->getType(DoctrineWithEmbedded::class, 'embedded'),
128121
);
129-
130-
$this->assertEquals($expectedTypes, $actualTypes);
131122
}
132123

133124
public function testExtractEnum()
134125
{
135-
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumString::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumString', []));
136-
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumInt', []));
137-
$this->assertNull($this->createExtractor()->getTypes(DoctrineEnum::class, 'enumStringArray', []));
138-
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class))], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumIntArray', []));
139-
$this->assertNull($this->createExtractor()->getTypes(DoctrineEnum::class, 'enumCustom', []));
126+
$this->assertEquals(Type::enum(EnumString::class), $this->createExtractor()->getType(DoctrineEnum::class, 'enumString'));
127+
$this->assertEquals(Type::enum(EnumInt::class), $this->createExtractor()->getType(DoctrineEnum::class, 'enumInt'));
128+
$this->assertNull($this->createExtractor()->getType(DoctrineEnum::class, 'enumStringArray'));
129+
$this->assertEquals(Type::list(Type::enum(EnumInt::class)), $this->createExtractor()->getType(DoctrineEnum::class, 'enumIntArray'));
130+
$this->assertNull($this->createExtractor()->getType(DoctrineEnum::class, 'enumCustom'));
140131
}
141132

142-
public static function typesProvider(): array
133+
/**
134+
* @return iterable<array{0: string, 1: ?Type}>
135+
*/
136+
public static function typeProvider(): iterable
143137
{
144-
return [
145-
['id', [new Type(Type::BUILTIN_TYPE_INT)]],
146-
['guid', [new Type(Type::BUILTIN_TYPE_STRING)]],
147-
['bigint', [new Type(Type::BUILTIN_TYPE_STRING)]],
148-
['time', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime')]],
149-
['timeImmutable', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeImmutable')]],
150-
['dateInterval', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateInterval')]],
151-
['float', [new Type(Type::BUILTIN_TYPE_FLOAT)]],
152-
['decimal', [new Type(Type::BUILTIN_TYPE_STRING)]],
153-
['bool', [new Type(Type::BUILTIN_TYPE_BOOL)]],
154-
['binary', [new Type(Type::BUILTIN_TYPE_RESOURCE)]],
155-
['jsonArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]],
156-
['foo', [new Type(Type::BUILTIN_TYPE_OBJECT, true, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')]],
157-
['bar', [new Type(
158-
Type::BUILTIN_TYPE_OBJECT,
159-
false,
160-
'Doctrine\Common\Collections\Collection',
161-
true,
162-
new Type(Type::BUILTIN_TYPE_INT),
163-
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
164-
)]],
165-
['indexedRguid', [new Type(
166-
Type::BUILTIN_TYPE_OBJECT,
167-
false,
168-
'Doctrine\Common\Collections\Collection',
169-
true,
170-
new Type(Type::BUILTIN_TYPE_STRING),
171-
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
172-
)]],
173-
['indexedBar', [new Type(
174-
Type::BUILTIN_TYPE_OBJECT,
175-
false,
176-
'Doctrine\Common\Collections\Collection',
177-
true,
178-
new Type(Type::BUILTIN_TYPE_STRING),
179-
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
180-
)]],
181-
['indexedFoo', [new Type(
182-
Type::BUILTIN_TYPE_OBJECT,
183-
false,
184-
'Doctrine\Common\Collections\Collection',
185-
true,
186-
new Type(Type::BUILTIN_TYPE_STRING),
187-
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation')
188-
)]],
189-
['indexedBaz', [new Type(
190-
Type::BUILTIN_TYPE_OBJECT,
191-
false,
192-
Collection::class,
193-
true,
194-
new Type(Type::BUILTIN_TYPE_INT),
195-
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
196-
)]],
197-
['simpleArray', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]],
198-
['customFoo', null],
199-
['notMapped', null],
200-
['indexedByDt', [new Type(
201-
Type::BUILTIN_TYPE_OBJECT,
202-
false,
203-
Collection::class,
204-
true,
205-
new Type(Type::BUILTIN_TYPE_OBJECT),
206-
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
207-
)]],
208-
['indexedByCustomType', null],
209-
['indexedBuz', [new Type(
210-
Type::BUILTIN_TYPE_OBJECT,
211-
false,
212-
Collection::class,
213-
true,
214-
new Type(Type::BUILTIN_TYPE_STRING),
215-
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
216-
)]],
217-
['dummyGeneratedValueList', [new Type(
218-
Type::BUILTIN_TYPE_OBJECT,
219-
false,
220-
'Doctrine\Common\Collections\Collection',
221-
true,
222-
new Type(Type::BUILTIN_TYPE_INT),
223-
new Type(Type::BUILTIN_TYPE_OBJECT, false, DoctrineRelation::class)
224-
)]],
225-
['json', null],
226-
];
138+
yield ['id', Type::int()];
139+
yield ['guid', Type::string()];
140+
yield ['bigint', Type::string()];
141+
yield ['time', Type::object(\DateTime::class)];
142+
yield ['timeImmutable', Type::object(\DateTimeImmutable::class)];
143+
yield ['dateInterval', Type::object(\DateInterval::class)];
144+
yield ['float', Type::float()];
145+
yield ['decimal', Type::string()];
146+
yield ['bool', Type::bool()];
147+
yield ['binary', Type::resource()];
148+
yield ['jsonArray', Type::array()];
149+
yield ['foo', Type::nullable(Type::object(DoctrineRelation::class))];
150+
yield ['bar', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::int())];
151+
yield ['indexedRguid', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::string())];
152+
yield ['indexedBar', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::string())];
153+
yield ['indexedFoo', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::string())];
154+
yield ['indexedBaz', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::int())];
155+
yield ['simpleArray', Type::list(Type::string())];
156+
yield ['customFoo', null];
157+
yield ['notMapped', null];
158+
yield ['indexedByDt', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::object())];
159+
yield ['indexedByCustomType', null];
160+
yield ['indexedBuz', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::string())];
161+
yield ['dummyGeneratedValueList', Type::collection(Type::object(Collection::class), Type::object(DoctrineRelation::class), Type::int())];
162+
yield ['json', null];
227163
}
228164

229165
public function testGetPropertiesCatchException()
230166
{
231167
$this->assertNull($this->createExtractor()->getProperties('Not\Exist'));
232168
}
233169

234-
public function testGetTypesCatchException()
170+
public function testGetTypeCatchException()
235171
{
236-
$this->assertNull($this->createExtractor()->getTypes('Not\Exist', 'baz'));
172+
$this->assertNull($this->createExtractor()->getType('Not\Exist', 'baz'));
237173
}
238174

239175
public function testGeneratedValueNotWritable()

0 commit comments

Comments
 (0)