Commit 0168fd0c authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Utilise le router Symfony pour déterminer les chemins exacts de ressources.

Showing with 64 additions and 15 deletions
+64 -15
......@@ -29,6 +29,7 @@
"symfony/dependency-injection": "^3.4 | ^4.0",
"symfony/http-kernel": "^3.4 | ^4.0",
"symfony/property-info": "^3.4 | ^4.0",
"symfony/routing": "^3.4 | ^4.0",
"symfony/serializer": "^3.4 | ^4.0",
"twig/twig": "^2.2"
},
......
......@@ -25,6 +25,8 @@ use ApiPlatform\Core\Api\FilterInterface;
use ApiPlatform\Core\Api\OperationMethodResolverInterface;
use ApiPlatform\Core\Api\OperationType;
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
use ApiPlatform\Core\Exception\PropertyNotFoundException;
use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
......@@ -36,6 +38,8 @@ use Irstea\NgModelGeneratorBundle\Models\ClassName;
use Irstea\NgModelGeneratorBundle\Models\PHPClass;
use Psr\Container\ContainerInterface;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\RouterInterface;
/**
* Class MetadataFactory
......@@ -79,6 +83,9 @@ final class MetadataFactory implements MetadataFactoryInterface
/** @var string[][] */
private $defaultGroups = [];
/** @var RouterInterface */
private $router;
/**
* MetadataFactory constructor.
*
......@@ -88,9 +95,9 @@ final class MetadataFactory implements MetadataFactoryInterface
* @param PropertyMetadataFactoryInterface $propertyMetadataFactory
* @param PropertyInfoExtractorInterface $propertyInfoExtractor
* @param OperationMethodResolverInterface $operationMethodResolver
* @param OperationPathResolverInterface $operationPathResolver
* @param ContainerInterface $filterLocator
* @param PaginationMetadata $paginationMetadata
* @param RouterInterface $router
* @param ClassHierarchy $classHierarchy
*/
public function __construct(
......@@ -100,7 +107,7 @@ final class MetadataFactory implements MetadataFactoryInterface
PropertyMetadataFactoryInterface $propertyMetadataFactory,
PropertyInfoExtractorInterface $propertyInfoExtractor,
OperationMethodResolverInterface $operationMethodResolver,
OperationPathResolverInterface $operationPathResolver,
RouterInterface $router,
ContainerInterface $filterLocator,
PaginationMetadata $paginationMetadata,
ClassHierarchy $classHierarchy
......@@ -111,10 +118,10 @@ final class MetadataFactory implements MetadataFactoryInterface
$this->propertyMetadataFactory = $propertyMetadataFactory;
$this->propertyInfoExtractor = $propertyInfoExtractor;
$this->operationMethodResolver = $operationMethodResolver;
$this->operationPathResolver = $operationPathResolver;
$this->filterLocator = $filterLocator;
$this->paginationMetadata = $paginationMetadata;
$this->classHierarchy = $classHierarchy;
$this->router = $router;
}
/**
......@@ -182,6 +189,10 @@ final class MetadataFactory implements MetadataFactoryInterface
/**
* @param ClassName $class
*
* @throws PropertyNotFoundException
* @throws ResourceClassNotFoundException
* @throws \ReflectionException
*
* @return OperationMetadata[]
*/
private function getOperations(ClassName $class): array
......@@ -212,6 +223,10 @@ final class MetadataFactory implements MetadataFactoryInterface
* @param string $type
* @param array $operation
*
* @throws PropertyNotFoundException
* @throws ResourceClassNotFoundException
* @throws \ReflectionException
*
* @return OperationMetadata
*/
private function getOperation(
......@@ -229,11 +244,8 @@ final class MetadataFactory implements MetadataFactoryInterface
$shortName = $resourceMetadata->getShortName();
Assertion::notNull($shortName);
/** @noinspection PhpMethodParametersCountMismatchInspection */
$path = $this->operationPathResolver->resolveOperationPath($shortName, $operation, $type);
// Suppression du suffixe de format, qui n'est pas utilisable en dehors de Symfony
$path = \str_replace('.{_format}', '', $path);
$path = $this->getOperationPath($class, $type, $name, $method);
$getAttribute = function (string $attrName, $default) use ($resourceMetadata, $type, $name) {
return $resourceMetadata->getTypedOperationAttribute($type, $name, $attrName, $default, true);
......@@ -303,6 +315,38 @@ final class MetadataFactory implements MetadataFactoryInterface
);
}
/**
* @param ClassName $class
* @param string $type
* @param string $name
* @param string $method
*
* @return string
*/
private function getOperationPath(ClassName $class, string $type, string $name, string $method): string
{
$className = $class->getFullName();
$path = null;
foreach ($this->router->getRouteCollection() as $route) {
if (
$route->getDefault('_api_resource_class') === $className
&& $route->getDefault("_api_${type}_operation_name") === $name
&& \in_array($method, $route->getMethods(), true)) {
$path = $route->getPath();
break;
}
}
if (!$path) {
throw new RouteNotFoundException("No route found for ${$type} operation ${name} on ${className}");
}
$path = str_replace('.{_format}', '', $path);
return $path;
}
/**
* @param ClassName $class
* @param array $filterIds
......@@ -332,8 +376,8 @@ final class MetadataFactory implements MetadataFactoryInterface
* @param bool $normalization
* @param string[] $groups
*
* @throws \ApiPlatform\Core\Exception\PropertyNotFoundException
* @throws \ApiPlatform\Core\Exception\ResourceClassNotFoundException
* @throws PropertyNotFoundException
* @throws ResourceClassNotFoundException
* @throws \ReflectionException
*
* @return SerializationMetadata
......@@ -360,8 +404,8 @@ final class MetadataFactory implements MetadataFactoryInterface
* @param OperationDef $opDef
* @param string[] $groups
*
* @throws \ApiPlatform\Core\Exception\PropertyNotFoundException
* @throws \ApiPlatform\Core\Exception\ResourceClassNotFoundException
* @throws PropertyNotFoundException
* @throws ResourceClassNotFoundException
* @throws \ReflectionException
*
* @return SerializationMetadata
......@@ -442,6 +486,8 @@ final class MetadataFactory implements MetadataFactoryInterface
* @param OperationDef|null $opDef
* @param array $groups
*
* @throws ResourceClassNotFoundException
*
* @return string
*/
private function getRepresentationName(
......@@ -477,6 +523,8 @@ final class MetadataFactory implements MetadataFactoryInterface
/**
* @param ClassName $class
*
* @throws ResourceClassNotFoundException
*
* @return array
*/
private function getDefaultGroups(ClassName $class): array
......
......@@ -61,10 +61,10 @@ final class ClassInfo implements ClassName
/**
* ClassInfo constructor.
*
* @param ClassName $class
* @param ClassName $class
* @param PropertyMetadata[] $properties
* @param bool $abstract
* @param bool $resource
* @param bool $abstract
* @param bool $resource
*/
public function __construct(ClassName $class, array $properties = [], bool $abstract = false, bool $resource = false)
{
......
......@@ -14,7 +14,7 @@
<argument type="service" id="api_platform.metadata.property.metadata_factory"/>
<argument type="service" id="property_info"/>
<argument type="service" id="api_platform.operation_method_resolver"/>
<argument type="service" id="api_platform.operation_path_resolver"/>
<argument type="service" id="router"/>
<argument type="service" id="api_platform.filter_locator"/>
<argument type="service" id="ng_model_generator.metadata.pagination"/>
<argument type="service" id="irstea_ng_model_generator.metadata.resource_class_hierarchy"/>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment