Development

/branches/1.3/lib/addon/sfPager.class.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/addon/sfPager.class.php

Revision 27747, 10.5 kB (checked in by Kris.Wallsmith, 5 years ago)

[1.3, 1.4] fixed doctrine pager iteration (closes #7758, refs #8021)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfPager class.
13  *
14  * @package    symfony
15  * @subpackage addon
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 abstract class sfPager implements Iterator, Countable
20 {
21   protected
22     $page            = 1,
23     $maxPerPage      = 0,
24     $lastPage        = 1,
25     $nbResults       = 0,
26     $class           = '',
27     $tableName       = '',
28     $objects         = null,
29     $cursor          = 1,
30     $parameters      = array(),
31     $currentMaxLink  = 1,
32     $parameterHolder = null,
33     $maxRecordLimit  = false,
34
35     // used by iterator interface
36     $results         = null,
37     $resultsCounter  = 0;
38
39   /**
40    * Constructor.
41    *
42    * @param string  $class      The model class
43    * @param integer $maxPerPage Number of records to display per page
44    */
45   public function __construct($class, $maxPerPage = 10)
46   {
47     $this->setClass($class);
48     $this->setMaxPerPage($maxPerPage);
49     $this->parameterHolder = new sfParameterHolder();
50   }
51
52   /**
53    * Initialize the pager.
54    *
55    * Function to be called after parameters have been set.
56    */
57   abstract public function init();
58
59   /**
60    * Returns an array of results on the given page.
61    *
62    * @return array
63    */
64   abstract public function getResults();
65
66   /**
67    * Returns an object at a certain offset.
68    *
69    * Used internally by {@link getCurrent()}.
70    *
71    * @return mixed
72    */
73   abstract protected function retrieveObject($offset);
74
75   /**
76    * Returns the current pager's max link.
77    *
78    * @return integer
79    */
80   public function getCurrentMaxLink()
81   {
82     return $this->currentMaxLink;
83   }
84
85   /**
86    * Returns the current pager's max record limit.
87    *
88    * @return integer
89    */
90   public function getMaxRecordLimit()
91   {
92     return $this->maxRecordLimit;
93   }
94
95   /**
96    * Sets the current pager's max record limit.
97    *
98    * @param integer $limit
99    */
100   public function setMaxRecordLimit($limit)
101   {
102     $this->maxRecordLimit = $limit;
103   }
104
105   /**
106    * Returns an array of page numbers to use in pagination links.
107    *
108    * @param  integer $nb_links The maximum number of page numbers to return
109    *
110    * @return array
111    */
112   public function getLinks($nb_links = 5)
113   {
114     $links = array();
115     $tmp   = $this->page - floor($nb_links / 2);
116     $check = $this->lastPage - $nb_links + 1;
117     $limit = $check > 0 ? $check : 1;
118     $begin = $tmp > 0 ? ($tmp > $limit ? $limit : $tmp) : 1;
119
120     $i = (int) $begin;
121     while ($i < $begin + $nb_links && $i <= $this->lastPage)
122     {
123       $links[] = $i++;
124     }
125
126     $this->currentMaxLink = count($links) ? $links[count($links) - 1] : 1;
127
128     return $links;
129   }
130
131   /**
132    * Returns true if the current query requires pagination.
133    *
134    * @return boolean
135    */
136   public function haveToPaginate()
137   {
138     return $this->getMaxPerPage() && $this->getNbResults() > $this->getMaxPerPage();
139   }
140
141   /**
142    * Returns the current cursor.
143    *
144    * @return integer
145    */
146   public function getCursor()
147   {
148     return $this->cursor;
149   }
150
151   /**
152    * Sets the current cursor.
153    *
154    * @param integer $pos
155    */
156   public function setCursor($pos)
157   {
158     if ($pos < 1)
159     {
160       $this->cursor = 1;
161     }
162     else if ($pos > $this->nbResults)
163     {
164       $this->cursor = $this->nbResults;
165     }
166     else
167     {
168       $this->cursor = $pos;
169     }
170   }
171
172   /**
173    * Returns an object by cursor position.
174    *
175    * @param  integer $pos
176    *
177    * @return mixed
178    */
179   public function getObjectByCursor($pos)
180   {
181     $this->setCursor($pos);
182
183     return $this->getCurrent();
184   }
185
186   /**
187    * Returns the current object.
188    *
189    * @return mixed
190    */
191   public function getCurrent()
192   {
193     return $this->retrieveObject($this->cursor);
194   }
195
196   /**
197    * Returns the next object.
198    *
199    * @return mixed|null
200    */
201   public function getNext()
202   {
203     if ($this->cursor + 1 > $this->nbResults)
204     {
205       return null;
206     }
207     else
208     {
209       return $this->retrieveObject($this->cursor + 1);
210     }
211   }
212
213   /**
214    * Returns the previous object.
215    *
216    * @return mixed|null
217    */
218   public function getPrevious()
219   {
220     if ($this->cursor - 1 < 1)
221     {
222       return null;
223     }
224     else
225     {
226       return $this->retrieveObject($this->cursor - 1);
227     }
228   }
229
230   /**
231    * Returns the first index on the current page.
232    *
233    * @return integer
234    */
235   public function getFirstIndice()
236   {
237     if ($this->page == 0)
238     {
239       return 1;
240     }
241     else
242     {
243       return ($this->page - 1) * $this->maxPerPage + 1;
244     }
245   }
246
247   /**
248    * Returns the last index on the current page.
249    *
250    * @return integer
251    */
252   public function getLastIndice()
253   {
254     if ($this->page == 0)
255     {
256       return $this->nbResults;
257     }
258     else
259     {
260       if ($this->page * $this->maxPerPage >= $this->nbResults)
261       {
262         return $this->nbResults;
263       }
264       else
265       {
266         return $this->page * $this->maxPerPage;
267       }
268     }
269   }
270
271   /**
272    * Returns the current class.
273    *
274    * @return string
275    */
276   public function getClass()
277   {
278     return $this->class;
279   }
280
281   /**
282    * Sets the current class.
283    *
284    * @param string $class
285    */
286   public function setClass($class)
287   {
288     $this->class = $class;
289   }
290
291   /**
292    * Returns the number of results.
293    *
294    * @return integer
295    */
296   public function getNbResults()
297   {
298     return $this->nbResults;
299   }
300
301   /**
302    * Sets the number of results.
303    *
304    * @param integer $nb
305    */
306   protected function setNbResults($nb)
307   {
308     $this->nbResults = $nb;
309   }
310
311   /**
312    * Returns the first page number.
313    *
314    * @return integer
315    */
316   public function getFirstPage()
317   {
318     return 1;
319   }
320
321   /**
322    * Returns the last page number.
323    *
324    * @return integer
325    */
326   public function getLastPage()
327   {
328     return $this->lastPage;
329   }
330
331   /**
332    * Sets the last page number.
333    *
334    * @param integer $page
335    */
336   protected function setLastPage($page)
337   {
338     $this->lastPage = $page;
339
340     if ($this->getPage() > $page)
341     {
342       $this->setPage($page);
343     }
344   }
345
346   /**
347    * Returns the current page.
348    *
349    * @return integer
350    */
351   public function getPage()
352   {
353     return $this->page;
354   }
355
356   /**
357    * Returns the next page.
358    *
359    * @return integer
360    */
361   public function getNextPage()
362   {
363     return min($this->getPage() + 1, $this->getLastPage());
364   }
365
366   /**
367    * Returns the previous page.
368    *
369    * @return integer
370    */
371   public function getPreviousPage()
372   {
373     return max($this->getPage() - 1, $this->getFirstPage());
374   }
375
376   /**
377    * Sets the current page.
378    *
379    * @param integer $page
380    */
381   public function setPage($page)
382   {
383     $this->page = intval($page);
384
385     if ($this->page <= 0)
386     {
387       // set first page, which depends on a maximum set
388       $this->page = $this->getMaxPerPage() ? 1 : 0;
389     }
390   }
391
392   /**
393    * Returns the maximum number of results per page.
394    *
395    * @return integer
396    */
397   public function getMaxPerPage()
398   {
399     return $this->maxPerPage;
400   }
401
402   /**
403    * Sets the maximum number of results per page.
404    *
405    * @param integer $max
406    */
407   public function setMaxPerPage($max)
408   {
409     if ($max > 0)
410     {
411       $this->maxPerPage = $max;
412       if ($this->page == 0)
413       {
414         $this->page = 1;
415       }
416     }
417     else if ($max == 0)
418     {
419       $this->maxPerPage = 0;
420       $this->page = 0;
421     }
422     else
423     {
424       $this->maxPerPage = 1;
425       if ($this->page == 0)
426       {
427         $this->page = 1;
428       }
429     }
430   }
431
432   /**
433    * Returns true if on the first page.
434    *
435    * @return boolean
436    */
437   public function isFirstPage()
438   {
439     return 1 == $this->page;
440   }
441
442   /**
443    * Returns true if on the last page.
444    *
445    * @return boolean
446    */
447   public function isLastPage()
448   {
449     return $this->page == $this->lastPage;
450   }
451
452   /**
453    * Returns the current pager's parameter holder.
454    *
455    * @return sfParameterHolder
456    */
457   public function getParameterHolder()
458   {
459     return $this->parameterHolder;
460   }
461
462   /**
463    * Returns a parameter.
464    *
465    * @param  string $name
466    * @param  mixed  $default
467    *
468    * @return mixed
469    */
470   public function getParameter($name, $default = null)
471   {
472     return $this->parameterHolder->get($name, $default);
473   }
474
475   /**
476    * Checks whether a parameter has been set.
477    *
478    * @param  string $name
479    *
480    * @return boolean
481    */
482   public function hasParameter($name)
483   {
484     return $this->parameterHolder->has($name);
485   }
486
487   /**
488    * Sets a parameter.
489    *
490    * @param  string $name
491    * @param  mixed  $value
492    */
493   public function setParameter($name, $value)
494   {
495     $this->parameterHolder->set($name, $value);
496   }
497
498   /**
499    * Returns true if the properties used for iteration have been initialized.
500    *
501    * @return boolean
502    */
503   protected function isIteratorInitialized()
504   {
505     return null !== $this->results;
506   }
507
508   /**
509    * Loads data into properties used for iteration.
510    */
511   protected function initializeIterator()
512   {
513     $this->results = $this->getResults();
514     $this->resultsCounter = count($this->results);
515   }
516
517   /**
518    * Empties properties used for iteration.
519    */
520   protected function resetIterator()
521   {
522     $this->results = null;
523     $this->resultsCounter = 0;
524   }
525
526   /**
527    * Returns the current result.
528    *
529    * @see Iterator
530    */
531   public function current()
532   {
533     if (!$this->isIteratorInitialized())
534     {
535       $this->initializeIterator();
536     }
537
538     return current($this->results);
539   }
540
541   /**
542    * Returns the current key.
543    *
544    * @see Iterator
545    */
546   public function key()
547   {
548     if (!$this->isIteratorInitialized())
549     {
550       $this->initializeIterator();
551     }
552
553     return key($this->results);
554   }
555
556   /**
557    * Advances the internal pointer and returns the current result.
558    *
559    * @see Iterator
560    */
561   public function next()
562   {
563     if (!$this->isIteratorInitialized())
564     {
565       $this->initializeIterator();
566     }
567
568     --$this->resultsCounter;
569
570     return next($this->results);
571   }
572
573   /**
574    * Resets the internal pointer and returns the current result.
575    *
576    * @see Iterator
577    */
578   public function rewind()
579   {
580     if (!$this->isIteratorInitialized())
581     {
582       $this->initializeIterator();
583     }
584
585     $this->resultsCounter = count($this->results);
586
587     return reset($this->results);
588   }
589
590   /**
591    * Returns true if pointer is within bounds.
592    *
593    * @see Iterator
594    */
595   public function valid()
596   {
597     if (!$this->isIteratorInitialized())
598     {
599       $this->initializeIterator();
600     }
601
602     return $this->resultsCounter > 0;
603   }
604
605   /**
606    * Returns the total number of results.
607    *
608    * @see Countable
609    */
610   public function count()
611   {
612     return $this->getNbResults();
613   }
614 }
615
Note: See TracBrowser for help on using the browser.