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

  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\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.      * @return object|null
  49.      */
  50.     private function getItemData($identifiers, array $attributes, array $context)
  51.     {
  52.         return $this->itemDataProvider->getItem($attributes['resource_class'], $identifiers$attributes['item_operation_name'], $context);
  53.     }
  54.     /**
  55.      * Gets data for a nested operation.
  56.      *
  57.      * @throws RuntimeException
  58.      *
  59.      * @return array|object|null
  60.      */
  61.     private function getSubresourceData($identifiers, array $attributes, array $context)
  62.     {
  63.         if (null === $this->subresourceDataProvider) {
  64.             throw new RuntimeException('Subresources not supported');
  65.         }
  66.         // TODO: SubresourceDataProvider wants: ['id' => ['id' => 1], 'relatedDummies' => ['id' => 2]], identifiers is ['id' => 1, 'relatedDummies' => 2]
  67.         $subresourceIdentifiers = [];
  68.         foreach ($attributes['identifiers'] as $parameterName => [$class$property]) {
  69.             if (false !== ($attributes['identifiers'][$parameterName][2] ?? null)) {
  70.                 $subresourceIdentifiers[$parameterName] = [$property => $identifiers[$parameterName]];
  71.             }
  72.         }
  73.         return $this->subresourceDataProvider->getSubresource($attributes['resource_class'], $subresourceIdentifiers$attributes['subresource_context'] + $context$attributes['subresource_operation_name']);
  74.     }
  75.     /**
  76.      * @param array $parameters - usually comes from $request->attributes->all()
  77.      *
  78.      * @throws InvalidIdentifierException
  79.      */
  80.     private function extractIdentifiers(array $parameters, array $attributes)
  81.     {
  82.         $identifiersKeys $attributes['identifiers'] ?? ['id' => [$attributes['resource_class'], 'id']];
  83.         $identifiers = [];
  84.         $identifiersNumber \count($identifiersKeys);
  85.         foreach ($identifiersKeys as $parameterName => $identifiedBy) {
  86.             if (!isset($parameters[$parameterName])) {
  87.                 if ($attributes['has_composite_identifier']) {
  88.                     $identifiers CompositeIdentifierParser::parse($parameters['id']);
  89.                     if (($currentIdentifiersNumber \count($identifiers)) !== $identifiersNumber) {
  90.                         throw new InvalidIdentifierException(sprintf('Expected %d identifiers, got %d'$identifiersNumber$currentIdentifiersNumber));
  91.                     }
  92.                     return $this->identifierConverter->convert($identifiers$identifiedBy[0]);
  93.                 }
  94.                 // TODO: Subresources tuple may have a third item representing if it is a "collection", this behavior will be removed in 3.0
  95.                 if (false === ($identifiedBy[2] ?? null)) {
  96.                     continue;
  97.                 }
  98.                 throw new InvalidIdentifierException(sprintf('Parameter "%s" not found'$parameterName));
  99.             }
  100.             $identifiers[$parameterName] = $parameters[$parameterName];
  101.         }
  102.         if ($this->identifierConverter instanceof ContextAwareIdentifierConverterInterface) {
  103.             return $this->identifierConverter->convert($identifiers$attributes['resource_class'], ['identifiers' => $identifiersKeys]);
  104.         }
  105.         return $this->identifierConverter->convert($identifiers$attributes['resource_class']);
  106.     }
  107. }