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