vendor/api-platform/core/src/Core/Metadata/Resource/Factory/OperationResourceMetadataFactory.php line 101

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\Metadata\Resource\Factory;
  12. use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
  13. /**
  14.  * Creates or completes operations.
  15.  *
  16.  * @author Kévin Dunglas <dunglas@gmail.com>
  17.  */
  18. final class OperationResourceMetadataFactory implements ResourceMetadataFactoryInterface
  19. {
  20.     /**
  21.      * @internal
  22.      */
  23.     public const SUPPORTED_COLLECTION_OPERATION_METHODS = [
  24.         'GET' => true,
  25.         'POST' => true,
  26.     ];
  27.     /**
  28.      * @internal
  29.      */
  30.     public const SUPPORTED_ITEM_OPERATION_METHODS = [
  31.         'GET' => true,
  32.         'PUT' => true,
  33.         // PATCH is automatically supported if at least one patch format has been configured
  34.         'DELETE' => true,
  35.     ];
  36.     private $decorated;
  37.     private $patchFormats;
  38.     public function __construct(ResourceMetadataFactoryInterface $decorated, array $patchFormats = [])
  39.     {
  40.         $this->decorated $decorated;
  41.         $this->patchFormats $patchFormats;
  42.     }
  43.     public function create(string $resourceClass): ResourceMetadata
  44.     {
  45.         $resourceMetadata $this->decorated->create($resourceClass);
  46.         $isAbstract = (new \ReflectionClass($resourceClass))->isAbstract();
  47.         $collectionOperations $resourceMetadata->getCollectionOperations();
  48.         if (null === $collectionOperations) {
  49.             $resourceMetadata $resourceMetadata->withCollectionOperations($this->createOperations($isAbstract ? ['GET'] : ['GET''POST'], $resourceMetadata));
  50.         } else {
  51.             $resourceMetadata $this->normalize(true$resourceClass$resourceMetadata$collectionOperations);
  52.         }
  53.         $itemOperations $resourceMetadata->getItemOperations();
  54.         if (null === $itemOperations) {
  55.             $methods = ['GET''DELETE'];
  56.             if (!$isAbstract) {
  57.                 $methods[] = 'PUT';
  58.                 if ($this->patchFormats) {
  59.                     $methods[] = 'PATCH';
  60.                 }
  61.             }
  62.             $resourceMetadata $resourceMetadata->withItemOperations($this->createOperations($methods$resourceMetadata));
  63.         } else {
  64.             $resourceMetadata $this->normalize(false$resourceClass$resourceMetadata$itemOperations);
  65.         }
  66.         $graphql $resourceMetadata->getGraphql();
  67.         if (null === $graphql) {
  68.             $resourceMetadata $resourceMetadata->withGraphql(['item_query' => [], 'collection_query' => [], 'delete' => [], 'update' => [], 'create' => []]);
  69.         } else {
  70.             $resourceMetadata $this->normalizeGraphQl($resourceMetadata$graphql);
  71.         }
  72.         return $resourceMetadata;
  73.     }
  74.     private function createOperations(array $methodsResourceMetadata $resourceMetadata): array
  75.     {
  76.         $operations = [];
  77.         foreach ($methods as $method) {
  78.             $operations[strtolower($method)] = ['method' => $method'stateless' => $resourceMetadata->getAttribute('stateless')];
  79.         }
  80.         return $operations;
  81.     }
  82.     private function normalize(bool $collectionstring $resourceClassResourceMetadata $resourceMetadata, array $operations): ResourceMetadata
  83.     {
  84.         $newOperations = [];
  85.         foreach ($operations as $operationName => $operation) {
  86.             // e.g.: @ApiResource(itemOperations={"get"})
  87.             if (\is_int($operationName) && \is_string($operation)) {
  88.                 $operationName $operation;
  89.                 $operation = [];
  90.             }
  91.             $upperOperationName strtoupper((string) $operationName);
  92.             if ($collection) {
  93.                 $supported = isset(self::SUPPORTED_COLLECTION_OPERATION_METHODS[$upperOperationName]);
  94.             } else {
  95.                 $supported = isset(self::SUPPORTED_ITEM_OPERATION_METHODS[$upperOperationName]) || ($this->patchFormats && 'PATCH' === $upperOperationName);
  96.             }
  97.             if (!isset($operation['method']) && !isset($operation['route_name'])) {
  98.                 if ($supported) {
  99.                     $operation['method'] = $upperOperationName;
  100.                 } else {
  101.                     @trigger_error(sprintf('The "route_name" attribute will not be set automatically again in API Platform 3.0, set it for the %s operation "%s" of the class "%s".'$collection 'collection' 'item'$operationName$resourceClass), \E_USER_DEPRECATED);
  102.                     $operation['route_name'] = $operationName;
  103.                 }
  104.             }
  105.             if (isset($operation['method'])) {
  106.                 $operation['method'] = strtoupper($operation['method']);
  107.             }
  108.             $operation['stateless'] = $operation['stateless'] ?? $resourceMetadata->getAttribute('stateless');
  109.             $newOperations[$operationName] = $operation;
  110.         }
  111.         return $collection $resourceMetadata->withCollectionOperations($newOperations) : $resourceMetadata->withItemOperations($newOperations);
  112.     }
  113.     private function normalizeGraphQl(ResourceMetadata $resourceMetadata, array $operations): ResourceMetadata
  114.     {
  115.         foreach ($operations as $operationName => $operation) {
  116.             if (\is_int($operationName) && \is_string($operation)) {
  117.                 unset($operations[$operationName]);
  118.                 $operations[$operation] = [];
  119.             }
  120.         }
  121.         return $resourceMetadata->withGraphql($operations);
  122.     }
  123. }