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