diff --git a/system/Pager/PagerRenderer.php b/system/Pager/PagerRenderer.php index 64c4c40c531d..f71cb665aab6 100644 --- a/system/Pager/PagerRenderer.php +++ b/system/Pager/PagerRenderer.php @@ -82,6 +82,21 @@ class PagerRenderer */ protected $pageSelector; + /** + * Returns the number of results per page that should be shown. + */ + protected ?int $perPage; + + /** + * The number of items the page starts with. + */ + protected ?int $perPageStart = null; + + /** + * The number of items the page ends with. + */ + protected ?int $perPageEnd = null; + /** * Constructor. */ @@ -98,6 +113,8 @@ public function __construct(array $details) $this->pageCount = $details['pageCount']; $this->segment = $details['segment'] ?? 0; $this->pageSelector = $details['pageSelector'] ?? 'page'; + $this->perPage = $details['perPage'] ?? null; + $this->updatePerPages(); } /** @@ -307,6 +324,28 @@ protected function updatePages(?int $count = null) $this->last = $this->current + $count <= $this->pageCount ? $this->current + $count : (int) $this->pageCount; } + /** + * Updates the start and end items per pages, which is + * the number of items displayed on the active page. + */ + protected function updatePerPages(): void + { + if ($this->total === null || $this->perPage === null) { + return; + } + + // When the page is the last, perform a different calculation. + if ($this->last === $this->current) { + $this->perPageStart = $this->perPage * ($this->current - 1) + 1; + $this->perPageEnd = $this->total; + + return; + } + + $this->perPageStart = $this->current === 1 ? 1 : ($this->perPage * $this->current) - $this->perPage + 1; + $this->perPageEnd = $this->perPage * $this->current; + } + /** * Checks to see if there is a "previous" page before our "first" page. */ @@ -430,4 +469,36 @@ public function getNextPageNumber(): ?int { return ($this->current === $this->pageCount) ? null : $this->current + 1; } + + /** + * Returns the total items of the page. + */ + public function getTotal(): ?int + { + return $this->total; + } + + /** + * Returns the number of items to be displayed on the page. + */ + public function getPerPage(): ?int + { + return $this->perPage; + } + + /** + * Returns the number of items the page starts with. + */ + public function getPerPageStart(): ?int + { + return $this->perPageStart; + } + + /** + * Returns the number of items the page ends with. + */ + public function getPerPageEnd(): ?int + { + return $this->perPageEnd; + } } diff --git a/tests/system/Pager/PagerRendererTest.php b/tests/system/Pager/PagerRendererTest.php index 8ac8683a4327..d06a040a7925 100644 --- a/tests/system/Pager/PagerRendererTest.php +++ b/tests/system/Pager/PagerRendererTest.php @@ -15,6 +15,7 @@ use CodeIgniter\HTTP\URI; use CodeIgniter\Test\CIUnitTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; /** @@ -619,4 +620,83 @@ public function testGetNextPageNumberNull(): void $this->assertNull($pager->getNextPageNumber()); } + + /** + * @param array> $details + */ + #[DataProvider('providePageStartEnd')] + public function testPageStartEnd(array $details, int $pageStart, int $pageEnd): void + { + $pager = new PagerRenderer($details); + $pager->setSurroundCount(2); + + $this->assertSame($pageStart, $pager->getPerPageStart()); + $this->assertSame($pageEnd, $pager->getPerPageEnd()); + } + + /** + * @return array> $details + */ + public static function providePageStartEnd(): iterable + { + $uri = new URI('http://example.com/foo'); + + return [ + 'first page' => [ + 'details' => [ + 'uri' => $uri, + 'pageCount' => 3, + 'total' => 25, + 'currentPage' => 1, + 'perPage' => 10, + ], + 'pageStart' => 1, + 'pageEnd' => 10, + ], + 'second page' => [ + 'details' => [ + 'uri' => $uri, + 'pageCount' => 3, + 'total' => 25, + 'currentPage' => 2, + 'perPage' => 10, + ], + 'pageStart' => 11, + 'pageEnd' => 20, + ], + 'last page' => [ + 'details' => [ + 'uri' => $uri, + 'pageCount' => 3, + 'total' => 25, + 'currentPage' => 3, + 'perPage' => 10, + ], + 'pageStart' => 21, + 'pageEnd' => 25, + ], + 'current greater last page' => [ + 'details' => [ + 'uri' => $uri, + 'pageCount' => 3, + 'total' => 25, + 'currentPage' => 5, + 'perPage' => 10, + ], + 'pageStart' => 41, + 'pageEnd' => 50, + ], + 'current equal last page' => [ + 'details' => [ + 'uri' => $uri, + 'pageCount' => 1, + 'total' => 10, + 'currentPage' => 1, + 'perPage' => 10, + ], + 'pageStart' => 1, + 'pageEnd' => 10, + ], + ]; + } } diff --git a/user_guide_src/source/changelogs/v4.6.0.rst b/user_guide_src/source/changelogs/v4.6.0.rst index db4e8abaa07b..fdc831dcbaca 100644 --- a/user_guide_src/source/changelogs/v4.6.0.rst +++ b/user_guide_src/source/changelogs/v4.6.0.rst @@ -246,6 +246,12 @@ Negotiator Previously, response with language headers ``Accept-language: en-US,en-GB;q=0.9`` returned the first allowed language ``en`` could instead of the exact language ``en-US`` or ``en-GB``. Set the value to ``true`` to enable comparison not only by language code ('en' - ISO 639-1) but also by regional code ('en-US' - ISO 639-1 plus ISO 3166-1 alpha). +Pagination +========== + +- Added a new feature to get the total and the range number of items of the current page. + See :ref:`Displaying the Number of Items on the Page ` for more details. + Testing ======= diff --git a/user_guide_src/source/libraries/pagination.rst b/user_guide_src/source/libraries/pagination.rst index ed5567372324..f718bab28fc6 100644 --- a/user_guide_src/source/libraries/pagination.rst +++ b/user_guide_src/source/libraries/pagination.rst @@ -340,3 +340,30 @@ getPageCount() -------------- This method returns total number of pages. + +.. _displaying-the-number-of-items-on-the-page: + +Displaying the Number of Items on the Page +========================================== + +.. versionadded:: 4.6.0 + +When paginating items, it’s often helpful to display the total number of items and the range of items shown on the current page. To simplify this task, new methods have been added. These methods make it easier to manage and display pagination details. Here's an example: + +.. literalinclude:: pagination/019.php + +getTotal() +---------- +Returns the total items of the page. + +getPerPage() +------------ +Returns the number of items to be displayed on the page. + +getPerPageStart() +----------------- +Returns the number of items the page starts with. + +getPerPageEnd() +--------------- +Returns the number of items the page ends with. diff --git a/user_guide_src/source/libraries/pagination/019.php b/user_guide_src/source/libraries/pagination/019.php new file mode 100644 index 000000000000..91c514948111 --- /dev/null +++ b/user_guide_src/source/libraries/pagination/019.php @@ -0,0 +1,7 @@ +setSurroundCount(1) ?> + +

+ Showing getPerPageStart() ?> + to getPerPageEnd() ?> + of getTotal() ?> results +