|
18 | 18 | use ApiPlatform\Doctrine\Orm\State\Options; |
19 | 19 | use ApiPlatform\Metadata\CollectionOperationInterface; |
20 | 20 | use ApiPlatform\Metadata\DeleteOperationInterface; |
| 21 | +use ApiPlatform\Metadata\HttpOperation; |
| 22 | +use ApiPlatform\Metadata\Link; |
21 | 23 | use ApiPlatform\Metadata\Operation; |
22 | 24 | use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; |
23 | 25 | use ApiPlatform\Metadata\Resource\ResourceMetadataCollection; |
24 | 26 | use ApiPlatform\State\Util\StateOptionsTrait; |
25 | 27 | use Doctrine\ORM\EntityManagerInterface; |
| 28 | +use Doctrine\ORM\Mapping\ClassMetadata; |
26 | 29 | use Doctrine\Persistence\ManagerRegistry; |
27 | 30 |
|
28 | 31 | final class DoctrineOrmResourceCollectionMetadataFactory implements ResourceMetadataCollectionFactoryInterface |
@@ -95,9 +98,56 @@ private function addDefaults(Operation $operation): Operation |
95 | 98 | $operation = $operation->withProcessor($this->getProcessor($operation)); |
96 | 99 | } |
97 | 100 |
|
| 101 | + if ($operation instanceof HttpOperation) { |
| 102 | + $operation = $operation->withRequirements($this->getRequirements($operation)); |
| 103 | + } |
| 104 | + |
98 | 105 | return $operation; |
99 | 106 | } |
100 | 107 |
|
| 108 | + /** |
| 109 | + * @return array<string, string> |
| 110 | + */ |
| 111 | + private function getRequirements(HttpOperation $operation): array |
| 112 | + { |
| 113 | + $requirements = $operation->getRequirements() ?? []; |
| 114 | + $uriVariables = (array) ($operation->getUriVariables() ?? []); |
| 115 | + |
| 116 | + foreach ($uriVariables as $paramName => $uriVariable) { |
| 117 | + if (isset($requirements[$paramName])) { |
| 118 | + continue; |
| 119 | + } |
| 120 | + |
| 121 | + if (!$uriVariable instanceof Link) { |
| 122 | + continue; |
| 123 | + } |
| 124 | + $identifiers = $uriVariable->getIdentifiers(); |
| 125 | + if (count($identifiers) !== 1) { |
| 126 | + continue; |
| 127 | + } |
| 128 | + |
| 129 | + $fromClass = $uriVariable->getFromClass(); |
| 130 | + $fieldName = $identifiers[0]; |
| 131 | + $classMetadata = $this->managerRegistry->getManagerForClass($fromClass)?->getClassMetadata($fromClass); |
| 132 | + |
| 133 | + $requirement = null; |
| 134 | + if ($classMetadata instanceof ClassMetadata && $classMetadata->hasField($fieldName)) { |
| 135 | + $requirement = match ($classMetadata->getFieldMapping($fieldName)->type) { |
| 136 | + 'uuid', 'guid' => '^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$', |
| 137 | + 'ulid' => '^[0-7][0-9A-HJKMNP-TV-Z]{25}$', |
| 138 | + 'smallint', 'integer', 'bigint' => '^-?[0-9]+$', |
| 139 | + default => null, |
| 140 | + }; |
| 141 | + } |
| 142 | + |
| 143 | + if (null !== $requirement) { |
| 144 | + $requirements[$paramName] = $requirement; |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + return $requirements; |
| 149 | + } |
| 150 | + |
101 | 151 | private function getProvider(Operation $operation): string |
102 | 152 | { |
103 | 153 | if ($operation instanceof CollectionOperationInterface) { |
|
0 commit comments