‪TYPO3CMS  ‪main
AbstractPaginator.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
21 {
25  protected ‪$numberOfPages = 1;
26 
30  protected ‪$keyOfFirstPaginatedItem = 0;
31 
35  protected ‪$keyOfLastPaginatedItem = 0;
36 
40  private ‪$currentPageNumber = 1;
41 
45  private ‪$itemsPerPage = 10;
46 
48  {
49  if (‪$itemsPerPage === $this->itemsPerPage) {
50  return $this;
51  }
52 
53  $new = clone $this;
54  $new->setItemsPerPage(‪$itemsPerPage);
55  $new->updateInternalState();
56 
57  return $new;
58  }
59 
61  {
62  if (‪$currentPageNumber === $this->currentPageNumber) {
63  return $this;
64  }
65 
66  $new = clone $this;
67  $new->setCurrentPageNumber(‪$currentPageNumber);
68  $new->updateInternalState();
69 
70  return $new;
71  }
72 
73  public function ‪getNumberOfPages(): int
74  {
76  }
77 
78  public function ‪getCurrentPageNumber(): int
79  {
81  }
82 
83  public function ‪getKeyOfFirstPaginatedItem(): int
84  {
86  }
87 
88  public function ‪getKeyOfLastPaginatedItem(): int
89  {
91  }
92 
97  abstract protected function ‪updatePaginatedItems(int ‪$itemsPerPage, int $offset): void;
98 
102  abstract protected function ‪getTotalAmountOfItems(): int;
103 
107  abstract protected function ‪getAmountOfItemsOnCurrentPage(): int;
108 
112  protected function ‪hasItemsOnCurrentPage(): bool
113  {
114  return $this->‪getAmountOfItemsOnCurrentPage() > 0;
115  }
116 
121  protected function ‪updateInternalState(): void
122  {
123  $offset = (int)($this->itemsPerPage * ($this->currentPageNumber - 1));
124  $totalAmountOfItems = $this->‪getTotalAmountOfItems();
125 
126  /*
127  * If the total amount of items is zero, then the number of pages is mathematically zero as
128  * well. As that looks strange in the frontend, the number of pages is forced to be at least
129  * one.
130  */
131  $this->numberOfPages = max(1, (int)ceil($totalAmountOfItems / $this->itemsPerPage));
132 
133  /*
134  * To prevent empty results in case the given current page number exceeds the maximum number
135  * of pages, we set the current page number to the last page and update the internal state
136  * with this value again. Such situation should in the first place be prevented by not allowing
137  * those values to be passed, e.g. by using the "max" attribute in the view. However there are
138  * valid cases. For example when a user deletes a record while the pagination is already visible
139  * to another user with, until then, a valid "max" value. Passing invalid values unintentionally
140  * should therefore just silently be resolved.
141  */
142  if ($this->currentPageNumber > $this->numberOfPages) {
143  $this->currentPageNumber = ‪$this->numberOfPages;
144  $this->‪updateInternalState();
145  return;
146  }
147 
148  $this->‪updatePaginatedItems($this->itemsPerPage, $offset);
149 
150  if (!$this->‪hasItemsOnCurrentPage()) {
151  $this->keyOfFirstPaginatedItem = 0;
152  $this->keyOfLastPaginatedItem = 0;
153  return;
154  }
155 
156  $indexOfLastPaginatedItem = min($offset + $this->itemsPerPage, $totalAmountOfItems);
157 
158  $this->keyOfFirstPaginatedItem = $offset;
159  $this->keyOfLastPaginatedItem = $indexOfLastPaginatedItem - 1;
160  }
161 
162  protected function ‪setItemsPerPage(int ‪$itemsPerPage): void
163  {
164  if (‪$itemsPerPage < 1) {
165  throw new \InvalidArgumentException(
166  'Argument $itemsPerPage must be greater than 0',
167  1573061766
168  );
169  }
170 
171  $this->itemsPerPage = ‪$itemsPerPage;
172  }
173 
174  protected function ‪setCurrentPageNumber(int ‪$currentPageNumber): void
175  {
176  if (‪$currentPageNumber < 1) {
177  throw new \InvalidArgumentException(
178  'Argument $currentPageNumber must be greater than 0',
179  1573047338
180  );
181  }
182 
183  $this->currentPageNumber = ‪$currentPageNumber;
184  }
185 }
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\setItemsPerPage
‪setItemsPerPage(int $itemsPerPage)
Definition: AbstractPaginator.php:157
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\$itemsPerPage
‪int $itemsPerPage
Definition: AbstractPaginator.php:40
‪TYPO3\CMS\Core\Pagination
Definition: AbstractPaginator.php:18
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\withItemsPerPage
‪withItemsPerPage(int $itemsPerPage)
Definition: AbstractPaginator.php:42
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getCurrentPageNumber
‪getCurrentPageNumber()
Definition: AbstractPaginator.php:73
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\updateInternalState
‪updateInternalState()
Definition: AbstractPaginator.php:116
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\$keyOfLastPaginatedItem
‪int $keyOfLastPaginatedItem
Definition: AbstractPaginator.php:32
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getNumberOfPages
‪getNumberOfPages()
Definition: AbstractPaginator.php:68
‪TYPO3\CMS\Core\Pagination\AbstractPaginator
Definition: AbstractPaginator.php:21
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\hasItemsOnCurrentPage
‪hasItemsOnCurrentPage()
Definition: AbstractPaginator.php:107
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getKeyOfLastPaginatedItem
‪getKeyOfLastPaginatedItem()
Definition: AbstractPaginator.php:83
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getTotalAmountOfItems
‪getTotalAmountOfItems()
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\withCurrentPageNumber
‪withCurrentPageNumber(int $currentPageNumber)
Definition: AbstractPaginator.php:55
‪TYPO3\CMS\Core\Pagination\PaginatorInterface
Definition: PaginatorInterface.php:25
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getAmountOfItemsOnCurrentPage
‪getAmountOfItemsOnCurrentPage()
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\$numberOfPages
‪int $numberOfPages
Definition: AbstractPaginator.php:24
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\updatePaginatedItems
‪updatePaginatedItems(int $itemsPerPage, int $offset)
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\getKeyOfFirstPaginatedItem
‪getKeyOfFirstPaginatedItem()
Definition: AbstractPaginator.php:78
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\$keyOfFirstPaginatedItem
‪int $keyOfFirstPaginatedItem
Definition: AbstractPaginator.php:28
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\$currentPageNumber
‪int $currentPageNumber
Definition: AbstractPaginator.php:36
‪TYPO3\CMS\Core\Pagination\AbstractPaginator\setCurrentPageNumber
‪setCurrentPageNumber(int $currentPageNumber)
Definition: AbstractPaginator.php:169