Completed
Push — master ( dc784f...42ddab )
by Song
07:01 queued 47s
created

Grid::disableCreation()   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 0
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 Illuminate\Support\Traits\Macroable;
21
use Jenssegers\Mongodb\Eloquent\Model as MongodbModel;
22
23
class Grid
24
{
25
    use Concerns\HasElementNames,
26
        Concerns\HasHeader,
27
        Concerns\HasFooter,
28
        Concerns\HasFilter,
29
        Concerns\HasTools,
30
        Concerns\HasTotalRow,
31
        Concerns\CanHidesColumns,
32
        Concerns\HasHotKeys,
33
        Macroable {
34
            __call as macroCall;
35
        }
36
37
    /**
38
     * The grid data model instance.
39
     *
40
     * @var \Encore\Admin\Grid\Model
41
     */
42
    protected $model;
43
44
    /**
45
     * Collection of all grid columns.
46
     *
47
     * @var \Illuminate\Support\Collection
48
     */
49
    protected $columns;
50
51
    /**
52
     * Collection of all data rows.
53
     *
54
     * @var \Illuminate\Support\Collection
55
     */
56
    protected $rows;
57
58
    /**
59
     * Rows callable fucntion.
60
     *
61
     * @var \Closure
62
     */
63
    protected $rowsCallback;
64
65
    /**
66
     * All column names of the grid.
67
     *
68
     * @var array
69
     */
70
    public $columnNames = [];
71
72
    /**
73
     * Grid builder.
74
     *
75
     * @var \Closure
76
     */
77
    protected $builder;
78
79
    /**
80
     * Mark if the grid is builded.
81
     *
82
     * @var bool
83
     */
84
    protected $builded = false;
85
86
    /**
87
     * All variables in grid view.
88
     *
89
     * @var array
90
     */
91
    protected $variables = [];
92
93
    /**
94
     * Resource path of the grid.
95
     *
96
     * @var
97
     */
98
    protected $resourcePath;
99
100
    /**
101
     * Default primary key name.
102
     *
103
     * @var string
104
     */
105
    protected $keyName = 'id';
106
107
    /**
108
     * Export driver.
109
     *
110
     * @var string
111
     */
112
    protected $exporter;
113
114
    /**
115
     * View for grid to render.
116
     *
117
     * @var string
118
     */
119
    protected $view = 'admin::grid.table';
120
121
    /**
122
     * Per-page options.
123
     *
124
     * @var array
125
     */
126
    public $perPages = [10, 20, 30, 50, 100];
127
128
    /**
129
     * Default items count per-page.
130
     *
131
     * @var int
132
     */
133
    public $perPage = 20;
134
135
    /**
136
     * Callback for grid actions.
137
     *
138
     * @var Closure
139
     */
140
    protected $actionsCallback;
141
142
    /**
143
     * Actions column display class.
144
     *
145
     * @var string
146
     */
147
    protected $actionsClass = Displayers\Actions::class;
148
149
    /**
150
     * Options for grid.
151
     *
152
     * @var array
153
     */
154
    protected $options = [
155
        'show_pagination'        => true,
156
        'show_tools'             => true,
157
        'show_filter'            => true,
158
        'show_exporter'          => true,
159
        'show_actions'           => true,
160
        'show_row_selector'      => true,
161
        'show_create_btn'        => true,
162
        'show_column_selector'   => true,
163
    ];
164
165
    /**
166
     * @var string
167
     */
168
    public $tableID;
169
170
    /**
171
     * Initialization closure array.
172
     *
173
     * @var []Closure
174
     */
175
    protected static $initCallbacks = [];
176
177
    /**
178
     * Create a new grid instance.
179
     *
180
     * @param Eloquent $model
181
     * @param Closure  $builder
182
     */
183
    public function __construct(Eloquent $model, Closure $builder = null)
184
    {
185
        $this->model = new Model($model, $this);
186
        $this->keyName = $model->getKeyName();
187
        $this->builder = $builder;
188
189
        $this->initialize();
190
191
        $this->handleExportRequest();
192
193
        $this->callInitCallbacks();
194
    }
195
196
    /**
197
     * Initialize.
198
     */
199
    protected function initialize()
200
    {
201
        $this->tableID = uniqid('grid-table');
202
203
        $this->columns = Collection::make();
204
        $this->rows = Collection::make();
205
206
        $this->initTools()
207
            ->initFilter();
208
    }
209
210
    /**
211
     * Initialize with user pre-defined default disables and exporter, etc.
212
     *
213
     * @param Closure $callback
214
     */
215
    public static function init(Closure $callback = null)
216
    {
217
        static::$initCallbacks[] = $callback;
218
    }
219
220
    /**
221
     * Call the initialization closure array in sequence.
222
     */
223
    protected function callInitCallbacks()
224
    {
225
        if (empty(static::$initCallbacks)) {
226
            return;
227
        }
228
229
        foreach (static::$initCallbacks as $callback) {
230
            call_user_func($callback, $this);
231
        }
232
    }
233
234
    /**
235
     * Handle export request.
236
     *
237
     * @param bool $forceExport
238
     */
239
    protected function handleExportRequest($forceExport = false)
240
    {
241
        if (!$scope = request(Exporter::$queryName)) {
242
            return;
243
        }
244
245
        // clear output buffer.
246
        if (ob_get_length()) {
247
            ob_end_clean();
248
        }
249
250
        $this->model()->usePaginate(false);
251
252
        if ($this->builder) {
253
            call_user_func($this->builder, $this);
254
255
            $this->getExporter($scope)->export();
256
        }
257
258
        if ($forceExport) {
259
            $this->getExporter($scope)->export();
260
        }
261
    }
262
263
    /**
264
     * @param string $scope
265
     *
266
     * @return AbstractExporter
267
     */
268
    protected function getExporter($scope)
269
    {
270
        return (new Exporter($this))->resolve($this->exporter)->withScope($scope);
271
    }
272
273
    /**
274
     * Get or set option for grid.
275
     *
276
     * @param string $key
277
     * @param mixed  $value
278
     *
279
     * @return $this|mixed
280
     */
281
    public function option($key, $value = null)
282
    {
283
        if (is_null($value)) {
284
            return $this->options[$key];
285
        }
286
287
        $this->options[$key] = $value;
288
289
        return $this;
290
    }
291
292
    /**
293
     * Get primary key name of model.
294
     *
295
     * @return string
296
     */
297
    public function getKeyName()
298
    {
299
        return $this->keyName ?: 'id';
300
    }
301
302
    /**
303
     * Add a column to Grid.
304
     *
305
     * @param string $name
306
     * @param string $label
307
     *
308
     * @return Column
309
     */
310
    public function column($name, $label = '')
311
    {
312
        if (Str::contains($name, '.')) {
313
            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 313 which is incompatible with the return type documented by Encore\Admin\Grid::column of type Encore\Admin\Grid\Column.
Loading history...
314
        }
315
316
        if (Str::contains($name, '->')) {
317
            return $this->addJsonColumn($name, $label);
318
        }
319
320
        return $this->__call($name, array_filter([$label]));
321
    }
322
323
    /**
324
     * Batch add column to grid.
325
     *
326
     * @example
327
     * 1.$grid->columns(['name' => 'Name', 'email' => 'Email' ...]);
328
     * 2.$grid->columns('name', 'email' ...)
329
     *
330
     * @param array $columns
331
     *
332
     * @return Collection|null
333
     */
334
    public function columns($columns = [])
335
    {
336
        if (func_num_args() == 0) {
337
            return $this->columns;
338
        }
339
340
        if (func_num_args() == 1 && is_array($columns)) {
341
            foreach ($columns as $column => $label) {
342
                $this->column($column, $label);
343
            }
344
345
            return;
346
        }
347
348
        foreach (func_get_args() as $column) {
349
            $this->column($column);
350
        }
351
    }
352
353
    /**
354
     * Add column to grid.
355
     *
356
     * @param string $column
357
     * @param string $label
358
     *
359
     * @return Column
360
     */
361 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...
362
    {
363
        $column = new Column($column, $label);
364
        $column->setGrid($this);
365
366
        return tap($column, function ($value) {
367
            $this->columns->push($value);
368
        });
369
    }
370
371
    /**
372
     * Add a relation column to grid.
373
     *
374
     * @param string $name
375
     * @param string $label
376
     *
377
     * @return $this|bool|Column
378
     */
379
    protected function addRelationColumn($name, $label = '')
380
    {
381
        list($relation, $column) = explode('.', $name);
382
383
        $model = $this->model()->eloquent();
384
385
        if (!method_exists($model, $relation) || !$model->{$relation}() instanceof Relations\Relation) {
386
            $class = get_class($model);
387
388
            admin_error("Call to undefined relationship [{$relation}] on model [{$class}].");
389
390
            return $this;
391
        }
392
393
        $name = Str::snake($relation).'.'.$column;
394
395
        $this->model()->with($relation);
396
397
        return $this->addColumn($name, $label)->setRelation($relation, $column);
398
    }
399
400
    /**
401
     * Add a json type column to grid.
402
     *
403
     * @param string $name
404
     * @param string $label
405
     *
406
     * @return Column
407
     */
408
    protected function addJsonColumn($name, $label = '')
409
    {
410
        $column = substr($name, strrpos($name, '->') + 2);
411
412
        $name = str_replace('->', '.', $name);
413
414
        return $this->addColumn($name, $label ?: ucfirst($column));
415
    }
416
417
    /**
418
     * Prepend column to grid.
419
     *
420
     * @param string $column
421
     * @param string $label
422
     *
423
     * @return Column
424
     */
425 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...
426
    {
427
        $column = new Column($column, $label);
428
        $column->setGrid($this);
429
430
        return tap($column, function ($value) {
431
            $this->columns->prepend($value);
432
        });
433
    }
434
435
    /**
436
     * Get Grid model.
437
     *
438
     * @return Model
439
     */
440
    public function model()
441
    {
442
        return $this->model;
443
    }
444
445
    /**
446
     * Paginate the grid.
447
     *
448
     * @param int $perPage
449
     *
450
     * @return void
451
     */
452
    public function paginate($perPage = 20)
453
    {
454
        $this->perPage = $perPage;
455
456
        $this->model()->setPerPage($perPage);
457
    }
458
459
    /**
460
     * Get the grid paginator.
461
     *
462
     * @return mixed
463
     */
464
    public function paginator()
465
    {
466
        return new Tools\Paginator($this);
467
    }
468
469
    /**
470
     * Disable grid pagination.
471
     *
472
     * @return $this
473
     */
474
    public function disablePagination(bool $disable = true)
475
    {
476
        $this->model->usePaginate(!$disable);
477
478
        return $this->option('show_pagination', !$disable);
479
    }
480
481
    /**
482
     * If this grid use pagination.
483
     *
484
     * @return bool
485
     */
486
    public function showPagination()
487
    {
488
        return $this->option('show_pagination');
489
    }
490
491
    /**
492
     * Set per-page options.
493
     *
494
     * @param array $perPages
495
     */
496
    public function perPages(array $perPages)
497
    {
498
        $this->perPages = $perPages;
499
    }
500
501
    /**
502
     * Disable all actions.
503
     *
504
     * @return $this
505
     */
506
    public function disableActions(bool $disable = true)
507
    {
508
        return $this->option('show_actions', !$disable);
509
    }
510
511
    /**
512
     * Set grid action callback.
513
     *
514
     * @param Closure|string $actions
515
     *
516
     * @return $this
517
     */
518
    public function actions($actions)
519
    {
520
        if ($actions instanceof Closure) {
521
            $this->actionsCallback = $actions;
522
        }
523
524
        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...
525
            $this->actionsClass = $actions;
526
        }
527
528
        return $this;
529
    }
