GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ModelAdmin::hasViewing()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace LaravelFlare\Flare\Admin\Models;
4
5
use Illuminate\Support\Str;
6
use LaravelFlare\Flare\Admin\Admin;
7
use LaravelFlare\Flare\Exceptions\ModelAdminException;
8
use LaravelFlare\Flare\Admin\Models\Traits\ModelSaving;
9
use LaravelFlare\Flare\Admin\Models\Traits\ModelQuerying;
10
use LaravelFlare\Flare\Contracts\ModelAdmin\ModelQueryable;
11
12
class ModelAdmin extends Admin implements ModelQueryable
13
{
14
    use ModelQuerying;
15
    use ModelSaving;
16
17
    /**
18
     * Class of Model to Manage.
19
     * 
20
     * @var string
21
     */
22
    protected $managedModel;
23
24
    /**
25
     * Entiy Title .
26
     *
27
     * @var string
28
     */
29
    protected $entityTitle;
30
31
    /**
32
     * Plural Entity Title.
33
     *
34
     * @var string
35
     */
36
    protected $pluralEntityTitle;
37
38
    /**
39
     * Validation Rules for onCreate, onEdit actions.
40
     * 
41
     * @var array
42
     */
43
    protected $rules = [];
44
45
    /**
46
     * Columns for Model.
47
     *
48
     * Defines which fields to show in the listing tables output.
49
     * 
50
     * @var array
51
     */
52
    protected $columns = [];
53
54
    /**
55
     * Map Model Attributes to FieldTypes with
56
     * additional parameters which will be output
57
     * as fields when viewing, editing or adding
58
     * a new model entry.
59
     * 
60
     * @var array
61
     */
62
    protected $fields = [];
63
64
    /**
65
     * Columns for Model are Sortable.
66
     *
67
     * @var bool
68
     */
69
    protected $sortable = true;
70
71
    /**
72
     * The Controller to be used by the Model Admin.
73
     *
74
     * This defaults to parent::getController()
75
     * if it has been left undefined. 
76
     * 
77
     * @var string
78
     */
79
    protected $controller = '\LaravelFlare\Flare\Admin\Models\ModelAdminController';
80
81
    /**
82
     * The Policy used for the Model Authorization logic.
83
     *
84
     * This class should implement the ModelAdminPoliceable which
85
     * includes authorization checks for the create, view, edit and delete actions.
86
     * 
87
     * @var string
88
     */
89
    protected $policy = '\LaravelFlare\Flare\Permissions\ModelAdminPolicy';
90
91
    /**
92
     * The current model to be managed.
93
     * 
94
     * @var Model
95
     */
96
    public $model;
97
98
    /**
99
     * __construct.
100
     */
101
    public function __construct()
102
    {
103
        $this->getManagedModel();
104
105
        $this->model = $this->model();
106
    }
107
108
    /**
109
     * Returns a Model Instance.
110
     * 
111
     * @return Model
112
     */
113
    public function model()
114
    {
115
        if (!$this->model) {
116
            $class = $this->getManagedModel();
117
118
            return $this->model = new $class();
119
        }
120
121
        return $this->model;
122
    }
123
124
    /**
125
     * Returns a New Model Instance.
126
     *
127
     * @return Model
128
     */
129
    public function newModel()
130
    {
131
        $class = self::getManagedModel();
132
133
        return new $class();
134
    }
135
136
    /**
137
     * Returns the Managed Model Class.
138
     * 
139
     * @return string
140
     */
141
    public function getManagedModel()
142
    {
143
        if (!isset($this->managedModel) || $this->managedModel === null) {
144
            throw new ModelAdminException('You have a ModelAdmin which does not have a model assigned to it. ModelAdmins must include a model to manage.', 1);
145
        }
146
147
        return $this->managedModel;
148
    }
149
150
    /**
151
     * Set the Managed Model Class.
152
     * 
153
     * @param string $managedModel
154
     */
155
    public function setManagedModel($managedModel = null)
156
    {
157
        $this->managedModel = $managedModel;
158
    }
159
160
    /**
161
     * Get the Entity Title.
162
     *
163
     * @return string
164
     */
165
    public function getEntityTitle()
166
    {
167
        if (!isset($this->entityTitle) || !$this->entityTitle) {
168
            return $this->getTitle();
169
        }
170
171
        return $this->entityTitle;
172
    }
173
174
    /**
175
     * Set Entity Title.
176
     *
177
     * @param string $entityTitle
178
     */
179
    public function setTitle($entityTitle = null)
180
    {
181
        $this->entityTitle = $title;
0 ignored issues
show
Bug introduced by
The variable $title does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
182
    }
183
184
    /**
185
     * Plural Entity Title.
186
     *
187
     * @return string
188
     */
189
    public function getPluralEntityTitle()
190
    {
191
        if (!isset($this->pluralEntityTitle) || !$this->pluralEntityTitle) {
192
            return Str::plural($this->getEntityTitle());
193
        }
194
195
        return $this->pluralEntityTitle;
196
    }
197
198
    /**
199
     * Set Plural Title.
200
     * 
201
     * @param string $pluralEntityTitle
202
     */
203
    public function setPluralTitle($pluralEntityTitle = null)
204
    {
205
        $this->pluralEntityTitle = $pluralEntityTitle;
206
    }
207
208
    /**
209
     * Returns the Route Paramets.
210
     * 
211
     * @return array
212
     */
213
    public function routeParameters()
214
    {
215
        return array_merge(parent::routeParameters(), [
216
                                                    'model' => $this->managedModel,
217
                                                ]);
218
    }
219
220
    /**
221
     * Formats and returns the Columns.
222
     *
223
     * This is really gross, I'm removing it soon.
224
     * 
225
     * @return
226
     */
227
    public function getColumns()
228
    {
229
        $columns = [];
230
231
        foreach ($this->columns as $field => $fieldTitle) {
232
            if (in_array($field, $this->model->getFillable())) {
233
                if (!$field) {
234
                    $field = $fieldTitle;
235
                    $fieldTitle = Str::title($fieldTitle);
236
                }
237
                $columns[$field] = $fieldTitle;
238
                continue;
239
            }
240
241
            // We can replace this with data_get() I believe.
242
            if (($methodBreaker = strpos($field, '.')) !== false) {
243
                $method = substr($field, 0, $methodBreaker);
244
                if (method_exists($this->model, $method)) {
245
                    if (method_exists($this->model->$method(), $submethod = str_replace($method.'.', '', $field))) {
246
                        $this->model->$method()->$submethod();
247
248
                        $columns[$field] = $fieldTitle;
249
                        continue;
250
                    }
251
                }
252
            }
253
254
            if (is_numeric($field)) {
255
                $field = $fieldTitle;
256
                $fieldTitle = Str::title($fieldTitle);
257
            }
258
259
            $columns[$field] = $fieldTitle;
260
        }
261
262
        if (count($columns)) {
263
            return $columns;
264
        }
265
266
        return [$this->model->getKeyName() => $this->model->getKeyName()];
267
    }
268
269
    /**
270
     * Return the Validation Rules.
271
     * 
272
     * @return array
273
     */
274
    public function getRules()
275
    {
276
        return $this->rules;
277
    }
278
279
    /**
280
     * Return the Create Model Entry Validation Rules.
281
     * 
282
     * @return array
283
     */
284
    public function getCreateRules()
285
    {
286
        return $this->getRules();
287
    }
288
289
    /**
290
     * Return the Update Model Entry Validation Rules.
291
     * 
292
     * @return array
293
     */
294
    public function getUpdateRules()
295
    {
296
        return $this->getRules();
297
    }
298
299
    /**
300
     * Gets an Attribute by the provided key
301
     * on either the current model or a provided model instance.
302
     * 
303
     * @param string $key
304
     * @param mixed  $model
305
     * 
306
     * @return mixed
307
     */
308
    public function getAttribute($key, $model = false)
309
    {
310
        if (!$key) {
311
            return;
312
        }
313
314
        if (!$model) {
315
            $model = $this->model;
316
        }
317
318
        $formattedKey = str_replace('.', '_', $key);
319
320 View Code Duplication
        if ($this->hasGetAccessor($formattedKey)) {
321
            $method = 'get'.Str::studly($formattedKey).'Attribute';
322
323
            return $this->{$method}($model);
324
        }
325
326 View Code Duplication
        if ($this->hasGetAccessor($key)) {
327
            $method = 'get'.Str::studly($key).'Attribute';
328
329
            return $this->{$method}($model);
330
        }
331
332
        if ($this->hasRelatedKey($key, $model)) {
333
            return $this->relatedKey($key, $model);
334
        }
335
336
        return $model->getAttribute($key);
337
    }
338
339
    /**
340
     * Determine if a get accessor exists for an attribute.
341
     *
342
     * @param string $key
343
     * 
344
     * @return bool
345
     */
346
    public function hasGetAccessor($key)
347
    {
348
        return method_exists($this, 'get'.Str::studly($key).'Attribute');
349
    }
350
351
    /**
352
     * Determines if a key resolved a related Model.
353
     * 
354
     * @param string $key
355
     * @param mixed  $model
356
     * 
357
     * @return bool
358
     */
359
    public function hasRelatedKey($key, $model = false)
360
    {
361
        if (!$model) {
362
            $model = $this->model;
363
        }
364
365
        if (($methodBreaker = strpos($key, '.')) !== false) {
366
            $method = substr($key, 0, $methodBreaker);
367
            if (method_exists($model, $method)) {
368
                return true;
369
            }
370
        }
371
372
        return false;
373
    }
374
375
    /**
376
     * Resolves a relation based on the key provided,
377
     * either on the current model or a provided model instance.
378
     * 
379
     * @param string $key
380
     * @param mixed  $model
381
     * 
382
     * @return mixed
383
     */
384
    public function relatedKey($key, $model = false)
385
    {
386
        if (!$model) {
387
            $model = $this->model;
388
        }
389
390
        if (($methodBreaker = strpos($key, '.')) !== false) {
391
            $method = substr($key, 0, $methodBreaker);
392
            if (method_exists($model, $method)) {
393
                if (method_exists($model->$method, $submethod = str_replace($method.'.', '', $key))) {
394
                    return $model->$method->$submethod();
395
                }
396
397
                if (isset($model->$method->$submethod)) {
398
                    return $model->$method->$submethod;
399
                }
400
401
                return $model->getRelationValue($method);
402
            }
403
        }
404
405
        return false;
406
    }
407
408
    /**
409
     * Set a given attribute on the model.
410
     *
411
     * @param string $key
412
     * @param mixed  $value
413
     */
414
    public function setAttribute($key, $value)
415
    {
416
        if ($this->hasSetMutator($key)) {
417
            $method = 'set'.Str::studly($key).'Attribute';
418
419
            return $this->{$method}($value);
420
        }
421
422
        $this->model->attributes[$key] = $value;
423
    }
424
425
    /**
426
     * Determine if a set mutator exists for an attribute.
427
     *
428
     * @param string $key
429
     * 
430
     * @return bool
431
     */
432
    public function hasSetMutator($key)
433
    {
434
        return method_exists($this, 'set'.Str::studly($key).'Attribute');
435
    }
436
437
    /**
438
     * Determine if a get mutator exists for an attribute.
439
     *
440
     * @param string $key
441
     * 
442
     * @return bool
443
     */
444
    public function hasGetMutator($key)
445
    {
446
        return method_exists($this, 'get'.Str::studly($key).'Attribute');
447
    }
448
449
    /**
450
     * Returns an array of Attribute Fields ready for output.
451
     * 
452
     * @return array
453
     */
454
    public function outputFields()
455
    {
456
        return $this->getFields();
457
    }
458
459
    /**
460
     * Gets the Managed Model Mapping.
461
     * 
462
     * @return array
463
     */
464
    public function getFields()
465
    {
466
        $this->setFields($this->fields);
467
468
        return $this->fields;
469
    }
470
471
    /**
472
     * Sets the Managed Model Mapping.
473
     * 
474
     * @param array $fields
475
     */
476
    public function setFields($fields = [])
477
    {
478
        $this->fields = $fields;
479
480
        $this->formatFields();
481
    }
482
483
    /**
484
     * Format the provided Attribute Fields into a more usable format.
485
     */
486
    protected function formatFields()
487
    {
488
        $fields = $this->fields;
489
490
        if (!$fields instanceof AttributeCollection) {
491
            $fields = new AttributeCollection($fields, $this);
492
        }
493
494
        return $this->fields = $fields->formatFields();
0 ignored issues
show
Documentation Bug introduced by
It seems like $fields->formatFields() of type object<LaravelFlare\Flar...ls\AttributeCollection> is incompatible with the declared type array of property $fields.

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...
495
    }
496
497
    /**
498
     * Determine if the Model Admin is sortable in it's list view.
499
     * 
500
     * @return bool
501
     */
502
    public function isSortable()
503
    {
504
        return isset($this->sortable) && $this->sortable ? true : false;
505
    }
506
507
    /**
508
     * Determine if the Model Admin is sortable by a defined key / column.
509
     *
510
     * @param string $key
511
     * 
512
     * @return bool
513
     */
514
    public function isSortableBy($key)
515
    {
516
        // Sorting is not allowed on Model Admin
517
        if (!$this->isSortable()) {
518
            return false;
519
        }
520
521
        // Key results are mutated, so sorting is not available
522
        if ($this->model()->hasGetMutator($key) || $this->hasGetMutator($key)) {
523
            return false;
524
        }
525
526
        // Key is a relation, so sorting is not available 
527
        if (strpos($key, '.') !== false) {
528
            return false;
529
        }
530
531
        return true;
532
    }
533
534
    /**
535
     * Determine if the Model Admin has Viewing Capabilities.
536
     * 
537
     * @return bool
538
     */
539
    public function hasViewing()
540
    {
541
        return $this->hasTrait(\LaravelFlare\Flare\Admin\Models\Traits\ModelViewing::class);
542
    }
543
544
    /**
545
     * Determine if the Model Admin has Creating Capabilities.
546
     * 
547
     * @return bool
548
     */
549
    public function hasCreating()
550
    {
551
        return is_callable([$this, 'create']);
552
    }
553
554
    /**
555
     * Determine if the Model Admin has Cloning Capabilities.
556
     * 
557
     * @return bool
558
     */
559
    public function hasCloning()
560
    {
561
        return is_callable([$this, 'clone']);
562
    }
563
564
    /**
565
     * Determine if the Model Admin has Editing Capabilities.
566
     * 
567
     * @return bool
568
     */
569
    public function hasEditing()
570
    {
571
        return is_callable([$this, 'edit']);
572
    }
573
574
    /**
575
     * Determine if the Model Admin has Deleting Capabilities.
576
     * 
577
     * @return bool
578
     */
579
    public function hasDeleting()
580
    {
581
        return is_callable([$this, 'delete']);
582
    }
583
584
    /**
585
     * Determine if the Managed Model is using the SoftDeletes Trait.
586
     *
587
     * This is guarded by hasDeleting, since we shouldn't allow SoftDeleting
588
     * without the deleting trait (even though it isn't really required).
589
     *
590
     * @return bool
591
     */
592
    public function hasSoftDeleting()
593
    {
594
        if (!$this->hasDeleting()) {
595
            return false;
596
        }
597
598
        $managedModelClass = $this->getManagedModel();
599
600
        return in_array(
601
            \Illuminate\Database\Eloquent\SoftDeletes::class, class_uses_recursive(get_class(new $managedModelClass()))
602
        ) && $this->hasDeleting();
603
    }
604
605
    /**
606
     * Determine if the Model Admin has Validating Capabilities.
607
     * 
608
     * @return bool
609
     */
610
    public function hasValidating()
611
    {
612
        return $this->hasTrait(\LaravelFlare\Flare\Admin\Models\Traits\ModelValidating::class);
613
    }
614
615
    /**
616
     * Determine if the Managed Model has a Trait and Contract.
617
     *
618
     * @return bool
619
     */
620
    public function hasTraitAndContract($trait = null, $contract = null)
621
    {
622
        return $this->hasTrait($trait) && $this->hasContract($contract);
623
    }
624
625
    /**
626
     * Returns whether the current ModelAdmin has a given trait.
627
     * 
628
     * @param string $trait
629
     * 
630
     * @return bool
631
     */
632
    public function hasTrait($trait = null)
633
    {
634
        if (!$trait) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $trait of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
635
            return;
636
        }
637
638
        return in_array($trait, class_uses_recursive(get_class($this)));
639
    }
640
641
    /**
642
     * Returns whether the current ModelAdmin has a given contract.
643
     * 
644
     * @param string $contract
645
     * 
646
     * @return bool
647
     */
648
    public function hasContract($contract = null)
0 ignored issues
show
Unused Code introduced by
The parameter $contract is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
649
    {
650
        if (!$trait) {
0 ignored issues
show
Bug introduced by
The variable $trait does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
651
            return;
652
        }
653
654
        $managedModelClass = $this->getManagedModel();
0 ignored issues
show
Unused Code introduced by
$managedModelClass is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
655
    }
656
}
657