1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: * @package Nette\Utils
11: */
12:
13:
14:
15: /**
16: * Paginating math.
17: *
18: * @author David Grudl
19: *
20: * @property int $page
21: * @property-read int $firstPage
22: * @property-read int|NULL $lastPage
23: * @property int $base
24: * @property-read bool $first
25: * @property-read bool $last
26: * @property-read int|NULL $pageCount
27: * @property int $itemsPerPage
28: * @property int|NULL $itemCount
29: * @property-read int $offset
30: * @property-read int|NULL $countdownOffset
31: * @property-read int|NULL $length
32: * @package Nette\Utils
33: */
34: class Paginator extends Object
35: {
36: /** @var int */
37: private $base = 1;
38:
39: /** @var int */
40: private $itemsPerPage = 1;
41:
42: /** @var int */
43: private $page;
44:
45: /** @var int|NULL */
46: private $itemCount;
47:
48:
49:
50: /**
51: * Sets current page number.
52: * @param int
53: * @return Paginator provides a fluent interface
54: */
55: public function setPage($page)
56: {
57: $this->page = (int) $page;
58: return $this;
59: }
60:
61:
62:
63: /**
64: * Returns current page number.
65: * @return int
66: */
67: public function getPage()
68: {
69: return $this->base + $this->getPageIndex();
70: }
71:
72:
73:
74: /**
75: * Returns first page number.
76: * @return int
77: */
78: public function getFirstPage()
79: {
80: return $this->base;
81: }
82:
83:
84:
85: /**
86: * Returns last page number.
87: * @return int|NULL
88: */
89: public function getLastPage()
90: {
91: return $this->itemCount === NULL ? NULL : $this->base + max(0, $this->getPageCount() - 1);
92: }
93:
94:
95:
96: /**
97: * Sets first page (base) number.
98: * @param int
99: * @return Paginator provides a fluent interface
100: */
101: public function setBase($base)
102: {
103: $this->base = (int) $base;
104: return $this;
105: }
106:
107:
108:
109: /**
110: * Returns first page (base) number.
111: * @return int
112: */
113: public function getBase()
114: {
115: return $this->base;
116: }
117:
118:
119:
120: /**
121: * Returns zero-based page number.
122: * @return int
123: */
124: protected function getPageIndex()
125: {
126: $index = max(0, $this->page - $this->base);
127: return $this->itemCount === NULL ? $index : min($index, max(0, $this->getPageCount() - 1));
128: }
129:
130:
131:
132: /**
133: * Is the current page the first one?
134: * @return bool
135: */
136: public function isFirst()
137: {
138: return $this->getPageIndex() === 0;
139: }
140:
141:
142:
143: /**
144: * Is the current page the last one?
145: * @return bool
146: */
147: public function isLast()
148: {
149: return $this->itemCount === NULL ? FALSE : $this->getPageIndex() >= $this->getPageCount() - 1;
150: }
151:
152:
153:
154: /**
155: * Returns the total number of pages.
156: * @return int|NULL
157: */
158: public function getPageCount()
159: {
160: return $this->itemCount === NULL ? NULL : (int) ceil($this->itemCount / $this->itemsPerPage);
161: }
162:
163:
164:
165: /**
166: * Sets the number of items to display on a single page.
167: * @param int
168: * @return Paginator provides a fluent interface
169: */
170: public function setItemsPerPage($itemsPerPage)
171: {
172: $this->itemsPerPage = max(1, (int) $itemsPerPage);
173: return $this;
174: }
175:
176:
177:
178: /**
179: * Returns the number of items to display on a single page.
180: * @return int
181: */
182: public function getItemsPerPage()
183: {
184: return $this->itemsPerPage;
185: }
186:
187:
188:
189: /**
190: * Sets the total number of items.
191: * @param int (or NULL as infinity)
192: * @return Paginator provides a fluent interface
193: */
194: public function setItemCount($itemCount)
195: {
196: $this->itemCount = ($itemCount === FALSE || $itemCount === NULL) ? NULL : max(0, (int) $itemCount);
197: return $this;
198: }
199:
200:
201:
202: /**
203: * Returns the total number of items.
204: * @return int|NULL
205: */
206: public function getItemCount()
207: {
208: return $this->itemCount;
209: }
210:
211:
212:
213: /**
214: * Returns the absolute index of the first item on current page.
215: * @return int
216: */
217: public function getOffset()
218: {
219: return $this->getPageIndex() * $this->itemsPerPage;
220: }
221:
222:
223:
224: /**
225: * Returns the absolute index of the first item on current page in countdown paging.
226: * @return int|NULL
227: */
228: public function getCountdownOffset()
229: {
230: return $this->itemCount === NULL
231: ? NULL
232: : max(0, $this->itemCount - ($this->getPageIndex() + 1) * $this->itemsPerPage);
233: }
234:
235:
236:
237: /**
238: * Returns the number of items on current page.
239: * @return int|NULL
240: */
241: public function getLength()
242: {
243: return $this->itemCount === NULL
244: ? $this->itemsPerPage
245: : min($this->itemsPerPage, $this->itemCount - $this->getPageIndex() * $this->itemsPerPage);
246: }
247:
248: }
249: