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