Skip to content

Commit 4b6eaa7

Browse files
committed
feat(metadata/doctrine): use TypeInfo's Type
1 parent ee0ce44 commit 4b6eaa7

36 files changed

+767
-203
lines changed

composer.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,10 @@
111111
"symfony/http-foundation": "^6.4 || ^7.0",
112112
"symfony/http-kernel": "^6.4 || ^7.0",
113113
"symfony/property-access": "^6.4 || ^7.0",
114-
"symfony/property-info": "^6.4 || ^7.1",
114+
"symfony/property-info": "^7.1",
115115
"symfony/serializer": "^6.4 || ^7.0",
116116
"symfony/translation-contracts": "^3.3",
117+
"symfony/type-info": "^7.2",
117118
"symfony/web-link": "^6.4 || ^7.0",
118119
"willdurand/negotiation": "^3.1"
119120
},
@@ -164,7 +165,7 @@
164165
"symfony/console": "^6.4 || ^7.0",
165166
"symfony/css-selector": "^6.4 || ^7.0",
166167
"symfony/dependency-injection": "^6.4 || ^7.0",
167-
"symfony/doctrine-bridge": "^6.4.2 || ^7.0.2",
168+
"symfony/doctrine-bridge": "^7.1",
168169
"symfony/dom-crawler": "^6.4 || ^7.0",
169170
"symfony/error-handler": "^6.4 || ^7.0",
170171
"symfony/event-dispatcher": "^6.4 || ^7.0",

docs/guides/create-a-custom-doctrine-filter.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
2727
use ApiPlatform\Metadata\Operation;
2828
use Doctrine\ORM\QueryBuilder;
29-
use Symfony\Component\PropertyInfo\Type;
3029

3130
final class RegexpFilter extends AbstractFilter
3231
{
@@ -67,7 +66,7 @@ public function getDescription(string $resourceClass): array
6766
foreach ($this->properties as $property => $strategy) {
6867
$description["regexp_$property"] = [
6968
'property' => $property,
70-
'type' => Type::BUILTIN_TYPE_STRING,
69+
'type' => 'string',
7170
'required' => false,
7271
'description' => 'Filter using a regex. This will appear in the OpenAPI documentation!',
7372
'openapi' => [

src/Doctrine/Odm/PropertyInfo/DoctrineExtractor.php

+75-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
namespace ApiPlatform\Doctrine\Odm\PropertyInfo;
1515

16-
use ApiPlatform\Metadata\Util\PropertyInfoToTypeInfoHelper;
1716
use Doctrine\Common\Collections\Collection;
1817
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as MongoDbClassMetadata;
1918
use Doctrine\ODM\MongoDB\Types\Type as MongoDbType;
@@ -25,6 +24,7 @@
2524
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
2625
use Symfony\Component\PropertyInfo\Type as LegacyType;
2726
use Symfony\Component\TypeInfo\Type;
27+
use Symfony\Component\TypeInfo\TypeIdentifier;
2828

2929
/**
3030
* Extracts data using Doctrine MongoDB ODM metadata.
@@ -52,13 +52,71 @@ public function getProperties($class, array $context = []): ?array
5252
return $metadata->getFieldNames();
5353
}
5454

55+
public function getType(string $class, string $property, array $context = []): ?Type
56+
{
57+
if (null === $metadata = $this->getMetadata($class)) {
58+
return null;
59+
}
60+
61+
if ($metadata->hasAssociation($property)) {
62+
/** @var class-string|null */
63+
$class = $metadata->getAssociationTargetClass($property);
64+
65+
if (null === $class) {
66+
return null;
67+
}
68+
69+
if ($metadata->isSingleValuedAssociation($property)) {
70+
$nullable = $metadata instanceof MongoDbClassMetadata && $metadata->isNullable($property);
71+
72+
return $nullable ? Type::nullable(Type::object($class)) : Type::object($class);
73+
}
74+
75+
return Type::collection(Type::object(Collection::class), Type::object($class), Type::int());
76+
}
77+
78+
if (!$metadata->hasField($property)) {
79+
return null;
80+
}
81+
82+
$typeOfField = $metadata->getTypeOfField($property);
83+
84+
if (!$typeIdentifier = $this->getTypeIdentifier($typeOfField)) {
85+
return null;
86+
}
87+
88+
$nullable = $metadata instanceof MongoDbClassMetadata && $metadata->isNullable($property);
89+
$enumType = null;
90+
91+
if (null !== $enumClass = $metadata instanceof MongoDbClassMetadata ? $metadata->getFieldMapping($property)['enumType'] ?? null : null) {
92+
$enumType = $nullable ? Type::nullable(Type::enum($enumClass)) : Type::enum($enumClass);
93+
}
94+
95+
$builtinType = $nullable ? Type::nullable(Type::builtin($typeIdentifier)) : Type::builtin($typeIdentifier);
96+
97+
$type = match ($typeOfField) {
98+
MongoDbType::DATE => Type::object(\DateTime::class),
99+
MongoDbType::DATE_IMMUTABLE => Type::object(\DateTimeImmutable::class),
100+
MongoDbType::HASH => Type::array(),
101+
MongoDbType::COLLECTION => Type::list(),
102+
MongoDbType::INT, MongoDbType::INTEGER, MongoDbType::STRING => $enumType ? $enumType : $builtinType,
103+
default => $builtinType,
104+
};
105+
106+
return $nullable ? Type::nullable($type) : $type;
107+
}
108+
55109
/**
56110
* {@inheritdoc}
57111
*
112+
* // deprecated since 4.2 use "getType" instead
113+
*
58114
* @return LegacyType[]|null
59115
*/
60-
public function getTypes(string $class, string $property, array $context = []): ?array
116+
public function getTypes($class, $property, array $context = []): ?array
61117
{
118+
// trigger_deprecation('api-platform/core', '4.2', 'The "%s()" method is deprecated, use "%s::getType()" instead.', __METHOD__, self::class);
119+
62120
if (null === $metadata = $this->getMetadata($class)) {
63121
return null;
64122
}
@@ -115,7 +173,7 @@ public function getTypes(string $class, string $property, array $context = []):
115173
}
116174
}
117175

118-
$builtinType = $this->getPhpType($typeOfField);
176+
$builtinType = $this->getPhpTypeLegacy($typeOfField);
119177

120178
return $builtinType ? [new LegacyType($builtinType, $nullable)] : null;
121179
}
@@ -156,15 +214,23 @@ private function getMetadata(string $class): ?ClassMetadata
156214
}
157215
}
158216

