Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfPager.class.php 27747 2010-02-08 18:02:19Z Kris.Wallsmith $
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
}