Completed
Pull Request — master (#1791)
by
unknown
06:17 queued 02:50
created

Grid::getKeyName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
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\Displayers\Actions;
9
use Encore\Admin\Grid\Displayers\RowSelector;
10
use Encore\Admin\Grid\Exporter;
11
use Encore\Admin\Grid\Filter;
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\BelongsTo;
17
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
18
use Illuminate\Database\Eloquent\Relations\HasMany;
19
use Illuminate\Database\Eloquent\Relations\HasOne;
20
use Illuminate\Database\Eloquent\Relations\MorphToMany;
21
use Illuminate\Database\Eloquent\Relations\Relation;
22
use Illuminate\Support\Collection;
23
use Illuminate\Support\Facades\Input;
24
use Illuminate\Support\Facades\Schema;
25
use Jenssegers\Mongodb\Eloquent\Model as MongodbModel;
26
27
class Grid
28
{
29
    /**
30
     * The grid data model instance.
31
     *
32
     * @var \Encore\Admin\Grid\Model
33
     */
34
    protected $model;
35
36
    /**
37
     * Collection of all grid columns.
38
     *
39
     * @var \Illuminate\Support\Collection
40
     */
41
    protected $columns;
42
43
    /**
44
     * Collection of table columns.
45
     *
46
     * @var \Illuminate\Support\Collection
47
     */
48
    protected $dbColumns;
49
50
    /**
51
     * Collection of all data rows.
52
     *
53
     * @var \Illuminate\Support\Collection
54
     */
55
    protected $rows;
56
57
    /**
58
     * Rows callable fucntion.
59
     *
60
     * @var \Closure
61
     */
62
    protected $rowsCallback;
63
64
    /**
65
     * All column names of the grid.
66
     *
67
     * @var array
68
     */
69
    public $columnNames = [];
70
71
    /**
72
     * Grid builder.
73
     *
74
     * @var \Closure
75
     */
76
    protected $builder;
77
78
    /**
79
     * Mark if the grid is builded.
80
     *
81
     * @var bool
82
     */
83
    protected $builded = false;
84
85
    /**
86
     * All variables in grid view.
87
     *
88
     * @var array
89
     */
90
    protected $variables = [];
91
92
    /**
93
     * The grid Filter.
94
     *
95
     * @var \Encore\Admin\Grid\Filter
96
     */
97
    protected $filter;
98
99
    /**
100
     * Resource path of the grid.
101
     *
102
     * @var
103
     */
104
    protected $resourcePath;
105
106
    /**
107
     * Default primary key name.
108
     *
109
     * @var string
110
     */
111
    protected $keyName = 'id';
112
113
    /**
114
     * Export driver.
115
     *
116
     * @var string
117
     */
118
    protected $exporter;
119
120
    /**
121
     * View for grid to render.
122
     *
123
     * @var string
124
     */
125
    protected $view = 'admin::grid.table';
126
127
    /**
128
     * Per-page options.
129
     *
130
     * @var array
131
     */
132
    public $perPages = [10, 20, 30, 50, 100];
133
134
    /**
135
     * Default items count per-page.
136
     *
137
     * @var int
138
     */
139
    public $perPage = 20;
140
141
    /**
142
     * Grid's box-title
143
     */
144
    public $title = '';
145
146
    /**
147
     * Header tools.
148
     *
149
     * @var Tools
150
     */
151
    public $tools;
152
153
    /**
154
     * Callback for grid actions.
155
     *
156
     * @var Closure
157
     */
158
    protected $actionsCallback;
159
160
    /**
161
     * Options for grid.
162
     *
163
     * @var array
164
     */
165
    protected $options = [
166
        'usePagination'  => true,
167
        'useFilter'      => true,
168
        'useExporter'    => true,
169
        'useActions'     => true,
170
        'useRowSelector' => true,
171
        'allowCreate'    => true,
172
    ];
173
174
    /**
175
     * @var Tools\Footer
176
     */
177
    protected $footer;
178
179
    /**
180
     * Create a new grid instance.
181
     *
182
     * @param Eloquent $model
183
     * @param Closure  $builder
184
     */
185
    public function __construct(Eloquent $model, Closure $builder)
186
    {
187
        $this->keyName = $model->getKeyName();
188
        $this->model = new Model($model);
189
        $this->columns = new Collection();
190
        $this->rows = new Collection();
191
        $this->builder = $builder;
192
193
        $this->setupTools();
194
        $this->setupFilter();
195
        $this->setupExporter();
196
    }
197
198
    /**
199
     * Setup grid tools.
200
     */
201
    public function setupTools()
202
    {
203
        $this->tools = new Tools($this);
204
    }
205
206
    /**
207
     * Setup grid filter.
208
     *
209
     * @return void
210
     */
211
    protected function setupFilter()
212
    {
213
        $this->filter = new Filter($this->model());
214
    }
215
216
    /**
217
     * Setup grid exporter.
218
     *
219
     * @return void
220
     */
221
    protected function setupExporter()
222
    {
223
        if ($scope = Input::get(Exporter::$queryName)) {
224
            $this->model()->usePaginate(false);
225
226
            call_user_func($this->builder, $this);
227
228
            (new Exporter($this))->resolve($this->exporter)->withScope($scope)->export();
229
        }
230
    }
231
232
    /**
233
     * Get or set option for grid.
234
     *
235
     * @param string $key
236
     * @param mixed  $value
237
     *
238
     * @return $this|mixed
239
     */
240
    public function option($key, $value = null)
241
    {
242
        if (is_null($value)) {
243
            return $this->options[$key];
244
        }
245
246
        $this->options[$key] = $value;
247
248
        return $this;
249
    }
250
251
    /**
252
     * Get primary key name of model.
253
     *
254
     * @return string
255
     */
256
    public function getKeyName()
257
    {
258
        return $this->keyName ?: 'id';
259
    }
260
261
    /**
262
     * Add column to Grid.
263
     *
264
     * @param string $name
265
     * @param string $label
266
     *
267
     * @return Column
268
     */
269
    public function column($name, $label = '')
270
    {
271
        $relationName = $relationColumn = '';
272
273
        if (strpos($name, '.') !== false) {
274
            list($relationName, $relationColumn) = explode('.', $name);
275
276
            $relation = $this->model()->eloquent()->$relationName();
277
278
            $label = empty($label) ? ucfirst($relationColumn) : $label;
279
280
            $name = snake_case($relationName).'.'.$relationColumn;
281
        }
282
283
        $column = $this->addColumn($name, $label);
284
285
        if (isset($relation) && $relation instanceof Relation) {
286
            $this->model()->with($relationName);
0 ignored issues
show
Documentation Bug introduced by
The method with does not exist on object<Encore\Admin\Grid\Model>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
287
            $column->setRelation($relationName, $relationColumn);
288
        }
289
290
        return $column;
291
    }
292
293
    /**
294
     * Batch add column to grid.
295
     *
296
     * @example
297
     * 1.$grid->columns(['name' => 'Name', 'email' => 'Email' ...]);
298
     * 2.$grid->columns('name', 'email' ...)
299
     *
300
     * @param array $columns
301
     *
302
     * @return Collection|null
303
     */
304
    public function columns($columns = [])
305
    {
306
        if (func_num_args() == 0) {
307
            return $this->columns;
308
        }
309
310
        if (func_num_args() == 1 && is_array($columns)) {
311
            foreach ($columns as $column => $label) {
312
                $this->column($column, $label);
313
            }
314
315
            return;
316
        }
317
318
        foreach (func_get_args() as $column) {
319
            $this->column($column);
320
        }
321
    }
322
323
    /**
324
     * Add column to grid.
325
     *
326
     * @param string $column
327
     * @param string $label
328
     *
329
     * @return Column
330
     */
331
    protected function addColumn($column = '', $label = '')
332
    {
333
        $column = new Column($column, $label);
334
        $column->setGrid($this);
335
336
        return $this->columns[] = $column;
337
    }
338
339
    /**
340
     * Get Grid model.
341
     *
342
     * @return Model
343
     */
344
    public function model()
345
    {
346
        return $this->model;
347
    }
348
349
    /**
350
     * Set the Grid's box-title
351
     *
352
     * @param string $title
353
     */
354
    public function title($title)
355
    {
356
        $this->title = $title;
357
    }
358
359
    /**
360
     * Paginate the grid.
361
     *
362
     * @param int $perPage
363
     *
364
     * @return void
365
     */
366
    public function paginate($perPage = 20)
367
    {
368
        $this->perPage = $perPage;
369
370
        $this->model()->paginate($perPage);
0 ignored issues
show
Bug introduced by
The method paginate() does not exist on Encore\Admin\Grid\Model. Did you maybe mean usePaginate()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
371
    }
372
373
    /**
374
     * Get the grid paginator.
375
     *
376
     * @return mixed
377
     */
378
    public function paginator()
379
    {
380
        return new Tools\Paginator($this);
381
    }
382
383
    /**
384
     * Disable grid pagination.
385
     *
386
     * @return $this
387
     */
388
    public function disablePagination()
389
    {
390
        $this->model->usePaginate(false);
391
392
        $this->option('usePagination', false);
393
394
        return $this;
395
    }
396
397
    /**
398
     * If this grid use pagination.
399
     *
400
     * @return bool
401
     */
402
    public function usePagination()
403
    {
404
        return $this->option('usePagination');
405
    }
406
407
    /**
408
     * Set per-page options.
409
     *
410
     * @param array $perPages
411
     */
412
    public function perPages(array $perPages)
413
    {
414
        $this->perPages = $perPages;
415
    }
416
417
    /**
418
     * Disable all actions.
419
     *
420
     * @return $this
421
     */
422
    public function disableActions()
423
    {
424
        return $this->option('useActions', false);
425
    }
426
427
    /**
428
     * Set grid action callback.
429
     *
430
     * @param Closure $callback
431
     *
432
     * @return $this
433
     */
434
    public function actions(Closure $callback)
435
    {
436
        $this->actionsCallback = $callback;
437
438
        return $this;
439
    }
440
441
    /**
442
     * Add `actions` column for grid.
443
     *
444
     * @return void
445
     */
446
    protected function appendActionsColumn()
447
    {
448
        if (!$this->option('useActions')) {
449
            return;
450
        }
451
452
        $grid = $this;
453
        $callback = $this->actionsCallback;
454
        $column = $this->addColumn('__actions__', trans('admin.action'));
455
456
        $column->display(function ($value) use ($grid, $column, $callback) {
457
            $actions = new Actions($value, $grid, $column, $this);
0 ignored issues
show
Documentation introduced by
$this is of type this<Encore\Admin\Grid>, but the function expects a object<stdClass>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
458
459
            return $actions->display($callback);
460
        });
461
    }
462
463
    /**
464
     * Disable row selector.
465
     *
466
     * @return Grid|mixed
467
     */
468
    public function disableRowSelector()
469
    {
470
        $this->tools(function ($tools) {
471
            /* @var Grid\Tools $tools */
472
            $tools->disableBatchActions();
473
        });
474
475
        return $this->option('useRowSelector', false);
476
    }
477
478
    /**
479
     * Prepend checkbox column for grid.
480
     *
481
     * @return void
482
     */
483
    protected function prependRowSelectorColumn()
484
    {
485
        if (!$this->option('useRowSelector')) {
486
            return;
487
        }
488
489
        $grid = $this;
490
491
        $column = new Column(Column::SELECT_COLUMN_NAME, ' ');
492
        $column->setGrid($this);
493
494
        $column->display(function ($value) use ($grid, $column) {
495
            $actions = new RowSelector($value, $grid, $column, $this);
0 ignored issues
show
Documentation introduced by
$this is of type this<Encore\Admin\Grid>, but the function expects a object<stdClass>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
496
497
            return $actions->display();
498
        });
499
500
        $this->columns->prepend($column);
501
    }
502
503
    /**
504
     * Build the grid.
505
     *
506
     * @return void
507
     */
508
    public function build()
509
    {
510
        if ($this->builded) {
511
            return;
512
        }
513
514
        $data = $this->processFilter();
515
516
        $this->prependRowSelectorColumn();
517
        $this->appendActionsColumn();
518
519
        Column::setOriginalGridData($data);
520
521
        $this->columns->map(function (Column $column) use (&$data) {
522
            $data = $column->fill($data);
523
524
            $this->columnNames[] = $column->getName();
525
        });
526
527
        $this->buildRows($data);
528
529
        $this->builded = true;
530
    }
531
532
    /**
533
     * Disable grid filter.
534
     *
535
     * @return $this
536
     */
537
    public function disableFilter()
538
    {
539
        $this->option('useFilter', false);
540
541
        return $this;
542
    }
543
544
    /**
545
     * Get filter of Grid.
546
     *
547
     * @return Filter
548
     */
549
    public function getFilter()
550
    {
551
        return $this->filter;
552
    }
553
554
    /**
555
     * Process the grid filter.
556
     *
557
     * @return array
558
     */
559
    public function processFilter()
560
    {
561
        call_user_func($this->builder, $this);
562
563
        return $this->filter->execute();
564
    }
565
566
    /**
567
     * Set the grid filter.
568
     *
569
     * @param Closure $callback
570
     */
571
    public function filter(Closure $callback)
572
    {
573
        call_user_func($callback, $this->filter);
574
    }
575
576
    /**
577
     * Render the grid filter.
578
     *
579
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
580
     */
581
    public function renderFilter()
582
    {
583
        if (!$this->option('useFilter')) {
584
            return '';
585
        }
586
587
        return $this->filter->render();
588
    }
589
590
    /**
591
     * Build the grid rows.
592
     *
593
     * @param array $data
594
     *
595
     * @return void
596
     */
597
    protected function buildRows(array $data)
598
    {
599
        $this->rows = collect($data)->map(function ($model, $number) {
600
            return new Row($number, $model);
601
        });
602
603
        if ($this->rowsCallback) {
604
            $this->rows->map($this->rowsCallback);
605
        }
606
    }
607
608
    /**
609
     * Set grid row callback function.
610
     *
611
     * @param Closure $callable
612
     *
613
     * @return Collection|null
614
     */
615
    public function rows(Closure $callable = null)
616
    {
617
        if (is_null($callable)) {
618
            return $this->rows;
619
        }
620
621
        $this->rowsCallback = $callable;
622
    }
623
624
    /**
625
     * Setup grid tools.
626
     *
627
     * @param Closure $callback
628
     *
629
     * @return void
630
     */
631
    public function tools(Closure $callback)
632
    {
633
        call_user_func($callback, $this->tools);
634
    }
635
636
    /**
637
     * Render custom tools.
638
     *
639
     * @return string
640
     */
641
    public function renderHeaderTools()
642
    {
643
        return $this->tools->render();
644
    }
645
646
    /**
647
     * Set exporter driver for Grid to export.
648
     *
649
     * @param $exporter
650
     *
651
     * @return $this
652
     */
653
    public function exporter($exporter)
654
    {
655
        $this->exporter = $exporter;
656
657
        return $this;
658
    }
659
660
    /**
661
     * Get the export url.
662
     *
663
     * @param int  $scope
664
     * @param null $args
665
     *
666
     * @return string
667
     */
668
    public function exportUrl($scope = 1, $args = null)
669
    {
670
        $input = array_merge(Input::all(), Exporter::formatExportQuery($scope, $args));
671
672
        return $this->resource().'?'.http_build_query($input);
673
    }
674
675
    /**
676
     * If grid allows export.s.
677
     *
678
     * @return bool
679
     */
680
    public function allowExport()
681
    {
682
        return $this->option('useExporter');
683
    }
684
685
    /**
686
     * Disable export.
687
     *
688
     * @return $this
689
     */
690
    public function disableExport()
691
    {
692
        return $this->option('useExporter', false);
693
    }
694
695
    /**
696
     * Render export button.
697
     *
698
     * @return Tools\ExportButton
699
     */
700
    public function renderExportButton()
701
    {
702
        return new Tools\ExportButton($this);
703
    }
704
705
    /**
706
     * Alias for method `disableCreateButton`.
707
     *
708
     * @return $this
709
     *
710
     * @deprecated
711
     */
712
    public function disableCreation()
713
    {
714
        return $this->disableCreateButton();
715
    }
716
717
    /**
718
     * Remove create button on grid.
719
     *
720
     * @return $this
721
     */
722
    public function disableCreateButton()
723
    {
724
        return $this->option('allowCreate', false);
725
    }
726
727
    /**
728
     * If allow creation.
729
     *
730
     * @return bool
731
     */
732
    public function allowCreation()
733
    {
734
        return $this->option('allowCreate');
735
    }
736
737
    /**
738
     * Render create button for grid.
739
     *
740
     * @return Tools\CreateButton
741
     */
742
    public function renderCreateButton()
743
    {
744
        return new Tools\CreateButton($this);
745
    }
746
747
    /**
748
     * Set grid footer.
749
     *
750
     * @param Closure|null $closure
751
     *
752
     * @return $this|Tools\Footer
753
     */
754
    public function footer(Closure $closure = null)
755
    {
756
        if (!$closure) {
757
            return $this->footer;
758
        }
759
760
        $this->footer = $closure;
0 ignored issues
show
Documentation Bug introduced by
It seems like $closure of type object<Closure> is incompatible with the declared type object<Encore\Admin\Grid\Tools\Footer> of property $footer.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
761
762
        return $this;
763
    }
764
765
    /**
766
     * Render grid footer.
767
     *
768
     * @return Tools\Footer|string
769
     */
770
    public function renderFooter()
771
    {
772
        if (!$this->footer) {
773
            return '';
774
        }
775
776
        return new Tools\Footer($this);
777
    }
778
779
    /**
780
     * Get current resource uri.
781
     *
782
     * @param string $path
783
     *
784
     * @return string
785
     */
786
    public function resource($path = null)
787
    {
788
        if (!empty($path)) {
789
            $this->resourcePath = $path;
790
791
            return $this;
792
        }
793
794
        if (!empty($this->resourcePath)) {
795
            return $this->resourcePath;
796
        }
797
798
        return url(app('request')->getPathInfo());
0 ignored issues
show
Bug Compatibility introduced by
The expression url(app('request')->getPathInfo()); of type Illuminate\Contracts\Routing\UrlGenerator|string adds the type Illuminate\Contracts\Routing\UrlGenerator to the return on line 798 which is incompatible with the return type documented by Encore\Admin\Grid::resource of type string.
Loading history...
799
    }
800
801
    /**
802
     * Get the table columns for grid.
803
     *
804
     * @return void
805
     */
806
    protected function setDbColumns()
807
    {
808
        $connection = $this->model()->eloquent()->getConnectionName();
809
810
        $this->dbColumns = collect(Schema::connection($connection)->getColumnListing($this->model()->getTable()));
811
    }
812
813
    /**
814
     * Handle table column for grid.
815
     *
816
     * @param string $method
817
     * @param string $label
818
     *
819
     * @return bool|Column
820
     */
821
    protected function handleTableColumn($method, $label)
822
    {
823
        if (empty($this->dbColumns)) {
824
            $this->setDbColumns();
825
        }
826
827
        if ($this->dbColumns->has($method)) {
828
            return $this->addColumn($method, $label);
829
        }
830
831
        return false;
832
    }
833
834
    /**
835
     * Handle get mutator column for grid.
836
     *
837
     * @param string $method
838
     * @param string $label
839
     *
840
     * @return bool|Column
841
     */
842
    protected function handleGetMutatorColumn($method, $label)
843
    {
844
        if ($this->model()->eloquent()->hasGetMutator($method)) {
845
            return $this->addColumn($method, $label);
846
        }
847
848
        return false;
849
    }
850
851
    /**
852
     * Handle relation column for grid.
853
     *
854
     * @param string $method
855
     * @param string $label
856
     *
857
     * @return bool|Column
858
     */
859
    protected function handleRelationColumn($method, $label)
860
    {
861
        $model = $this->model()->eloquent();
862
863
        if (!method_exists($model, $method)) {
864
            return false;
865
        }
866
867
        if (!($relation = $model->$method()) instanceof Relation) {
868
            return false;
869
        }
870
871
        if ($relation instanceof HasOne || $relation instanceof BelongsTo) {
872
            $this->model()->with($method);
0 ignored issues
show
Documentation Bug introduced by
The method with does not exist on object<Encore\Admin\Grid\Model>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
873
874
            return $this->addColumn($method, $label)->setRelation(snake_case($method));
875
        }
876
877
        if ($relation instanceof HasMany || $relation instanceof BelongsToMany || $relation instanceof MorphToMany) {
878
            $this->model()->with($method);
0 ignored issues
show
Documentation Bug introduced by
The method with does not exist on object<Encore\Admin\Grid\Model>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
879
880
            return $this->addColumn(snake_case($method), $label);
881
        }
882
883
        return false;
884
    }
885
886
    /**
887
     * Dynamically add columns to the grid view.
888
     *
889
     * @param $method
890
     * @param $arguments
891
     *
892
     * @return Column
893
     */
894
    public function __call($method, $arguments)
895
    {
896
        $label = isset($arguments[0]) ? $arguments[0] : ucfirst($method);
897
898
        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...
899
            return $this->addColumn($method, $label);
900
        }
901
902
        if ($column = $this->handleGetMutatorColumn($method, $label)) {
903
            return $column;
904
        }
905
906
        if ($column = $this->handleRelationColumn($method, $label)) {
907
            return $column;
908
        }
909
910
        if ($column = $this->handleTableColumn($method, $label)) {
911
            return $column;
912
        }
913
914
        return $this->addColumn($method, $label);
915
    }
916
917
    /**
918
     * Register column displayers.
919
     *
920
     * @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...
921
     */
922
    public static function registerColumnDisplayer()
923
    {
924
        $map = [
925
            'editable'    => \Encore\Admin\Grid\Displayers\Editable::class,
926
            'switch'      => \Encore\Admin\Grid\Displayers\SwitchDisplay::class,
927
            'switchGroup' => \Encore\Admin\Grid\Displayers\SwitchGroup::class,
928
            'select'      => \Encore\Admin\Grid\Displayers\Select::class,
929
            'image'       => \Encore\Admin\Grid\Displayers\Image::class,
930
            'label'       => \Encore\Admin\Grid\Displayers\Label::class,
931
            'button'      => \Encore\Admin\Grid\Displayers\Button::class,
932
            'link'        => \Encore\Admin\Grid\Displayers\Link::class,
933
            'badge'       => \Encore\Admin\Grid\Displayers\Badge::class,
934
            'progressBar' => \Encore\Admin\Grid\Displayers\ProgressBar::class,
935
            'radio'       => \Encore\Admin\Grid\Displayers\Radio::class,
936
            'checkbox'    => \Encore\Admin\Grid\Displayers\Checkbox::class,
937
            'orderable'   => \Encore\Admin\Grid\Displayers\Orderable::class,
938
        ];
939
940
        foreach ($map as $abstract => $class) {
941
            Column::extend($abstract, $class);
942
        }
943
    }
944
945
    /**
946
     * Add variables to grid view.
947
     *
948
     * @param array $variables
949
     *
950
     * @return $this
951
     */
952
    public function with($variables = [])
953
    {
954
        $this->variables = $variables;
955
956
        return $this;
957
    }
958
959
    /**
960
     * Get all variables will used in grid view.
961
     *
962
     * @return array
963
     */
964
    protected function variables()
965
    {
966
        $this->variables['grid'] = $this;
967
968
        return $this->variables;
969
    }
970
971
    /**
972
     * Set a view to render.
973
     *
974
     * @param string $view
975
     * @param array  $variables
976
     */
977
    public function setView($view, $variables = [])
978
    {
979
        if (!empty($variables)) {
980
            $this->with($variables);
981
        }
982
983
        $this->view = $view;
984
    }
985
986
    /**
987
     * Get the string contents of the grid view.
988
     *
989
     * @return string
990
     */
991
    public function render()
992
    {
993
        try {
994
            $this->build();
995
        } catch (\Exception $e) {
996
            return Handler::renderException($e);
997
        }
998
999
        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...
1000
    }
1001
1002
    /**
1003
     * Get the string contents of the grid view.
1004
     *
1005
     * @return string
1006
     */
1007
    public function __toString()
1008
    {
1009
        return $this->render();
1010
    }
1011
}
1012