Skip to content

Commit d9aca42

Browse files
authored
feat: add page start end total to PagerRenderer (#9371)
* Add some methods to the page renderer to make easier to get the first item, the last item and the total of items. * Add type hint to the new per page variable on the page renderer. * Create more tests for the page start and end, and improve the comment of the variables from the PagerRenderer class. * Add a documentation and also improve some comments. * Use version added instead of warning on the documentation * Add changelog. * Fix CR issues. * Add null as the default value for perPageStart and End
1 parent c79d3a9 commit d9aca42

File tree

5 files changed

+191
-0
lines changed

5 files changed

+191
-0
lines changed

system/Pager/PagerRenderer.php

+71
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ class PagerRenderer
8282
*/
8383
protected $pageSelector;
8484

85+
/**
86+
* Returns the number of results per page that should be shown.
87+
*/
88+
protected ?int $perPage;
89+
90+
/**
91+
* The number of items the page starts with.
92+
*/
93+
protected ?int $perPageStart = null;
94+
95+
/**
96+
* The number of items the page ends with.
97+
*/
98+
protected ?int $perPageEnd = null;
99+
85100
/**
86101
* Constructor.
87102
*/
@@ -98,6 +113,8 @@ public function __construct(array $details)
98113
$this->pageCount = $details['pageCount'];
99114
$this->segment = $details['segment'] ?? 0;
100115
$this->pageSelector = $details['pageSelector'] ?? 'page';
116+
$this->perPage = $details['perPage'] ?? null;
117+
$this->updatePerPages();
101118
}
102119

103120
/**
@@ -307,6 +324,28 @@ protected function updatePages(?int $count = null)
307324
$this->last = $this->current + $count <= $this->pageCount ? $this->current + $count : (int) $this->pageCount;
308325
}
309326

327+
/**
328+
* Updates the start and end items per pages, which is
329+
* the number of items displayed on the active page.
330+
*/
331+
protected function updatePerPages(): void
332+
{
333+
if ($this->total === null || $this->perPage === null) {
334+
return;
335+
}
336+
337+
// When the page is the last, perform a different calculation.
338+
if ($this->last === $this->current) {
339+
$this->perPageStart = $this->perPage * ($this->current - 1) + 1;
340+
$this->perPageEnd = $this->total;
341+
342+
return;
343+
}
344+
345+
$this->perPageStart = $this->current === 1 ? 1 : ($this->perPage * $this->current) - $this->perPage + 1;
346+
$this->perPageEnd = $this->perPage * $this->current;
347+
}
348+
310349
/**
311350
* Checks to see if there is a "previous" page before our "first" page.
312351
*/
@@ -430,4 +469,36 @@ public function getNextPageNumber(): ?int
430469
{
431470
return ($this->current === $this->pageCount) ? null : $this->current + 1;
432471
}
472+
473+
/**
474+
* Returns the total items of the page.
475+
*/
476+
public function getTotal(): ?int
477+
{
478+
return $this->total;
479+
}
480+
481+
/**
482+
* Returns the number of items to be displayed on the page.
483+
*/
484+
public function getPerPage(): ?int
485+
{
486+
return $this->perPage;
487+
}
488+
489+
/**
490+
* Returns the number of items the page starts with.
491+
*/
492+
public function getPerPageStart(): ?int
493+
{
494+
return $this->perPageStart;
495+
}
496+
497+
/**
498+
* Returns the number of items the page ends with.
499+
*/
500+
public function getPerPageEnd(): ?int
501+
{
502+
return $this->perPageEnd;
503+
}
433504
}

tests/system/Pager/PagerRendererTest.php

+80
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use CodeIgniter\HTTP\URI;
1717
use CodeIgniter\Test\CIUnitTestCase;
18+
use PHPUnit\Framework\Attributes\DataProvider;
1819
use PHPUnit\Framework\Attributes\Group;
1920

