-
-
Notifications
You must be signed in to change notification settings - Fork 936
Open
@VincentLanglet
Description
Description
When defining a route
new Get()
The uri template 'uriTemplate': 'projects/{uuid}' is automatically added by ApiPlatform and the Links too.
It would be great having the requirement detected base on the ORM field.
Example
I tried locally with something like
class RequirementResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
{
private const string INT_PATTERN = '^-?[0-9]+$';
private const string UUID_PATTERN = '^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$';
private const string ULID_PATTERN = '^[0-7][0-9A-HJKMNP-TV-Z]{25}$';
public function __construct(
private ResourceMetadataCollectionFactoryInterface $decorated,
private EntityManagerInterface $entityManager
) {}
public function create(string $resourceClass): ResourceMetadataCollection
{
$collection = $this->decorated->create($resourceClass);
foreach ($collection as $i => $resource) {
$operations = $resource->getOperations();
if (null === $operations) {
continue;
}
foreach ($resource->getOperations() as $operationName => $operation) {
$requirements = $operation->getRequirements() ?? [];
$uriVariables = (array) ($operation->getUriVariables() ?? []);
if ([] === $uriVariables) {
continue;
}
foreach ($uriVariables as $paramName => $uriVariable) {
if (isset($requirements[$paramName])) {
continue;
}
if (!$uriVariable instanceof Link) {
continue;
}
$identifiers = $uriVariable->getIdentifiers();
if (count($identifiers) !== 1) {
continue;
}
$fromClass = $uriVariable->getFromClass();
$fieldPattern = $this->getFieldPattern($fromClass, $identifiers[0]);
if (null !== $fieldPattern) {
$requirements[$paramName] = $fieldPattern;
}
}
if ([] !== $requirements) {
$operations->add($operationName, $operation->withRequirements($requirements));
}
}
$collection[$i] = $resource->withOperations($operations);
}
return $collection;
}
private function getFieldPattern(string $class, string $fieldName): ?string
{
try {
$classMetadata = $this->entityManager->getClassMetadata($class);
} catch (\Exception) {
return null;
}
if (!$classMetadata->hasField($fieldName)) {
return null;
}
return match ($classMetadata->getFieldMapping($fieldName)->type) {
'uuid', 'guid' => self::UUID_PATTERN,
'ulid' => self::ULID_PATTERN,
'smallint', 'integer', 'bigint' => self::INT_PATTERN,
default => null,
};
}
}
I dunno if my implementation is missing something
Metadata
Metadata
Assignees
Labels
No labels