530
531
    /**
532
     * Set grid batch-action callback.
533
     *
534
     * @param Closure $closure
535
     *
536
     * @return $this
537
     */
538
    public function batchActions(Closure $closure)
539
    {
540
        $this->tools(function (Tools $tools) use ($closure) {
541
            $tools->batch($closure);
542
        });
543
544
        return $this;
545
    }
546
547
    /**
548
     * Add `actions` column for grid.
549
     *
550
     * @return void
551
     */
552
    protected function appendActionsColumn()
553
    {
554
        if (!$this->option('show_actions')) {
555
            return;
556
        }
557
558
        $this->addColumn(Column::ACTION_COLUMN_NAME, trans('admin.action'))
559
            ->displayUsing($this->actionsClass, [$this->actionsCallback]);
560
    }
561
562
    /**
563
     * Disable row selector.
564
     *
565
     * @return Grid|mixed
566
     */
567
    public function disableRowSelector(bool $disable = true)
568
    {
569
        $this->tools->disableBatchActions($disable);
570
571
        return $this->option('show_row_selector', !$disable);
572
    }
573
574
    /**
575
     * Prepend checkbox column for grid.
576
     *
577
     * @return void
578
     */
579
    protected function prependRowSelectorColumn()
580
    {
581
        if (!$this->option('show_row_selector')) {
582
            return;
583
        }
584
585
        $checkAllBox = "<input type=\"checkbox\" class=\"{$this->getSelectAllName()}\" />&nbsp;";
586
587
        $this->prependColumn(Column::SELECT_COLUMN_NAME, ' ')
588
            ->displayUsing(Displayers\RowSelector::class)
589
            ->addHeader($checkAllBox);
590
    }
