1: <?php
2: /**
3: * XOOPS page navigation
4: *
5: * You may not change or alter any portion of this comment or credits
6: * of supporting developers from this source code or any supporting source code
7: * which is considered copyrighted (c) material of the original comment or credit authors.
8: * This program is distributed in the hope that it will be useful,
9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11: *
12: * @copyright (c) 2000-2021 XOOPS Project (www.xoops.org)
13: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @since 2.0.0
16: * @author Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
17: */
18:
19: use Xmf\Request;
20:
21: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
22:
23: /**
24: * Class XoopsPageNav
25: */
26: class XoopsPageNav
27: {
28: /**
29: * *#@+
30: *
31: * @access private
32: */
33: public $total;
34: public $perpage;
35: public $current;
36: public $url;
37: public $extra;
38: /**
39: * *#@-
40: */
41:
42: /**
43: * Constructor
44: *
45: * @param int $total_items Total number of items
46: * @param int $items_perpage Number of items per page
47: * @param int $current_start First item on the current page
48: * @param string $start_name Name for "start" or "offset"
49: * @param string $extra_arg Additional arguments to pass in the URL
50: */
51: public function __construct($total_items, $items_perpage, $current_start, $start_name = 'start', $extra_arg = '')
52: {
53: $this->total = (int)$total_items;
54: $this->perpage = (int)$items_perpage;
55: $this->current = (int)$current_start;
56: $this->extra = $extra_arg;
57: if ($extra_arg != '' && (substr($extra_arg, -5) !== '&amp;' || substr($extra_arg, -1) !== '&')) {
58: $this->extra = '&amp;' . $extra_arg;
59: }
60: $this->url = htmlspecialchars(Request::getString('PHP_SELF', '', 'SERVER'), ENT_QUOTES) . '?' . trim($start_name) . '=';
61: }
62:
63: /**
64: * Create text navigation
65: *
66: * @param integer $offset
67: * @return string
68: */
69: public function renderNav($offset = 4)
70: {
71: $ret = '';
72: if ($this->total <= $this->perpage) {
73: return $ret;
74: }
75: if (($this->total != 0) && ($this->perpage != 0)) {
76: $navigation = array();
77: $total_pages = ceil($this->total / $this->perpage);
78: if ($total_pages > 1) {
79: $i = 0;
80: $prev = $this->current - $this->perpage;
81: if ($prev >= 0) {
82: $navigation[$i]['url'] = $this->url . $prev . $this->extra;
83: $navigation[$i]['value'] = '';
84: $navigation[$i]['option'] = 'first';
85: ++$i;
86: }
87: $counter = 1;
88: $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
89: while ($counter <= $total_pages) {
90: if ($counter == $current_page) {
91: $navigation[$i]['url'] = $this->url . $prev . $this->extra;
92: $navigation[$i]['value'] = $counter;
93: $navigation[$i]['option'] = 'selected';
94: } elseif (($counter > $current_page - $offset && $counter < $current_page + $offset) || $counter == 1 || $counter == $total_pages) {
95: if ($counter == $total_pages && $current_page < $total_pages - $offset) {
96: $navigation[$i]['url'] = '';
97: $navigation[$i]['value'] = '';
98: $navigation[$i]['option'] = 'break';
99: ++$i;
100: }
101: $navigation[$i]['url'] = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
102: $navigation[$i]['value'] = $counter;
103: $navigation[$i]['option'] = 'show';
104: ++$i;
105: if ($counter == 1 && $current_page > 1 + $offset) {
106: $navigation[$i]['url'] = '';
107: $navigation[$i]['value'] = '';
108: $navigation[$i]['option'] = 'break';
109: }
110: }
111: ++$counter;
112: ++$i;
113: }
114: $next = $this->current + $this->perpage;
115: if ($this->total > $next) {
116: $navigation[$i]['url'] = $this->url . $next . $this->extra;
117: $navigation[$i]['value'] = '';
118: $navigation[$i]['option'] = 'last';
119: }
120: }
121: return $this->displayPageNav('Nav', $navigation);
122: }
123: return $ret;
124: }
125:
126: /**
127: * Create a navigational dropdown list
128: *
129: * @param boolean $showbutton Show the "Go" button?
130: * @return string
131: */
132: public function renderSelect($showbutton = false)
133: {
134: $ret = '';
135: if ($this->total < $this->perpage) {
136: return $ret;
137: }
138: $total_pages = ceil($this->total / $this->perpage);
139: if ($total_pages > 1) {
140: $counter = 1;
141: $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
142: while ($counter <= $total_pages) {
143: if ($counter == $current_page) {
144: $ret .= '<option value="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '" selected>' . $counter . '</option>';
145: } else {
146: $ret .= '<option value="' . $this->url . (($counter - 1) * $this->perpage) . $this->extra . '">' . $counter . '</option>';
147: }
148: ++$counter;
149: }
150: if ($showbutton) {
151: $navigation['button'] = true;
152: } else {
153: $navigation['button'] = false;
154: }
155: $navigation['select'] = $ret;
156: return $this->displayPageNav('Select', $navigation);
157: }
158: return $ret;
159: }
160:
161: /**
162: * Create navigation with images
163: *
164: * @param integer $offset
165: * @return string
166: */
167: public function renderImageNav($offset = 4)
168: {
169: $ret = '';
170: if ($this->total < $this->perpage) {
171: return $ret;
172: }
173: $total_pages = ceil($this->total / $this->perpage);
174: if ($total_pages > 1) {
175: $i = 0;
176: $prev = $this->current - $this->perpage;
177: if ($prev >= 0) {
178: $navigation[$i]['url'] = $this->url . $prev . $this->extra;
179: $navigation[$i]['value'] = '';
180: $navigation[$i]['option'] = 'first';
181: ++$i;
182: } else {
183: $navigation[$i]['url'] = '';
184: $navigation[$i]['value'] = '';
185: $navigation[$i]['option'] = 'firstempty';
186: ++$i;
187: }
188: $counter = 1;
189: $current_page = (int)floor(($this->current + $this->perpage) / $this->perpage);
190: while ($counter <= $total_pages) {
191: if ($counter == $current_page) {
192: $navigation[$i]['url'] = '';
193: $navigation[$i]['value'] = $counter;
194: $navigation[$i]['option'] = 'selected';
195: } elseif (($counter > $current_page - $offset && $counter < $current_page + $offset) || $counter == 1 || $counter == $total_pages) {
196: if ($counter == $total_pages && $current_page < $total_pages - $offset) {
197: $navigation[$i]['url'] = '';
198: $navigation[$i]['value'] = '';
199: $navigation[$i]['option'] = 'break';
200: ++$i;
201: }
202: $navigation[$i]['url'] = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
203: $navigation[$i]['value'] = $counter;
204: $navigation[$i]['option'] = 'show';
205: ++$i;
206: if ($counter == 1 && $current_page > 1 + $offset) {
207: $navigation[$i]['url'] = '';
208: $navigation[$i]['value'] = '';
209: $navigation[$i]['option'] = 'break';
210: }
211: }
212: ++$counter;
213: ++$i;
214: }
215: $next = $this->current + $this->perpage;
216: if ($this->total > $next) {
217: $navigation[$i]['url'] = $this->url . $next . $this->extra;
218: $navigation[$i]['value'] = '';
219: $navigation[$i]['option'] = 'last';
220: ++$i;
221: } else {
222: $navigation[$i]['url'] = '';
223: $navigation[$i]['value'] = '';
224: $navigation[$i]['option'] = 'lastempty';
225: }
226: return $this->displayPageNav('Image', $navigation);
227: }
228: return $ret;
229: }
230:
231: /**
232: * Display navigation in template
233: *
234: * @param string $type
235: * @param array $navigation
236: * @return string
237: */
238: private function displayPageNav($type = 'nav', $navigation = array()){
239: if (!isset($GLOBALS['xoTheme']) || !is_object($GLOBALS['xoTheme'])) {
240: include_once $GLOBALS['xoops']->path('/class/theme.php');
241: $GLOBALS['xoTheme'] = new \xos_opal_Theme();
242: }
243: require_once $GLOBALS['xoops']->path('/class/template.php');
244: $pageNavTpl = new \XoopsTpl();
245: $pageNavTpl->assign('pageNavType', $type);
246: $pageNavTpl->assign('pageNavigation', $navigation);
247:
248: return $pageNavTpl->fetch("db:system_pagenav.tpl");
249:
250: }
251: }
252: