diff --git a/src/Database/Paginator.php b/src/Database/Paginator.php index 42a0d0c8..25006c16 100644 --- a/src/Database/Paginator.php +++ b/src/Database/Paginator.php @@ -72,8 +72,12 @@ public function hasNextPage() return $this->currentPage < $this->lastPage; } - public function from(): int + public function from(): int|null { + if ($this->total === 0) { + return null; + } + return (($this->currentPage - 1) * $this->perPage) + 1; } @@ -88,42 +92,38 @@ public function to(): int public function links(): array { + if ($this->total === 0 || $this->lastPage === 0) { + return []; + } + $links = []; $separator = ['url' => null, 'label' => '...']; - $prepend = ($this->currentPage + 1) - $this->itemsEachSide; - $prepend = $prepend < 0 ? 0 : $prepend; + $start = max(1, $this->currentPage - $this->itemsEachSide); + $end = min($this->lastPage, $this->currentPage + $this->itemsEachSide); - if ($prepend > ($this->itemsEachSide + 1)) { - $prepend = $this->itemsEachSide; - - $links[] = $this->buildLink(1); - $links[] = $separator; + if ($this->currentPage <= ($this->linksNumber - 1)) { + $start = 1; + $end = min($this->lastPage, $this->linksNumber); } - $start = $this->currentPage - $prepend; + if ($start > 1) { + $links[] = $this->buildLink(1); - for ($i = $start; $i < $this->currentPage; $i++) { - $links[] = $this->buildLink($i); + if ($start > 2) { + $links[] = $separator; + } } - $append = $this->linksNumber - $prepend; - $append = ($this->currentPage + $append) > $this->lastPage - ? ($this->lastPage - $this->currentPage) + 1 - : $append; - - $limit = $this->currentPage + $append; - - for ($i = $this->currentPage; $i < $limit; $i++) { + for ($i = $start; $i <= $end; $i++) { $links[] = $this->buildLink($i); } - if (($this->lastPage - ($this->currentPage + $append)) >= 1) { - $links[] = $separator; - $links[] = $this->buildLink($this->lastPage); - } + if ($end < $this->lastPage) { + if ($end < ($this->lastPage - 1)) { + $links[] = $separator; + } - if (($this->lastPage - ($this->currentPage + $append)) === 0) { $links[] = $this->buildLink($this->lastPage); } @@ -179,8 +179,12 @@ private function getFirstPageUrl(): string return $this->buildPageUrl(1); } - private function getLastPageUrl(): string + private function getLastPageUrl(): string|null { + if ($this->lastPage === 0) { + return null; + } + return $this->buildPageUrl($this->lastPage); } diff --git a/tests/Unit/Database/PaginatorTest.php b/tests/Unit/Database/PaginatorTest.php index 8472a271..e2d7e39a 100644 --- a/tests/Unit/Database/PaginatorTest.php +++ b/tests/Unit/Database/PaginatorTest.php @@ -196,3 +196,35 @@ 'links' => $links, ]); }); + +it('handles empty dataset gracefully', function () { + $uri = Http::new(URL::build('users', ['page' => 1])); + + $paginator = new Paginator($uri, new Collection('array'), 0, 1, 15); + + expect($paginator->data()->toArray())->toBe([]); + expect($paginator->total())->toBe(0); + expect($paginator->lastPage())->toBe(0); + expect($paginator->currentPage())->toBe(1); + expect($paginator->perPage())->toBe(15); + expect($paginator->hasPreviousPage())->toBeFalse(); + expect($paginator->hasNextPage())->toBeFalse(); + expect($paginator->from())->toBeNull(); + expect($paginator->to())->toBe(0); + + expect($paginator->toArray())->toBe([ + 'path' => URL::build('users'), + 'current_page' => 1, + 'last_page' => 0, + 'per_page' => 15, + 'total' => 0, + 'first_page_url' => URL::build('users', ['page' => 1]), + 'last_page_url' => null, + 'prev_page_url' => null, + 'next_page_url' => null, + 'from' => null, + 'to' => 0, + 'data' => [], + 'links' => [], + ]); +});