591
592
    /**
593
     * Apply column filter to grid query.
594
     *
595
     * @return void
596
     */
597
    protected function applyColumnFilter()
598
    {
599
        $this->columns->each->bindFilterQuery($this->model());
600
    }
601
602
    /**
603
     * Build the grid.
604
     *
605
     * @return void
606
     */
607
    public function build()
608
    {
609
        if ($this->builded) {
610
            return;
611
        }
612
613
        $this->applyQuickSearch();
614
615
        $this->applyColumnFilter();
616
617
        $collection = $this->applyFilter(false);
618
619
        $this->prependRowSelectorColumn();
620
        $this->appendActionsColumn();
621
622
        Column::setOriginalGridModels($collection);
623
624
        $data = $collection->toArray();
625
626
        $this->columns->map(function (Column $column) use (&$data) {
627
            $data = $column->fill($data);
628
629
            $this->columnNames[] = $column->getName();
630
        });
631
632
        $this->buildRows($data);
633
634
        $this->builded = true;
635
    }
636
637
    /**
638
     * Build the grid rows.
639
     *
640
     * @param array $data
641
     *
642
     * @return void
643
     */
644
    protected function buildRows(array $data)
645
    {
646
        $this->rows = collect($data)->map(function ($model, $number) {
647
            return new Row($number, $model);
648
        });
649
650
        if ($this->rowsCallback) {
651
            $this->rows->map($this->rowsCallback);
652
        }
653
    }
