diff --git a/CHANGELOG.md b/CHANGELOG.md index 009e5e5..b77af38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Forked from [`ashleydawson/simple-pagination`](https://github.com/AshleyDawson/S * Updated project namespaces to `Esi\Pagination`. * `lib` folder renamed to `src` + * Refactored the `Paginator::paginate()` function to reduce it's complexity. Uses new helper functions. * Updated composer.json * Bumped minimum PHP version to 8.2 * Autoloading should follow PSR-4 @@ -27,6 +28,12 @@ Forked from [`ashleydawson/simple-pagination`](https://github.com/AshleyDawson/S #### Added + * Helper functions to simplify the `Paginator::paginate()` function. Note: these have protected access. + * `prepareBeforeQueryCallback()` - Handles either returning the beforeQueryCallback, or returning an empty \Closure. + * `prepareAfterQueryCallback()` - Handles either returning the afterQueryCallback, or returning an empty \Closure. + * `determinePageRange()` - Given `$currentPageNumber`, `$pagesInRange`, and `$numberOfPages`, returns an array of pages. + * `determinePreviousPageNumber()` + * `determineNextPageNumber()` * dev-dependencies for PHP-CS-Fixer and PHPStan (w/extensions for phpunit, strict rules) * Imports for all used functions, constants, and class names. * Github workflows for testing and static analysis. diff --git a/src/Paginator.php b/src/Paginator.php index 9812031..ce76733 100644 --- a/src/Paginator.php +++ b/src/Paginator.php @@ -144,47 +144,23 @@ public function paginate(int $currentPageNumber = 1): Pagination ); } - $beforeQueryCallback = $this->beforeQueryCallback instanceof Closure - ? $this->beforeQueryCallback - : static function (): void {} - ; - - $afterQueryCallback = $this->afterQueryCallback instanceof Closure - ? $this->afterQueryCallback - : static function (): void {} - ; + $sliceCallback = $this->sliceCallback; + $itemTotalCallback = $this->itemTotalCallback; + /** @var Closure $beforeQueryCallback */ + $beforeQueryCallback = $this->prepareBeforeQueryCallback(); + /** @var Closure $afterQueryCallback */ + $afterQueryCallback = $this->prepareAfterQueryCallback(); $pagination = new Pagination(); - $itemTotalCallback = $this->itemTotalCallback; - $beforeQueryCallback($this, $pagination); $totalNumberOfItems = (int) $itemTotalCallback($pagination); $afterQueryCallback($this, $pagination); $numberOfPages = (int) ceil($totalNumberOfItems / $this->itemsPerPage); - $pagesInRange = $this->pagesInRange; - - if ($pagesInRange > $numberOfPages) { - $pagesInRange = $numberOfPages; - } - - $change = (int) ceil($pagesInRange / 2); - - if (($currentPageNumber - $change) > ($numberOfPages - $pagesInRange)) { - $pages = range(($numberOfPages - $pagesInRange) + 1, $numberOfPages); - } else { - if (($currentPageNumber - $change) < 0) { - $change = $currentPageNumber; - } - - $offset = $currentPageNumber - $change; - $pages = range(($offset + 1), $offset + $pagesInRange); - } - - $offset = ($currentPageNumber - 1) * $this->itemsPerPage; - - $sliceCallback = $this->sliceCallback; + $pagesInRange = $this->pagesInRange > $numberOfPages ? $numberOfPages : $this->pagesInRange; + $pages = $this->determinePageRange($currentPageNumber, $pagesInRange, $numberOfPages); + $offset = ($currentPageNumber - 1) * $this->itemsPerPage; $beforeQueryCallback($this, $pagination); @@ -200,20 +176,10 @@ public function paginate(int $currentPageNumber = 1): Pagination $afterQueryCallback($this, $pagination); - $previousPageNumber = null; - - if (($currentPageNumber - 1) > 0) { - $previousPageNumber = $currentPageNumber - 1; - } - - $nextPageNumber = null; - - if (($currentPageNumber + 1) <= $numberOfPages) { - $nextPageNumber = $currentPageNumber + 1; - } + $previousPageNumber = $this->determinePreviousPageNumber($currentPageNumber); + $nextPageNumber = $this->determineNextPageNumber($currentPageNumber, $numberOfPages); /** @var non-empty-array $pages **/ - $pagination ->setItems($items) ->setPages($pages) @@ -246,6 +212,7 @@ public function getSliceCallback(): ?Closure public function setSliceCallback(?Closure $sliceCallback): static { $this->sliceCallback = $sliceCallback; + return $this; } @@ -271,6 +238,7 @@ public function getBeforeQueryCallback(): ?Closure public function setBeforeQueryCallback(?Closure $beforeQueryCallback): static { $this->beforeQueryCallback = $beforeQueryCallback; + return $this; } @@ -288,6 +256,7 @@ public function getAfterQueryCallback(): ?Closure public function setAfterQueryCallback(?Closure $afterQueryCallback): static { $this->afterQueryCallback = $afterQueryCallback; + return $this; } @@ -297,6 +266,7 @@ public function setAfterQueryCallback(?Closure $afterQueryCallback): static public function setItemTotalCallback(?Closure $itemTotalCallback): static { $this->itemTotalCallback = $itemTotalCallback; + return $this; } @@ -314,6 +284,7 @@ public function getItemsPerPage(): int public function setItemsPerPage(int $itemsPerPage): static { $this->itemsPerPage = $itemsPerPage; + return $this; } @@ -331,6 +302,78 @@ public function getPagesInRange(): int public function setPagesInRange(int $pagesInRange): static { $this->pagesInRange = $pagesInRange; + return $this; } + + // Helper functions to the main paginate() function. + + /** + */ + protected function prepareBeforeQueryCallback(): Closure + { + if ($this->beforeQueryCallback instanceof Closure) { + return $this->beforeQueryCallback; + } + + return static function (): void {}; + } + + /** + */ + protected function prepareAfterQueryCallback(): Closure + { + if ($this->afterQueryCallback instanceof Closure) { + return $this->afterQueryCallback; + } + + return static function (): void {}; + } + + /** + * @return array + */ + protected function determinePageRange(int $currentPageNumber, int $pagesInRange, int $numberOfPages): array + { + $change = (int) ceil($pagesInRange / 2); + + if (($currentPageNumber - $change) > ($numberOfPages - $pagesInRange)) { + $pages = range(($numberOfPages - $pagesInRange) + 1, $numberOfPages); + } else { + if (($currentPageNumber - $change) < 0) { + $change = $currentPageNumber; + } + + $offset = $currentPageNumber - $change; + $pages = range(($offset + 1), $offset + $pagesInRange); + } + + return $pages; + } + + /** + */ + protected function determinePreviousPageNumber(int $currentPageNumber): ?int + { + $previousPageNumber = null; + + if (($currentPageNumber - 1) > 0) { + $previousPageNumber = $currentPageNumber - 1; + } + + return $previousPageNumber; + } + + /** + */ + protected function determineNextPageNumber(int $currentPageNumber, int $numberOfPages): ?int + { + $nextPageNumber = null; + + if (($currentPageNumber + 1) <= $numberOfPages) { + $nextPageNumber = $currentPageNumber + 1; + } + + return $nextPageNumber; + } }