PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.0
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Pagination / AbstractPaginator.php

AbstractPaginator.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 2.7.0, at vendor/wpfluent/framework/src/WPFluent/Pagination/AbstractPaginator.php

738 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Framework\Pagination;
4
5 use Closure;
6 use FluentCommunity\Framework\Foundation\App;
7 use FluentCommunity\Framework\Support\Arr;
8 use FluentCommunity\Framework\Support\Str;
9 use FluentCommunity\Framework\Support\Helper;
10 use FluentCommunity\Framework\Support\Tappable;
11 use FluentCommunity\Framework\Support\Collection;
12 use FluentCommunity\Framework\Support\ForwardsCalls;
13
14 /**
15 * @mixin \FluentCommunity\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 \FluentCommunity\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 if (!preg_match('/^https?:\/\//i', $path)) {
439 $path = App::make('request')->url() . '/' . trim($path, '/');
440 }
441
442 $this->path = $path;
443
444 return $this;
445 }
446
447 /**
448 * Set the number of links to display on each side of current page link.
449 *
450 * @param int $count
451 * @return $this
452 */
453 public function onEachSide($count)
454 {
455 $this->onEachSide = $count;
456
457 return $this;
458 }
459
460 /**
461 * Get the base path for paginator generated URLs.
462 *
463 * @return string|null
464 */
465 public function path()
466 {
467 return $this->path;
468 }
469
470 /**
471 * Resolve the current request path or return the default value.
472 *
473 * @param string $default
474 * @return string
475 */
476 public static function resolveCurrentPath($default = '/')
477 {
478 if (isset(static::$currentPathResolver)) {
479 return call_user_func(static::$currentPathResolver);
480 }
481
482 return $default;
483 }
484
485 /**
486 * Set the current request path resolver callback.
487 *
488 * @param \Closure $resolver
489 * @return void
490 */
491 public static function currentPathResolver(Closure $resolver)
492 {
493 static::$currentPathResolver = $resolver;
494 }
495
496 /**
497 * Resolve the current page or return the default value.
498 *
499 * @param string $pageName
500 * @param int $default
501 * @return int
502 */
503 public static function resolveCurrentPage($pageName = 'page', $default = 1)
504 {
505 if (isset(static::$currentPageResolver)) {
506 return (int) call_user_func(static::$currentPageResolver, $pageName);
507 }
508
509 return $default;
510 }
511
512 /**
513 * Set the current page resolver callback.
514 *
515 * @param \Closure $resolver
516 * @return void
517 */
518 public static function currentPageResolver(Closure $resolver)
519 {
520 static::$currentPageResolver = $resolver;
521 }
522
523 /**
524 * Resolve the query string or return the default value.
525 *
526 * @param string|array|null $default
527 * @return string
528 */
529 public static function resolveQueryString($default = null)
530 {
531 if (isset(static::$queryStringResolver)) {
532 return (static::$queryStringResolver)();
533 }
534
535 return $default;
536 }
537
538 /**
539 * Set with query string resolver callback.
540 *
541 * @param \Closure $resolver
542 * @return void
543 */
544 public static function queryStringResolver(Closure $resolver)
545 {
546 static::$queryStringResolver = $resolver;
547 }
548
549 /**
550 * Render the paginator using the given view.
551 *
552 * @param string|null $view
553 * @param array $data
554 * @return \FluentCommunity\Framework\View\View
555 */
556 public function links($view = 'web.pagination.default', $data = [])
557 {
558 $elements = method_exists($this, 'elements') ? $this->elements() : null;
559
560 return App::make('view')->make($view ?: static::$defaultView, array_merge($data, [
561 'paginator' => $this,
562 'elements' => $elements
563 ]));
564 }
565
566 /**s
567 * Set the default pagination view.
568 *
569 * @param string $view
570 * @return void
571 */
572 public static function defaultView($view)
573 {
574 static::$defaultView = $view;
575 }
576
577 /**
578 * Set the default "simple" pagination view.
579 *
580 * @param string $view
581 * @return void
582 */
583 public static function defaultSimpleView($view)
584 {
585 static::$defaultSimpleView = $view;
586 }
587
588 /**
589 * Get an iterator for the items.
590 *
591 * @return \ArrayIterator
592 */
593 #[\ReturnTypeWillChange]
594 public function getIterator()
595 {
596 return $this->items->getIterator();
597 }
598
599 /**
600 * Determine if the list of items is empty.
601 *
602 * @return bool
603 */
604 public function isEmpty()
605 {
606 return $this->items->isEmpty();
607 }
608
609 /**
610 * Determine if the list of items is not empty.
611 *
612 * @return bool
613 */
614 public function isNotEmpty()
615 {
616 return $this->items->isNotEmpty();
617 }
618
619 /**
620 * Get the number of items for the current page.
621 *
622 * @return int
623 */
624 #[\ReturnTypeWillChange]
625 public function count()
626 {
627 return $this->items->count();
628 }
629
630 /**
631 * Get the paginator's underlying collection.
632 *
633 * @return \FluentCommunity\Framework\Support\Collection
634 */
635 public function getCollection()
636 {
637 return $this->items;
638 }
639
640 /**
641 * Set the paginator's underlying collection.
642 *
643 * @param \FluentCommunity\Framework\Support\Collection $collection
644 * @return $this
645 */
646 public function setCollection(Collection $collection)
647 {
648 $this->items = $collection;
649
650 return $this;
651 }
652
653 /**
654 * Get the paginator options.
655 *
656 * @return array
657 */
658 public function getOptions()
659 {
660 return $this->options;
661 }
662
663 /**
664 * Determine if the given item exists.
665 *
666 * @param mixed $key
667 * @return bool
668 */
669 #[\ReturnTypeWillChange]
670 public function offsetExists($key)
671 {
672 return $this->items->has($key);
673 }
674
675 /**
676 * Get the item at the given offset.
677 *
678 * @param mixed $key
679 * @return mixed
680 */
681 #[\ReturnTypeWillChange]
682 public function offsetGet($key)
683 {
684 return $this->items->get($key);
685 }
686
687 /**
688 * Set the item at the given offset.
689 *
690 * @param mixed $key
691 * @param mixed $value
692 * @return void
693 */
694 #[\ReturnTypeWillChange]
695 public function offsetSet($key, $value)
696 {
697 $this->items->put($key, $value);
698 }
699
700 /**
701 * Unset the item at the given key.
702 *
703 * @param mixed $key
704 * @return void
705 */
706 #[\ReturnTypeWillChange]
707 public function offsetUnset($key)
708 {
709 $this->items->forget($key);
710 }
711
712 /**
713 * Make dynamic calls into the collection.
714 *
715 * @param string $method
716 * @param array $parameters
717 * @return mixed
718 */
719 public function __call($method, $parameters)
720 {
721 return $this->forwardCallTo($this->getCollection(), $method, $parameters);
722 }
723
724 /**
725 * Render the contents of the paginator when casting to a string.
726 *
727 * @return string
728 */
729 public function __toString()
730 {
731 if (method_exists($this, 'render')) {
732 return $this->render();
733 }
734
735 return get_class($this);
736 }
737 }
738