]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Core/Pagination.php
Add missing variable to hide pagination
[galette.git] / galette / lib / Galette / Core / Pagination.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Global pagination
7 *
8 * PHP version 5
9 *
10 * Copyright © 2010-2023 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Core
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2010-2023 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7dev - 2010-03-03
35 */
36
37 namespace Galette\Core;
38
39 use Slim\Routing\RouteParser;
40 use Slim\Slim;
41 use Analog\Analog;
42 use Laminas\Db\Sql\Select;
43
44 /**
45 * Pagination and ordering facilities
46 *
47 * @name Pagination
48 * @category Core
49 * @package Galette
50 *
51 * @author Johan Cwiklinski <johan@x-tnd.be>
52 * @copyright 2010-2023 The Galette Team
53 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
54 * @link http://galette.tuxfamily.org
55 *
56 * @property integer $current_page
57 * @property string $orderby
58 * @property string $ordered
59 * @property integer $show
60 * @property integer $pages
61 * @property integer $counter
62 */
63
64 abstract class Pagination
65 {
66 private $current_page;
67 private $orderby;
68 private $ordered;
69 private $show;
70 private $pages = 1;
71 private $counter = null;
72 protected $view;
73 protected $routeparser;
74
75 public const ORDER_ASC = 'ASC';
76 public const ORDER_DESC = 'DESC';
77
78 protected $pagination_fields = array(
79 'current_page',
80 'orderby',
81 'ordered',
82 'show',
83 'pages',
84 'counter'
85 );
86
87 /**
88 * Default constructor
89 */
90 public function __construct()
91 {
92 $this->reinit();
93 }
94
95 /**
96 * Returns the field we want to default set order to
97 *
98 * @return int|string
99 */
100 abstract protected function getDefaultOrder();
101
102 /**
103 * Return the default direction for ordering
104 *
105 * @return string ASC or DESC
106 */
107 protected function getDefaultDirection()
108 {
109 return self::ORDER_ASC;
110 }
111
112 /**
113 * Reinit default parameters
114 *
115 * @return void
116 */
117 public function reinit()
118 {
119 global $preferences;
120
121 $this->current_page = 1;
122 $this->orderby = $this->getDefaultOrder();
123 $this->ordered = $this->getDefaultDirection();
124 $this->show = (int)$preferences->pref_numrows;
125 }
126
127 /**
128 * Invert sort order
129 *
130 * @return void
131 */
132 public function invertorder()
133 {
134 $actual = $this->ordered;
135 if ($actual == self::ORDER_ASC) {
136 $this->ordered = self::ORDER_DESC;
137 }
138 if ($actual == self::ORDER_DESC) {
139 $this->ordered = self::ORDER_ASC;
140 }
141 }
142
143 /**
144 * Get current sort direction
145 *
146 * @return self::ORDER_ASC|self::ORDER_DESC
147 */
148 public function getDirection()
149 {
150 return $this->ordered;
151 }
152
153 /**
154 * Set sort direction
155 *
156 * @param string $direction self::ORDER_ASC|self::ORDER_DESC
157 *
158 * @return void
159 */
160 public function setDirection($direction)
161 {
162 if ($direction == self::ORDER_ASC || $direction == self::ORDER_DESC) {
163 $this->ordered = $direction;
164 } else {
165 Analog::log(
166 'Trying to set a sort direction that is not know (`' .
167 $direction . '`). Reverting to default value.',
168 Analog::WARNING
169 );
170 $this->ordered == self::ORDER_ASC;
171 }
172 }
173
174 /**
175 * Add limits so we retrieve only relavant rows
176 *
177 * @param Select $select Original select
178 *
179 * @return void
180 */
181 public function setLimits(Select $select)
182 {
183 if ($this->show !== 0) {
184 $select->limit($this->show);
185 $select->offset(
186 ($this->current_page - 1) * $this->show
187 );
188 }
189 }
190
191 /**
192 * Set counter
193 *
194 * @param int $c Count
195 *
196 * @return void
197 */
198 public function setCounter($c)
199 {
200 $this->counter = (int)$c;
201 $this->countPages();
202 }
203
204 /**
205 * Update or set pages count
206 *
207 * @return void
208 */
209 protected function countPages()
210 {
211 if ($this->show !== 0) {
212 if ($this->counter % $this->show == 0) {
213 $this->pages = (int)($this->counter / $this->show);
214 } else {
215 $this->pages = (int)($this->counter / $this->show) + 1;
216 }
217 } else {
218 $this->pages = 0;
219 }
220 if ($this->pages === 0) {
221 $this->pages = 1;
222 }
223 if ($this->current_page > $this->pages) {
224 $this->current_page = $this->pages;
225 }
226 }
227
228 /**
229 * Creates pagination links and assign some useful variables to the template
230 *
231 * @param RouteParser $routeparser Application instance
232 * @param mixed $view View instance
233 * @param boolean $restricted Do not permit to display all
234 *
235 * @return void
236 *
237 * @deprecated 1.0.0 use setViewPagination
238 */
239 public function setSmartyPagination(RouteParser $routeparser, $view, $restricted = true)
240 {
241 $this->setViewPagination($routeparser, $view, $restricted);
242 }
243
244 /**
245 * Creates pagination links and assign some useful variables to the template
246 *
247 * @param RouteParser $routeparser Application instance
248 * @param mixed $view View instance
249 * @param boolean $restricted Do not permit to display all
250 *
251 * @return void
252 */
253 public function setViewPagination(RouteParser $routeparser, $view, $restricted = true)
254 {
255 $is_paginated = true;
256 $paginate = null;
257 $this->view = $view;
258 $this->routeparser = $routeparser;
259
260 //Create pagination links
261 if ($this->current_page < 11) {
262 $idepart = 1;
263 } else {
264 $idepart = $this->current_page - 10;
265 }
266 if ($this->current_page + 10 < $this->pages) {
267 $ifin = $this->current_page + 10;
268 } else {
269 $ifin = $this->pages;
270 }
271
272 $next = $this->current_page + 1;
273 $previous = $this->current_page - 1;
274
275 if ($this->current_page != 1) {
276 $paginate .= $this->getLink(
277 '&lt;&lt;',
278 $this->getHref(1),
279 preg_replace("(%i)", $next, _T("First page"))
280 );
281
282 $paginate .= $this->getLink(
283 '&lt;',
284 $this->getHref($previous),
285 preg_replace("(%i)", $previous, _T("Previous page (%i)"))
286 );
287 }
288
289 for ($i = $idepart; $i <= $ifin; $i++) {
290 if ($i == $this->current_page) {
291 $paginate .= $this->getLink(
292 "$i",
293 $this->getHref($this->current_page),
294 preg_replace(
295 "(%i)",
296 $this->current_page,
297 _T("Current page (%i)")
298 ),
299 true
300 );
301 } else {
302 $paginate .= $this->getLink(
303 $i,
304 $this->getHref($i),
305 preg_replace("(%i)", $i, _T("Page %i"))
306 );
307 }
308 }
309 if ($this->current_page != $this->pages) {
310 $paginate .= $this->getLink(
311 '&gt;',
312 $this->getHref($next),
313 preg_replace("(%i)", $next, _T("Next page (%i)"))
314 );
315
316 $paginate .= $this->getLink(
317 '&gt;&gt;',
318 $this->getHref($this->pages),
319 preg_replace("(%i)", $this->pages, _T("Last page (%i)"))
320 );
321 }
322 if ($this->current_page == 1 && $this->current_page == $this->pages) {
323 $is_paginated = false;
324 }
325
326 $options = array(
327 10 => "10",
328 20 => "20",
329 50 => "50",
330 100 => "100"
331 );
332
333 if ($restricted === false) {
334 $options[0] = _T("All");
335 }
336
337 //Now, we assign common variables to template
338 $view->getEnvironment()->addGlobal('nb_pages', $this->pages);
339 $view->getEnvironment()->addGlobal('page', $this->current_page);
340 $view->getEnvironment()->addGlobal('numrows', $this->show);
341 $view->getEnvironment()->addGlobal('is_paginated', $is_paginated);
342 $view->getEnvironment()->addGlobal('pagination', $paginate);
343 $view->getEnvironment()->addGlobal('nbshow_options', $options);
344
345 $this->view = null;
346 $this->routeparser = null;
347 }
348
349 /**
350 * Get a pagination link
351 *
352 * @param string $content Links content
353 * @param string $url URL the link to point on
354 * @param string $title Link's title
355 * @param bool $current Is current page
356 *
357 * @return string
358 */
359 private function getLink($content, $url, $title, $current = false)
360 {
361 if ($current === true) {
362 $active = "active ";
363 } else {
364 $active = "";
365 }
366 $link = "<a href=\"" . $url . "\" " .
367 "title=\"" . $title . "\" class=\"" . $active . "item\">" . $content . "</a>\n";
368 return $link;
369 }
370
371 /**
372 * Build href
373 *
374 * @param int $page Page
375 *
376 * @return string
377 */
378 protected function getHref($page)
379 {
380 $args = [
381 'option' => 'page',
382 'value' => $page
383 ];
384
385 if ($this->view->getEnvironment()->getGlobals()['cur_subroute']) {
386 $args['type'] = $this->view->getEnvironment()->getGlobals()['cur_subroute'];
387 }
388
389 $href = $this->routeparser->urlFor(
390 $this->view->getEnvironment()->getGlobals()['cur_route'],
391 $args
392 );
393 return $href;
394 }
395
396 /**
397 * Global getter method
398 *
399 * @param string $name name of the property we want to retrive
400 *
401 * @return mixed the called property
402 */
403 public function __get($name)
404 {
405 if (in_array($name, $this->pagination_fields)) {
406 return $this->$name;
407 } else {
408 Analog::log(
409 '[' . get_class($this) .
410 '|Pagination] Unable to get proprety `' . $name . '`',
411 Analog::WARNING
412 );
413 }
414 }
415
416 /**
417 * Global isset method
418 * Required for twig to access properties via __get
419 *
420 * @param string $name name of the property we want to retrive
421 *
422 * @return bool
423 */
424 public function __isset($name)
425 {
426 if (in_array($name, $this->pagination_fields)) {
427 return true;
428 }
429 return property_exists($this, $name);
430 }
431
432 /**
433 * Global setter method
434 *
435 * @param string $name name of the property we want to assign a value to
436 * @param mixed $value a relevant value for the property
437 *
438 * @return void
439 */
440 public function __set($name, $value)
441 {
442 switch ($name) {
443 case 'ordered':
444 if ($value == self::ORDER_ASC || $value == self::ORDER_DESC) {
445 $this->$name = $value;
446 } else {
447 Analog::log(
448 '[' . get_class($this) .
449 '|Pagination] Possibles values for field `' .
450 $name . '` are: `' . self::ORDER_ASC . '` or `' .
451 self::ORDER_DESC . '` - `' . $value . '` given',
452 Analog::WARNING
453 );
454 }
455 break;
456 case 'orderby':
457 if ($this->$name == $value) {
458 $this->invertorder();
459 } else {
460 $this->$name = $value;
461 $this->setDirection(self::ORDER_ASC);
462 }
463 break;
464 case 'current_page':
465 case 'counter':
466 case 'pages':
467 if (is_int($value) && $value > 0) {
468 $this->$name = $value;
469 } else {
470 Analog::log(
471 '[' . get_class($this) .
472 '|Pagination] Value for field `' .
473 $name . '` should be a positive integer - (' .
474 gettype($value) . ')' . $value . ' given',
475 Analog::WARNING
476 );
477 }
478 break;
479 case 'show':
480 if (
481 $value == 'all'
482 || preg_match('/[[:digit:]]/', $value)
483 && $value >= 0
484 ) {
485 $this->$name = (int)$value;
486 } else {
487 Analog::log(
488 '[' . get_class($this) . '|Pagination] Value for `' .
489 $name . '` should be a positive integer or \'all\' - (' .
490 gettype($value) . ')' . $value . ' given',
491 Analog::WARNING
492 );
493 }
494 break;
495 default:
496 Analog::log(
497 '[' . get_class($this) .
498 '|Pagination] Unable to set proprety `' . $name . '`',
499 Analog::WARNING
500 );
501 break;
502 }
503 }
504 }