Skip to content

Commit 91711b7

Browse files
Try adding requirements
1 parent 15ea6d8 commit 91711b7

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
use ApiPlatform\Doctrine\Orm\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\ORM\EntityManagerInterface;
28+
use Doctrine\ORM\Mapping\ClassMetadata;
2629
use Doctrine\Persistence\ManagerRegistry;
2730

2831
final class DoctrineOrmResourceCollectionMetadataFactory implements ResourceMetadataCollectionFactoryInterface
@@ -95,9 +98,56 @@ private function addDefaults(Operation $operation): Operation
9598
$operation = $operation->withProcessor($this->getProcessor($operation));
9699
}
97100

101+
if ($operation instanceof HttpOperation) {
102+
$operation = $operation->withRequirements($this->getRequirements($operation));
103+
}
104+
98105
return $operation;
99106
}
100107

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+
101151
private function getProvider(Operation $operation): string
102152
{
103153
if ($operation instanceof CollectionOperationInterface) {

src/Metadata/Link.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER)]
2020
final class Link extends Parameter
2121
{
22+
/**
23+
* @param class-string|null $fromClass
24+
* @param class-string|null $toClass
25+
*/
2226
public function __construct(
2327
private ?string $parameterName = null,
2428
private ?string $fromProperty = null,
@@ -87,11 +91,17 @@ public function withParameterName(string $parameterName): self
8791
return $self;
8892
}
8993

94+
/**
95+
* @return class-string|null
96+
*/
9097
public function getFromClass(): ?string
9198
{
9299
return $this->fromClass;
93100
}
94101

102+
/**
103+
* @param class-string $fromClass
104+
*/
95105
public function withFromClass(string $fromClass): self
96106
{
97107
$self = clone $this;
@@ -100,11 +110,17 @@ public function withFromClass(string $fromClass): self
100110
return $self;
101111
}
102112

113+
/**
114+
* @return class-string|null
115+
*/
103116
public function getToClass(): ?string
104117
{
105118
return $this->toClass;
106119
}
107120

121+
/**
122+
* @param class-string $toClass
123+
*/
108124
public function withToClass(string $toClass): self
109125
{
110126
$self = clone $this;

0 commit comments

Comments
 (0)