Skip to content

Commit

Permalink
Add PageNotFoundException (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
vjik committed Jan 30, 2024
1 parent 1673525 commit b0352e0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,11 @@
`getNextPageToken()` with `getNextToken()`, `getPreviousPageToken()` with `getPreviousToken()`, and add `getToken()`.
These methods use new `PageToken` class (@vjik)
- New #160: Add `Sort::hasFieldInConfig()` method that checks for the presence of a field in the sort config (@vjik)
- New #161: Add `PageNotFoundException` (@vjik)
- Chg #161: `PaginatorInterface::getCurrentPageSize()` returns 0 instead throws exception if page specified is
not found (@vjik)
- Enh #161: Add more specified psalm annotations to `CountableDataInterface::count()`,
`PaginatorInterface::getCurrentPageSize()` and `OffsetPaginator::getTotalItems()` (@vjik)

## 1.0.1 January 25, 2023

Expand Down
13 changes: 10 additions & 3 deletions src/Paginator/OffsetPaginator.php
Expand Up @@ -46,6 +46,7 @@ final class OffsetPaginator implements PaginatorInterface

/**
* @var int Maximum number of items per page.
* @psalm-var positive-int
*/
private int $pageSize = self::DEFAULT_PAGE_SIZE;

Expand Down Expand Up @@ -169,10 +170,11 @@ public function getCurrentPageSize(): int
}

if ($currentPage === $pages) {
/** @psalm-var positive-int Because total items is more than offset */
return $this->getTotalItems() - $this->getOffset();
}

throw new PaginatorException('Page not found.');
return 0;
}

/**
Expand All @@ -189,6 +191,8 @@ public function getOffset(): int
* Get total number of items in the whole data reader being paginated.
*
* @return int Total items number.
*
* @psalm-return non-negative-int
*/
public function getTotalItems(): int
{
Expand Down Expand Up @@ -232,7 +236,7 @@ public function getSort(): ?Sort
public function read(): iterable
{
if ($this->getCurrentPage() > $this->getInternalTotalPages()) {
throw new PaginatorException('Page not found.');
throw new PageNotFoundException();
}

yield from $this->dataReader
Expand All @@ -257,7 +261,7 @@ public function isOnFirstPage(): bool
public function isOnLastPage(): bool
{
if ($this->getCurrentPage() > $this->getInternalTotalPages()) {
throw new PaginatorException('Page not found.');
throw new PageNotFoundException();
}

return $this->getCurrentPage() === $this->getInternalTotalPages();
Expand All @@ -268,6 +272,9 @@ public function isPaginationRequired(): bool
return $this->getTotalPages() > 1;
}

/**
* @psalm-return non-negative-int
*/
private function getInternalTotalPages(): int
{
return max(1, $this->getTotalPages());
Expand Down
13 changes: 13 additions & 0 deletions src/Paginator/PageNotFoundException.php
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Paginator;

final class PageNotFoundException extends PaginatorException
{
public function __construct()
{
parent::__construct('Page not found.');
}
}
8 changes: 4 additions & 4 deletions src/Paginator/PaginatorInterface.php
Expand Up @@ -84,9 +84,9 @@ public function getPageSize(): int;
*
* @see getPageSize()
*
* @throws PaginatorException If page specified is not found.
*
* @return int Current page size.
*
* @psalm-return non-negative-int
*/
public function getCurrentPageSize(): int;

Expand Down Expand Up @@ -116,7 +116,7 @@ public function getSort(): ?Sort;
/**
* Get iterator that could be used to read currently active page items.
*
* @throws PaginatorException If page specified is not found.
* @throws PageNotFoundException If page specified is not found.
*
* @return iterable Iterator with items for the current page.
* @psalm-return iterable<TKey, TValue>
Expand All @@ -126,7 +126,7 @@ public function read(): iterable;
/**
* Get whether current page is the last one.
*
* @throws PaginatorException If page specified is not found.
* @throws PageNotFoundException If page specified is not found.
*
* @return bool Whether current page is the last one.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Reader/CountableDataInterface.php
Expand Up @@ -13,6 +13,8 @@ interface CountableDataInterface extends Countable
{
/**
* @return int Number of items in the data.
*
* @psalm-return non-negative-int
*/
public function count(): int;
}
13 changes: 5 additions & 8 deletions tests/Paginator/OffsetPaginatorTest.php
Expand Up @@ -8,6 +8,7 @@
use LogicException;
use PHPUnit\Framework\Attributes\DataProvider;
use Yiisoft\Data\Paginator\OffsetPaginator;
use Yiisoft\Data\Paginator\PageNotFoundException;
use Yiisoft\Data\Paginator\PageToken;
use Yiisoft\Data\Paginator\PaginatorException;
use Yiisoft\Data\Paginator\PaginatorInterface;
Expand Down Expand Up @@ -222,7 +223,7 @@ public function testReadCurrentPageCannotBeLargerThanMaxPages(): void
;

$this->assertSame(3, $paginator->getTotalPages());
$this->expectException(PaginatorException::class);
$this->expectException(PageNotFoundException::class);
$this->expectExceptionMessage('Page not found.');

$this->iterableToArray($paginator->read());
Expand Down Expand Up @@ -397,7 +398,7 @@ public function testIsLastPageBeyondMaxPages(): void
;

$this->assertSame(3, $paginator->getTotalPages());
$this->expectException(PaginatorException::class);
$this->expectException(PageNotFoundException::class);
$this->expectExceptionMessage('Page not found.');

$paginator->isOnLastPage();
Expand Down Expand Up @@ -446,14 +447,10 @@ public function testGetCurrentPageCannotBeLargerThanMaxPages(): void
$dataReader = new IterableDataReader(self::DEFAULT_DATASET);
$paginator = (new OffsetPaginator($dataReader))
->withPageSize(2)
->withCurrentPage(4)
;
->withCurrentPage(4);

$this->assertSame(5, $paginator->getTotalItems());
$this->expectException(PaginatorException::class);
$this->expectExceptionMessage('Page not found.');

$paginator->getCurrentPageSize();
$this->assertSame(0, $paginator->getCurrentPageSize());
}

public function testEmptyDataSet(): void
Expand Down

0 comments on commit b0352e0

Please sign in to comment.