654
655
    /**
656
     * Set grid row callback function.
657
     *
658
     * @param Closure $callable
659
     *
660
     * @return Collection|null
661
     */
662
    public function rows(Closure $callable = null)
663
    {
664
        if (is_null($callable)) {
665
            return $this->rows;
666
        }
667
668
        $this->rowsCallback = $callable;
669
    }
670
671
    /**
672
     * Set exporter driver for Grid to export.
673
     *
674
     * @param $exporter
675
     *
676
     * @return $this
677
     */
678
    public function exporter($exporter)
679
    {
680
        $this->exporter = $exporter;
681
682
        return $this;
683
    }
684
685
    /**
686
     * Get the export url.
687
     *
688
     * @param int  $scope
689
     * @param null $args
690
     *
691
     * @return string
692
     */
693
    public function getExportUrl($scope = 1, $args = null)
694
    {
695
        $input = array_merge(Input::all(), Exporter::formatExportQuery($scope, $args));
696
697
        if ($constraints = $this->model()->getConstraints()) {
698
            $input = array_merge($input, $constraints);
699
        }
700
701
        return $this->resource().'?'.http_build_query($input);
702
    }
703
704
    /**
705
     * Get create url.
706
     *
707
     * @return string
708
     */
709
    public function getCreateUrl()
