You are here

public function EntityResource::getCollection in JSON:API 8

Same name and namespace in other branches
  1. 8.2 src/Controller/EntityResource.php \Drupal\jsonapi\Controller\EntityResource::getCollection()

Gets the collection of entities.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The request object.

Return value

\Drupal\jsonapi\ResourceResponse The response.

Throws

\Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException

File

src/Controller/EntityResource.php, line 356

Class

EntityResource
Process all entity requests.

Namespace

Drupal\jsonapi\Controller

Code

public function getCollection(Request $request) {

  // Instantiate the query for the filtering.
  $entity_type_id = $this->resourceType
    ->getEntityTypeId();
  $params = static::getJsonApiParams($request, $this->resourceType);
  $query_cacheability = new CacheableMetadata();
  $query = $this
    ->getCollectionQuery($entity_type_id, $params, $query_cacheability);
  try {
    $results = $this
      ->executeQueryInRenderContext($query, $query_cacheability);
  } catch (\LogicException $e) {

    // Ensure good DX when an entity query involves a config entity type.
    // @todo Core should throw a better exception.
    if (strpos($e
      ->getMessage(), 'Getting the base fields is not supported for entity type') === 0) {
      preg_match('/entity type (.*)\\./', $e
        ->getMessage(), $matches);
      $config_entity_type_id = $matches[1];
      throw new BadRequestHttpException(sprintf("Filtering on config entities is not supported by Drupal's entity API. You tried to filter on a %s config entity.", $config_entity_type_id));
    }
    else {
      throw $e;
    }
  }
  $storage = $this->entityTypeManager
    ->getStorage($entity_type_id);

  // We request N+1 items to find out if there is a next page for the pager.
  // We may need to remove that extra item before loading the entities.
  $pager_size = $query
    ->getMetaData('pager_size');
  if ($has_next_page = $pager_size < count($results)) {

    // Drop the last result.
    array_pop($results);
  }

  // Each item of the collection data contains an array with 'entity' and
  // 'access' elements.
  $collection_data = $this
    ->loadEntitiesWithAccess($storage, $results);
  $entity_collection = new EntityCollection(array_column($collection_data, 'entity'));
  $entity_collection
    ->setHasNextPage($has_next_page);

  // Calculate all the results and pass them to the EntityCollectionInterface.
  $count_query_cacheability = new CacheableMetadata();
  if ($this->resourceType
    ->includeCount()) {
    $count_query = $this
      ->getCollectionCountQuery($entity_type_id, $params, $count_query_cacheability);
    $total_results = $this
      ->executeQueryInRenderContext($count_query, $count_query_cacheability);
    $entity_collection
      ->setTotalCount($total_results);
  }
  $response = $this
    ->respondWithCollection($entity_collection, $entity_type_id);

  // Add cacheable metadata for the access result.
  $access_info = array_column($collection_data, 'access');
  array_walk($access_info, function ($access) use ($response) {
    $response
      ->addCacheableDependency($access);
  });
  $response
    ->addCacheableDependency($query_cacheability);
  $response
    ->addCacheableDependency($count_query_cacheability);
  return $response;
}