vendor/api-platform/core/src/Core/Bridge/Symfony/Routing/IriConverter.php line 126

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the API Platform project.
  4.  *
  5.  * (c) Kévin Dunglas <dunglas@gmail.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace ApiPlatform\Core\Bridge\Symfony\Routing;
  12. use ApiPlatform\Core\Api\IdentifiersExtractor;
  13. use ApiPlatform\Core\Api\IdentifiersExtractorInterface;
  14. use ApiPlatform\Core\Api\IriConverterInterface;
  15. use ApiPlatform\Core\Api\OperationType;
  16. use ApiPlatform\Core\Api\ResourceClassResolverInterface;
  17. use ApiPlatform\Core\Api\UrlGeneratorInterface;
  18. use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
  19. use ApiPlatform\Core\DataProvider\OperationDataProviderTrait;
  20. use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
  21. use ApiPlatform\Core\Identifier\CompositeIdentifierParser;
  22. use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
  23. use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
  24. use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
  25. use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
  26. use ApiPlatform\Exception\InvalidArgumentException;
  27. use ApiPlatform\Exception\InvalidIdentifierException;
  28. use ApiPlatform\Exception\ItemNotFoundException;
  29. use ApiPlatform\Exception\RuntimeException;
  30. use ApiPlatform\Util\AttributesExtractor;
  31. use ApiPlatform\Util\ResourceClassInfoTrait;
  32. use Symfony\Component\PropertyAccess\PropertyAccess;
  33. use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
  34. use Symfony\Component\Routing\Exception\ExceptionInterface as RoutingExceptionInterface;
  35. use Symfony\Component\Routing\RouterInterface;
  36. /**
  37.  * @author Kévin Dunglas <dunglas@gmail.com>
  38.  *
  39.  * @deprecated Since Api Platform 2.7, use ApiPlatform\Symfony\Routing\IriConverter instead.
  40.  */
  41. final class IriConverter implements IriConverterInterface
  42. {
  43.     use OperationDataProviderTrait;
  44.     use ResourceClassInfoTrait;
  45.     private $routeNameResolver;
  46.     private $router;
  47.     private $identifiersExtractor;
  48.     public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactoryPropertyMetadataFactoryInterface $propertyMetadataFactoryItemDataProviderInterface $itemDataProviderRouteNameResolverInterface $routeNameResolverRouterInterface $routerPropertyAccessorInterface $propertyAccessor nullIdentifiersExtractorInterface $identifiersExtractor nullSubresourceDataProviderInterface $subresourceDataProvider nullIdentifierConverterInterface $identifierConverter nullResourceClassResolverInterface $resourceClassResolver nullResourceMetadataFactoryInterface $resourceMetadataFactory null)
  49.     {
  50.         $this->itemDataProvider $itemDataProvider;
  51.         $this->routeNameResolver $routeNameResolver;
  52.         $this->router $router;
  53.         $this->subresourceDataProvider $subresourceDataProvider;
  54.         $this->identifierConverter $identifierConverter;
  55.         $this->resourceClassResolver $resourceClassResolver;
  56.         $this->identifiersExtractor $identifiersExtractor ?: new IdentifiersExtractor($propertyNameCollectionFactory$propertyMetadataFactory$propertyAccessor ?? PropertyAccess::createPropertyAccessor());
  57.         $this->resourceMetadataFactory $resourceMetadataFactory;
  58.     }
  59.     /**
  60.      * @return object
  61.      */
  62.     public function getItemFromIri(string $iri, array $context = [])
  63.     {
  64.         try {
  65.             $parameters $this->router->match($iri);
  66.         } catch (RoutingExceptionInterface $e) {
  67.             throw new InvalidArgumentException(sprintf('No route matches "%s".'$iri), $e->getCode(), $e);
  68.         }
  69.         if (!isset($parameters['_api_resource_class'])) {
  70.             throw new InvalidArgumentException(sprintf('No resource associated to "%s".'$iri));
  71.         }
  72.         if (isset($parameters['_api_collection_operation_name'])) {
  73.             throw new InvalidArgumentException(sprintf('The iri "%s" references a collection not an item.'$iri));
  74.         }
  75.         $attributes AttributesExtractor::extractAttributes($parameters);
  76.         try {
  77.             $identifiers $this->extractIdentifiers($parameters$attributes);
  78.         } catch (InvalidIdentifierException $e) {
  79.             throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
  80.         }
  81.         if ($this->identifierConverter) {
  82.             $context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] = true;
  83.         }
  84.         if (isset($attributes['subresource_operation_name'])) {
  85.             if (($item $this->getSubresourceData($identifiers$attributes$context)) && !\is_array($item)) {
  86.                 return $item;
  87.             }
  88.             throw new ItemNotFoundException(sprintf('Item not found for "%s".'$iri));
  89.         }
  90.         if ($item $this->getItemData($identifiers$attributes$context)) {
  91.             return $item;
  92.         }
  93.         throw new ItemNotFoundException(sprintf('Item not found for "%s".'$iri));
  94.     }
  95.     public function getIriFromItem($itemint $referenceType null): string
  96.     {
  97.         $resourceClass $this->getResourceClass($itemtrue);
  98.         try {
  99.             $identifiers $this->identifiersExtractor->getIdentifiersFromItem($item);
  100.         } catch (RuntimeException $e) {
  101.             throw new InvalidArgumentException(sprintf('Unable to generate an IRI for the item of type "%s"'$resourceClass), $e->getCode(), $e);
  102.         }
  103.         return $this->getItemIriFromResourceClass($resourceClass$identifiers$this->getReferenceType($resourceClass$referenceType));
  104.     }
  105.     public function getIriFromResourceClass(string $resourceClassint $referenceType null): string
  106.     {
  107.         try {
  108.             return $this->router->generate($this->routeNameResolver->getRouteName($resourceClassOperationType::COLLECTION), [], $this->getReferenceType($resourceClass$referenceType));
  109.         } catch (RoutingExceptionInterface $e) {
  110.             throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".'$resourceClass), $e->getCode(), $e);
  111.         }
  112.     }
  113.     public function getItemIriFromResourceClass(string $resourceClass, array $identifiersint $referenceType null): string
  114.     {
  115.         $routeName $this->routeNameResolver->getRouteName($resourceClassOperationType::ITEM);
  116.         $metadata $this->resourceMetadataFactory->create($resourceClass);
  117.         if (\count($identifiers) > && true === $metadata->getAttribute('composite_identifier'true)) {
  118.             $identifiers = ['id' => CompositeIdentifierParser::stringify($identifiers)];
  119.         }
  120.         try {
  121.             return $this->router->generate($routeName$identifiers$this->getReferenceType($resourceClass$referenceType));
  122.         } catch (RoutingExceptionInterface $e) {
  123.             throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".'$resourceClass), $e->getCode(), $e);
  124.         }
  125.     }
  126.     public function getSubresourceIriFromResourceClass(string $resourceClass, array $contextint $referenceType null): string
  127.     {
  128.         try {
  129.             return $this->router->generate($this->routeNameResolver->getRouteName($resourceClassOperationType::SUBRESOURCE$context), $context['subresource_identifiers'], $this->getReferenceType($resourceClass$referenceType));
  130.         } catch (RoutingExceptionInterface $e) {
  131.             throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".'$resourceClass), $e->getCode(), $e);
  132.         }
  133.     }
  134.     private function getReferenceType(string $resourceClass, ?int $referenceType): ?int
  135.     {
  136.         if (null === $referenceType && null !== $this->resourceMetadataFactory) {
  137.             $metadata $this->resourceMetadataFactory->create($resourceClass);
  138.             $referenceType $metadata->getAttribute('url_generation_strategy');
  139.         }
  140.         return $referenceType ?? UrlGeneratorInterface::ABS_PATH;
  141.     }
  142. }