source: pro-violet-viettel/sourcecode/api.violet.vn/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPager.php

Last change on this file was 289, checked in by dungnv, 11 years ago
File size: 12.5 KB
Line 
1<?php
2/*
3 *  $Id: PropelPager.php 563 2007-02-01 09:45:55Z heltem $
4 *
5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 *
17 * This software consists of voluntary contributions made by many individuals
18 * and is licensed under the LGPL. For more information please see
19 * <http://propel.phpdb.org>.
20 */
21
22/**
23 *  PropelPager
24 *
25 *  Example Usage:
26 *
27 *  require_once 'propel/util/PropelPager.php';
28 *  require_once 'PEACH/Propel/Poem/poemPeer.php';
29 *
30 *  $c = new Criteria();
31 *  $c->addDescendingOrderByColumn(poemPeer::SID);
32 *
33 *  // with join
34 *  $pager = new PropelPager($c, 'poemPeer', 'doSelectJoinPoemUsers', 1, 50);
35 *
36 *  // without Join
37 *
38 *  $pager = new PropelPager($c, 'poemPeer', 'doSelect', 1, 50);
39 *
40 * Some template:
41 *
42 * <p>
43 * Total Pages: <?=$pager->getTotalPages()?>  Total Records: <?=$pager->getTotalRecordCount()?>
44 * </p>
45 * <table>
46 * <tr>
47 * <td>
48 * <?if ($link = $pager->getFirstPage):?>
49 * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
50 * <?endif?>
51 * </td>
52 * <td>
53 * <?if ($link = $pager->getPrev()):?>
54 * <a href="somescript?page=<?=$link?>">Previous</a>|
55 * <?endif?>
56 * </td>
57 * <td>
58 * <?foreach ($pager->getPrevLinks() as $link):?>
59 * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
60 * <?endforeach?>
61 * </td>
62 * <td><?=$pager->getPage()?></td>
63 * <td>
64 * <?foreach ($pager->getNextLinks() as $link):?>
65 * | <a href="somescript?page=<?=$link?>"><?=$link?></a>
66 * <?endforeach?>
67 * </td>
68 * <td>
69 * <?if ($link = $pager->getNext()):?>
70 * <a href="somescript?page=<?=$link?>">Last</a>|
71 * <?endif?>
72 * </td>
73 * <td>
74 * <?if ($link = $pager->getLastPage()):?>
75 * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
76 * <?endif?>
77 * </td>
78 * </tr>
79 * </table>
80 * <table id="latestPoems">
81 * <tr>
82 * <th>Title</th>
83 * <th>Auteur</th>
84 * <th>Date</th>
85 * <th>comments</th>
86 * </tr>
87 * <?foreach ($pager->getResult() as $poem):?>
88 * <tr>
89 * <td><?=$poem->getTitle()?></td>
90 * <td><?=$poem->getPoemUsers()->getUname()?></td>
91 * <td><?=$poem->getTime()?></td>
92 * <td><?=$poem->getComments()?></td>
93 * </tr>
94 * <?endforeach?>
95 * </table>
96 *
97 *
98 * @author     Rob Halff <info@rhalff.com>
99 * @version    $Revision: 563 $
100 * @copyright  Copyright (c) 2004 Rob Halff: LGPL - See LICENCE
101 * @package    propel.util
102 */
103class PropelPager {
104
105        private $recordCount;
106        private $pages;
107        private $peerClass;
108        private $peerSelectMethod;
109        private $peerCountMethod;
110        private $criteria;
111        private $countCriteria;
112        private $page;
113        private $rs = null;
114
115        /** @var        int Start row (offset) */
116        protected $start = 0;
117
118        /** @var        int Max rows to return (0 means all) */
119        protected $max = 0;
120
121        /**
122         * Create a new Propel Pager.
123         * @param      Criteria $c
124         * @param      string $peerClass The name of the static Peer class.
125         * @param      string $peerSelectMethod The name of the static method for selecting content from the Peer class.
126         * @param      int $page The current page (1-based).
127         * @param      int $rowsPerPage The number of rows that should be displayed per page.
128         */
129        public function __construct($c = null, $peerClass = null, $peerSelectMethod = null, $page = 1, $rowsPerPage = 25)
130        {
131                if (!isset($c)) {
132                        $c = new Criteria();
133                }
134                $this->setCriteria($c);
135                $this->setPeerClass($peerClass);
136                $this->setPeerSelectMethod($peerSelectMethod);
137                $this->guessPeerCountMethod();
138                $this->setPage($page);
139                $this->setRowsPerPage($rowsPerPage);
140        }
141
142        /**
143         * Set the criteria for this pager.
144         * @param      Criteria $c
145         * @return     void
146         */
147        public function setCriteria(Criteria $c)
148        {
149                $this->criteria = $c;
150        }
151
152        /**
153         * Return the Criteria object for this pager.
154         * @return     Criteria
155         */
156        public function getCriteria()
157        {
158                return $this->criteria;
159        }
160
161        /**
162         * Set the Peer Classname
163         *
164         * @param      string $class
165         * @return     void
166         */
167        public function setPeerClass($class)
168        {
169                $this->peerClass = $class;
170        }
171
172        /**
173         * Return the Peer Classname.
174         * @return     string
175         */
176        public function getPeerClass()
177        {
178                return $this->peerClass;
179        }
180
181        /**
182         * Set the Peer select method.
183         * This exists for legacy support, please use setPeerSelectMethod().
184         * @param      string $method The name of the static method to call on the Peer class.
185         * @return     void
186         * @see        setPeerSelectMethod()
187         * @deprecated
188         */
189        public function setPeerMethod($method)
190        {
191                $this->setPeerSelectMethod($method);
192        }
193
194        /**
195         * Return the Peer select method.
196         * This exists for legacy support, please use getPeerSelectMethod().
197         * @return     string
198         * @see        getPeerSelectMethod()
199         * @deprecated
200         */
201        public function getPeerMethod()
202        {
203                return $this->getPeerSelectMethod();
204        }
205
206        /**
207         * Set the Peer select method.
208         *
209         * @param      string $method The name of the static method to call on the Peer class.
210         * @return     void
211         */
212        public function setPeerSelectMethod($method)
213        {
214                $this->peerSelectMethod = $method;
215        }
216
217        /**
218         * Return the Peer select method.
219         * @return     string
220         */
221        public function getPeerSelectMethod()
222        {
223                return $this->peerSelectMethod;
224        }
225
226        /**
227         * Sets the Count method.
228         * This is set based on the Peer method, for example if Peer method is doSelectJoin*() then the
229         * count method will be doCountJoin*().
230         * @param      string $method The name of the static method to call on the Peer class.
231         */
232        public function setPeerCountMethod($method)
233        {
234                $this->peerCountMethod = $method;
235        }
236
237        /**
238         * Return the Peer count method.
239         */
240        public function getPeerCountMethod()
241        {
242                return $this->peerCountMethod;
243        }
244
245        /**
246         * Guesses the Peer count method based on the select method.
247         */
248        private function guessPeerCountMethod()
249        {
250                $selectMethod = $this->getPeerSelectMethod();
251                if ($selectMethod == 'doSelect') {
252                        $countMethod = 'doCount';
253                } elseif ( ($pos = stripos($selectMethod, 'doSelectJoin')) === 0) {
254                        $countMethod = 'doCount' . substr($selectMethod, strlen('doSelect'));
255                } else {
256                        // we will fall back to doCount() if we don't understand the join
257                        // method; however, it probably won't be accurate.  Maybe triggering an error would
258                        // be appropriate ...
259                        $countMethod = 'doCount';
260                }
261                $this->setPeerCountMethod($countMethod);
262        }
263
264        /**
265         * Get the paged resultset
266         *
267         * @return     mixed $rs
268         */
269        public function getResult()
270        {
271                if (!isset($this->rs)) {
272                        $this->doRs();
273                }
274
275                return $this->rs;
276        }
277
278        /**
279         * Get the paged resultset
280         *
281         * Main method which creates a paged result set based on the criteria
282         * and the requested peer select method.
283         *
284         */
285        private function doRs()
286        {
287                $this->rs = array();
288                $this->criteria->setOffset($this->start);
289                $this->criteria->setLimit($this->max);
290                $start = $this->start;
291                $total = $this->getTotalRecordCount();
292                $order = $this->criteria->getOrderByColumns();
293                if ($start < 0 || $start >= $total) return;
294                if (count($order)==1 && $total > 240 && $start > $total/2) {
295                  $c = clone $this->criteria;
296                  $start = $total - $start - $this->max;
297                  if ($start >= 0) $c->setOffset($start);
298                  else {
299                    $c->setOffset(0);
300                    $c->setLimit($start + $this->max);
301                  }
302                  $c->clearOrderByColumns();
303                  $params = explode(" ", $order[0]);
304                  if ($params[1] == Criteria::DESC) $c->addAscendingOrderByColumn($params[0]);
305                  else $c->addDescendingOrderByColumn($params[0]);
306                  $rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $c);
307                  while (!empty($rs)) array_push($this->rs, array_pop($rs));
308                }
309                else
310                $this->rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $this->criteria);
311        }
312
313        /**
314         * Get the first page
315         *
316         * For now I can only think of returning 1 always.
317         * It should probably return 0 if there are no pages
318         *
319         * @return     int 1
320         */
321        public function getFirstPage()
322        {
323                return '1';
324        }
325
326        /**
327         * Convenience method to indicate whether current page is the first page.
328         *
329         * @return     boolean
330         */
331        public function atFirstPage()
332        {
333                return $this->getPage() == $this->getFirstPage();
334        }
335
336        /**
337         * Get last page
338         *
339         * @return     int $lastPage
340         */
341        public function getLastPage()
342        {
343                $totalPages = $this->getTotalPages();
344                if ($totalPages == 0) {
345                        return 1;
346                } else {
347                        return $totalPages;
348                }
349        }
350
351        /**
352         * Convenience method to indicate whether current page is the last page.
353         *
354         * @return     boolean
355         */
356        public function atLastPage()
357        {
358                return $this->getPage() == $this->getLastPage();
359        }
360
361        /**
362         * get total pages
363         *
364         * @return     int $this->pages
365         */
366        public function getTotalPages() {
367                if (!isset($this->pages)) {
368                        $recordCount = $this->getTotalRecordCount();
369                        if ($this->max > 0) {
370                                        $this->pages = ceil($recordCount/$this->max);
371                        } else {
372                                        $this->pages = 0;
373                        }
374                }
375                return $this->pages;
376        }
377
378        /**
379         * get an array of previous id's
380         *
381         * @param      int $range
382         * @return     array $links
383         */
384        public function getPrevLinks($range = 5)
385        {
386                $total = $this->getTotalPages();
387                $start = $this->getPage() - 1;
388                $end = $this->getPage() - $range;
389                $first =  $this->getFirstPage();
390                $links = array();
391                for ($i=$start; $i>$end; $i--) {
392                        if ($i < $first) {
393                                        break;
394                        }
395                        $links[] = $i;
396                }
397
398                return array_reverse($links);
399        }
400
401        /**
402         * get an array of next id's
403         *
404         * @param      int $range
405         * @return     array $links
406         */
407        public function getNextLinks($range = 5)
408        {
409                $total = $this->getTotalPages();
410                $start = $this->getPage() + 1;
411                $end = $this->getPage() + $range;
412                $last =  $this->getLastPage();
413                $links = array();
414                for ($i=$start; $i<$end; $i++) {
415                        if ($i > $last) {
416                                        break;
417                        }
418                        $links[] = $i;
419                }
420
421                return $links;
422        }
423
424        /**
425         * Returns whether last page is complete
426         *
427         * @return     bool Last page complete or not
428         */
429        public function isLastPageComplete()
430        {
431                return !($this->getTotalRecordCount() % $this->max);
432        }
433
434        /**
435         * get previous id
436         *
437         * @return     mixed $prev
438         */
439        public function getPrev() {
440                if ($this->getPage() != $this->getFirstPage()) {
441                                $prev = $this->getPage() - 1;
442                } else {
443                                $prev = false;
444                }
445                return $prev;
446        }
447
448        /**
449         * get next id
450         *
451         * @return     mixed $next
452         */
453        public function getNext() {
454                if ($this->getPage() != $this->getLastPage()) {
455                                $next = $this->getPage() + 1;
456                } else {
457                                $next = false;
458                }
459                return $next;
460        }
461
462        /**
463         * Set the current page number (First page is 1).
464         * @param      int $page
465         * @return     void
466         */
467        public function setPage($page)
468        {
469                $this->page = $page;
470                // (re-)calculate start rec
471                $this->calculateStart();
472        }
473
474        /**
475         * Get current page.
476         * @return     int
477         */
478        public function getPage()
479        {
480                return $this->page;
481        }
482
483        /**
484         * Set the number of rows per page.
485         * @param      int $r
486         */
487        public function setRowsPerPage($r)
488        {
489                $this->max = $r;
490                // (re-)calculate start rec
491                $this->calculateStart();
492        }
493
494        /**
495         * Get number of rows per page.
496         * @return     int
497         */
498        public function getRowsPerPage()
499        {
500                return $this->max;
501        }
502
503        /**
504         * Calculate startrow / max rows based on current page and rows-per-page.
505         * @return     void
506         */
507        private function calculateStart()
508        {
509                $this->start = ( ($this->page - 1) * $this->max );
510        }
511
512        /**
513         * Gets the total number of (un-LIMITed) records.
514         *
515         * This method will perform a query that executes un-LIMITed query.
516         *
517         * @return     int Total number of records - disregarding page, maxrows, etc.
518         */
519        public function getTotalRecordCount()
520        {
521                                if (empty($this->recordCount)) {
522                                                $this->countCriteria = clone $this->criteria;
523                                                $this->countCriteria->setLimit(0);
524                                                $this->countCriteria->setOffset(0);
525
526                                                $this->recordCount = call_user_func(
527                                                                        array(
528                                                                                $this->getPeerClass(),
529                                                                                                $this->getPeerCountMethod()
530                                                                             ),
531                                                                        $this->countCriteria
532                                                                        );
533
534                                }
535
536                                return $this->recordCount;
537
538        }
539
540        /**
541         * Sets the start row or offset.
542         * @param      int $v
543         */
544        public function setStart($v)
545        {
546                $this->start = $v;
547        }
548
549        /**
550         * Sets max rows (limit).
551         * @param      int $v
552         * @return     void
553         */
554        public function setMax($v)
555        {
556                $this->max = $v;
557        }
558
559}
Note: See TracBrowser for help on using the repository browser.