2021
/**
@@ -619,4 +620,83 @@ public function testGetNextPageNumberNull(): void
619620

620621
$this->assertNull($pager->getNextPageNumber());
621622
}
623+
624+
/**
625+
* @param array<string, array<string, mixed>> $details
626+
*/
627+
#[DataProvider('providePageStartEnd')]
628+
public function testPageStartEnd(array $details, int $pageStart, int $pageEnd): void
629+
{
630+
$pager = new PagerRenderer($details);
631+
$pager->setSurroundCount(2);
632+
633+
$this->assertSame($pageStart, $pager->getPerPageStart());
634+
$this->assertSame($pageEnd, $pager->getPerPageEnd());
635+
}
636+
637+
/**
638+
* @return array<string, array<string, mixed>> $details
639+
*/
640+
public static function providePageStartEnd(): iterable
641+
{
642+
$uri = new URI('http://example.com/foo');
643+
644+
return [
645+
'first page' => [
646+
'details' => [
647+
'uri' => $uri,
648+
'pageCount' => 3,
649+
'total' => 25,
650+
'currentPage' => 1,
651+
'perPage' => 10,
652+
],
653+
'pageStart' => 1,
654+
'pageEnd' => 10,
655+
],
656+
'second page' => [
657+
'details' => [
658+
'uri' => $uri,
659+
'pageCount' => 3,
660+
'total' => 25,
661+
'currentPage' => 2,
662+
'perPage' => 10,
663+
],
664+
'pageStart' => 11,
665+
'pageEnd' => 20,
666+
],
667+
'last page' => [
668+
'details' => [
669+
'uri' => $uri,
670+
'pageCount' => 3,
671+
'total' => 25,
672+
'currentPage' => 3,
673+
'perPage' => 10,
674+
],
675+
'pageStart' => 21,
676+
'pageEnd' => 25,
677+
],
678+
'current greater last page' => [
679+
'details' => [
680+
'uri' => $uri,
681+
'pageCount' => 3,
682+
'total' => 25,
683+
'currentPage' => 5,
684+
'perPage' => 10,
685+
],
686+
'pageStart' => 41,
687+
'pageEnd' => 50,
688+
],
689+
'current equal last page' => [
690+
'details' => [
691+
'uri' => $uri,
692+
'pageCount' => 1,
693+
'total' => 10,
694+
'currentPage' => 1,
695+
'perPage' => 10,
696+
],
697+
'pageStart' => 1,
698+
'pageEnd' => 10,
699+
],
700+
];
701+
}
622702
}

user_guide_src/source/changelogs/v4.6.0.rst

+6
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ Negotiator
247247
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``.
248248
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).
249249

250+
Pagination
251+
==========
252+
253+
- Added a new feature to get the total and the range number of items of the current page.
254+
See :ref:`Displaying the Number of Items on the Page <displaying-the-number-of-items-on-the-page>` for more details.
255+
250256
Testing
251257
=======
252258

user_guide_src/source/libraries/pagination.rst

+27
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,30 @@ getPageCount()
340340
--------------
341341

342342
This method returns total number of pages.
343+
344+
.. _displaying-the-number-of-items-on-the-page:
345+
346+
Displaying the Number of Items on the Page
347+
==========================================
348+
349+
.. versionadded:: 4.6.0
350+
351+
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:
352+
353+
.. literalinclude:: pagination/019.php
354+
355+
getTotal()
356+
----------
357+
Returns the total items of the page.
358+
359+
getPerPage()
360+
------------
361+
Returns the number of items to be displayed on the page.
362+
363+
getPerPageStart()
364+
-----------------
365+
Returns the number of items the page starts with.
366+
367+
getPerPageEnd()
368+
---------------
369+
Returns the number of items the page ends with.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php $pager->setSurroundCount(1) ?>
2+
3+
<p>
4+
Showing <span class="font-medium"><?= $pager->getPerPageStart() ?></span>
5+
to <span class="font-medium"><?= $pager->getPerPageEnd() ?></span>
6+
of <span class="font-medium"><?= $pager->getTotal() ?></span> results
7+
</p>

0 commit comments

Comments
 (0)