Merging changes from the 2.1.x branch back to trunk (r860-862)
[isso.git] / Pagination.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Blue Static ISSO Framework
5 || # Copyright ©2002-[#]year[#] 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 [#]gpl[#] 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 ©2002 - [#]year[#], Blue Static
38 * @version $Revision$
39 * @package ISSO
40 *
41 */
42 class BSPagination
43 {
44 /**
45 * Current page number
46 * @var integer
47 */
48 private $page;
49
50 /**
51 * Per-page value
52 * @var integer
53 */
54 private $perpage;
55
56 /**
57 * Number of page links
58 * @var integer
59 */
60 private $pagelinks;
61
62 /**
63 * Total number of results
64 * @var integer
65 */
66 private $total;
67
68 /**
69 * Total number of pages
70 * @var integer
71 */
72 private $pagecount;
73
74 /**
75 * Name of page variable
76 * @var array
77 */
78 private $pagevar = 'p';
79
80 /**
81 * Name of per-page variable
82 * @var integer
83 */
84 private $perpagevar = 'pp';
85
86 /**
87 * Maximum number of per-page results
88 * @var integer
89 */
90 private $maxperpage = 100;
91
92 /**
93 * Default number of per-page results
94 * @var integer
95 */
96 private $defaultperpage = 20;
97
98 /**
99 * The processing callback public function for individual pagenav bits
100 * @var string
101 */
102 private $bitprocessor = ':undefined:';
103
104 /**
105 * The processing callback public function for the entire pagenav system
106 * @var string
107 */
108 private $pagenavprocessor = ':undefined:';
109
110 // ###################################################################
111 /**
112 * Callback public function for the processing of an indivdual page. Needs
113 * the signature:
114 * public string callback(string $baseLink, boolean $noLink, integer $pageNumber, Pagination $this)
115 *
116 * @param string Callback function
117 */
118 public function setBitProcessor($callback)
119 {
120 $this->bitprocessor = $callback;
121 }
122
123 // ###################################################################
124 /**
125 * Callback public function for the processing the entire page navigator. Needs
126 * the signature:
127 * public string callback(string $baseLink, integer $nextPage, integer $prevPage array $show['first'=>first page, 'last'=>last page, 'prev'=>previous page, 'next'=>next page], string $bits, Pagination $this)
128 *
129 * @param string Callback function
130 */
131 public function setNavigatorProcessor($callback)
132 {
133 $this->pagenavprocessor = $callback;
134 }
135
136 // ###################################################################
137 /**
138 * Returns the current page number
139 *
140 * @return integer Current page
141 */
142 public function getPage()
143 {
144 return $this->page;
145 }
146
147 // ###################################################################
148 /**
149 * Returns the current perpage value
150 *
151 * @return integer Current perpage
152 */
153 public function getPerPage()
154 {
155 return $this->perpage;
156 }
157
158 // ###################################################################
159 /**
160 * Sets total
161 *
162 * @param integer Total number
163 */
164 public function setTotal($total)
165 {
166 $this->total = $total;
167 }
168
169 // ###################################################################
170 /**
171 * Returns the number of pages to be in the navigator
172 *
173 * @param integer Number of pages
174 */
175 public function getPageCount()
176 {
177 return $this->pagecount;
178 }
179
180 // ###################################################################
181 /**
182 * Sets pagelinks
183 *
184 * @param integer Number of page links
185 */
186 public function setPageLinks($pagelinks)
187 {
188 $this->pagelinks = $pagelinks;
189 }
190
191 // ###################################################################
192 /**
193 * Sets pagevar
194 *
195 * @param string Page variable
196 */
197 public function setPageVar($pagevar)
198 {
199 $this->pagevar = $pagevar;
200 }
201
202 // ###################################################################
203 /**
204 * Sets perpagevar
205 *
206 * @param string Per-page variable
207 */
208 public function setPerPageVar($perpagevar)
209 {
210 $this->perpagevar = $perpagevar;
211 }
212
213 // ###################################################################
214 /**
215 * Sets maxperpage
216 *
217 * @param integer Maximum number per page
218 */
219 public function setMaxPerPage($maxperpage)
220 {
221 $this->maxperpage = $maxperpage;
222 }
223
224 // ###################################################################
225 /**
226 * Sets defaultperpage
227 *
228 * @param integer Total number
229 */
230 public function setDefaultPerPage($defaultperpage)
231 {
232 $this->defaultperpage = $defaultperpage;
233 }
234
235 // ###################################################################
236 /**
237 * Takes all of the information from the set() functions and then
238 * prepares all of the data through verification
239 */
240 public function processIncomingData()
241 {
242 $input = BSRegister::GetType('Input');
243 if ($input == null)
244 {
245 BSRegister::Debug('ISSO/Input not loaded, so manually doing so');
246 $input = BSRegister::LoadModule('Input');
247 }
248
249 $this->page = $input->inputClean($this->pagevar, TYPE_INT);
250 $this->perpage = $input->inputClean($this->perpagevar, TYPE_INT);
251 $this->pagelinks = $input->clean($this->pagelinks, TYPE_INT);
252
253 if ($this->page <= 0)
254 {
255 $this->page = 1;
256 }
257
258 if ($this->perpage <= 0)
259 {
260 $this->perpage = $this->defaultperpage;
261 }
262 if ($this->perpage > $this->maxperpage)
263 {
264 $this->perpage = $this->maxperpage;
265 }
266
267 $this->perpage = $input->clean($this->perpage, TYPE_INT);
268 }
269
270 // ###################################################################
271 /**
272 * Takes the variables and splits up the pages
273 */
274 public function splitPages()
275 {
276 $this->pagecount = ceil($this->total / $this->perpage);
277 if ($this->pagelinks == 0)
278 {
279 $this->pagelinks = $this->pagecount;
280 }
281 }
282
283 // ###################################################################
284 /**
285 * Returns the lower limit of the pages
286 *
287 * @param integer Page number
288 *
289 * @return integer Lower result limit
290 */
291 public function fetchLimit($page = null)
292 {
293 if ($page === null)
294 {
295 $page = $this->page;
296 }
297
298 $limit = $page * $this->perpage;
299
300 if ($page < 1)
301 {
302 $page = 1;
303 $limit = 0;
304 }
305 else if ($page > $this->pagecount)
306 {
307 $page = $this->pagecount - 1;
308 $limit = $this->total;
309 }
310
311 if ($limit < 0)
312 {
313 return 0;
314 }
315 else if ($limit > $this->total)
316 {
317 return $this->total;
318 }
319 else
320 {
321 return $limit;
322 }
323 }
324
325 // ###################################################################
326 /**
327 * Constructs the page navigator
328 *
329 * @param string Base link path
330 * @param bool Add a ? or a & to the path so it's link-friendly
331 *
332 * @return string Generated HTML page navigator
333 */
334 public function constructPageNav($baselink, $addParam = true)
335 {
336 global $bugsys;
337
338 // handle base link
339 if ($addParam)
340 {
341 if (strpos($baselink, '?') === false)
342 {
343 $baselink .= '?';
344 }
345 else if (!preg_match('#\?$#', $baselink) AND !preg_match('#(&|&amp;)$#', $baselink))
346 {
347 $baselink .= '&amp;';
348 }
349 }
350
351 // first page number in page nav
352 $startpage = $this->page - $this->pagelinks;
353 if ($startpage < 1)
354 {
355 $startpage = 1;
356 }
357
358 // last page number in page nav
359 $endpage = $this->page + $this->pagelinks;
360 if ($endpage > $this->pagecount)
361 {
362 $endpage = $this->pagecount;
363 }
364
365 // prev page in page nav
366 $prevpage = $this->page - 1;
367 if ($prevpage < 1)
368 {
369 $prevpage = 1;
370 }
371
372 // next page in page nav
373 $nextpage = $this->page + 1;
374 if ($nextpage > $this->pagecount)
375 {
376 $nextpage = $this->pagecount;
377 }
378
379 // show the prev page
380 $show['prev'] = true;
381 if ($this->page == $startpage)
382 {
383 $show['prev'] = false;
384 }
385
386 // show the next page
387 $show['next'] = true;
388 if ($this->page == $endpage)
389 {
390 $show['next'] = false;
391 }
392
393 // show the first page
394 $show['first'] = false;
395 if ($startpage > 1)
396 {
397 $show['first'] = true;
398 }
399
400 // show the last page
401 $show['last'] = false;
402 if ($endpage < $this->pagecount)
403 {
404 $show['last'] = true;
405 }
406
407 // construct the page bits
408 $bits = '';
409 $call = $this->bitprocessor;
410 for ($i = $startpage; $i <= $endpage; $i++)
411 {
412 if ($i == $this->page)
413 {
414 $nolink = true;
415 }
416 else
417 {
418 $nolink = false;
419 }
420
421 $bits .= $call($baselink, $nolink, $i, $this);
422 }
423
424 $call = $this->pagenavprocessor;
425 return $call($baselink, $nextpage, $prevpage, $show, $bits, $this);
426 }
427 }
428
429 /*=====================================================================*\
430 || ###################################################################
431 || # $HeadURL$
432 || # $Id$
433 || ###################################################################
434 \*=====================================================================*/
435 ?>