vendor/api-platform/core/src/Core/DataProvider/OperationDataProviderTrait.php line 64

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the API Platform project.
  4.  *
  5.  * (c) Kévin Dunglas <[email protected]>
  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\DataProvider;
  12. use ApiPlatform\Core\Identifier\CompositeIdentifierParser;
  13. use ApiPlatform\Core\Identifier\ContextAwareIdentifierConverterInterface;
  14. use ApiPlatform\Core\Identifier\IdentifierConverterInterface;
  15. use ApiPlatform\Exception\InvalidIdentifierException;
  16. use ApiPlatform\Exception\RuntimeException;
  17. /**
  18.  * @internal
  19.  */
  20. trait OperationDataProviderTrait
  21. {
  22.     /**
  23.      * @var CollectionDataProviderInterface
  24.      */
  25.     private $collectionDataProvider;
  26.     /**
  27.      * @var ItemDataProviderInterface
  28.      */
  29.     private $itemDataProvider;
  30.     /**
  31.      * @var SubresourceDataProviderInterface|null
  32.      */
  33.     private $subresourceDataProvider;
  34.     /**
  35.      * @var IdentifierConverterInterface|null
  36.      */
  37.     private $identifierConverter;
  38.     /**
  39.      * Retrieves data for a collection operation.
  40.      */
  41.     private function getCollectionData(array $attributes, array $context): iterable
  42.     {
  43.         return $this->collectionDataProvider->getCollection($attributes['resource_class'], $attributes['collection_operation_name'], $context);
  44.     }
  45.     /**
  46.      * Gets data for an item operation.
  47.      *
  48.      * @param mixed $identifiers
  49.      *
  50.      * @return object|null
  51.      */
  52.     private function getItemData($identifiers, array $attributes, array $context)
  53.     {
  54.         return $this->itemDataProvider->getItem($attributes['resource_class'], $identifiers$attributes['item_operation_name'], $context);
  55.     }
  56.     /**
  57.      * Gets data for a nested operation.
  58.      *
  59.      * @param mixed $identifiers
  60.      *
  61.      * @throws RuntimeException
  62.      *
  63.      * @return array|object|null
  64.      */
  65.     private function getSubresourceData($identifiers, array $attributes, array $context)
  66.     {
  67.         if (null === $this->subresourceDataProvider) {
  68.             throw new RuntimeException('Subresources not supported');
  69.         }
  70.         // TODO: SubresourceDataProvider wants: ['id' => ['id' => 1], 'relatedDummies' => ['id' => 2]], identifiers is ['id' => 1, 'relatedDummies' => 2]
  71.         $subresourceIdentifiers = [];
  72.         foreach ($attributes['identifiers'] as $parameterName => [$class$property]) {
  73.             if (false !== ($attributes['identifiers'][$parameterName][2] ?? null)) {
  74.                 $subresourceIdentifiers[$parameterName] = [$property => $identifiers[$parameterName]];
  75.             }
  76.         }
  77.         return $this->subresourceDataProvider->getSubresource($attributes['resource_class'], $subresourceIdentifiers$attributes['subresource_context'] + $context$attributes['subresource_operation_name']);
  78.     }
  79.     /**
  80.      * @param array $parameters - usually comes from $request->attributes->all()
  81.      *
  82.      * @throws InvalidIdentifierException
  83.      */
  84.     private function extractIdentifiers(array $parameters, array $attributes)
  85.     {
  86.         $identifiersKeys $attributes['identifiers'] ?? ['id' => [$attributes['resource_class'], 'id']];
  87.         $identifiers = [];
  88.         $identifiersNumber \count($identifiersKeys);
  89.         foreach ($identifiersKeys as $parameterName => $identifiedBy) {
  90.             if (!isset($parameters[$parameterName])) {
  91.                 if ($attributes['has_composite_identifier']) {
  92.                     $identifiers CompositeIdentifierParser::parse($parameters['id']);
  93.                     if (($currentIdentifiersNumber \count($identifiers)) !== $identifiersNumber) {
  94.                         throw new InvalidIdentifierException(sprintf('Expected %d identifiers, got %d'$identifiersNumber$currentIdentifiersNumber));
  95.                     }
  96.                     return $this->identifierConverter->convert($identifiers$identifiedBy[0]);
  97.                 }
  98.                 // TODO: Subresources tuple may have a third item representing if it is a "collection", this behavior will be removed in 3.0
  99.                 if (false === ($identifiedBy[2] ?? null)) {
  100.                     continue;
  101.                 }
  102.                 throw new InvalidIdentifierException(sprintf('Parameter "%s" not found'$parameterName));
  103.             }
  104.             $identifiers[$parameterName] = $parameters[$parameterName];
  105.         }
  106.         if ($this->identifierConverter instanceof ContextAwareIdentifierConverterInterface) {
  107.             return $this->identifierConverter->convert($identifiers$attributes['resource_class'], ['identifiers' => $identifiersKeys]);
  108.         }
  109.         return $this->identifierConverter->convert($identifiers$attributes['resource_class']);
  110.     }
  111. }