Skip to content

Commit a609735

Browse files
Improve
1 parent fd6be16 commit a609735

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

src/Doctrine/Odm/Metadata/Resource/DoctrineMongoDbOdmResourceCollectionMetadataFactory.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
use ApiPlatform\Doctrine\Odm\State\Options;
1919
use ApiPlatform\Metadata\CollectionOperationInterface;
2020
use ApiPlatform\Metadata\DeleteOperationInterface;
21+
use ApiPlatform\Metadata\HttpOperation;
22+
use ApiPlatform\Metadata\Link;
2123
use ApiPlatform\Metadata\Operation;
2224
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2325
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2426
use ApiPlatform\State\Util\StateOptionsTrait;
2527
use Doctrine\ODM\MongoDB\DocumentManager;
28+
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
2629
use Doctrine\Persistence\ManagerRegistry;
2730

2831
final class DoctrineMongoDbOdmResourceCollectionMetadataFactory implements ResourceMetadataCollectionFactoryInterface
@@ -92,9 +95,61 @@ private function addDefaults(Operation $operation): Operation
9295
$operation = $operation->withProcessor($this->getProcessor($operation));
9396
}
9497

98+
if ($operation instanceof HttpOperation) {
99+
$operation = $operation->withRequirements($this->getRequirements($operation));
100+
}
101+
95102
return $operation;
96103
}
97104

105+
/**
106+
* @return array<string, string>
107+
*/
108+
private function getRequirements(HttpOperation $operation): array
109+
{
110+
$requirements = $operation->getRequirements() ?? [];
111+
$uriVariables = (array) ($operation->getUriVariables() ?? []);
112+
113+
foreach ($uriVariables as $paramName => $uriVariable) {
114+
if (isset($requirements[$paramName])) {
115+
continue;
116+
}
117+
118+
if (!$uriVariable instanceof Link) {
119+
continue;
120+
}
121+
122+
$identifiers = $uriVariable->getIdentifiers();
123+
if (1 !== \count($identifiers)) {
124+
continue;
125+
}
126+
$fieldName = $identifiers[0];
127+
128+
$fromClass = $uriVariable->getFromClass();
129+
if (null === $fromClass) {
130+
continue;
131+
}
132+
$classMetadata = $this->managerRegistry->getManagerForClass($fromClass)?->getClassMetadata($fromClass);
133+
134+
$requirement = null;
135+
if ($classMetadata instanceof ClassMetadata && $classMetadata->hasField($fieldName)) {
136+
$fieldMapping = $classMetadata->getFieldMapping($fieldName);
137+
$requirement = match ($fieldMapping['type']) {
138+
'uuid', 'guid' => '^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$',
139+
'ulid' => '^[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}$',
140+
'smallint', 'integer', 'bigint' => '^-?[0-9]+$',
141+
default => null,
142+
};
143+
}
144+
145+
if (null !== $requirement) {
146+
$requirements[$paramName] = $requirement;
147+
}
148+
}
149+
150+
return $requirements;
151+
}
152+
98153
private function getProvider(Operation $operation): string
99154
{
100155
if ($operation instanceof CollectionOperationInterface) {

src/Doctrine/Orm/Metadata/Resource/DoctrineOrmResourceCollectionMetadataFactory.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use ApiPlatform\State\Util\StateOptionsTrait;
2727
use Doctrine\ORM\EntityManagerInterface;
2828
use Doctrine\ORM\Mapping\ClassMetadata;
29+
use Doctrine\ORM\Mapping\FieldMapping;
2930
use Doctrine\Persistence\ManagerRegistry;
3031

3132
final class DoctrineOrmResourceCollectionMetadataFactory implements ResourceMetadataCollectionFactoryInterface
@@ -122,17 +123,27 @@ private function getRequirements(HttpOperation $operation): array
122123
continue;
123124
}
124125
$identifiers = $uriVariable->getIdentifiers();
125-
if (1 !== count($identifiers)) {
126+
if (1 !== \count($identifiers)) {
126127
continue;
127128
}
129+
$fieldName = $identifiers[0];
128130

129131
$fromClass = $uriVariable->getFromClass();
130-
$fieldName = $identifiers[0];
132+
if (null === $fromClass) {
133+
continue;
134+
}
131135
$classMetadata = $this->managerRegistry->getManagerForClass($fromClass)?->getClassMetadata($fromClass);
132136

133137
$requirement = null;
134138
if ($classMetadata instanceof ClassMetadata && $classMetadata->hasField($fieldName)) {
135-
$requirement = match ($classMetadata->getFieldMapping($fieldName)->type) {
139+
$fieldMapping = $classMetadata->getFieldMapping($fieldName);
140+
if (class_exists(FieldMapping::class)) {
141+
$type = $fieldMapping->type;
142+
} else {
143+
$type = $fieldMapping['type'];
144+
}
145+
146+
$requirement = match ($type) {
136147
'uuid', 'guid' => '^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$',
137148
'ulid' => '^[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}$',
138149
'smallint', 'integer', 'bigint' => '^-?[0-9]+$',

0 commit comments

Comments
 (0)