0 follower

Final Class Yiisoft\Data\Paginator\KeysetPaginator

InheritanceYiisoft\Data\Paginator\KeysetPaginator
ImplementsYiisoft\Data\Paginator\PaginatorInterface

Keyset paginator.

Advantages:

  • Performance doesn't depend on page number
  • Consistent results regardless of insertions and deletions

Disadvantages:

  • Total number of pages is not available
  • Can't get to specific page, only "previous" and "next"
  • Data can't be unordered
  • The limit set in the data reader leads to an exception

Psalm Types

Name Value
FilterCallback callable

Constants

Hide inherited constants

Constant Value Description Defined By
DEFAULT_PAGE_SIZE 10 Page size that is used in case it is not set explicitly. Yiisoft\Data\Paginator\PaginatorInterface

Method Details

Hide inherited methods

__clone() public method

public mixed __clone ( )

                public function __clone()
{
    $this->readCache = null;
    $this->hasPreviousPage = false;
    $this->hasNextPage = false;
    $this->currentFirstValue = null;
    $this->currentLastValue = null;
}

            
__construct() public method

public mixed __construct ( Yiisoft\Data\Reader\ReadableDataInterface $dataReader )
$dataReader Yiisoft\Data\Reader\ReadableDataInterface

Data reader being paginated.

                public function __construct(ReadableDataInterface $dataReader)
{
    if (!$dataReader instanceof FilterableDataInterface) {
        throw new InvalidArgumentException(sprintf(
            'Data reader should implement "%s" to be used with keyset paginator.',
            FilterableDataInterface::class,
        ));
    }
    if (!$dataReader instanceof SortableDataInterface) {
        throw new InvalidArgumentException(sprintf(
            'Data reader should implement "%s" to be used with keyset paginator.',
            SortableDataInterface::class,
        ));
    }
    if (!$dataReader instanceof LimitableDataInterface) {
        throw new InvalidArgumentException(sprintf(
            'Data reader should implement "%s" to be used with keyset paginator.',
            LimitableDataInterface::class,
        ));
    }
    if ($dataReader->getLimit() !== null) {
        throw new InvalidArgumentException('Limited data readers are not supported by keyset pagination.');
    }
    $this->dataReader = $this->prepareSortInDataReader($dataReader, $dataReader->getSort());
}

            
getCurrentPageSize() public method

public integer getCurrentPageSize ( )

                public function getCurrentPageSize(): int
{
    $this->initialize();
    return count($this->readCache);
}

            
getFilter() public method

public Yiisoft\Data\Reader\FilterInterface getFilter ( )

                public function getFilter(): FilterInterface
{
    return $this->dataReader->getFilter();
}

            
getNextToken() public method

public Yiisoft\Data\Paginator\PageToken|null getNextToken ( )

                public function getNextToken(): ?PageToken
{
    return $this->isOnLastPage()
        ? null
        : ($this->currentLastValue === null ? null : PageToken::next($this->currentLastValue));
}

            
getPageSize() public method

public integer getPageSize ( )

                public function getPageSize(): int
{
    return $this->pageSize;
}

            
getPreviousToken() public method

public Yiisoft\Data\Paginator\PageToken|null getPreviousToken ( )

                public function getPreviousToken(): ?PageToken
{
    return $this->isOnFirstPage()
        ? null
        : ($this->currentFirstValue === null ? null : PageToken::previous($this->currentFirstValue));
}

            
getSort() public method

public Yiisoft\Data\Reader\Sort|null getSort ( )

                public function getSort(): ?Sort
{
    return $this->dataReader->getSort();
}

            
getToken() public method

public Yiisoft\Data\Paginator\PageToken|null getToken ( )

                public function getToken(): ?PageToken
{
    return $this->token;
}

            
isFilterable() public method

public boolean isFilterable ( )

                public function isFilterable(): bool
{
    return true;
}

            
isOnFirstPage() public method

public boolean isOnFirstPage ( )

                public function isOnFirstPage(): bool
{
    if ($this->token === null) {
        /** @infection-ignore-all */
        return true;
    }
    $this->initialize();
    return !$this->hasPreviousPage;
}

            
isOnLastPage() public method

