diff --git a/CHANGELOG.md b/CHANGELOG.md index bffd0e1b..b9bd47fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,13 @@ - Enh #214: Improved interface hierarchy (@samdark) - Enh #207: More specific Psalm type for `OffsetPaginator::withCurrentPage()` parameter (@samdark) - Enh #210: More specific Psalm type for `PaginatorInterface::getPageSize()` result (@vjik) +- Chg #219: Narrow type of page size in `PaginatorInterface::withPageSize()` method to positive int by psalm + annotation and throw `InvalidArgumentException` if non-positive value is passed (@vjik) +- Enh #219: Add page to message of `PageNotFoundException` exception (@vjik) +- Chg #219: Throw `InvalidArgumentException` instead of `PaginatorException` in `OffsetPaginator::withCurrentPage()` + method when non-positive value is passed (@vjik) +- Chg #219: Don't check correctness of current page in `PaginatorInterface::isOnLastPage()` method (@vjik) +- Chg #219: Rename `PaginatorException` to `InvalidPageException` (@vjik) ## 1.0.1 January 25, 2023 diff --git a/src/Paginator/InvalidPageException.php b/src/Paginator/InvalidPageException.php new file mode 100644 index 00000000..b91eb7b4 --- /dev/null +++ b/src/Paginator/InvalidPageException.php @@ -0,0 +1,14 @@ +withCurrentPage($token === null ? 1 : (int)$token->value); + 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); } public function withPageSize(int $pageSize): static { + /** @psalm-suppress DocblockTypeContradiction We don't believe in psalm types */ if ($pageSize < 1) { - throw new PaginatorException('Page size should be at least 1.'); + throw new InvalidArgumentException('Page size should be at least 1.'); } $new = clone $this; @@ -113,17 +122,18 @@ public function withPageSize(int $pageSize): static * Get a new instance with the given current page number set. * * @param int $page Page number. - * @psalm-param positive-int $page * - * @throws PaginatorException If the current page is incorrect. + * @throws InvalidArgumentException If page is not a positive number. * * @return self New instance. + * + * @psalm-param positive-int $page */ public function withCurrentPage(int $page): self { /** @psalm-suppress DocblockTypeContradiction */ if ($page < 1) { - throw new PaginatorException('Current page should be at least 1.'); + throw new InvalidArgumentException('Current page should be at least 1.'); } $new = clone $this; @@ -276,8 +286,9 @@ public function withFilter(FilterInterface $filter): static */ public function read(): iterable { - if ($this->getCurrentPage() > $this->getInternalTotalPages()) { - throw new PageNotFoundException(); + $currentPage = $this->getCurrentPage(); + if ($currentPage > $this->getInternalTotalPages()) { + throw new PageNotFoundException($currentPage); } $limit = $this->pageSize; @@ -316,11 +327,7 @@ public function isOnFirstPage(): bool public function isOnLastPage(): bool { - if ($this->getCurrentPage() > $this->getInternalTotalPages()) { - throw new PageNotFoundException(); - } - - return $this->getCurrentPage() === $this->getInternalTotalPages(); + return $this->getCurrentPage() >= $this->getInternalTotalPages(); } public function isPaginationRequired(): bool diff --git a/src/Paginator/PageNotFoundException.php b/src/Paginator/PageNotFoundException.php index 279967fb..1341829e 100644 --- a/src/Paginator/PageNotFoundException.php +++ b/src/Paginator/PageNotFoundException.php @@ -4,10 +4,14 @@ namespace Yiisoft\Data\Paginator; -final class PageNotFoundException extends PaginatorException +use function sprintf; + +final class PageNotFoundException extends InvalidPageException { - public function __construct() + public function __construct(int $page) { - parent::__construct('Page not found.'); + parent::__construct( + sprintf('Page %d not found.', $page) + ); } } diff --git a/src/Paginator/PaginatorException.php b/src/Paginator/PaginatorException.php deleted file mode 100644 index c821196e..00000000 --- a/src/Paginator/PaginatorException.php +++ /dev/null @@ -1,16 +0,0 @@ -expectException(PaginatorException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Current page should be at least 1.'); $paginator->withCurrentPage(0); @@ -235,7 +234,7 @@ public function testReadCurrentPageCannotBeLargerThanMaxPages(): void $this->assertSame(3, $paginator->getTotalPages()); $this->expectException(PageNotFoundException::class); - $this->expectExceptionMessage('Page not found.'); + $this->expectExceptionMessage('Page 4 not found.'); $this->iterableToArray($paginator->read()); } @@ -255,7 +254,7 @@ public function testPageSizeCannotBeLessThanOne(): void $dataReader = new IterableDataReader(self::DEFAULT_DATASET); $paginator = new OffsetPaginator($dataReader); - $this->expectException(PaginatorException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Page size should be at least 1.'); $paginator->withPageSize(0); @@ -400,21 +399,6 @@ public function testIsLastPageOnLastPage(): void $this->assertTrue($paginator->isOnLastPage()); } - public function testIsLastPageBeyondMaxPages(): void - { - $dataReader = new IterableDataReader(self::DEFAULT_DATASET); - $paginator = (new OffsetPaginator($dataReader)) - ->withPageSize(2) - ->withCurrentPage(4) - ; - - $this->assertSame(3, $paginator->getTotalPages()); - $this->expectException(PageNotFoundException::class); - $this->expectExceptionMessage('Page not found.'); - - $paginator->isOnLastPage(); - } - public function testGetCurrentPageSizeFirstFullPage(): void { $dataReader = new IterableDataReader(self::DEFAULT_DATASET);