3 namespace Friendica\Content;
5 use Friendica\Core\L10n;
6 use Friendica\Core\Renderer;
7 use Friendica\Util\Strings;
10 * The Pager has two very different output, Minimal and Full, see renderMinimal() and renderFull() for more details.
12 * @author Hypolite Petovan <mrpetovan@gmail.com>
23 private $itemsPerPage = 50;
28 private $baseQueryString = '';
31 * Instantiates a new Pager with the base parameters.
33 * Guesses the page number from the GET parameter 'page'.
35 * @param string $queryString The query string of the current page
36 * @param integer $itemsPerPage An optional number of items per page to override the default value
38 public function __construct($queryString, $itemsPerPage = 50)
40 $this->setQueryString($queryString);
41 $this->setItemsPerPage($itemsPerPage);
42 $this->setPage(defaults($_GET, 'page', 1));
46 * Returns the start offset for a LIMIT clause. Starts at 0.
50 public function getStart()
52 return max(0, ($this->page * $this->itemsPerPage) - $this->itemsPerPage);
56 * Returns the number of items per page
60 public function getItemsPerPage()
62 return $this->itemsPerPage;
66 * Returns the current page number
70 public function getPage()
76 * Returns the base query string.
78 * Warning: this isn't the same value as passed to the constructor.
79 * See setQueryString() for the inventory of transformations
84 public function getBaseQueryString()
86 return $this->baseQueryString;
90 * Sets the number of items per page, 1 minimum.
92 * @param integer $itemsPerPage
94 public function setItemsPerPage($itemsPerPage)
96 $this->itemsPerPage = max(1, intval($itemsPerPage));
100 * Sets the current page number. Starts at 1.
102 * @param integer $page
104 public function setPage($page)
106 $this->page = max(1, intval($page));
110 * Sets the base query string from a full query string.
112 * Strips the 'page' parameter, and remove the 'q=' string for some reason.
114 * @param string $queryString
116 public function setQueryString($queryString)
118 $stripped = preg_replace('/([&?]page=[0-9]*)/', '', $queryString);
120 $stripped = str_replace('q=', '', $stripped);
121 $stripped = trim($stripped, '/');
123 $this->baseQueryString = $stripped;
127 * Ensures the provided URI has its query string punctuation in order.
132 private function ensureQueryParameter($uri)
134 if (strpos($uri, '?') === false && ($pos = strpos($uri, '&')) !== false) {
135 $uri = substr($uri, 0, $pos) . '?' . substr($uri, $pos + 1);
142 * @brief Minimal pager (newer/older)
144 * This mode is intended for reverse chronological pages and presents only two links, newer (previous) and older (next).
145 * The itemCount is the number of displayed items. If no items are displayed, the older button is disabled.
149 * $pager = new Pager($a->query_string);
151 * $params = ['order' => ['sort_field' => true], 'limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
152 * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params));
154 * $html = $pager->renderMinimal(count($items));
156 * @param integer $itemCount The number of displayed items on the page
157 * @return string HTML string of the pager
159 public function renderMinimal($itemCount)
161 $displayedItemCount = max(0, intval($itemCount));
166 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
167 'text' => L10n::t('newer'),
168 'class' => 'previous' . ($this->getPage() == 1 ? ' disabled' : '')
171 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
172 'text' => L10n::t('older'),
173 'class' => 'next' . ($displayedItemCount < $this->getItemsPerPage() ? ' disabled' : '')
177 $tpl = Renderer::getMarkupTemplate('paginate.tpl');
178 return Renderer::replaceMacros($tpl, ['pager' => $data]);
182 * @brief Full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last)
184 * This mode presents page numbers as well as first, previous, next and last links.
185 * The itemCount is the total number of items including those not displayed.
189 * $total = DBA::count($table, $condition);
191 * $pager = new Pager($a->query_string, $total);
193 * $params = ['limit' => [$pager->getStart(), $pager->getItemsPerPage()]];
194 * $items = DBA::toArray(DBA::select($table, $fields, $condition, $params));
196 * $html = $pager->renderFull();
198 * @param integer $itemCount The total number of items including those note displayed on the page
199 * @return string HTML string of the pager
201 public function renderFull($itemCount)
203 $totalItemCount = max(0, intval($itemCount));
207 $data['class'] = 'pagination';
208 if ($totalItemCount > $this->getItemsPerPage()) {
210 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=1'),
211 'text' => L10n::t('first'),
212 'class' => $this->getPage() == 1 ? 'disabled' : ''
215 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() - 1)),
216 'text' => L10n::t('prev'),
217 'class' => $this->getPage() == 1 ? 'disabled' : ''
220 $numpages = $totalItemCount / $this->getItemsPerPage();
223 $numstop = $numpages;
225 // Limit the number of displayed page number buttons.
227 $numstart = (($this->getPage() > 4) ? ($this->getPage() - 4) : 1);
228 $numstop = (($this->getPage() > ($numpages - 7)) ? $numpages : ($numstart + 8));
233 for ($i = $numstart; $i <= $numstop; $i++) {
234 if ($i == $this->getPage()) {
238 'class' => 'current active'
242 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . $i),
249 if (($totalItemCount % $this->getItemsPerPage()) != 0) {
250 if ($i == $this->getPage()) {
254 'class' => 'current active'
258 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . $i),
265 $data['pages'] = $pages;
267 $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages);
270 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . ($this->getPage() + 1)),
271 'text' => L10n::t('next'),
272 'class' => $this->getPage() == $lastpage ? 'disabled' : ''
275 'url' => Strings::ensureQueryParameter($this->baseQueryString . '&page=' . $lastpage),
276 'text' => L10n::t('last'),
277 'class' => $this->getPage() == $lastpage ? 'disabled' : ''
281 $tpl = Renderer::getMarkupTemplate('paginate.tpl');
282 return Renderer::replaceMacros($tpl, ['pager' => $data]);