You are here

public function OffsetLimitPaginator::getPaginationLinks in JSON:API Resources 8

Get pagination links. Must not be called before executing the query.

Parameters

\Drupal\Core\Entity\Query\QueryInterface $executed_query: The executed query to which the paginator was applied. The query must have been executed and its results should have been saved. This method will modify the given query and render it unusable for fetching results.

\Drupal\Core\Cache\CacheableMetadata $cacheable_metadata: A CacheableMetadata object that will be used to capture any cacheability information generated while generating pagination links. The same object that is passed to this method should be added to the cacheability of the final response by the caller.

bool $calculate_last_link: (optional) Whether the paginator should attempt to calculate a `last` page link. By default, this is FALSE. Passing TRUE may require that entity query be re-executed in order to get a total count, which may make response times slower by increasing the time spent executing database requests.

Return value

\Drupal\jsonapi\JsonApiResource\LinkCollection An LinkCollection, with:

  • a 'next' key if it is not the last page;
  • 'prev' and 'first' keys if it's not the first page.

Overrides PaginatorInterface::getPaginationLinks

File

src/Unstable/Entity/Query/Pagination/OffsetLimitPaginator.php, line 96

Class

OffsetLimitPaginator
A paginator for handling offset-limit pagination in JSON:API request.

Namespace

Drupal\jsonapi_resources\Unstable\Entity\Query\Pagination

Code

public function getPaginationLinks(QueryInterface $executed_query, CacheableMetadata $cacheable_metadata, $calculate_last_link = FALSE) : LinkCollection {
  $paginator_metadata = $executed_query
    ->getMetaData(PaginatorMetadata::KEY);
  assert($paginator_metadata instanceof PaginatorMetadata);
  $has_next_page = !empty($paginator_metadata->hasNextPage);
  if ($calculate_last_link && $has_next_page) {
    $count_query = $executed_query
      ->range(NULL, NULL)
      ->count();
    $total_count = (int) $this->entityQueryExecutor
      ->executeQueryAndCaptureCacheability($count_query, $cacheable_metadata);
    if (empty($total_count)) {
      return new LinkCollection([]);
    }
  }
  $pager_links = new LinkCollection([]);

  /** @var \Drupal\jsonapi\Query\OffsetPage $page_param */
  $offset = $paginator_metadata->pageLocation;
  $size = $paginator_metadata->pageSizeMax;
  if ($size <= 0) {
    $cacheability = (new CacheableMetadata())
      ->addCacheContexts([
      'url.query_args:page',
    ]);
    throw new CacheableBadRequestHttpException($cacheability, sprintf('The page size needs to be a positive integer.'));
  }
  $query = (array) $this->request->query
    ->getIterator();

  // Check if this is not the last page.
  if ($has_next_page) {
    $next_url = static::getRequestLink($this->request, static::getPagerQueries('next', $offset, $size, $query));
    $pager_links = $pager_links
      ->withLink('next', new Link(new CacheableMetadata(), $next_url, 'next'));
    if (!empty($total_count)) {
      $last_url = static::getRequestLink($this->request, static::getPagerQueries('last', $offset, $size, $query, $total_count));
      $pager_links = $pager_links
        ->withLink('last', new Link(new CacheableMetadata(), $last_url, 'last'));
    }
  }

  // Check if this is not the first page.
  if ($offset > 0) {
    $first_url = static::getRequestLink($this->request, static::getPagerQueries('first', $offset, $size, $query));
    $pager_links = $pager_links
      ->withLink('first', new Link(new CacheableMetadata(), $first_url, 'first'));
    $prev_url = static::getRequestLink($this->request, static::getPagerQueries('prev', $offset, $size, $query));
    $pager_links = $pager_links
      ->withLink('prev', new Link(new CacheableMetadata(), $prev_url, 'prev'));
  }
  return $pager_links;
}