Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id$
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, see
19
 * <http://www.doctrine-project.org>.
20
 */
21
 
22
/**
23
 * Doctrine_Pager
24
 *
25
 * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
26
 * @package     Doctrine
27
 * @subpackage  Pager
28
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
29
 * @version     $Revision$
30
 * @link        www.doctrine-project.org
31
 * @since       0.9
32
 */
33
class Doctrine_Pager
34
{
35
    /**
36
     * @var Doctrine_Query $_query      Doctrine_Query object related to the pager
37
     */
38
    protected $_query;
39
 
40
    /**
41
     * @var Doctrine_Query $_countQuery Doctrine_Query object related to the counter of pager
42
     */
43
    protected $_countQuery;
44
 
45
    /**
46
     * @var array $_countQueryParams    Hold the params to be used by Doctrine_Query counter object of pager
47
     */
48
    protected $_countQueryParams;
49
 
50
    /**
51
     * @var integer $_numResults        Number of results found
52
     */
53
    protected $_numResults;
54
 
55
    /**
56
     * @var integer $_maxPerPage        Maximum number of itens per page
57
     */
58
    protected $_maxPerPage;
59
 
60
    /**
61
     * @var integer $page               Current page
62
     */
63
    protected $_page;
64
 
65
    /**
66
     * @var integer $_lastPage          Last page (total of pages)
67
     */
68
    protected $_lastPage;
69
 
70
    /**
71
     * @var boolean $_executed          Pager was initialized (called "execute" at least once)
72
     */
73
    protected $_executed;
74
 
75
 
76
 
77
    /**
78
     * __construct
79
     *
80
     * @param mixed $query     Accepts either a Doctrine_Query object or a string
81
     *                        (which does the Doctrine_Query class creation).
82
     * @param int $page     Current page
83
     * @param int $maxPerPage     Maximum itens per page
84
     * @return void
85
     */
86
    public function __construct($query, $page, $maxPerPage = 0)
87
    {
88
        $this->_setExecuted(false);
89
 
90
        $this->_setQuery($query);
91
        $this->_setPage($page);
92
 
93
        $this->setMaxPerPage($maxPerPage);
94
    }
95
 
96
    /**
97
     * _initialize
98
     *
99
     * Initialize Pager object calculating number of results
100
     *
101
     * @param $params  Optional parameters to Doctrine_Query::execute
102
     * @return void
103
     */
104
    protected function _initialize($params = array())
105
    {
106
        // retrieve the number of items found
107
        $countQuery = $this->getCountQuery();
108
        $count = $countQuery->count($this->getCountQueryParams($params));
109
 
110
        $this->_setNumResults($count);
111
        $this->_setExecuted(true); // _adjustOffset relies of _executed equals true = getNumResults()
112
 
113
        $this->_adjustOffset();
114
    }
115
 
116
    /**
117
     * _adjustOffset
118
     *
119
     * Adjusts last page of Doctrine_Pager, offset and limit of Doctrine_Query associated
120
     *
121
     * @return void
122
     */
123
    protected function _adjustOffset()
124
    {
125
        // Define new total of pages
126
        $this->_setLastPage(
127
            max(1, ceil($this->getNumResults() / $this->getMaxPerPage()))
128
        );
129
        $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
130
 
131
        // Assign new offset and limit to Doctrine_Query object
132
        $p = $this->getQuery();
133
        $p->offset($offset);
134
        $p->limit($this->getMaxPerPage());
135
    }
136
 
137
    /**
138
     * getExecuted
139
     *
140
     * Returns the check if Pager was already executed at least once
141
     *
142
     * @return boolen        Pager was executed
143
     */
144
    public function getExecuted()
145
    {
146
        return $this->_executed;
147
    }
148
 
149
    /**
150
     * _setExecuted
151
     *
152
     * Defines if Pager was already executed
153
     *
154
     * @param $executed       Pager was executed
155
     * @return void
156
     */
157
    protected function _setExecuted($executed)
158
    {
159
        $this->_executed = $executed;
160
    }
161
 
162
    /**
163
     * getRange
164
     *
165
     * Builds and return a Doctrine_Pager_Range_* based on arguments
166
     *
167
     * @param string $rangeStyle Pager Range style
168
     * @param array $options     Custom subclass implementation options.
169
     *                           Default is a blank array
170
     * @return Doctrine_Pager_Range Pager Range
171
     */
172
    public function getRange($rangeStyle, $options = array())
173
    {
174
        $class = 'Doctrine_Pager_Range_' . ucfirst($rangeStyle);
175
 
176
        return new $class($options, $this);
177
    }
178
 
179
    /**
180
     * getNumResults
181
     *
182
     * Returns the number of results found
183
     *
184
     * @return int        the number of results found
185
     */
186
    public function getNumResults()
187
    {
188
        if ($this->getExecuted()) {
189
            return $this->_numResults;
190
        }
191
 
192
        throw new Doctrine_Pager_Exception(
193
            'Cannot retrieve the number of results of a not yet executed Pager query'
194
        );
195
    }
196
 
197
    /**
198
     * _setNumResults
199
     *
200
     * Defines the number of total results on initial query
201
     *
202
     * @param $nb       Number of results found on initial query fetch
203
     * @return void
204
     */
205
    protected function _setNumResults($nb)
206
    {
207
        $this->_numResults = $nb;
208
    }
209
 
210
    /**
211
     * getFirstPage
212
     *
213
     * Returns the first page
214
     *
215
     * @return int        first page
216
     */
217
    public function getFirstPage()
218
    {
219
        return 1;
220
    }
221
 
222
    /**
223
     * getLastPage
224
     *
225
     * Returns the last page (total of pages)
226
     *
227
     * @return int        last page (total of pages)
228
     */
229
    public function getLastPage()
230
    {
231
        if ($this->getExecuted()) {
232
            return $this->_lastPage;
233
        }
234
 
235
        throw new Doctrine_Pager_Exception(
236
            'Cannot retrieve the last page number of a not yet executed Pager query'
237
        );
238
    }
239
 
240
    /**
241
     * _setLastPage
242
     *
243
     * Defines the last page (total of pages)
244
     *
245
     * @param $page       last page (total of pages)
246
     * @return void
247
     */
248
    protected function _setLastPage($page)
249
    {
250
        $this->_lastPage = $page;
251
 
252
        if ($this->getPage() > $page) {
253
            $this->_setPage($page);
254
        }
255
    }
256
 
257
    /**
258
     * getLastPage
259
     *
260
     * Returns the current page
261
     *
262
     * @return int        current page
263
     */
264
    public function getPage()
265
    {
266
        return $this->_page;
267
    }
268
 
269
    /**
270
     * getNextPage
271
     *
272
     * Returns the next page
273
     *
274
     * @return int        next page
275
     */
276
    public function getNextPage()
277
    {
278
        if ($this->getExecuted()) {
279
            return min($this->getPage() + 1, $this->getLastPage());
280
        }
281
 
282
        throw new Doctrine_Pager_Exception(
283
            'Cannot retrieve the last page number of a not yet executed Pager query'
284
        );
285
    }
286
 
287
    /**
288
     * getPreviousPage
289
     *
290
     * Returns the previous page
291
     *
292
     * @return int        previous page
293
     */
294
    public function getPreviousPage()
295
    {
296
        if ($this->getExecuted()) {
297
            return max($this->getPage() - 1, $this->getFirstPage());
298
        }
299
 
300
        throw new Doctrine_Pager_Exception(
301
            'Cannot retrieve the previous page number of a not yet executed Pager query'
302
        );
303
    }
304
 
305
    /**
306
     * getFirstIndice
307
     *
308
     * Return the first indice number for the current page
309
     *
310
     * @return int First indice number
311
     */
312
    public function getFirstIndice()
313
    {
314
        return ($this->getPage() - 1) * $this->getMaxPerPage() + 1;
315
    }
316
 
317
    /**
318
     * getLastIndice
319
     *
320
     * Return the last indice number for the current page
321
     *
322
     * @return int Last indice number
323
     */
324
    public function getLastIndice()
325
    {
326
        return min($this->getNumResults(), ($this->getPage() * $this->getMaxPerPage()));
327
    }
328
 
329
    /**
330
     * haveToPaginate
331
     *
332
     * Return true if it's necessary to paginate or false if not
333
     *
334
     * @return bool        true if it is necessary to paginate, false otherwise
335
     */
336
    public function haveToPaginate()
337
    {
338
        if ($this->getExecuted()) {
339
            return $this->getNumResults() > $this->getMaxPerPage();
340
        }
341
 
342
        throw new Doctrine_Pager_Exception(
343
            'Cannot know if it is necessary to paginate a not yet executed Pager query'
344
        );
345
    }
346
 
347
    /**
348
     * setPage
349
     *
350
     * Defines the current page and automatically adjust offset and limits
351
     *
352
     * @param $page       current page
353
     * @return void
354
     */
355
    public function setPage($page)
356
    {
357
        $this->_setPage($page);
358
        $this->_setExecuted(false);
359
    }
360
 
361
    /**
362
     * _setPage
363
     *
364
     * Defines the current page
365
     *
366
     * @param $page       current page
367
     * @return void
368
     */
369
    protected function _setPage($page)
370
    {
371
        $page = intval($page);
372
        $this->_page = ($page <= 0) ? 1 : $page;
373
    }
374
 
375
    /**
376
     * getLastPage
377
     *
378
     * Returns the maximum number of itens per page
379
     *
380
     * @return int        maximum number of itens per page
381
     */
382
    public function getMaxPerPage()
383
    {
384
        return $this->_maxPerPage;
385
    }
386
 
387
    /**
388
     * setMaxPerPage
389
     *
390
     * Defines the maximum number of itens per page and automatically adjust offset and limits
391
     *
392
     * @param $max       maximum number of itens per page
393
     * @return void
394
     */
395
    public function setMaxPerPage($max)
396
    {
397
        if ($max > 0) {
398
            $this->_maxPerPage = $max;
399
        } else if ($max == 0) {
400
            $this->_maxPerPage = 25;
401
        } else {
402
            $this->_maxPerPage = abs($max);
403
        }
404
 
405
        $this->_setExecuted(false);
406
    }
407
 
408
    /**
409
     * getResultsInPage
410
     *
411
     * Returns the number of itens in current page
412
     *
413
     * @return int    Number of itens in current page
414
     */
415
    public function getResultsInPage()
416
    {
417
        $page = $this->getPage();
418
 
419
        if ($page != $this->getLastPage()) {
420
            return $this->getMaxPerPage();
421
        }
422
 
423
        $offset = ($this->getPage() - 1) * $this->getMaxPerPage();
424
 
425
        return abs($this->getNumResults() - $offset);
426
    }
427
 
428
    /**
429
     * getQuery
430
     *
431
     * Returns the Doctrine_Query collector object related to the pager
432
     *
433
     * @return Doctrine_Query    Doctrine_Query object related to the pager
434
     */
435
    public function getQuery()
436
    {
437
        return $this->_query;
438
    }
439
 
440
    /**
441
     * _setQuery
442
     *
443
     * Defines the collector query to be used by pager
444
     *
445
     * @param Doctrine_Query     Accepts either a Doctrine_Query object or a string
446
     *                           (which does the Doctrine_Query class creation).
447
     * @return void
448
     */
449
    protected function _setQuery($query)
450
    {
451
        if (is_string($query)) {
452
            $query = Doctrine_Query::create()
453
                ->parseDqlQuery($query);
454
        }
455
 
456
        $this->_query = $query;
457
    }
458
 
459
    /**
460
     * getCountQuery
461
     *
462
     * Returns the Doctrine_Query object that is used to make the count results to pager
463
     *
464
     * @return Doctrine_Query     Doctrine_Query object related to the pager
465
     */
466
    public function getCountQuery()
467
    {
468
        return ($this->_countQuery !== null) ? $this->_countQuery : $this->_query;
469
    }
470
 
471
    /**
472
     * setCountQuery
473
     *
474
     * Defines the counter query to be used by pager
475
     *
476
     * @param Doctrine_Query  Accepts either a Doctrine_Query object or a string
477
     *                        (which does the Doctrine_Query class creation).
478
     * @param array           Optional params to be used by counter Doctrine_Query.
479
     *                        If not defined, the params passed to execute method will be used.
480
     * @return void
481
     */
482
    public function setCountQuery($query, $params = null)
483
    {
484
        if (is_string($query)) {
485
            $query = Doctrine_Query::create()
486
                ->parseDqlQuery($query);
487
        }
488
 
489
        $this->_countQuery = $query;
490
 
491
        $this->setCountQueryParams($params);
492
 
493
        $this->_setExecuted(false);
494
    }
495
 
496
    /**
497
     * getCountQueryParams
498
     *
499
     * Returns the params to be used by counter Doctrine_Query
500
     *
501
     * @return array     Doctrine_Query counter params
502
     */
503
    public function getCountQueryParams($defaultParams = array())
504
    {
505
        return ($this->_countQueryParams !== null) ? $this->_countQueryParams : $defaultParams;
506
    }
507
 
508
    /**
509
     * setCountQueryParams
510
     *
511
     * Defines the params to be used by counter Doctrine_Query
512
     *
513
     * @param array       Optional params to be used by counter Doctrine_Query.
514
     *                    If not defined, the params passed to execute method will be used.
515
     * @param boolean     Optional argument that append the query param instead of overriding the existent ones.
516
     * @return void
517
     */
518
    public function setCountQueryParams($params = array(), $append = false)
519
    {
520
        if ($append && is_array($this->_countQueryParams)) {
521
            $this->_countQueryParams = array_merge($this->_countQueryParams, $params);
522
        } else {
523
            if ($params !== null && !is_array($params)) {
524
                $params = array($params);
525
            }
526
 
527
            $this->_countQueryParams = $params;
528
        }
529
 
530
        $this->_setExecuted(false);
531
    }
532
 
533
    /**
534
     * execute
535
     *
536
     * Executes the query, populates the collection and then return it
537
     *
538
     * @param $params               Optional parameters to Doctrine_Query::execute
539
     * @param $hydrationMode        Hydration Mode of Doctrine_Query::execute returned ResultSet.
540
     * @return Doctrine_Collection  The root collection
541
     */
542
    public function execute($params = array(), $hydrationMode = null)
543
    {
544
        if ( !$this->getExecuted()) {
545
            $this->_initialize($params);
546
        }
547
 
548
        return $this->getQuery()->execute($params, $hydrationMode);
549
    }
550
}