710
    {
711
        $queryString = '';
712
713
        if ($constraints = $this->model()->getConstraints()) {
714
            $queryString = http_build_query($constraints);
715
        }
716
717
        return sprintf('%s/create%s',
718
            $this->resource(),
719
            $queryString ? ('?'.$queryString) : ''
720
        );
721
    }
722
723
    /**
724
     * If grid show export btn.
725
     *
726
     * @return bool
727
     */
728
    public function showExportBtn()
729
    {
730
        return $this->option('show_exporter');
731
    }
732
733
    /**
734
     * Disable export.
735
     *
736
     * @return $this
737
     */
738
    public function disableExport(bool $disable = true)
739
    {
740
        return $this->option('show_exporter', !$disable);
741
    }
742
743
    /**
744
     * Render export button.
745
     *
746
     * @return string
747
     */
748
    public function renderExportButton()
749
    {
750
        return (new Tools\ExportButton($this))->render();
751
    }
752
753
    /**
754
     * Alias for method `disableCreateButton`.
755
     *
756
     * @return $this
757
     *
758
     * @deprecated
759
     */
760
    public function disableCreation()
761
    {
762
        return $this->disableCreateButton();
763
    }
764
765
    /**
766
     * Remove create button on grid.
767
     *
768
     * @return $this
769
     */
770
    public function disableCreateButton(bool $disable = true)
771
    {
772
        return $this->option('show_create_btn', !$disable);
773
    }
774
775
    /**
776
     * If allow creation.
777
     *
778
     * @return bool
779
     */
780
    public function showCreateBtn()
781
    {
782
        return $this->option('show_create_btn');
783
    }
784
785
    /**
786
     * Render create button for grid.
787
     *
788
     * @return string
789
     */
790
    public function renderCreateButton()
791
    {
792
        return (new Tools\CreateButton($this))->render();
793
    }
794
795
    /**
796
     * Get current resource uri.
797
     *
798
     * @param string $path
799
     *
800
     * @return string
801
     */
802
    public function resource($path = null)
803
    {
804
        if (!empty($path)) {
805
            $this->resourcePath = $path;
806
807
            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...
808
        }
809
810
        if (!empty($this->resourcePath)) {
811
            return $this->resourcePath;
812
        }
813
814
        return app('request')->getPathInfo();
815
    }
816
817
    /**
818
     * Handle get mutator column for grid.
819
     *
820
     * @param string $method
821
     * @param string $label
822
     *
823
     * @return bool|Column
824
     */
825
    protected function handleGetMutatorColumn($method, $label)
826
    {
827
        if ($this->model()->eloquent()->hasGetMutator($method)) {
828
            return $this->addColumn($method, $label);
829
        }
830
831
        return false;
832
    }
833
834
    /**
835
     * Handle relation column for grid.
836
     *
837
     * @param string $method
838
     * @param string $label
839
     *
840
     * @return bool|Column
841
     */
842
    protected function handleRelationColumn($method, $label)
843
    {
844
        $model = $this->model()->eloquent();
845
846
        if (!method_exists($model, $method)) {
847
            return false;
848
        }
849
850
        if (!($relation = $model->$method()) instanceof Relations\Relation) {
851
            return false;
852
        }
853
854
        if ($relation instanceof Relations\HasOne ||
855
            $relation instanceof Relations\BelongsTo ||
856
            $relation instanceof Relations\MorphOne
857
        ) {
858
            $this->model()->with($method);
859
860
            return $this->addColumn($method, $label)->setRelation(Str::snake($method));
861
        }
862
863
        if ($relation instanceof Relations\HasMany
864
            || $relation instanceof Relations\BelongsToMany
865
            || $relation instanceof Relations\MorphToMany
866
            || $relation instanceof Relations\HasManyThrough
867
        ) {
868
            $this->model()->with($method);
869
870
            return $this->addColumn(Str::snake($method), $label);
871
        }
872
873
        return false;
874
    }
875
876
    /**
877
     * Dynamically add columns to the grid view.
878
     *
879
     * @param $method
880
     * @param $arguments
881
     *
882
     * @return Column
883
     */
