Completed
Push — master ( 69a7c6...5199b6 )
by Song
02:55
created

Grid::disableExport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin;
4
5
use Closure;
6
use Encore\Admin\Exception\Handler;
7
use Encore\Admin\Grid\Column;
8
use Encore\Admin\Grid\Concerns;
9
use Encore\Admin\Grid\Displayers;
10
use Encore\Admin\Grid\Exporter;
11
use Encore\Admin\Grid\Exporters\AbstractExporter;
12
use Encore\Admin\Grid\Model;
13
use Encore\Admin\Grid\Row;
14
use Encore\Admin\Grid\Tools;
15
use Illuminate\Database\Eloquent\Model as Eloquent;
16
use Illuminate\Database\Eloquent\Relations;
17
use Illuminate\Support\Collection;
18
use Illuminate\Support\Facades\Input;
19
use Illuminate\Support\Str;
20
use Jenssegers\Mongodb\Eloquent\Model as MongodbModel;
21
22
class Grid
23
{
24
    use Concerns\HasElementNames,
25
        Concerns\HasHeader,
26
        Concerns\HasFooter,
27
        Concerns\HasFilter,
28
        Concerns\HasTools,
29
        Concerns\HasTotalRow,
30
        Concerns\CanHidesColumns;
31
32
    /**
33
     * The grid data model instance.
34
     *
35
     * @var \Encore\Admin\Grid\Model
36
     */
37
    protected $model;
38
39
    /**
40
     * Collection of all grid columns.
41
     *
42
     * @var \Illuminate\Support\Collection
43
     */
44
    protected $columns;
45
46
    /**
47
     * Collection of all data rows.
48
     *
49
     * @var \Illuminate\Support\Collection
50
     */
51
    protected $rows;
52
53
    /**
54
     * Rows callable fucntion.
55
     *
56
     * @var \Closure
57
     */
58
    protected $rowsCallback;
59
60
    /**
61
     * All column names of the grid.
62
     *
63
     * @var array
64
     */
65
    public $columnNames = [];
66
67
    /**
68
     * Grid builder.
69
     *
70
     * @var \Closure
71
     */
72
    protected $builder;
73
74
    /**
75
     * Mark if the grid is builded.
76
     *
77
     * @var bool
78
     */
79
    protected $builded = false;
80
81
    /**
82
     * All variables in grid view.
83
     *
84
     * @var array
85
     */
86
    protected $variables = [];
87
88
    /**
89
     * Resource path of the grid.
90
     *
91
     * @var
92
     */
93
    protected $resourcePath;
94
95
    /**
96
     * Default primary key name.
97
     *
98
     * @var string
99
     */
100
    protected $keyName = 'id';
101
102
    /**
103
     * Export driver.
104
     *
105
     * @var string
106
     */
107
    protected $exporter;
108
109
    /**
110
     * View for grid to render.
111
     *
112
     * @var string
113
     */
114
    protected $view = 'admin::grid.table';
115
116
    /**
117
     * Per-page options.
118
     *
119
     * @var array
120
     */
121
    public $perPages = [10, 20, 30, 50, 100];
122
123
    /**
124
     * Default items count per-page.
125
     *
126
     * @var int
127
     */
128
    public $perPage = 20;
129
130
    /**
131
     * Callback for grid actions.
132
     *
133
     * @var Closure
134
     */
135
    protected $actionsCallback;
136
137
    /**
138
     * Actions column display class.
139
     *
140
     * @var string
141
     */
142
    protected $actionsClass = Displayers\Actions::class;
143
144
    /**
145
     * Options for grid.
146
     *
147
     * @var array
148
     */
149
    protected $options = [
150
        'show_pagination'        => true,
151
        'show_tools'             => true,
152
        'show_filter'            => true,
153
        'show_exporter'          => true,
154
        'show_actions'           => true,
155
        'show_row_selector'      => true,
156
        'show_create_btn'        => true,
157
        'show_column_selector'   => true,
158
    ];
159
160
    /**
161
     * @var string
162
     */
163
    public $tableID;
164
165
    /**
166
     * Initialization closure array.
167
     *
168
     * @var []Closure
169
     */
170
    protected static $initCallbacks = [];
171
172
    /**
173
     * Create a new grid instance.
174
     *
175
     * @param Eloquent $model
176
     * @param Closure  $builder
177
     */
178
    public function __construct(Eloquent $model, Closure $builder = null)
179
    {
180
        $this->model = new Model($model, $this);
181
        $this->keyName = $model->getKeyName();
182
        $this->builder = $builder;
183
184
        $this->initialize();
185
186
        $this->handleExportRequest();
187
188
        $this->callInitCallbacks();
189
    }
190
191
    /**
192
     * Initialize.
193
     */
194
    protected function initialize()
195
    {
196
        $this->tableID = uniqid('grid-table');
197
198
        $this->columns = Collection::make();
199
        $this->rows = Collection::make();
200
201
        $this->initTools()
202
            ->initFilter();
203
    }
204
205
    /**
206
     * Initialize with user pre-defined default disables and exporter, etc.
207
     *
208
     * @param Closure $callback
209
     */
210
    public static function init(Closure $callback = null)
211
    {
212
        static::$initCallbacks[] = $callback;
213
    }
214
215
    /**
216
     * Call the initialization closure array in sequence.
217
     */
218
    protected function callInitCallbacks()
219
    {
220
        if (empty(static::$initCallbacks)) {
221
            return;
222
        }
223
224
        foreach (static::$initCallbacks as $callback) {
225
            call_user_func($callback, $this);
226
        }
227
    }
228
229
    /**
230
     * Handle export request.
231
     *
232
     * @param bool $forceExport
233
     */
234
    protected function handleExportRequest($forceExport = false)
235
    {
236
        if (!$scope = request(Exporter::$queryName)) {
237
            return;
238
        }
239
240
        // clear output buffer.
241
        if (ob_get_length()) {
242
            ob_end_clean();
243
        }
244
245
        $this->model()->usePaginate(false);
246
247
        if ($this->builder) {
248
            call_user_func($this->builder, $this);
249
250
            $this->getExporter($scope)->export();
251
        }
252
253
        if ($forceExport) {
254
            $this->getExporter($scope)->export();
255
        }
256
    }
257
258
    /**
259
     * @param string $scope
260
     *
261
     * @return AbstractExporter
262
     */
263
    protected function getExporter($scope)
264
    {
265
        return (new Exporter($this))->resolve($this->exporter)->withScope($scope);
266
    }
267
268
    /**
269
     * Get or set option for grid.
270
     *
271
     * @param string $key
272
     * @param mixed  $value
273
     *
274
     * @return $this|mixed
275
     */
276
    public function option($key, $value = null)
277
    {
278
        if (is_null($value)) {
279
            return $this->options[$key];
280
        }
281
282
        $this->options[$key] = $value;
283
284
        return $this;
285
    }
286
287
    /**
288
     * Get primary key name of model.
289
     *
290
     * @return string
291
     */
292
    public function getKeyName()
293
    {
294
        return $this->keyName ?: 'id';
295
    }
296
297
    /**
298
     * Add a column to Grid.
299
     *
300
     * @param string $name
301
     * @param string $label
302
     *
303
     * @return Column
304
     */
305
    public function column($name, $label = '')
306
    {
307
        if (Str::contains($name, '.')) {
308
            return $this->addRelationColumn($name, $label);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->addRelationColumn($name, $label); of type Encore\Admin\Grid|Encore\Admin\Grid\Column adds the type Encore\Admin\Grid to the return on line 308 which is incompatible with the return type documented by Encore\Admin\Grid::column of type Encore\Admin\Grid\Column.
Loading history...
309
        }
310
311
        if (Str::contains($name, '->')) {
312
            return $this->addJsonColumn($name, $label);
313
        }
314
315
        return $this->__call($name, array_filter([$label]));
316
    }
317
318
    /**
319
     * Batch add column to grid.
320
     *
321
     * @example
322
     * 1.$grid->columns(['name' => 'Name', 'email' => 'Email' ...]);
323
     * 2.$grid->columns('name', 'email' ...)
324
     *
325
     * @param array $columns
326
     *
327
     * @return Collection|null
328
     */
329
    public function columns($columns = [])
330
    {
331
        if (func_num_args() == 0) {
332
            return $this->columns;
333
        }
334
335
        if (func_num_args() == 1 && is_array($columns)) {
336
            foreach ($columns as $column => $label) {
337
                $this->column($column, $label);
338
            }
339
340
            return;
341
        }
342
343
        foreach (func_get_args() as $column) {
344
            $this->column($column);
345
        }
346
    }
347
348
    /**
349
     * Add column to grid.
350
     *
351
     * @param string $column
352
     * @param string $label
353
     *
354
     * @return Column
355
     */
356 View Code Duplication
    protected function addColumn($column = '', $label = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
357
    {
358
        $column = new Column($column, $label);
359
        $column->setGrid($this);
360
361
        return tap($column, function ($value) {
362
            $this->columns->push($value);
363
        });
364
    }
365
366
    /**
367
     * Add a relation column to grid.
368
     *
369
     * @param string $name
370
     * @param string $label
371
     *
372
     * @return $this|bool|Column
373
     */
374
    protected function addRelationColumn($name, $label = '')
375
    {
376
        list($relation, $column) = explode('.', $name);
377
378
        $model = $this->model()->eloquent();
379
380
        if (!method_exists($model, $relation) || !$model->{$relation}() instanceof Relations\Relation) {
381
            $class = get_class($model);
382
383
            admin_error("Call to undefined relationship [{$relation}] on model [{$class}].");
384
385
            return $this;
386
        }
387
388
        $name = Str::snake($relation).'.'.$column;
389
390
        $this->model()->with($relation);
391
392
        return $this->addColumn($name, $label)->setRelation($relation, $column);
393
    }
394
395
    /**
396
     * Add a json type column to grid.
397
     *
398
     * @param string $name
399
     * @param string $label
400
     *
401
     * @return Column
402
     */
403
    protected function addJsonColumn($name, $label = '')
404
    {
405
        $column = substr($name, strrpos($name, '->') + 2);
406
407
        $name = str_replace('->', '.', $name);
408
409
        return $this->addColumn($name, $label ?: ucfirst($column));
410
    }
411
412
    /**
413
     * Prepend column to grid.
414
     *
415
     * @param string $column
416
     * @param string $label
417
     *
418
     * @return Column
419
     */
420 View Code Duplication
    protected function prependColumn($column = '', $label = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
421
    {
422
        $column = new Column($column, $label);
423
        $column->setGrid($this);
424
425
        return tap($column, function ($value) {
426
            $this->columns->prepend($value);
427
        });
428
    }
429
430
    /**
431
     * Get Grid model.
432
     *
433
     * @return Model
434
     */
435
    public function model()
436
    {
437
        return $this->model;
438
    }
439
440
    /**
441
     * Paginate the grid.
442
     *
443
     * @param int $perPage
444
     *
445
     * @return void
446
     */
447
    public function paginate($perPage = 20)
448
    {
449
        $this->perPage = $perPage;
450
451
        $this->model()->setPerPage($perPage);
452
    }
453
454
    /**
455
     * Get the grid paginator.
456
     *
457
     * @return mixed
458
     */
459
    public function paginator()
460
    {
461
        return new Tools\Paginator($this);
462
    }
463
464
    /**
465
     * Disable grid pagination.
466
     *
467
     * @return $this
468
     */
469
    public function disablePagination(bool $disable = true)
470
    {
471
        $this->model->usePaginate(!$disable);
472
473
        return $this->option('show_pagination', !$disable);
474
    }
475
476
    /**
477
     * If this grid use pagination.
478
     *
479
     * @return bool
480
     */
481
    public function showPagination()
482
    {
483
        return $this->option('show_pagination');
484
    }
485
486
    /**
487
     * Set per-page options.
488
     *
489
     * @param array $perPages
490
     */
491
    public function perPages(array $perPages)
492
    {
493
        $this->perPages = $perPages;
494
    }
495
496
    /**
497
     * Disable all actions.
498
     *
499
     * @return $this
500
     */
501
    public function disableActions(bool $disable = true)
502
    {
503
        return $this->option('show_actions', !$disable);
504
    }
505
506
    /**
507
     * Set grid action callback.
508
     *
509
     * @param Closure|string $actions
510
     *
511
     * @return $this
512
     */
513
    public function actions($actions)
514
    {
515
        if ($actions instanceof Closure) {
516
            $this->actionsCallback = $actions;
517
        }
518
519
        if (is_string($actions) && is_subclass_of($actions, Displayers\Actions::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Encore\Admin\Grid\Displayers\Actions::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
520
            $this->actionsClass = $actions;
521
        }
522
523
        return $this;
524
    }
525
526
    /**
527
     * Add `actions` column for grid.
528
     *
529
     * @return void
530
     */
531
    protected function appendActionsColumn()
532
    {
533
        if (!$this->option('show_actions')) {
534
            return;
535
        }
536
537
        $this->addColumn(Column::ACTION_COLUMN_NAME, trans('admin.action'))
538
            ->displayUsing($this->actionsClass, [$this->actionsCallback]);
539
    }
540
541
    /**
542
     * Disable row selector.
543
     *
544
     * @return Grid|mixed
545
     */
546
    public function disableRowSelector(bool $disable = true)
547
    {
548
        $this->tools->disableBatchActions($disable);
549
550
        return $this->option('show_row_selector', !$disable);
551
    }
552
553
    /**
554
     * Prepend checkbox column for grid.
555
     *
556
     * @return void
557
     */
558
    protected function prependRowSelectorColumn()
559
    {
560
        if (!$this->option('show_row_selector')) {
561
            return;
562
        }
563
564
        $this->prependColumn(Column::SELECT_COLUMN_NAME, ' ')
565
            ->displayUsing(Displayers\RowSelector::class);
566
    }
567
568
    /**
569
     * Build the grid.
570
     *
571
     * @return void
572
     */
573
    public function build()
574
    {
575
        if ($this->builded) {
576
            return;
577
        }
578
579
        $collection = $this->processFilter(false);
580
581
        $data = $collection->toArray();
582
583
        $this->prependRowSelectorColumn();
584
        $this->appendActionsColumn();
585
586
        Column::setOriginalGridModels($collection);
587
588
        $this->columns->map(function (Column $column) use (&$data) {
589
            $data = $column->fill($data);
590
591
            $this->columnNames[] = $column->getName();
592
        });
593
594
        $this->buildRows($data);
595
596
        $this->builded = true;
597
    }
598
599
    /**
600
     * Build the grid rows.
601
     *
602
     * @param array $data
603
     *
604
     * @return void
605
     */
606
    protected function buildRows(array $data)
607
    {
608
        $this->rows = collect($data)->map(function ($model, $number) {
609
            return new Row($number, $model);
610
        });
611
612
        if ($this->rowsCallback) {
613
            $this->rows->map($this->rowsCallback);
614
        }
615
    }
616
617
    /**
618
     * Set grid row callback function.
619
     *
620
     * @param Closure $callable
621
     *
622
     * @return Collection|null
623
     */
624
    public function rows(Closure $callable = null)
625
    {
626
        if (is_null($callable)) {
627
            return $this->rows;
628
        }
629
630
        $this->rowsCallback = $callable;
631
    }
632
633
    /**
634
     * Set exporter driver for Grid to export.
635
     *
636
     * @param $exporter
637
     *
638
     * @return $this
639
     */
640
    public function exporter($exporter)
641
    {
642
        $this->exporter = $exporter;
643
644
        return $this;
645
    }
646
647
    /**
648
     * Get the export url.
649
     *
650
     * @param int  $scope
651
     * @param null $args
652
     *
653
     * @return string
654
     */
655
    public function getExportUrl($scope = 1, $args = null)
656
    {
657
        $input = array_merge(Input::all(), Exporter::formatExportQuery($scope, $args));
658
659
        if ($constraints = $this->model()->getConstraints()) {
660
            $input = array_merge($input, $constraints);
661
        }
662
663
        return $this->resource().'?'.http_build_query($input);
664
    }
665
666
    /**
667
     * Get create url.
668
     *
669
     * @return string
670
     */
671
    public function getCreateUrl()
672
    {
673
        $queryString = '';
674
675
        if ($constraints = $this->model()->getConstraints()) {
676
            $queryString = http_build_query($constraints);
677
        }
678
679
        return sprintf('%s/create%s',
680
            $this->resource(),
681
            $queryString ? ('?'.$queryString) : ''
682
        );
683
    }
684
685
    /**
686
     * If grid show export btn.
687
     *
688
     * @return bool
689
     */
690
    public function showExportBtn()
691
    {
692
        return $this->option('show_exporter');
693
    }
694
695
    /**
696
     * Disable export.
697
     *
698
     * @return $this
699
     */
700
    public function disableExport(bool $disable = true)
701
    {
702
        return $this->option('show_exporter', !$disable);
703
    }
704
705
    /**
706
     * Render export button.
707
     *
708
     * @return string
709
     */
710
    public function renderExportButton()
711
    {
712
        return (new Tools\ExportButton($this))->render();
713
    }
714
715
    /**
716
     * Alias for method `disableCreateButton`.
717
     *
718
     * @return $this
719
     *
720
     * @deprecated
721
     */
722
    public function disableCreation()
723
    {
724
        return $this->disableCreateButton();
725
    }
726
727
    /**
728
     * Remove create button on grid.
729
     *
730
     * @return $this
731
     */
732
    public function disableCreateButton(bool $disable = true)
733
    {
734
        return $this->option('show_create_btn', !$disable);
735
    }
736
737
    /**
738
     * If allow creation.
739
     *
740
     * @return bool
741
     */
742
    public function showCreateBtn()
743
    {
744
        return $this->option('show_create_btn');
745
    }
746
747
    /**
748
     * Render create button for grid.
749
     *
750
     * @return string
751
     */
752
    public function renderCreateButton()
753
    {
754
        return (new Tools\CreateButton($this))->render();
755
    }
756
757
    /**
758
     * Get current resource uri.
759
     *
760
     * @param string $path
761
     *
762
     * @return string
763
     */
764
    public function resource($path = null)
765
    {
766
        if (!empty($path)) {
767
            $this->resourcePath = $path;
768
769
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Encore\Admin\Grid) is incompatible with the return type documented by Encore\Admin\Grid::resource of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
770
        }
771
772
        if (!empty($this->resourcePath)) {
773
            return $this->resourcePath;
774
        }
775
776
        return app('request')->getPathInfo();
777
    }
778
779
    /**
780
     * Handle get mutator column for grid.
781
     *
782
     * @param string $method
783
     * @param string $label
784
     *
785
     * @return bool|Column
786
     */
787
    protected function handleGetMutatorColumn($method, $label)
788
    {
789
        if ($this->model()->eloquent()->hasGetMutator($method)) {
790
            return $this->addColumn($method, $label);
791
        }
792
793
        return false;
794
    }
795
796
    /**
797
     * Handle relation column for grid.
798
     *
799
     * @param string $method
800
     * @param string $label
801
     *
802
     * @return bool|Column
803
     */
804
    protected function handleRelationColumn($method, $label)
805
    {
806
        $model = $this->model()->eloquent();
807
808
        if (!method_exists($model, $method)) {
809
            return false;
810
        }
811
812
        if (!($relation = $model->$method()) instanceof Relations\Relation) {
813
            return false;
814
        }
815
816
        if ($relation instanceof Relations\HasOne ||
817
            $relation instanceof Relations\BelongsTo ||
818
            $relation instanceof Relations\MorphOne
819
        ) {
820
            $this->model()->with($method);
821
822
            return $this->addColumn($method, $label)->setRelation(Str::snake($method));
823
        }
824
825
        if ($relation instanceof Relations\HasMany
826
            || $relation instanceof Relations\BelongsToMany
827
            || $relation instanceof Relations\MorphToMany
828
            || $relation instanceof Relations\HasManyThrough
829
        ) {
830
            $this->model()->with($method);
831
832
            return $this->addColumn(Str::snake($method), $label);
833
        }
834
835
        return false;
836
    }
837
838
    /**
839
     * Dynamically add columns to the grid view.
840
     *
841
     * @param $method
842
     * @param $arguments
843
     *
844
     * @return Column
845
     */
846
    public function __call($method, $arguments)
847
    {
848
        $label = $arguments[0] ?? null;
849
850
        if ($this->model()->eloquent() instanceof MongodbModel) {
0 ignored issues
show
Bug introduced by
The class Jenssegers\Mongodb\Eloquent\Model does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
851
            return $this->addColumn($method, $label);
852
        }
853
854
        if ($column = $this->handleGetMutatorColumn($method, $label)) {
855
            return $column;
856
        }
857
858
        if ($column = $this->handleRelationColumn($method, $label)) {
859
            return $column;
860
        }
861
862
        return $this->addColumn($method, $label);
863
    }
864
865
    /**
866
     * Register column displayers.
867
     *
868
     * @return void.
0 ignored issues
show
Documentation introduced by
The doc-type void. could not be parsed: Unknown type name "void." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
869
     */
870
    public static function registerColumnDisplayer()
871
    {
872
        $map = [
873
            'editable'    => Displayers\Editable::class,
874
            'switch'      => Displayers\SwitchDisplay::class,
875
            'switchGroup' => Displayers\SwitchGroup::class,
876
            'select'      => Displayers\Select::class,
877
            'image'       => Displayers\Image::class,
878
            'label'       => Displayers\Label::class,
879
            'button'      => Displayers\Button::class,
880
            'link'        => Displayers\Link::class,
881
            'badge'       => Displayers\Badge::class,
882
            'progressBar' => Displayers\ProgressBar::class,
883
            'radio'       => Displayers\Radio::class,
884
            'checkbox'    => Displayers\Checkbox::class,
885
            'orderable'   => Displayers\Orderable::class,
886
            'table'       => Displayers\Table::class,
887
            'expand'      => Displayers\Expand::class,
888
            'modal'       => Displayers\Modal::class,
889
            'gravatar'    => Displayers\Gravatar::class,
890
            'carousel'    => Displayers\Carousel::class,
891
        ];
892
893
        foreach ($map as $abstract => $class) {
894
            Column::extend($abstract, $class);
895
        }
896
    }
897
898
    /**
899
     * Add variables to grid view.
900
     *
901
     * @param array $variables
902
     *
903
     * @return $this
904
     */
905
    public function with($variables = [])
906
    {
907
        $this->variables = $variables;
908
909
        return $this;
910
    }
911
912
    /**
913
     * Get all variables will used in grid view.
914
     *
915
     * @return array
916
     */
917
    protected function variables()
918
    {
919
        $this->variables['grid'] = $this;
920
921
        return $this->variables;
922
    }
923
924
    /**
925
     * Set a view to render.
926
     *
927
     * @param string $view
928
     * @param array  $variables
929
     */
930
    public function setView($view, $variables = [])
931
    {
932
        if (!empty($variables)) {
933
            $this->with($variables);
934
        }
935
936
        $this->view = $view;
937
    }
938
939
    /**
940
     * Set grid title.
941
     *
942
     * @param string $title
943
     *
944
     * @return $this
945
     */
946
    public function setTitle($title)
947
    {
948
        $this->variables['title'] = $title;
949
950
        return $this;
951
    }
952
953
    /**
954
     * Set relation for grid.
955
     *
956
     * @param Relations\Relation $relation
957
     *
958
     * @return $this
959
     */
960
    public function setRelation(Relations\Relation $relation)
961
    {
962
        $this->model()->setRelation($relation);
963
964
        return $this;
965
    }
966
967
    /**
968
     * Set resource path for grid.
969
     *
970
     * @param string $path
971
     *
972
     * @return $this
973
     */
974
    public function setResource($path)
975
    {
976
        $this->resourcePath = $path;
977
978
        return $this;
979
    }
980
981
    /**
982
     * Get the string contents of the grid view.
983
     *
984
     * @return string
985
     */
986
    public function render()
987
    {
988
        $this->handleExportRequest(true);
989
990
        try {
991
            $this->build();
992
        } catch (\Exception $e) {
993
            return Handler::renderException($e);
994
        }
995
996
        return view($this->view, $this->variables())->render();
0 ignored issues
show
Bug introduced by
The method render does only exist in Illuminate\View\View, but not in Illuminate\Contracts\View\Factory.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
997
    }
998
}
999