PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.21
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.21
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Pagination / AbstractPaginator.php

AbstractPaginator.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.21, at vendor/wpfluent/framework/src/WPFluent/Pagination/AbstractPaginator.php

731 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Pagination;
4
5 use Closure;
6 use FluentBoards\Framework\Foundation\App;
7 use FluentBoards\Framework\Support\Arr;
8 use FluentBoards\Framework\Support\Str;
9 use FluentBoards\Framework\Support\Helper;
10 use FluentBoards\Framework\Support\Tappable;
11 use FluentBoards\Framework\Support\Collection;
12 use FluentBoards\Framework\Support\ForwardsCalls;
13 use FluentBoards\Framework\Database\Orm\ResourceAbleTrait;
14
15 /**
16 * @mixin \FluentBoards\Framework\Support\Collection
17 */
18 abstract class AbstractPaginator
19 {
20 use ForwardsCalls, Tappable, ResourceAbleTrait;
21
22 /**
23 * All of the items being paginated.
24 *
25 * @var \FluentBoards\Framework\Support\Collection
26 */
27 protected $items;
28
29 /**
30 * The number of items to be shown per page.
31 *
32 * @var int
33 */
34 protected $perPage;
35
36 /**
37 * The current page being "viewed".
38 *
39 * @var int
40 */
41 protected $currentPage;
42
43 /**
44 * The base path to assign to all URLs.
45 *
46 * @var string
47 */
48 protected $path = '/';
49
50 /**
51 * The query parameters to add to all URLs.
52 *
53 * @var array
54 */
55 protected $query = [];
56
57 /**
58 * The URL fragment to add to all URLs.
59 *
60 * @var string|null
61 */
62 protected $fragment;
63
64 /**
65 * The query string variable used to store the page.
66 *
67 * @var string
68 */
69 protected $pageName = 'page';
70
71 /**
72 * The number of links to display on each side of current page link.
73 *
74 * @var int
75 */
76 public $onEachSide = 3;
77
78 /**
79 * The paginator options.
80 *
81 * @var array
82 */
83 protected $options;
84
85 /**
86 * The current path resolver callback.
87 *
88 * @var \Closure
89 */
90 protected static $currentPathResolver;
91
92 /**
93 * The current page resolver callback.
94 *
95 * @var \Closure
96 */
97 protected static $currentPageResolver;
98
99 /**
100 * The query string resolver callback.
101 *
102 * @var \Closure
103 */
104 protected static $queryStringResolver;
105
106 /**
107 * The default pagination view.
108 *
109 * @var string
110 */
111 public static $defaultView = 'pagination::tailwind';
112
113 /**
114 * The default "simple" pagination view.
115 *
116 * @var string
117 */
118 public static $defaultSimpleView = 'pagination::simple-tailwind';
119
120 /**
121 * Determine if the given value is a valid page number.
122 *
123 * @param int $page
124 * @return bool
125 */
126 protected function isValidPageNumber($page)
127 {
128 return $page >= 1 && filter_var($page, FILTER_VALIDATE_INT) !== false;
129 }
130
131 /**
132 * Get the URL for the previous page.
133 *
134 * @return string|null
135 */
136 public function previousPageUrl()
137 {
138 if ($this->currentPage() > 1) {
139 return $this->url($this->currentPage() - 1);
140 }
141 }
142
143 /**
144 * Create a range of pagination URLs.
145 *
146 * @param int $start
147 * @param int $end
148 * @return array
149 */
150 public function getUrlRange($start, $end)
151 {
152 return Helper::collect(range($start, $end))->mapWithKeys(function ($page) {
153 return [$page => $this->url($page)];
154 })->all();
155 }
156
157 /**
158 * Get the URL for a given page number.
159 *
160 * @param int $page
161 * @return string
162 */
163 public function url($page)
164 {
165 if ($page <= 0) {
166 $page = 1;
167 }
168
169 // If we have any extra query string key / value pairs that need to be added
170 // onto the URL, we will put them in query string form and then attach it
171 // to the URL. This allows for extra information like sortings storage.
172 $parameters = [$this->pageName => $page];
173
174 if (count($this->query) > 0) {
175 $parameters = array_merge($this->query, $parameters);
176 }
177
178 return $this->path()
179 .(Str::contains($this->path(), '?') ? '&' : '?')
180 .Arr::query($parameters)
181 .$this->buildFragment();
182 }
183
184 /**
185 * Get / set the URL fragment to be appended to URLs.
186 *
187 * @param string|null $fragment
188 * @return $this|string|null
189 */
190 public function fragment($fragment = null)
191 {
192 if (is_null($fragment)) {
193 return $this->fragment;
194 }
195
196 $this->fragment = $fragment;
197
198 return $this;
199 }
200
201 /**
202 * Add a set of query string values to the paginator.
203 *
204 * @param array|string|null $key
205 * @param string|null $value
206 * @return $this
207 */
208 public function appends($key, $value = null)
209 {
210 if (is_null($key)) {
211 return $this;
212 }
213
214 if (is_array($key)) {
215 return $this->appendArray($key);
216 }
217
218 return $this->addQuery($key, $value);
219 }
220
221 /**
222 * Add an array of query string values.
223 *
224 * @param array $keys
225 * @return $this
226 */
227 protected function appendArray(array $keys)
228 {
229 foreach ($keys as $key => $value) {
230 $this->addQuery($key, $value);
231 }
232
233 return $this;
234 }
235
236 /**
237 * Add all current query string values to the paginator.
238 *
239 * @return $this
240 */
241 public function withQueryString()
242 {
243 if (isset(static::$queryStringResolver)) {
244 return $this->appends(call_user_func(static::$queryStringResolver));
245 }
246
247 return $this;
248 }
249
250 /**
251 * Add a query string value to the paginator.
252 *
253 * @param string $key
254 * @param string $value
255 * @return $this
256 */
257 protected function addQuery($key, $value)
258 {
259 if ($key !== $this->pageName) {
260 $this->query[$key] = $value;
261 }
262
263 return $this;
264 }
265
266 /**
267 * Build the full fragment portion of a URL.
268 *
269 * @return string
270 */
271 protected function buildFragment()
272 {
273 return $this->fragment ? '#'.$this->fragment : '';
274 }
275
276 /**
277 * Load a set of relationships onto the mixed relationship collection.
278 *
279 * @param string $relation
280 * @param array $relations
281 * @return $this
282 */
283 public function loadMorph($relation, $relations)
284 {
285 $this->getCollection()->loadMorph($relation, $relations);
286
287 return $this;
288 }
289
290 /**
291 * Load a set of relationship counts onto the mixed relationship collection.
292 *
293 * @param string $relation
294 * @param array $relations
295 * @return $this
296 */
297 public function loadMorphCount($relation, $relations)
298 {
299 $this->getCollection()->loadMorphCount($relation, $relations);
300
301 return $this;
302 }
303
304 /**
305 * Get the slice of items being paginated.
306 *
307 * @return array
308 */
309 public function items()
310 {
311 return $this->items->all();
312 }
313
314 /**
315 * Get the number of the first item in the slice.
316 *
317 * @return int
318 */
319 public function firstItem()
320 {
321 return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null;
322 }
323
324 /**
325 * Get the number of the last item in the slice.
326 *
327 * @return int
328 */
329 public function lastItem()
330 {
331 return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null;
332 }
333
334 /**
335 * Transform each item in the slice of items using a callback.
336 *
337 * @param callable $callback
338 * @return $this
339 */
340 public function through(callable $callback)
341 {
342 $this->items->transform($callback);
343
344 return $this;
345 }
346
347 /**
348 * Get the number of items shown per page.
349 *
350 * @return int
351 */
352 public function perPage()
353 {
354 return $this->perPage;
355 }
356
357 /**
358 * Determine if there are enough items to split into multiple pages.
359 *
360 * @return bool
361 */
362 public function hasPages()
363 {
364 return $this->currentPage() != 1 || $this->hasMorePages();
365 }
366
367 /**
368 * Determine if the paginator is on the first page.
369 *
370 * @return bool
371 */
372 public function onFirstPage()
373 {
374 return $this->currentPage() <= 1;
375 }
376
377 /**
378 * Determine if the paginator is on the last page.
379 *
380 * @return bool
381 */
382 public function onLastPage()
383 {
384 return ! $this->hasMorePages();
385 }
386
387 /**
388 * Get the current page.
389 *
390 * @return int
391 */
392 public function currentPage()
393 {
394 return $this->currentPage;
395 }
396
397 /**
398 * Get the query string variable used to store the page.
399 *
400 * @return string
401 */
402 public function getPageName()
403 {
404 return $this->pageName;
405 }
406
407 /**
408 * Set the query string variable used to store the page.
409 *
410 * @param string $name
411 * @return $this
412 */
413 public function setPageName($name)
414 {
415 $this->pageName = $name;
416
417 return $this;
418 }
419
420 /**
421 * Set the base path to assign to all URLs.
422 *
423 * @param string $path
424 * @return $this
425 */
426 public function withPath($path)
427 {
428 return $this->setPath($path);
429 }
430
431 /**
432 * Set the base path to assign to all URLs.
433 *
434 * @param string $path
435 * @return $this
436 */
437 public function setPath($path)
438 {
439 $this->path = $path;
440
441 return $this;
442 }
443
444 /**
445 * Set the number of links to display on each side of current page link.
446 *
447 * @param int $count
448 * @return $this
449 */
450 public function onEachSide($count)
451 {
452 $this->onEachSide = $count;
453
454 return $this;
455 }
456
457 /**
458 * Get the base path for paginator generated URLs.
459 *
460 * @return string|null
461 */
462 public function path()
463 {
464 return $this->path;
465 }
466
467 /**
468 * Resolve the current request path or return the default value.
469 *
470 * @param string $default
471 * @return string
472 */
473 public static function resolveCurrentPath($default = '/')
474 {
475 if (isset(static::$currentPathResolver)) {
476 return call_user_func(static::$currentPathResolver);
477 }
478
479 return $default;
480 }
481
482 /**
483 * Set the current request path resolver callback.
484 *
485 * @param \Closure $resolver
486 * @return void
487 */
488 public static function currentPathResolver(Closure $resolver)
489 {
490 static::$currentPathResolver = $resolver;
491 }
492
493 /**
494 * Resolve the current page or return the default value.
495 *
496 * @param string $pageName
497 * @param int $default
498 * @return int
499 */
500 public static function resolveCurrentPage($pageName = 'page', $default = 1)
501 {
502 if (isset(static::$currentPageResolver)) {
503 return (int) call_user_func(static::$currentPageResolver, $pageName);
504 }
505
506 return $default;
507 }
508
509 /**
510 * Set the current page resolver callback.
511 *
512 * @param \Closure $resolver
513 * @return void
514 */
515 public static function currentPageResolver(Closure $resolver)
516 {
517 static::$currentPageResolver = $resolver;
518 }
519
520 /**
521 * Resolve the query string or return the default value.
522 *
523 * @param string|array|null $default
524 * @return string
525 */
526 public static function resolveQueryString($default = null)
527 {
528 if (isset(static::$queryStringResolver)) {
529 return (static::$queryStringResolver)();
530 }
531
532 return $default;
533 }
534
535 /**
536 * Set with query string resolver callback.
537 *
538 * @param \Closure $resolver
539 * @return void
540 */
541 public static function queryStringResolver(Closure $resolver)
542 {
543 static::$queryStringResolver = $resolver;
544 }
545
546 /**
547 * Render the paginator using the given view.
548 *
549 * @param string|null $view
550 * @param array $data
551 * @return \FluentBoards\Framework\View\View
552 */
553 public function links($view = 'web.pagination.default', $data = [])
554 {
555 $elements = method_exists($this, 'elements') ? $this->elements() : null;
556
557 return App::make('view')->make($view ?: static::$defaultView, array_merge($data, [
558 'paginator' => $this,
559 'elements' => $elements
560 ]));
561 }
562
563 /**s
564 * Set the default pagination view.
565 *
566 * @param string $view
567 * @return void
568 */
569 public static function defaultView($view)
570 {
571 static::$defaultView = $view;
572 }
573
574 /**
575 * Set the default "simple" pagination view.
576 *
577 * @param string $view
578 * @return void
579 */
580 public static function defaultSimpleView($view)
581 {
582 static::$defaultSimpleView = $view;
583 }
584
585 /**
586 * Get an iterator for the items.
587 *
588 * @return \ArrayIterator
589 */
590 #[\ReturnTypeWillChange]
591 public function getIterator()
592 {
593 return $this->items->getIterator();
594 }
595
596 /**
597 * Determine if the list of items is empty.
598 *
599 * @return bool
600 */
601 public function isEmpty()
602 {
603 return $this->items->isEmpty();
604 }
605
606 /**
607 * Determine if the list of items is not empty.
608 *
609 * @return bool
610 */
611 public function isNotEmpty()
612 {
613 return $this->items->isNotEmpty();
614 }
615
616 /**
617 * Get the number of items for the current page.
618 *
619 * @return int
620 */
621 #[\ReturnTypeWillChange]
622 public function count()
623 {
624 return $this->items->count();
625 }
626
627 /**
628 * Get the paginator's underlying collection.
629 *
630 * @return \FluentBoards\Framework\Support\Collection
631 */
632 public function getCollection()
633 {
634 return $this->items;
635 }
636
637 /**
638 * Set the paginator's underlying collection.
639 *
640 * @param \FluentBoards\Framework\Support\Collection $collection
641 * @return $this
642 */
643 public function setCollection(Collection $collection)
644 {
645 $this->items = $collection;
646
647 return $this;
648 }
649
650 /**
651 * Get the paginator options.
652 *
653 * @return array
654 */
655 public function getOptions()
656 {
657 return $this->options;
658 }
659
660 /**
661 * Determine if the given item exists.
662 *
663 * @param mixed $key
664 * @return bool
665 */
666 #[\ReturnTypeWillChange]
667 public function offsetExists($key)
668 {
669 return $this->items->has($key);
670 }
671
672 /**
673 * Get the item at the given offset.
674 *
675 * @param mixed $key
676 * @return mixed
677 */
678 #[\ReturnTypeWillChange]
679 public function offsetGet($key)
680 {
681 return $this->items->get($key);
682 }
683
684 /**
685 * Set the item at the given offset.
686 *
687 * @param mixed $key
688 * @param mixed $value
689 * @return void
690 */
691 #[\ReturnTypeWillChange]
692 public function offsetSet($key, $value)
693 {
694 $this->items->put($key, $value);
695 }
696
697 /**
698 * Unset the item at the given key.
699 *
700 * @param mixed $key
701 * @return void
702 */
703 #[\ReturnTypeWillChange]
704 public function offsetUnset($key)
705 {
706 $this->items->forget($key);
707 }
708
709 /**
710 * Make dynamic calls into the collection.
711 *
712 * @param string $method
713 * @param array $parameters
714 * @return mixed
715 */
716 public function __call($method, $parameters)
717 {
718 return $this->forwardCallTo($this->getCollection(), $method, $parameters);
719 }
720
721 /**
722 * Render the contents of the paginator when casting to a string.
723 *
724 * @return string
725 */
726 public function __toString()
727 {
728 return (string) $this->toArray();
729 }
730 }
731