Change BSApi::remove() to BSApi::delete()
[isso.git] / Pagination.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Blue Static ISSO Framework
5 || # Copyright (c)2005-2008 Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version 2 of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Pagination System (Pagination.php)
24 *
25 * @package ISSO
26 */
27
28 /**
29 * Pagination System
30 *
31 * On many pages, it is necessary to limit the amount of records to display.
32 * Using this class, you can set the maximum and minimum values to display,
33 * and then the input variables for page number and perpage. This will
34 * then create a page navigator and manage the SQL LIMIT statements.
35 *
36 * @author Blue Static
37 * @copyright Copyright (c)2005 - 2008, Blue Static
38 * @package ISSO
39 *
40 */
41 abstract class BSPagination
42 {
43 /**
44 * Current page number
45 * @var integer
46 */
47 public $page;
48
49 /**
50 * Per-page value
51 * @var integer
52 */
53 public $perpage;
54
55 /**
56 * Number of page links
57 * @var integer
58 */
59 protected $pagelinks;
60
61 /**
62 * Total number of results
63 * @var integer
64 */
65 protected $total;
66
67 /**
68 * Total number of pages
69 * @var integer
70 */
71 protected $pagecount;
72
73 /**
74 * Maximum number of per-page results
75 * @var integer
76 */
77 protected $maxperpage = 100;
78
79 /**
80 * Default number of per-page results
81 * @var integer
82 */
83 protected $defaultperpage = 20;
84
85 /**
86 * Callback public function for the processing of an indivdual page link
87 *
88 * @param string The base link
89 * @param boolean Wether or not the item is the current page
90 * @param integer Page number
91 *
92 * @return string Compiled HTML
93 */
94 protected abstract function _bitProcessor($baselink, $isCurrent, $pagenumber);
95
96 /**
97 * Callback public function for the processing the entire page navigator
98 *
99 * @param string The base link
100 * @param integer Next page number
101 * @param integer Previous page number
102 * @param array Show options: array('first' => (boolean)first page link, 'last' => boolean, 'prev' => boolean, 'next' => boolean)
103 * @param string Bits to process
104 *
105 * @return string Compiled HTML
106 */
107 protected abstract function _navigationProcessor($baselink, $next, $prev, $show, $bits);
108
109 /**
110 * Set the Pagination->perpage and Pagination->page variables
111 */
112 protected abstract function _setVariables();
113
114 /**
115 * Constructor
116 */
117 public function __construct()
118 {
119 if (!BSApp::$input instanceof BSInput)
120 {
121 throw new Exception('BSApp::$input is not an instance of BSInput');
122 }
123 }
124
125 /**
126 * Returns the current page number
127 *
128 * @return integer Current page
129 */
130 public function getPage()
131 {
132 return $this->page;
133 }
134
135 /**
136 * Returns the current perpage value
137 *
138 * @return integer Current perpage
139 */
140 public function getPerPage()
141 {
142 return $this->perpage;
143 }
144
145 /**
146 * Sets total
147 *
148 * @param integer Total number
149 */
150 public function setTotal($total)
151 {
152 $this->total = $total;
153 }
154
155 /**
156 * Returns the number of pages to be in the navigator
157 *
158 * @param integer Number of pages
159 */
160 public function getPageCount()
161 {
162 return $this->pagecount;
163 }
164
165 /**
166 * Takes all of the information from the set() functions and then
167 * prepares all of the data through verification
168 */
169 public function processIncomingData()
170 {
171 $this->_setVariables();
172 $this->page = BSApp::$input->clean($this->page, TYPE_INT);
173 $this->perpage = BSApp::$input->clean($this->perpage, TYPE_INT);
174 $this->pagelinks = BSApp::$input->clean($this->pagelinks, TYPE_INT);
175
176 if ($this->page <= 0)
177 {
178 $this->page = 1;
179 }
180
181 if ($this->perpage <= 0)
182 {
183 $this->perpage = $this->defaultperpage;
184 }
185 if ($this->perpage > $this->maxperpage)
186 {
187 $this->perpage = $this->maxperpage;
188 }
189
190 $this->perpage = BSApp::$input->clean($this->perpage, TYPE_INT);
191 }
192
193 /**
194 * Takes the variables and splits up the pages
195 */
196 public function splitPages()
197 {
198 $this->pagecount = ceil($this->total / $this->perpage);
199 if ($this->pagelinks == 0)
200 {
201 $this->pagelinks = $this->pagecount;
202 }
203 }
204
205 /**
206 * Returns the lower limit of the pages
207 *
208 * @param integer Page number
209 *
210 * @return integer Lower result limit
211 */
212 public function fetchLimit($page = null)
213 {
214 if ($page === null)
215 {
216 $page = $this->page;
217 }
218
219 $limit = $page * $this->perpage;
220
221 if ($page < 1)
222 {
223 $page = 1;
224 $limit = 0;
225 }
226 else if ($page > $this->pagecount)
227 {
228 $page = $this->pagecount - 1;
229 $limit = $this->total;
230 }
231
232 if ($limit < 0)
233 {
234 return 0;
235 }
236 else if ($limit > $this->total)
237 {
238 return $this->total;
239 }
240 else
241 {
242 return $limit;
243 }
244 }
245
246 /**
247 * Constructs the page navigator
248 *
249 * @param string Base link path
250 * @param bool Add a ? or a & to the path so it's link-friendly
251 *
252 * @return string Generated HTML page navigator
253 */
254 public function constructPageNav($baselink, $addParam = true)
255 {
256 // handle base link
257 if ($addParam)
258 {
259 if (strpos($baselink, '?') === false)
260 {
261 $baselink .= '?';
262 }
263 else if (!strpos($baselink, '#\?$#') && !strpos($baselink, '&'))
264 {
265 $baselink .= '&amp;';
266 }
267 }
268
269 // first page number in page nav
270 $startpage = $this->page - $this->pagelinks;
271 if ($startpage < 1)
272 {
273 $startpage = 1;
274 }
275
276 // last page number in page nav
277 $endpage = $this->page + $this->pagelinks;
278 if ($endpage > $this->pagecount)
279 {
280 $endpage = $this->pagecount;
281 }
282
283 // prev page in page nav
284 $prevpage = $this->page - 1;
285 if ($prevpage < 1)
286 {
287 $prevpage = 1;
288 }
289
290 // next page in page nav
291 $nextpage = $this->page + 1;
292 if ($nextpage > $this->pagecount)
293 {
294 $nextpage = $this->pagecount;
295 }
296
297 // show the prev page
298 $show['prev'] = true;
299 if ($this->page == $startpage)
300 {
301 $show['prev'] = false;
302 }
303
304 // show the next page
305 $show['next'] = true;
306 if ($this->page == $endpage)
307 {
308 $show['next'] = false;
309 }
310
311 // show the first page
312 $show['first'] = false;
313 if ($startpage > 1)
314 {
315 $show['first'] = true;
316 }
317
318 // show the last page
319 $show['last'] = false;
320 if ($endpage < $this->pagecount)
321 {
322 $show['last'] = true;
323 }
324
325 // construct the page bits
326 $bits = '';
327 for ($i = $startpage; $i <= $endpage; $i++)
328 {
329 if ($i == $this->page)
330 {
331 $nolink = true;
332 }
333 else
334 {
335 $nolink = false;
336 }
337
338 $bits .= $this->_bitProcessor($baselink, $nolink, $i);
339 }
340
341 return $this->_navigationProcessor($baselink, $nextpage, $prevpage, $show, $bits);
342 }
343 }
344
345 ?>