Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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