PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.23
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.23
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.23, at vendor/wpfluent/framework/src/WPFluent/Pagination/AbstractPaginator.php

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