vendor/api-platform/core/src/Symfony/Bundle/DataCollector/RequestDataCollector.php line 39

  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\Symfony\Bundle\DataCollector;
  12. use ApiPlatform\Metadata\ApiResource;
  13. use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
  14. use ApiPlatform\Util\RequestAttributesExtractor;
  15. use PackageVersions\Versions;
  16. use Psr\Container\ContainerInterface;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\HttpKernel\DataCollector\DataCollector;
  20. use Symfony\Component\VarDumper\Cloner\Data;
  21. /**
  22.  * @author Julien DENIAU <julien.deniau@gmail.com>
  23.  * @author Anthony GRASSIOT <antograssiot@free.fr>
  24.  */
  25. final class RequestDataCollector extends DataCollector
  26. {
  27.     public function __construct(private readonly ResourceMetadataCollectionFactoryInterface $metadataFactory, private readonly ContainerInterface $filterLocator)
  28.     {
  29.     }
  30.     /**
  31.      * {@inheritdoc}
  32.      */
  33.     public function collect(Request $requestResponse $response\Throwable $exception null): void
  34.     {
  35.         if ($request->attributes->get('_graphql'false)) {
  36.             $resourceClasses array_keys($request->attributes->get('_graphql_args', []));
  37.         } else {
  38.             $resourceClasses array_filter([$request->attributes->get('_api_resource_class')]);
  39.         }
  40.         $requestAttributes RequestAttributesExtractor::extractAttributes($request);
  41.         if (isset($requestAttributes['previous_data'])) {
  42.             $requestAttributes['previous_data'] = $this->cloneVar($requestAttributes['previous_data']);
  43.         }
  44.         $this->data['request_attributes'] = $requestAttributes;
  45.         $this->data['acceptable_content_types'] = $request->getAcceptableContentTypes();
  46.         $this->data['resources'] = array_map(fn (string $resourceClass): DataCollected => $this->collectDataByResource($resourceClass$request), $resourceClasses);
  47.     }
  48.     private function setFilters(ApiResource $resourceMetadataint $index, array &$filters, array &$counters): void
  49.     {
  50.         foreach ($resourceMetadata->getFilters() ?? [] as $id) {
  51.             if ($this->filterLocator->has($id)) {
  52.                 $filters[$index][$id] = $this->filterLocator->get($id)::class;
  53.                 continue;
  54.             }
  55.             $filters[$index][$id] = null;
  56.             ++$counters['ignored_filters'];
  57.         }
  58.     }
  59.     public function getVersion(): ?string
  60.     {
  61.         if (!class_exists(Versions::class)) {
  62.             return null;
  63.         }
  64.         $version Versions::getVersion('api-platform/core');
  65.         preg_match('/^v(.*?)@/', (string) $version$output);
  66.         return $output[1] ?? strtok($version'@');
  67.     }
  68.     /**
  69.      * {@inheritdoc}
  70.      */
  71.     public function getName(): string
  72.     {
  73.         return 'api_platform.data_collector.request';
  74.     }
  75.     public function getData(): array|Data
  76.     {
  77.         return $this->data;
  78.     }
  79.     public function getAcceptableContentTypes(): array
  80.     {
  81.         return $this->data['acceptable_content_types'] ?? [];
  82.     }
  83.     public function getRequestAttributes(): array
  84.     {
  85.         return $this->data['request_attributes'] ?? [];
  86.     }
  87.     public function getResources(): array
  88.     {
  89.         return $this->data['resources'] ?? [];
  90.     }
  91.     /**
  92.      * {@inheritdoc}
  93.      */
  94.     public function reset(): void
  95.     {
  96.         $this->data = [];
  97.     }
  98.     private function collectDataByResource(string $resourceClassRequest $request): DataCollected
  99.     {
  100.         $resourceMetadataCollection $resourceClass $this->metadataFactory->create($resourceClass) : [];
  101.         $filters = [];
  102.         $counters = ['ignored_filters' => 0];
  103.         $resourceMetadataCollectionData = [];
  104.         /** @var ApiResource $resourceMetadata */
  105.         foreach ($resourceMetadataCollection as $index => $resourceMetadata) {
  106.             $this->setFilters($resourceMetadata$index$filters$counters);
  107.             $resourceMetadataCollectionData[] = [
  108.                 'resource' => $resourceMetadata,
  109.                 'operations' => null !== $resourceMetadata->getOperations() ? iterator_to_array($resourceMetadata->getOperations()) : [],
  110.             ];
  111.         }
  112.         return new DataCollected(
  113.             $resourceClass,
  114.             $this->cloneVar($resourceMetadataCollectionData),
  115.             $filters,
  116.             $counters
  117.         );
  118.     }
  119. }