XCL Web Application Platform 2.5.0
The XoopsCube Legacy Project
Loading...
Searching...
No Matches
XCube_PageNavigator.class.php
1<?php
14
15define( 'XCUBE_PAGENAVI_START', 1 );
16define( 'XCUBE_PAGENAVI_PERPAGE', 2 );
17
18define( 'XCUBE_PAGENAVI_SORT', 1 );
19define( 'XCUBE_PAGENAVI_PAGE', 4 );
20
21define( 'XCUBE_PAGENAVI_DEFAULT_PERPAGE', 20 );
22
23
24class XCube_PageNavigator {
29 public $mAttributes = [];
30
35 public $mStart = 0;
36
41 public $mTotalItems = 0;
42
47 public $mPerpage = XCUBE_PAGENAVI_DEFAULT_PERPAGE;
48
54 public $mPerpageFreeze = false;
55
60 public $mSort = [];
61
66 public $mUrl = '';
67
72 public $mPrefix;
73
77 public $mExtra = [];
78
82 public $mFlags = 0;
83
87 public $mFetch;
88
94 public $_mIsSpecifedTotalItems = false;
95
103 public $mGetTotalItems;
107 public $_mIsSpecifiedTotal;
111 public $mTotal;
115
116
123 public function __construct( $url, $flags = XCUBE_PAGENAVI_START ) {
124 $this->mUrl = $url;
125 $this->mFlags = $flags;
126
127 $this->mFetch = new XCube_Delegate();
128 $this->mFetch->add( [ &$this, 'fetchNaviControl' ] );
129
130 $this->mGetTotalItems = new XCube_Delegate();
131 }
132
133 public function XCube_PageNavigator( $url, $flags = XCUBE_PAGENAVI_START ) {
134 return $this->__construct( $url, $flags );
135 }
136
141 public function fetch() {
142 $this->mFetch->call( new XCube_Ref( $this ) );
143 }
144
145 public function fetchNaviControl( &$navi ) {
146 $root =& XCube_Root::getSingleton();
147
148 $startKey = $navi->getStartKey();
149 $perpageKey = $navi->getPerpageKey();
150
151 if ( $navi->mFlags & XCUBE_PAGENAVI_START ) {
152 $t_start = $root->mContext->mRequest->getRequest( $navi->getStartKey() );
153 if ( null !== $t_start && (int) $t_start >= 0 ) {
154 $navi->mStart = (int) $t_start;
155 }
156 }
157
158 if ( $navi->mFlags & XCUBE_PAGENAVI_PERPAGE && ! $navi->mPerpageFreeze ) {
159 $t_perpage = $root->mContext->mRequest->getRequest( $navi->getPerpageKey() );
160 if ( null !== $t_perpage && (int) $t_perpage > 0 ) {
161 $navi->mPerpage = (int) $t_perpage;
162 }
163 }
164 }
165
166 public function addExtra( $key, $value ) {
167 $this->mExtra[ $key ] = $value;
168 }
169
170 public function removeExtra( $key ) {
171 if ( $this->mExtra[ $key ] ) {
172 unset( $this->mExtra[ $key ] );
173 }
174 }
175
176
177 protected function _renderExtra( /*** string ***/ $key, /*** mixed ***/ $extra, /*** string[] ***/ &$query ) {
178 if ( ! is_array( $extra ) ) {
179 $query[] = $key . '=' . urlencode( $extra );
180 } else { //array
181 foreach ( $extra as $k => $value ) {
182 $this->_renderExtra( $key . '[' . $k . ']', $value, $query );
183 }
184 }
185 }
186
187 public function getRenderBaseUrl( $mask = null ) {
188 if ( null === $mask ) {
189 $mask = [];
190 }
191 if ( ! is_array( $mask ) ) {
192 $mask = [ $mask ];
193 }
194
195 if ( count( $this->mExtra ) > 0 ) {
196 $tarr = [];
197
198 foreach ( $this->mExtra as $key => $value ) {
199 if ( is_array( $mask ) && ! in_array( $key, $mask, true ) ) {
200 $this->_renderExtra( $key, $value, $tarr );
201 }
202 }
203
204 if ( 0 === (is_countable($tarr) ? count( $tarr ) : 0) ) {
205 return $this->mUrl;
206 }
207 // TODO XCL 2.3.x 'strpos' call can be converted to 'str_contains'
208 if ( false !== strpos( $this->mUrl, '?' ) ) {
209 return $this->mUrl . '&amp;' . implode( '&amp;', $tarr );
210 }
211
212 return $this->mUrl . '?' . implode( '&amp;', $tarr );
213 }
214
215 return $this->mUrl;
216 }
217
224 public function getRenderUrl( $mask = null ) {
225 if ( null !== $mask && ! is_array( $mask ) ) {
226 $mask = [ $mask ];
227 }
228
229 $delimiter = '?';
230 $url = $this->getRenderBaseUrl( $mask );
231 // TODO XCL 2.3.x 'strpos' call can be converted to 'str_contains'
232 if ( false !== strpos( $url, '?' ) ) {
233 $delimiter = '&amp;';
234 }
235
236 return $url . $delimiter . $this->getStartKey() . '=';
237 }
238
239 public function renderUrlForSort() {
240 if ( count( $this->mExtra ) > 0 ) {
241 $tarr = [];
242
243 foreach ( $this->mExtra as $key => $value ) {
244 //$tarr[]=$key."=".urlencode($value);
245 $this->_renderExtra( $key, $value, $tarr );
246 }
247
248 $tarr[] = $this->getPerpageKey() . '=' . $this->mPerpage;
249 // TODO XCL 2.3.x 'strpos' call can be converted to 'str_contains'
250 if ( false !== strpos( $this->mUrl, '?' ) ) {
251 return $this->mUrl . '&amp;' . implode( '&amp;', $tarr );
252 }
253
254 return $this->mUrl . '?' . implode( '&amp;', $tarr );
255 }
256
257 return $this->mUrl;
258 }
259
260 public function renderUrlForPage( $page = null ) {
261 $tarr = [];
262
263 foreach ( $this->mExtra as $key => $value ) {
264 //$tarr[]=$key."=".urlencode($value);
265 $this->_renderExtra( $key, $value, $tarr );
266 }
267
268 foreach ( $this->mSort as $key => $value ) {
269 $tarr[] = $key . '=' . urlencode( $value );
270 }
271
272 $tarr[] = $this->getPerpageKey() . '=' . $this->getPerpage();
273
274 if ( null !== $page ) {
275 $tarr[] = $this->getStartKey() . '=' . (int) $page;
276 }
277 // TODO XCL 2.3.x 'strpos' call can be converted to 'str_contains'
278 if ( false !== strpos( $this->mUrl, '?' ) ) {
279 return $this->mUrl . '&amp;' . implode( '&amp;', $tarr );
280 }
281
282 return $this->mUrl . '?' . implode( '&amp;', $tarr );
283 }
284
293 public function renderSortUrl( $mask = null ) {
294 return $this->renderUrlForSort();
295 }
296
297 public function setStart( $start ) {
298 $this->mStart = (int) $start;
299 }
300
301 public function getStart() {
302 return $this->mStart;
303 }
304
305 public function setTotalItems( $total ) {
306 $this->mTotal = (int) $total;
307 $this->_mIsSpecifiedTotal = true;
308 }
309
310 public function getTotalItems() {
311 if ( false === $this->_mIsSpecifedTotalItems ) {
312 $this->mGetTotalItems->call( new XCube_Ref( $this->mTotal ) );
313 $this->_mIsSpecifedTotalItems = true;
314 }
315
316 return $this->mTotal;
317 }
318
319 public function getTotalPages() {
320 if ( $this->getPerpage() > 0 ) {
321 return ceil( $this->getTotalItems() / $this->getPerpage() );
322 }
323
324 return 0;
325 }
326
327 public function setPerpage( $perpage ) {
328 $this->mPerpage = (int) $perpage;
329 }
330
331 public function freezePerpage() {
332 $this->mPerpageFreeze = true;
333 }
334
335 public function getPerpage() {
336 return $this->mPerpage;
337 }
338
339 public function setPrefix( $prefix ) {
340 $this->mPrefix = $prefix;
341 }
342
343 public function getPrefix() {
344 return $this->mPrefix;
345 }
346
347 public function getStartKey() {
348 return $this->mPrefix . 'start';
349 }
350
351 public function getPerpageKey() {
352 return $this->mPrefix . 'perpage';
353 }
354
355 public function getCurrentPage() {
356 return (int) floor( ( $this->getStart() + $this->getPerpage() ) / $this->getPerpage() );
357 }
358
359 public function hasPrivPage() {
360 return ( $this->getStart() - $this->getPerpage() ) >= 0;
361 }
362
363 public function getPrivStart() {
364 $prev = $this->getStart() - $this->getPerpage();
365
366 return ( $prev > 0 ) ? $prev : 0;
367 }
368
369 public function hasNextPage() {
370 return $this->getTotalItems() > ( $this->getStart() + $this->getPerpage() );
371 }
372
373 public function getNextStart() {
374 $next = $this->getStart() + $this->getPerpage();
375
376 return ( $this->getTotalItems() > $next ) ? $next : 0;
377 }
378}
[Final] Used for the simple mechanism for common delegation in XCube.
_renderExtra($key, $extra, &$query)
__construct( $url, $flags=XCUBE_PAGENAVI_START)