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