884
    public function __call($method, $arguments)
885
    {
886
        if (static::hasMacro($method)) {
887
            return $this->macroCall($method, $arguments);
888
        }
889
890
        $label = $arguments[0] ?? null;
891
892
        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...
893
            return $this->addColumn($method, $label);
894
        }
895
896
        if ($column = $this->handleGetMutatorColumn($method, $label)) {
897
            return $column;
898
        }
899
900
        if ($column = $this->handleRelationColumn($method, $label)) {
901
            return $column;
902
        }
903
904
        return $this->addColumn($method, $label);
905
    }
906
907
    /**
908
     * Register column displayers.
909
     *
910
     * @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...
911
     */
912
    public static function registerColumnDisplayer()
913
    {
914
        $map = [
915
            'editable'    => Displayers\Editable::class,
916
            'switch'      => Displayers\SwitchDisplay::class,
917
            'switchGroup' => Displayers\SwitchGroup::class,
918
            'select'      => Displayers\Select::class,
919
            'image'       => Displayers\Image::class,
920
            'label'       => Displayers\Label::class,
921
            'button'      => Displayers\Button::class,
922
            'link'        => Displayers\Link::class,
923
            'badge'       => Displayers\Badge::class,
924
            'progressBar' => Displayers\ProgressBar::class,
925
            'radio'       => Displayers\Radio::class,
926
            'checkbox'    => Displayers\Checkbox::class,
927
            'orderable'   => Displayers\Orderable::class,
928
            'table'       => Displayers\Table::class,
929
            'expand'      => Displayers\Expand::class,
930
            'modal'       => Displayers\Modal::class,
931
            'carousel'    => Displayers\Carousel::class,
932
            'downloadable'=> Displayers\Downloadable::class,
933
            'copyable'    => Displayers\Copyable::class,
934
            'qrcode'      => Displayers\QRCode::class,
935
        ];
936
937
        foreach ($map as $abstract => $class) {
938
            Column::extend($abstract, $class);
939
        }
940
    }
941
942
    /**
943
     * Add variables to grid view.
944
     *
945
     * @param array $variables
946
     *
947
     * @return $this
948
     */
949
    public function with($variables = [])
950
    {
951
        $this->variables = $variables;
952
953
        return $this;
954
    }
955
956
    /**
957
     * Get all variables will used in grid view.
958
     *
959
     * @return array
960
     */
961
    protected function variables()
962
    {
963
        $this->variables['grid'] = $this;
964
965
        return $this->variables;
966
    }
967
968
    /**
969
     * Set a view to render.
970
     *
971
     * @param string $view
972
     * @param array  $variables
973
     */
974
    public function setView($view, $variables = [])
975
    {
976
        if (!empty($variables)) {
977
            $this->with($variables);
978
        }
979
980
        $this->view = $view;
981
    }
982
983
    /**
984
     * Set grid title.
985
     *
986
     * @param string $title
987
     *
988
     * @return $this
989
     */
990
    public function setTitle($title)
991
    {
992
        $this->variables['title'] = $title;
993
994
        return $this;
995
    }
996
997
    /**
998
     * Set relation for grid.
999
     *
1000
     * @param Relations\Relation $relation
1001
     *
1002
     * @return $this
1003
     */
1004
    public function setRelation(Relations\Relation $relation)
1005
    {
1006
        $this->model()->setRelation($relation);
1007
1008
        return $this;
1009
    }
1010
1011
    /**
1012
     * Set resource path for grid.
1013
     *
1014
     * @param string $path
1015
     *
1016
     * @return $this
1017
     */
1018
    public function setResource($path)
1019
    {
1020
        $this->resourcePath = $path;
1021
1022
        return $this;
1023
    }
1024
1025
    /**
1026
     * Get the string contents of the grid view.
1027
     *
1028
     * @return string
1029
     */
1030
    public function render()
1031
    {
1032
        $this->handleExportRequest(true);
1033
1034
        try {
1035
            $this->build();
1036
        } catch (\Exception $e) {
1037
            return Handler::renderException($e);
1038
        }
1039
1040
        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...
1041
    }
1042
}
1043