|
13 | 13 |
|
14 | 14 | namespace ApiPlatform\Doctrine\Odm\PropertyInfo;
|
15 | 15 |
|
16 |
| -use ApiPlatform\Metadata\Util\PropertyInfoToTypeInfoHelper; |
17 | 16 | use Doctrine\Common\Collections\Collection;
|
18 | 17 | use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as MongoDbClassMetadata;
|
19 | 18 | use Doctrine\ODM\MongoDB\Types\Type as MongoDbType;
|
|
25 | 24 | use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
26 | 25 | use Symfony\Component\PropertyInfo\Type as LegacyType;
|
27 | 26 | use Symfony\Component\TypeInfo\Type;
|
| 27 | +use Symfony\Component\TypeInfo\TypeIdentifier; |
28 | 28 |
|
29 | 29 | /**
|
30 | 30 | * Extracts data using Doctrine MongoDB ODM metadata.
|
@@ -52,13 +52,71 @@ public function getProperties($class, array $context = []): ?array
|
52 | 52 | return $metadata->getFieldNames();
|
53 | 53 | }
|
54 | 54 |
|
| 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 | + |
55 | 109 | /**
|
56 | 110 | * {@inheritdoc}
|
57 | 111 | *
|
| 112 | + * // deprecated since 4.2 use "getType" instead |
| 113 | + * |
58 | 114 | * @return LegacyType[]|null
|
59 | 115 | */
|
60 |
| - public function getTypes(string $class, string $property, array $context = []): ?array |
| 116 | + public function getTypes($class, $property, array $context = []): ?array |
61 | 117 | {
|
| 118 | + // trigger_deprecation('api-platform/core', '4.2', 'The "%s()" method is deprecated, use "%s::getType()" instead.', __METHOD__, self::class); |
| 119 | + |
62 | 120 | if (null === $metadata = $this->getMetadata($class)) {
|
63 | 121 | return null;
|
64 | 122 | }
|
@@ -115,7 +173,7 @@ public function getTypes(string $class, string $property, array $context = []):
|
115 | 173 | }
|
116 | 174 | }
|
117 | 175 |
|
118 |
| - $builtinType = $this->getPhpType($typeOfField); |
| 176 | + $builtinType = $this->getPhpTypeLegacy($typeOfField); |
119 | 177 |
|
120 | 178 | return $builtinType ? [new LegacyType($builtinType, $nullable)] : null;
|
121 | 179 | }
|
@@ -156,15 +214,23 @@ private function getMetadata(string $class): ?ClassMetadata
|
156 | 214 | }
|
157 | 215 | }
|
158 | 216 |
|
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 |
160 | 221 | {
|
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 | + }; |
162 | 231 | }
|
163 | 232 |
|
164 |
| - /** |
165 |
| - * Gets the corresponding built-in PHP type. |
166 |
| - */ |
167 |
| - private function getPhpType(string $doctrineType): ?string |
| 233 | + private function getPhpTypeLegacy(string $doctrineType): ?string |
168 | 234 | {
|
169 | 235 | return match ($doctrineType) {
|
170 | 236 | MongoDbType::INTEGER, MongoDbType::INT, MongoDbType::INTID, MongoDbType::KEY => LegacyType::BUILTIN_TYPE_INT,
|
|
0 commit comments