]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Core/Pagination.php
Remove 'svn' lines
[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-2014 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-2014 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\Slim;
40 use Analog\Analog;
41
42 /**
43 * Pagination and ordering facilities
44 *
45 * @name Pagination
46 * @category Core
47 * @package Galette
48 *
49 * @author Johan Cwiklinski <johan@x-tnd.be>
50 * @copyright 2010-2014 The Galette Team
51 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
52 * @link http://galette.tuxfamily.org
53 */
54
55 abstract class Pagination
56 {
57 private $current_page;
58 private $orderby;
59 private $ordered;
60 private $show;
61 private $pages = 1;
62 private $counter = null;
63 protected $view;
64 protected $router;
65
66 const ORDER_ASC = 'ASC';
67 const ORDER_DESC = 'DESC';
68
69 protected $pagination_fields = array(
70 'current_page',
71 'orderby',
72 'ordered',
73 'show',
74 'pages',
75 'counter'
76 );
77
78 /**
79 * Default constructor
80 */
81 public function __construct()
82 {
83 $this->reinit();
84 }
85
86 /**
87 * Returns the field we want to default set order to
88 *
89 * @return string field name
90 */
91 abstract protected function getDefaultOrder();
92
93 /**
94 * Return the default direction for ordering
95 *
96 * @return string ASC or DESC
97 */
98 protected function getDefaultDirection()
99 {
100 return self::ORDER_ASC;
101 }
102
103 /**
104 * Reinit default parameters
105 *
106 * @return void
107 */
108 public function reinit()
109 {
110 global $preferences;
111
112 $this->current_page = 1;
113 $this->orderby = $this->getDefaultOrder();
114 $this->ordered = $this->getDefaultDirection();
115 $this->show = (int)$preferences->pref_numrows;
116 }
117
118 /**
119 * Invert sort order
120 *
121 * @return void
122 */
123 public function invertorder()
124 {
125 $actual = $this->ordered;
126 if ($actual == self::ORDER_ASC) {
127 $this->ordered = self::ORDER_DESC;
128 }
129 if ($actual == self::ORDER_DESC) {
130 $this->ordered = self::ORDER_ASC;
131 }
132 }
133
134 /**
135 * Get current sort direction
136 *
137 * @return self::ORDER_ASC|self::ORDER_DESC
138 */
139 public function getDirection()
140 {
141 return $this->ordered;
142 }
143
144 /**
145 * Set sort direction
146 *
147 * @param string $direction self::ORDER_ASC|self::ORDER_DESC
148 *
149 * @return void
150 */
151 public function setDirection($direction)
152 {
153 if ($direction == self::ORDER_ASC || $direction == self::ORDER_DESC) {
154 $this->ordered = $direction;
155 } else {
156 Analog::log(
157 'Trying to set a sort direction that is not know (`' .
158 $direction . '`). Reverting to default value.',
159 Analog::WARNING
160 );
161 $this->ordered == self::ORDER_ASC;
162 }
163 }
164
165 /**
166 * Add limits so we retrieve only relavant rows
167 *
168 * @param Select $select Original select
169 *
170 * @return void
171 */
172 public function setLimits($select)
173 {
174 if ($this->show !== 0) {
175 $select->limit($this->show);
176 $select->offset(
177 ($this->current_page - 1) * $this->show
178 );
179 }
180 }
181
182 /**
183 * Set counter
184 *
185 * @param int $c Count
186 *
187 * @return void
188 */
189 public function setCounter($c)
190 {
191 $this->counter = (int)$c;
192 $this->countPages();
193 }
194
195 /**
196 * Update or set pages count
197 *
198 * @return void
199 */
200 protected function countPages()
201 {
202 if ($this->show !== 0) {
203 if ($this->counter % $this->show == 0) {
204 $this->pages = intval($this->counter / $this->show);
205 } else {
206 $this->pages = intval($this->counter / $this->show) + 1;
207 }
208 } else {
209 $this->pages = 0;
210 }
211 if ($this->pages == 0) {
212 $this->pages = 1;
213 }
214 if ($this->current_page > $this->pages) {
215 $this->current_page = $this->pages;
216 }
217 }
218
219 /**
220 * Creates pagination links and assign some usefull variables to the
221 * Smarty template
222 *
223 * @param Router $router Application instance
224 * @param Smarty $view View instance
225 * @param boolean $restricted Do not permit to display all
226 *
227 * @return void
228 */
229 public function setSmartyPagination(\Slim\Router $router, \Smarty $view, $restricted = true)
230 {
231 $paginate = null;
232 $this->view = $view;
233 $this->router = $router;
234
235 //Create pagination links
236 if ($this->current_page < 11) {
237 $idepart = 1;
238 } else {
239 $idepart = $this->current_page - 10;
240 }
241 if ($this->current_page + 10 < $this->pages) {
242 $ifin = $this->current_page + 10;
243 } else {
244 $ifin = $this->pages;
245 }
246
247 $next = $this->current_page + 1;
248 $previous = $this->current_page - 1;
249
250 if ($this->current_page != 1) {
251 $paginate .= $this->getLink(
252 '&lt;&lt;',
253 $this->getHref(1),
254 preg_replace("(%i)", $next, _T("First page"))
255 );
256
257 $paginate .= $this->getLink(
258 '&lt;',
259 $this->getHref($previous),
260 preg_replace("(%i)", $previous, _T("Previous page (%i)"))
261 );
262 }
263
264 for ($i = $idepart; $i <= $ifin; $i++) {
265 if ($i == $this->current_page) {
266 $paginate .= $this->getLink(
267 "-&nbsp;$i&nbsp;-",
268 $this->getHref($this->current_page),
269 preg_replace(
270 "(%i)",
271 $this->current_page,
272 _T("Current page (%i)")
273 ),
274 true
275 );
276 } else {
277 $paginate .= $this->getLink(
278 $i,
279 $this->getHref($i),
280 preg_replace("(%i)", $i, _T("Page %i"))
281 );
282 }
283 }
284 if ($this->current_page != $this->pages) {
285 $paginate .= $this->getLink(
286 '&gt;',
287 $this->getHref($next),
288 preg_replace("(%i)", $next, _T("Next page (%i)"))
289 );
290
291 $paginate .= $this->getLink(
292 '&gt;&gt;',
293 $this->getHref($this->pages),
294 preg_replace("(%i)", $this->pages, _T("Last page (%i)"))
295 );
296 }
297
298 $options = array(
299 10 => "10",
300 20 => "20",
301 50 => "50",
302 100 => "100"
303 );
304
305 if ($restricted === false) {
306 $options[0] = _T("All");
307 }
308
309 //Now, we assign common variables to Smarty template
310 $view->assign('nb_pages', $this->pages);
311 $view->assign('page', $this->current_page);
312 $view->assign('numrows', $this->show);
313 $view->assign('pagination', $paginate);
314 $view->assign('nbshow_options', $options);
315
316 $this->view = null;
317 $this->router = null;
318 }
319
320 /**
321 * Get a pagination link
322 *
323 * @param string $content Links content
324 * @param string $url URL the link to point on
325 * @param string $title Link's title
326 * @param bool $current Is current page
327 *
328 * @return string
329 */
330 private function getLink($content, $url, $title, $current = false)
331 {
332 $tabs = "\t\t\t\t\t\t";
333 $link = $tabs . "<li";
334 if ($current === true) {
335 $link .= " class=\"current\" ";
336 }
337 $link .= "><a href=\"" . $url . "\" " .
338 "title=\"" . $title . "\">" . $content . "</a></li>\n";
339 return $link;
340 }
341
342 /**
343 * Build href
344 *
345 * @param int $page Page
346 *
347 * @return string
348 */
349 protected function getHref($page)
350 {
351 $args = [
352 'option' => 'page',
353 'value' => $page
354 ];
355
356 if ($this->view->getTemplateVars('cur_subroute')) {
357 $args['type'] = $this->view->getTemplateVars('cur_subroute');
358 }
359
360 $href = $this->router->pathFor(
361 $this->view->getTemplateVars('cur_route'),
362 $args
363 );
364 return $href;
365 }
366
367 /**
368 * Global getter method
369 *
370 * @param string $name name of the property we want to retrive
371 *
372 * @return object the called property
373 */
374 public function __get($name)
375 {
376
377 Analog::log(
378 '[' . get_class($this) .
379 '|Pagination] Getting property `' . $name . '`',
380 Analog::DEBUG
381 );
382
383 if (in_array($name, $this->pagination_fields)) {
384 return $this->$name;
385 } else {
386 Analog::log(
387 '[' . get_class($this) .
388 '|Pagination] Unable to get proprety `' . $name . '`',
389 Analog::WARNING
390 );
391 }
392 }
393
394 /**
395 * Global setter method
396 *
397 * @param string $name name of the property we want to assign a value to
398 * @param object $value a relevant value for the property
399 *
400 * @return void
401 */
402 public function __set($name, $value)
403 {
404
405 Analog::log(
406 '[' . get_class($this) . '|Pagination] Setting property `' .
407 $name . '`',
408 Analog::DEBUG
409 );
410
411 switch ($name) {
412 case 'ordered':
413 if ($value == self::ORDER_ASC || $value == self::ORDER_DESC) {
414 $this->$name = $value;
415 } else {
416 Analog::log(
417 '[' . get_class($this) .
418 '|Pagination] Possibles values for field `' .
419 $name . '` are: `' . self::ORDER_ASC . '` or `' .
420 self::ORDER_DESC . '` - `' . $value . '` given',
421 Analog::WARNING
422 );
423 }
424 break;
425 case 'orderby':
426 if ($this->$name == $value) {
427 $this->invertorder();
428 } else {
429 $this->$name = $value;
430 $this->setDirection(self::ORDER_ASC);
431 }
432 break;
433 case 'current_page':
434 case 'counter':
435 case 'pages':
436 if (is_int($value) && $value > 0) {
437 $this->$name = $value;
438 } else {
439 Analog::log(
440 '[' . get_class($this) .
441 '|Pagination] Value for field `' .
442 $name . '` should be a positive integer - (' .
443 gettype($value) . ')' . $value . ' given',
444 Analog::WARNING
445 );
446 }
447 break;
448 case 'show':
449 if (
450 $value == 'all'
451 || preg_match('/[[:digit:]]/', $value)
452 && $value >= 0
453 ) {
454 $this->$name = (int)$value;
455 } else {
456 Analog::log(
457 '[' . get_class($this) . '|Pagination] Value for `' .
458 $name . '` should be a positive integer or \'all\' - (' .
459 gettype($value) . ')' . $value . ' given',
460 Analog::WARNING
461 );
462 }
463 break;
464 default:
465 Analog::log(
466 '[' . get_class($this) .
467 '|Pagination] Unable to set proprety `' . $name . '`',
468 Analog::WARNING
469 );
470 break;
471 }
472 }
473 }