159-
public function getType(string $class, string $property, array $context = []): ?Type
217+
/**
218+
* Gets the corresponding built-in PHP type identifier.
219+
*/
220+
private function getTypeIdentifier(string $doctrineType): ?TypeIdentifier
160221
{
161-
return PropertyInfoToTypeInfoHelper::convertLegacyTypesToType($this->getTypes($class, $property, $context));
222+
return match ($doctrineType) {
223+
MongoDbType::INTEGER, MongoDbType::INT, MongoDbType::INTID, MongoDbType::KEY => TypeIdentifier::INT,
224+
MongoDbType::FLOAT => TypeIdentifier::FLOAT,
225+
MongoDbType::STRING, MongoDbType::ID, MongoDbType::OBJECTID, MongoDbType::TIMESTAMP, MongoDbType::BINDATA, MongoDbType::BINDATABYTEARRAY, MongoDbType::BINDATACUSTOM, MongoDbType::BINDATAFUNC, MongoDbType::BINDATAMD5, MongoDbType::BINDATAUUID, MongoDbType::BINDATAUUIDRFC4122 => TypeIdentifier::STRING,
226+
MongoDbType::BOOLEAN, MongoDbType::BOOL => TypeIdentifier::BOOL,
227+
MongoDbType::DATE, MongoDbType::DATE_IMMUTABLE => TypeIdentifier::OBJECT,
228+
MongoDbType::HASH, MongoDbType::COLLECTION => TypeIdentifier::ARRAY,
229+
default => null,
230+
};
162231
}
163232

164-
/**
165-
* Gets the corresponding built-in PHP type.
166-
*/
167-
private function getPhpType(string $doctrineType): ?string
233+
private function getPhpTypeLegacy(string $doctrineType): ?string
168234
{
169235
return match ($doctrineType) {
170236
MongoDbType::INTEGER, MongoDbType::INT, MongoDbType::INTID, MongoDbType::KEY => LegacyType::BUILTIN_TYPE_INT,

0 commit comments

Comments
 (0)