public boolean isOnLastPage ( )

                public function isOnLastPage(): bool
{
    $this->initialize();
    return !$this->hasNextPage;
}

            
isPaginationRequired() public method

public boolean isPaginationRequired ( )

                public function isPaginationRequired(): bool
{
    return !$this->isOnFirstPage() || !$this->isOnLastPage();
}

            
isSortable() public method

public boolean isSortable ( )

                public function isSortable(): bool
{
    return true;
}

            
nextPage() public method

public static|null nextPage ( )

                public function nextPage(): ?static
{
    $nextToken = $this->getNextToken();
    return $nextToken === null
        ? null
        : $this->withToken($nextToken);
}

            
previousPage() public method

public static|null previousPage ( )

                public function previousPage(): ?static
{
    $previousToken = $this->getPreviousToken();
    return $previousToken === null
        ? null
        : $this->withToken($previousToken);
}

            
read() public method

Reads items of the page.

This method uses the read cache to prevent duplicate reads from the data source. See more {@see \Yiisoft\Data\Paginator\resetInternal()}.

public iterable read ( )

                public function read(): iterable
{
    if ($this->readCache !== null) {
        return $this->readCache;
    }
    /** @var Sort $sort */
    $sort = $this->dataReader->getSort();
    /** @infection-ignore-all Any value more than one in the line below will be ignored in `readData()` method */
    $dataReader = $this->dataReader->withLimit($this->pageSize + 1);
    if ($this->token?->isPrevious === true) {
        $sort = $this->reverseSort($sort);
        $dataReader = $dataReader->withSort($sort);
    }
    if ($this->token !== null) {
        $dataReader = $dataReader->withFilter($this->createFilter($sort));
        $this->hasPreviousPage = $this->previousPageExist($dataReader, $sort);
    }
    $data = $this->readData($dataReader, $sort);
    if ($this->token?->isPrevious === true) {
        $data = $this->reverseData($data);
    }
    return $this->readCache = $data;
}

            
readOne() public method

public array|object|null readOne ( )

                public function readOne(): array|object|null
{
    foreach ($this->read() as $item) {
        return $item;
    }
    return null;
}

            
withFilter() public method

public Yiisoft\Data\Paginator\KeysetPaginator withFilter ( Yiisoft\Data\Reader\FilterInterface $filter )
$filter Yiisoft\Data\Reader\FilterInterface

                public function withFilter(FilterInterface $filter): static
{
    $new = clone $this;
    $new->dataReader = $this->dataReader->withFilter($filter);
    return $new;
}

            
withFilterCallback() public method

Returns a new instance with defined closure for preparing data reader filters.

public self withFilterCallback ( Closure|null $callback )
$callback Closure|null

                public function withFilterCallback(?Closure $callback): self
{
    $new = clone $this;
    $new->filterCallback = $callback;
    return $new;
}

            
withPageSize() public method

public Yiisoft\Data\Paginator\KeysetPaginator withPageSize ( integer $pageSize )
$pageSize integer

                public function withPageSize(int $pageSize): static
{
    /** @psalm-suppress DocblockTypeContradiction We don't believe in psalm types */
    if ($pageSize < 1) {
        throw new InvalidArgumentException('Page size should be at least 1.');
    }
    $new = clone $this;
    $new->pageSize = $pageSize;
    return $new;
}

            
withSort() public method

public Yiisoft\Data\Paginator\KeysetPaginator withSort ( Yiisoft\Data\Reader\Sort|null $sort )
$sort Yiisoft\Data\Reader\Sort|null

                public function withSort(?Sort $sort): static
{
    $new = clone $this;
    $new->dataReader = $this->prepareSortInDataReader($this->dataReader, $sort);
    return $new;
}

            
withToken() public method

public Yiisoft\Data\Paginator\KeysetPaginator withToken ( Yiisoft\Data\Paginator\PageToken|null $token )
$token Yiisoft\Data\Paginator\PageToken|null

                public function withToken(?PageToken $token): static
{
    $new = clone $this;
    $new->token = $token;
    return $new;
}