Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add page start end total to PagerRenderer #9371

71 changes: 71 additions & 0 deletions system/Pager/PagerRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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();
}

/**
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}
}
80 changes: 80 additions & 0 deletions tests/system/Pager/PagerRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use CodeIgniter\HTTP\URI;
use CodeIgniter\Test\CIUnitTestCase;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;

/**
Expand Down Expand Up @@ -619,4 +620,83 @@ public function testGetNextPageNumberNull(): void

$this->assertNull($pager->getNextPageNumber());
}

/**
* @param array<string, array<string, mixed>> $details
*/
#[DataProvider('providePageStartEnd')]
murilohpucci marked this conversation as resolved.
Show resolved Hide resolved
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<string, array<string, mixed>> $details
*/
public static function providePageStartEnd(): iterable
murilohpucci marked this conversation as resolved.
Show resolved Hide resolved
{
$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,
],
murilohpucci marked this conversation as resolved.
Show resolved Hide resolved
'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,
],
];
}
}
6 changes: 6 additions & 0 deletions user_guide_src/source/changelogs/v4.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <displaying-the-number-of-items-on-the-page>` for more details.

Testing
=======

Expand Down
27 changes: 27 additions & 0 deletions user_guide_src/source/libraries/pagination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
7 changes: 7 additions & 0 deletions user_guide_src/source/libraries/pagination/019.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php $pager->setSurroundCount(1) ?>

<p>
Showing <span class="font-medium"><?= $pager->getPerPageStart() ?></span>
to <span class="font-medium"><?= $pager->getPerPageEnd() ?></span>
of <span class="font-medium"><?= $pager->getTotal() ?></span> results
</p>
Loading