1: <?php
2: 3: 4: 5: 6: 7:
8:
9:
10: namespace Rundiz\Pagination;
11:
12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
34: class Pagination
35: {
36:
37:
38:
39:
40: 41: 42: 43: 44: 45: 46: 47:
48: public $base_url;
49:
50: 51: 52:
53: public $total_records;
54:
55: 56: 57:
58: public $items_per_page = 10;
59:
60: 61: 62: 63:
64: public $page_number_type = 'start_num';
65:
66: 67: 68:
69: public $page_number_value;
70:
71: 72: 73:
74: public $overall_tag_open = '';
75: 76: 77:
78: public $overall_tag_close = '';
79:
80: 81: 82:
83: public $first_page_text = '« First';
84: 85: 86:
87: public $first_page_always_show = false;
88: 89: 90:
91: public $first_tag_open = ' ';
92: 93: 94:
95: public $first_tag_close = ' ';
96:
97: 98: 99:
100: public $last_page_text = 'Last »';
101: 102: 103:
104: public $last_page_always_show = false;
105: 106: 107:
108: public $last_tag_open = ' ';
109: 110: 111:
112: public $last_tag_close = ' ';
113:
114: 115: 116:
117: public $next_page_text = 'Next ›';
118: 119: 120:
121: public $next_page_always_show = false;
122: 123: 124:
125: public $next_tag_open = ' ';
126: 127: 128:
129: public $next_tag_close = ' ';
130:
131: 132: 133:
134: public $previous_page_text = '‹ Previous';
135: 136: 137:
138: public $previous_page_always_show = false;
139: 140: 141:
142: public $previous_tag_open = ' ';
143: 144: 145:
146: public $previous_tag_close = ' ';
147:
148: 149: 150:
151: public $current_page_link = false;
152: 153: 154:
155: public $current_tag_open = ' <strong>';
156: 157: 158:
159: public $current_tag_close = '</strong> ';
160:
161: 162: 163:
164: public $number_display = true;
165: 166: 167:
168: public $number_tag_open = ' ';
169: 170: 171:
172: public $number_tag_close = ' ';
173: 174: 175:
176: public $number_adjacent_pages = 5;
177:
178: 179: 180:
181: public $unavailable_display = false;
182: 183: 184:
185: public $unavailable_text = '…';
186: 187: 188:
189: public $unavailable_tag_open = ' ';
190: 191: 192:
193: public $unavailable_tag_close = ' ';
194: 195: 196:
197: public $unavailable_before = 2;
198: 199: 200:
201: public $unavailable_after = 2;
202:
203:
204: 205: 206:
207: protected $temp_properties;
208:
209: 210: 211:
212: protected $total_pages;
213:
214:
215: public function __construct()
216: {
217: $class_properties = get_class_vars(__CLASS__);
218: $this->temp_properties = $class_properties;
219: unset($class_properties);
220: }
221:
222:
223: public function __destruct()
224: {
225: $this->clear();
226: }
227:
228:
229: 230: 231:
232: public function clear()
233: {
234: if (is_array($this->temp_properties)) {
235: foreach ($this->temp_properties as $key => $value) {
236: if (property_exists($this, $key)) {
237: $this->$key = $value;
238: }
239: }
240: unset($key, $value);
241:
242: $this->temp_properties = null;
243: }
244: }
245:
246:
247: 248: 249: 250: 251: 252:
253: public function createLinks($result_string = 'Displaying page :current_page_number_displaying of :total_pages<br>:pagination')
254: {
255: $pagination_data = $this->getPaginationData();
256:
257: if (!is_array($pagination_data)) {
258: return null;
259: }
260:
261: if ($result_string == null) {
262: $result_string = 'Displaying page :current_page_number_displaying of :total_pages<br>:pagination';
263: }
264:
265:
266: $pagination_rendered = "\n";
267: if (array_key_exists('overall_tag_open', $pagination_data)) {
268: $pagination_rendered .= $pagination_data['overall_tag_open'];
269: }
270: if (array_key_exists('generated_pages', $pagination_data) && is_array($pagination_data['generated_pages'])) {
271: foreach ($pagination_data['generated_pages'] as $page_key => $page_item) {
272: if (is_array($page_item)) {
273: if (array_key_exists('tag_open', $page_item)) {
274: $pagination_rendered .= $page_item['tag_open'];
275: }
276: if (array_key_exists('link', $page_item) && $page_item['link'] != null) {
277: $pagination_rendered .= '<a href="' . $page_item['link'] . '">';
278: }
279: if (array_key_exists('text', $page_item)) {
280: $pagination_rendered .= $page_item['text'];
281: }
282: if (array_key_exists('link', $page_item) && $page_item['link'] != null) {
283: $pagination_rendered .= '</a>';
284: }
285: if (array_key_exists('tag_close', $page_item)) {
286: $pagination_rendered .= $page_item['tag_close'];
287: }
288: }
289: }
290: unset($page_item, $page_key);
291: }
292: if (array_key_exists('overall_tag_close', $pagination_data)) {
293: $pagination_rendered .= $pagination_data['overall_tag_close'];
294: }
295: $pagination_rendered .= "\n";
296:
297:
298: $output = $result_string;
299: if (array_key_exists('total_pages', $pagination_data)) {
300: $output = str_replace(':total_pages', $pagination_data['total_pages'], $output);
301: }
302: if (array_key_exists('page_number_type', $pagination_data)) {
303: $output = str_replace(':page_number_type', $pagination_data['total_pages'], $output);
304: }
305: if (array_key_exists('current_page_number_displaying', $pagination_data)) {
306: $output = str_replace(':current_page_number_displaying', $pagination_data['current_page_number_displaying'], $output);
307: }
308: if (isset($pagination_rendered)) {
309: $output = str_replace(':pagination', $pagination_rendered, $output);
310: }
311:
312: unset($pagination_data, $pagination_rendered);
313: return $output;
314: }
315:
316:
317: 318: 319: 320: 321: 322: 323: 324:
325: private function generateUrl($page_value, $direction = '', $return_value_only = false)
326: {
327: switch ($direction) {
328: case 'first':
329: if ($this->page_number_type == 'start_num') {
330: $page_value = 0;
331: } elseif ($this->page_number_type == 'page_num') {
332: $page_value = 1;
333: }
334: break;
335: case 'previous':
336: if ($this->page_number_type == 'start_num') {
337: $page_value = ($page_value - $this->items_per_page);
338: if ($page_value < 0) {
339: $page_value = 0;
340: }
341: } elseif ($this->page_number_type == 'page_num') {
342: $page_value = ($page_value - 1);
343: if ($page_value <= 0) {
344: $page_value = 1;
345: }
346: }
347: break;
348: case 'next':
349: if ($this->page_number_type == 'start_num') {
350: $page_value = ($page_value + $this->items_per_page);
351: if ($page_value > (($this->total_pages*$this->items_per_page) - $this->items_per_page)) {
352: $page_value = (($this->total_pages*$this->items_per_page) - $this->items_per_page);
353: }
354: } elseif ($this->page_number_type == 'page_num') {
355: $page_value = ($page_value + 1);
356: if ($page_value > (($this->total_pages*$this->items_per_page) / $this->items_per_page)) {
357: $page_value = (($this->total_pages*$this->items_per_page) / $this->items_per_page);
358: }
359: }
360: break;
361: case 'last':
362: if ($this->page_number_type == 'start_num') {
363: $page_value = ($page_value - $this->items_per_page);
364: } elseif ($this->page_number_type == 'page_num') {
365: $page_value = ($page_value / $this->items_per_page);
366: }
367: break;
368: default:
369:
370: if ($this->page_number_type == 'start_num') {
371: $page_value = (($page_value * $this->items_per_page) - $this->items_per_page);
372: }
373: break;
374: }
375:
376: if ($return_value_only === true) {
377: return $page_value;
378: } else {
379: return str_replace('%PAGENUMBER%', $page_value, $this->base_url);
380: }
381: }
382:
383:
384: 385: 386: 387: 388: 389: 390:
391: public function getPaginationData()
392: {
393:
394: $this->validateCorrectProperties();
395:
396: $this->validateRequiredProperties();
397:
398:
399: $output = array();
400:
401: $this->total_pages = ceil($this->total_records/$this->items_per_page);
402: $output['total_pages'] = $this->total_pages;
403:
404: $output['page_number_type'] = $this->page_number_type;
405: $output['current_page_number_displaying'] = 1;
406:
407:
408: if ($this->page_number_type == 'start_num') {
409:
410: $output['current_page_number_displaying'] = ceil(($this->page_number_value/$this->items_per_page)+1);
411: } elseif ($this->page_number_type == 'page_num') {
412:
413: $output['current_page_number_displaying'] = $this->page_number_value;
414: }
415: if ($output['current_page_number_displaying'] > $this->total_pages) {
416: $output['current_page_number_displaying'] = $this->total_pages;
417: } elseif ($output['current_page_number_displaying'] < 1) {
418: $output['current_page_number_displaying'] = 1;
419: }
420:
421: $output['overall_tag_open'] = $this->overall_tag_open;
422:
423: $generated_pages = array();
424:
425:
426: $generated_pages['first_page'] = array();
427: $generated_pages['first_page']['tag_open'] = null;
428: $generated_pages['first_page']['link'] = null;
429: $generated_pages['first_page']['page_value'] = null;
430: $generated_pages['first_page']['text'] = null;
431: $generated_pages['first_page']['tag_close'] = null;
432: if ($this->first_page_text !== false) {
433: if ($this->first_page_always_show === true || ($this->first_page_always_show === false && !$this->isCurrentlyFirstPage())) {
434: $generated_pages['first_page']['tag_open'] = $this->first_tag_open;
435: $generated_pages['first_page']['link'] = $this->generateUrl($this->page_number_value, 'first');
436: $generated_pages['first_page']['page_value'] = $this->generateUrl($this->page_number_value, 'first', true);
437: $generated_pages['first_page']['text'] = $this->first_page_text;
438: $generated_pages['first_page']['tag_close'] = $this->first_tag_close;
439: }
440: }
441:
442:
443: $generated_pages['previous_page'] = array();
444: $generated_pages['previous_page']['tag_open'] = null;
445: $generated_pages['previous_page']['link'] = null;
446: $generated_pages['previous_page']['page_value'] = null;
447: $generated_pages['previous_page']['text'] = null;
448: $generated_pages['previous_page']['tag_close'] = null;
449: if ($this->previous_page_text !== false) {
450: if ($this->previous_page_always_show === true || ($this->previous_page_always_show === false && !$this->isCurrentlyFirstPage())) {
451: $generated_pages['previous_page']['tag_open'] = $this->previous_tag_open;
452: $generated_pages['previous_page']['link'] = $this->generateUrl($this->page_number_value, 'previous');
453: $generated_pages['previous_page']['page_value'] = $this->generateUrl($this->page_number_value, 'previous', true);
454: $generated_pages['previous_page']['text'] = $this->previous_page_text;
455: $generated_pages['previous_page']['tag_close'] = $this->previous_tag_close;
456: }
457: }
458:
459:
460: if ($this->number_display === true) {
461:
462: if ($this->unavailable_display === true && $this->unavailable_before !== false && ($output['current_page_number_displaying'] - $this->number_adjacent_pages) > 1) {
463: $number_adjacent_before_current = ($output['current_page_number_displaying'] - $this->number_adjacent_pages);
464: $number_before_unavailable = $this->unavailable_before;
465: if ($number_adjacent_before_current <= $number_before_unavailable) {
466: $number_before_unavailable = ($number_adjacent_before_current - 1);
467: }
468: for ($i = 1; $i <= $number_before_unavailable; $i++) {
469: $generated_pages[$i] = array();
470: $generated_pages[$i]['tag_open'] = $this->number_tag_open;
471: $generated_pages[$i]['link'] = $this->generateUrl($i);
472: $generated_pages[$i]['page_value'] = $this->generateUrl($i, '', true);
473: $generated_pages[$i]['text'] = $i;
474: $generated_pages[$i]['tag_close'] = $this->number_tag_close;
475: }
476: if ($number_adjacent_before_current > ($number_before_unavailable + 1)) {
477: $generated_pages['unavailable_before'] = array();
478: $generated_pages['unavailable_before']['tag_open'] = $this->unavailable_tag_open;
479: $generated_pages['unavailable_before']['link'] = null;
480: $generated_pages['unavailable_before']['page_value'] = null;
481: $generated_pages['unavailable_before']['text'] = $this->unavailable_text;
482: $generated_pages['unavailable_before']['tag_close'] = $this->unavailable_tag_close;
483: }
484: unset($i, $number_adjacent_before_current, $number_before_unavailable);
485: }
486:
487:
488: if ($this->number_adjacent_pages > 0) {
489: for ($i = ($output['current_page_number_displaying'] - $this->number_adjacent_pages); $i < $output['current_page_number_displaying']; $i++) {
490: if ($i > 0) {
491: $generated_pages[$i] = array();
492: $generated_pages[$i]['tag_open'] = $this->number_tag_open;
493: $generated_pages[$i]['link'] = $this->generateUrl($i);
494: $generated_pages[$i]['page_value'] = $this->generateUrl($i, '', true);
495: $generated_pages[$i]['text'] = $i;
496: $generated_pages[$i]['tag_close'] = $this->number_tag_close;
497: }
498: }
499: }
500:
501:
502: $generated_pages[$i] = array();
503: $generated_pages[$i]['tag_open'] = $this->current_tag_open;
504: $generated_pages[$i]['link'] = ($this->current_page_link === true ? $this->generateUrl($i) : null);
505: $generated_pages[$i]['page_value'] = $this->generateUrl($i, '', true);
506: $generated_pages[$i]['text'] = $output['current_page_number_displaying'];
507: $generated_pages[$i]['tag_close'] = $this->current_tag_close;
508:
509:
510: if ($this->number_adjacent_pages > 0) {
511: for ($i = ($output['current_page_number_displaying'] + 1); $i <= ($output['current_page_number_displaying'] + $this->number_adjacent_pages); $i++) {
512: if ($i <= $this->total_pages) {
513: $generated_pages[$i] = array();
514: $generated_pages[$i]['tag_open'] = $this->number_tag_open;
515: $generated_pages[$i]['link'] = $this->generateUrl($i);
516: $generated_pages[$i]['page_value'] = $this->generateUrl($i, '', true);
517: $generated_pages[$i]['text'] = $i;
518: $generated_pages[$i]['tag_close'] = $this->number_tag_close;
519: }
520: }
521: }
522:
523:
524: if ($this->unavailable_display === true && $this->unavailable_after !== false && ($output['current_page_number_displaying'] + $this->number_adjacent_pages) < $this->total_pages) {
525: $number_adjacent_after_current = ($output['current_page_number_displaying'] + $this->number_adjacent_pages);
526: $number_after_unavailable = ($this->total_pages - ($this->unavailable_after - 1));
527: if ($number_adjacent_after_current >= $number_after_unavailable) {
528: $number_after_unavailable = ($number_adjacent_after_current + 1);
529: }
530: if (($number_adjacent_after_current + 1) < $number_after_unavailable) {
531: $generated_pages['unavailable_after'] = array();
532: $generated_pages['unavailable_after']['tag_open'] = $this->unavailable_tag_open;
533: $generated_pages['unavailable_after']['link'] = null;
534: $generated_pages['unavailable_after']['page_value'] = null;
535: $generated_pages['unavailable_after']['text'] = $this->unavailable_text;
536: $generated_pages['unavailable_after']['tag_close'] = $this->unavailable_tag_close;
537: }
538: for ($i = $number_after_unavailable; $i <= $this->total_pages; $i++) {
539: $generated_pages[$i] = array();
540: $generated_pages[$i]['tag_open'] = $this->number_tag_open;
541: $generated_pages[$i]['link'] = $this->generateUrl($i);
542: $generated_pages[$i]['page_value'] = $this->generateUrl($i, '', true);
543: $generated_pages[$i]['text'] = $i;
544: $generated_pages[$i]['tag_close'] = $this->number_tag_close;
545: }
546: unset($i, $number_adjacent_after_current, $number_after_unavailable);
547: }
548: }
549:
550:
551: $generated_pages['next_page'] = array();
552: $generated_pages['next_page']['tag_open'] = null;
553: $generated_pages['next_page']['link'] = null;
554: $generated_pages['next_page']['page_value'] = null;
555: $generated_pages['next_page']['text'] = null;
556: $generated_pages['next_page']['tag_close'] = null;
557: if ($this->next_page_text !== false) {
558: if ($this->next_page_always_show === true || ($this->next_page_always_show === false && !$this->isCurrentlyLastPage())) {
559: $generated_pages['next_page']['tag_open'] = $this->next_tag_open;
560: $generated_pages['next_page']['link'] = $this->generateUrl($this->page_number_value, 'next');
561: $generated_pages['next_page']['page_value'] = $this->generateUrl($this->page_number_value, 'next', true);
562: $generated_pages['next_page']['text'] = $this->next_page_text;
563: $generated_pages['next_page']['tag_close'] = $this->next_tag_close;
564: }
565: }
566:
567:
568: $generated_pages['last_page'] = array();
569: $generated_pages['last_page']['tag_open'] = null;
570: $generated_pages['last_page']['link'] = null;
571: $generated_pages['last_page']['page_value'] = null;
572: $generated_pages['last_page']['text'] = null;
573: $generated_pages['last_page']['tag_close'] = null;
574: if ($this->last_page_text !== false) {
575: if ($this->last_page_always_show === true || ($this->last_page_always_show === false && !$this->isCurrentlyLastPage())) {
576: $generated_pages['last_page']['tag_open'] = $this->last_tag_open;
577: $generated_pages['last_page']['link'] = $this->generateUrl(($this->total_pages*$this->items_per_page), 'last');
578: $generated_pages['last_page']['page_value'] = $this->generateUrl(($this->total_pages*$this->items_per_page), 'last', true);
579: $generated_pages['last_page']['text'] = $this->last_page_text;
580: $generated_pages['last_page']['tag_close'] = $this->last_tag_close;
581: }
582: }
583:
584: $output['generated_pages'] = $generated_pages;
585: unset($generated_pages);
586:
587: $output['overall_tag_close'] = $this->overall_tag_close;
588:
589: return $output;
590: }
591:
592:
593: 594: 595: 596: 597:
598: private function isCurrentlyFirstPage()
599: {
600: if ($this->page_number_type === 'start_num') {
601: if ($this->page_number_value === 0) {
602: return true;
603: }
604: return false;
605: } elseif ($this->page_number_type === 'page_num') {
606: if ($this->page_number_value === 1) {
607: return true;
608: }
609: return false;
610: }
611: return false;
612: }
613:
614:
615: 616: 617: 618: 619:
620: private function isCurrentlyLastPage()
621: {
622: if ($this->page_number_type === 'start_num') {
623: if ($this->page_number_value >= ($this->total_pages*$this->items_per_page)-$this->items_per_page) {
624: return true;
625: }
626: return false;
627: } elseif ($this->page_number_type === 'page_num') {
628: if ($this->page_number_value >= $this->total_pages) {
629: return true;
630: }
631: return false;
632: }
633: return false;
634: }
635:
636:
637: 638: 639: 640:
641: private function validateCorrectProperties()
642: {
643: if (!is_bool($this->current_page_link)) {
644: $this->current_page_link = false;
645: }
646:
647: if (!is_bool($this->first_page_always_show)) {
648: $this->first_page_always_show = false;
649: }
650:
651: if (is_numeric($this->items_per_page)) {
652: $this->items_per_page = intval($this->items_per_page);
653: if ($this->items_per_page <= 0) {
654: $this->items_per_page = 10;
655: }
656: } elseif (!is_numeric($this->items_per_page)) {
657: $this->items_per_page = 10;
658: }
659:
660: if (!is_bool($this->last_page_always_show)) {
661: $this->last_page_always_show = false;
662: }
663:
664: if (!is_bool($this->next_page_always_show)) {
665: $this->next_page_always_show = false;
666: }
667:
668: if (is_numeric($this->number_adjacent_pages)) {
669: $this->number_adjacent_pages = intval($this->number_adjacent_pages);
670: if ($this->number_adjacent_pages < 0) {
671: $this->number_adjacent_pages = 5;
672: }
673: } else {
674: $this->number_adjacent_pages = 5;
675: }
676:
677: if (!is_bool($this->number_display)) {
678: $this->number_display = false;
679: }
680:
681: if ($this->page_number_type != 'start_num' && $this->page_number_type != 'page_num') {
682: $this->page_number_type = 'start_num';
683: }
684:
685: if (!is_bool($this->previous_page_always_show)) {
686: $this->previous_page_always_show = false;
687: }
688:
689: if (is_numeric($this->unavailable_after)) {
690: $this->unavailable_after = intval($this->unavailable_after);
691: if ($this->unavailable_after <= 0) {
692: $this->unavailable_after = 2;
693: }
694: } else {
695: $this->unavailable_after = false;
696: }
697:
698: if (is_numeric($this->unavailable_before)) {
699: $this->unavailable_before = intval($this->unavailable_before);
700: if ($this->unavailable_before <= 0) {
701: $this->unavailable_before = 2;
702: }
703: } else {
704: $this->unavailable_before = false;
705: }
706:
707: if (!is_bool($this->unavailable_display)) {
708: $this->unavailable_display = false;
709: }
710: }
711:
712:
713: 714: 715: 716: 717:
718: private function validateRequiredProperties()
719: {
720: if ($this->base_url == null) {
721: throw new \Exception('The base_url property was not set.');
722: }
723:
724: if (is_numeric($this->total_records)) {
725: $this->total_records = intval($this->total_records);
726: } else {
727: throw new \Exception('The total_records property was not set.');
728: }
729:
730: if (!is_numeric($this->page_number_value)) {
731: throw new \Exception('The page_number_value property was not set.');
732: }
733: }
734:
735:
736: }
737: