Final Class Yiisoft\Data\Paginator\OffsetPaginator
| Inheritance | Yiisoft\Data\Paginator\OffsetPaginator |
|---|---|
| Implements | Yiisoft\Data\Paginator\PaginatorInterface |
Offset paginator.
Advantages:
- Total number of pages is available
- Can get to specific page
- Data can be unordered
- The limit set in the data reader is taken into account
Disadvantages:
- Performance degrades with page number increase
- Insertions or deletions in the middle of the data are making results inconsistent
Public Methods
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
| 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 OffsetableDataInterface) {
throw new InvalidArgumentException(sprintf(
'Data reader should implement "%s" in order to be used with offset paginator.',
OffsetableDataInterface::class,
));
}
if (!$dataReader instanceof CountableDataInterface) {
throw new InvalidArgumentException(sprintf(
'Data reader should implement "%s" in order to be used with offset paginator.',
CountableDataInterface::class,
));
}
if (!$dataReader instanceof LimitableDataInterface) {
throw new InvalidArgumentException(sprintf(
'Data reader should implement "%s" in order to be used with offset paginator.',
LimitableDataInterface::class,
));
}
$this->dataReader = $dataReader;
$this->token = PageToken::next('1');
}
Get the current page number.
| public integer getCurrentPage ( ) | ||
| return | integer |
Current page number. |
|---|---|---|
public function getCurrentPage(): int
{
/** @var positive-int */
return (int) $this->token->value;
}
| public integer getCurrentPageSize ( ) |
public function getCurrentPageSize(): int
{
$pages = $this->getInternalTotalPages();
if ($pages === 1) {
return $this->getTotalItems();
}
$currentPage = $this->getCurrentPage();
if ($currentPage < $pages) {
return $this->pageSize;
}
if ($currentPage === $pages) {
/** @psalm-var positive-int Because the total items number is more than offset */
return $this->getTotalItems() - $this->getOffset();
}
return 0;
}
| public Yiisoft\Data\Reader\FilterInterface getFilter ( ) |
public function getFilter(): FilterInterface
{
if (!$this->isFilterable()) {
throw new LogicException('Data reader doesn\'t support filtering.');
}
return $this->dataReader->getFilter();
}
| public Yiisoft\Data\Paginator\PageToken|null getNextToken ( ) |
public function getNextToken(): ?PageToken
{
return $this->isOnLastPage() ? null : PageToken::next((string) ($this->getCurrentPage() + 1));
}
Get offset for the current page, that is the number of items to skip before the current page is reached.
| public integer getOffset ( ) | ||
| return | integer |
Offset. |
|---|---|---|
public function getOffset(): int
{
return $this->pageSize * ($this->getCurrentPage() - 1);
}
| public Yiisoft\Data\Paginator\PageToken|null getPreviousToken ( ) |
public function getPreviousToken(): ?PageToken
{
return $this->isOnFirstPage() ? null : PageToken::next((string) ($this->getCurrentPage() - 1));
}
| public Yiisoft\Data\Reader\Sort|null getSort ( ) |
public function getSort(): ?Sort
{
return $this->dataReader instanceof SortableDataInterface ? $this->dataReader->getSort() : null;
}
| public Yiisoft\Data\Paginator\PageToken getToken ( ) |
public function getToken(): PageToken
{
return $this->token;
}
Get total number of items in the whole data reader being paginated.
| public integer getTotalItems ( ) | ||
| return | integer |
Total items number. |
|---|---|---|
public function getTotalItems(): int
{
$count = $this->dataReader->count();
$dataReaderLimit = $this->dataReader->getLimit();
if ($dataReaderLimit !== null && $count > $dataReaderLimit) {
return $dataReaderLimit;
}
return $count;
}
Get total number of pages in a data reader being paginated.
| public integer getTotalPages ( ) | ||
| return | integer |
Total pages number. |
|---|---|---|
public function getTotalPages(): int
{
return (int) ceil($this->getTotalItems() / $this->pageSize);
}
| public boolean isFilterable ( ) |
public function isFilterable(): bool
{
return $this->dataReader instanceof FilterableDataInterface;
}
| public boolean isOnFirstPage ( ) |
public function isOnFirstPage(): bool
{
return $this->token->value === '1';
}
| public boolean isOnLastPage ( ) |
public function isOnLastPage(): bool
{
return $this->getCurrentPage() >= $this->getInternalTotalPages();
}
| public boolean isPaginationRequired ( ) |
public function isPaginationRequired(): bool
{
return $this->getTotalPages() > 1;
}
| public boolean isSortable ( ) |
public function isSortable(): bool
{
if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) {
return false;
}
return $this->dataReader instanceof SortableDataInterface;
}
| public static|null nextPage ( ) |
public function nextPage(): ?static
{
$nextToken = $this->getNextToken();
return $nextToken === null
? null
: $this->withToken($nextToken);
}
| public static|null previousPage ( ) |
public function previousPage(): ?static
{
$previousToken = $this->getPreviousToken();
return $previousToken === null
? null
: $this->withToken($previousToken);
}
| public iterable read ( ) |
public function read(): iterable
{
$currentPage = $this->getCurrentPage();
if ($currentPage > $this->getInternalTotalPages()) {
throw new PageNotFoundException($currentPage);
}
$limit = $this->pageSize;
$dataReaderLimit = $this->dataReader->getLimit();
if ($dataReaderLimit !== null && ($this->getOffset() + $this->pageSize) > $dataReaderLimit) {
/** @psalm-var non-negative-int $limit */
$limit = $dataReaderLimit - $this->getOffset();
}
yield from $this->dataReader
->withLimit($limit)
->withOffset($this->getOffset())
->read();
}
| public array|object|null readOne ( ) |
public function readOne(): array|object|null
{
$limit = 1;
$dataReaderLimit = $this->dataReader->getLimit();
if ($dataReaderLimit !== null && ($this->getOffset() + 1) > $dataReaderLimit) {
$limit = 0;
}
return $this->dataReader
->withLimit($limit)
->withOffset($this->getOffset())
->readOne();
}
Get a new instance with the given current page number set.
| public self withCurrentPage ( integer $page ) | ||
| $page | integer |
Page number. |
| return | self |
New instance. |
|---|---|---|
| throws | InvalidArgumentException |
If page is not a positive number. |
public function withCurrentPage(int $page): self
{
/** @psalm-suppress DocblockTypeContradiction */
if ($page < 1) {
throw new InvalidArgumentException('Current page should be at least 1.');
}
$new = clone $this;
$new->token = PageToken::next((string) $page);
return $new;
}
| public Yiisoft\Data\Paginator\OffsetPaginator withFilter ( Yiisoft\Data\Reader\FilterInterface $filter ) | ||
| $filter | Yiisoft\Data\Reader\FilterInterface | |
public function withFilter(FilterInterface $filter): static
{
if (!$this->isFilterable()) {
throw new LogicException('Data reader doesn\'t support filtering.');
}
$new = clone $this;
$new->dataReader = $this->dataReader->withFilter($filter);
return $new;
}
| public Yiisoft\Data\Paginator\OffsetPaginator 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;
}
| public Yiisoft\Data\Paginator\OffsetPaginator withSort ( Yiisoft\Data\Reader\Sort|null $sort ) | ||
| $sort | Yiisoft\Data\Reader\Sort|null | |
public function withSort(?Sort $sort): static
{
if (!$this->isSortable()) {
throw new LogicException('Changing sorting is not supported.');
}
$new = clone $this;
$new->dataReader = $this->dataReader->withSort($sort);
return $new;
}
| public Yiisoft\Data\Paginator\OffsetPaginator withToken ( Yiisoft\Data\Paginator\PageToken|null $token ) | ||
| $token | Yiisoft\Data\Paginator\PageToken|null | |
public function withToken(?PageToken $token): static
{
if ($token === null) {
$page = 1;
} else {
$page = (int) $token->value;
if ($page < 1) {
throw new InvalidPageException('Current page should be at least 1.');
}
}
return $this->withCurrentPage($page);
}
Signup or Login in order to comment.