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.
Completed
Branch master (9e3162)
by Dave
63:34
created

ModelConfigurationManager   F

Complexity

Total Complexity 64

Size/Duplication

Total Lines 622
Duplicated Lines 0 %

Test Coverage

Coverage 87.58%

Importance

Changes 0
Metric Value
eloc 109
dl 0
loc 622
ccs 134
cts 153
cp 0.8758
rs 3.28
c 0
b 0
f 0
wmc 64

51 Methods

Rating   Name   Duplication   Size   Complexity  
A setEventDispatcher() 0 3 1
A isRestorableModel() 0 3 1
A getIcon() 0 3 1
A getDisplayUrl() 0 5 1
A getRestoreUrl() 0 5 1
A __call() 0 12 2
A getClass() 0 3 1
A getControllerClass() 0 3 1
A setDefaultAlias() 0 3 1
A getMessageOnUpdate() 0 3 1
A getUpdateUrl() 0 5 1
A addToNavigation() 0 7 1
A getCancelUrl() 0 3 1
A enableAccessCheck() 0 5 1
A isDeletable() 0 3 1
A getMessageOnRestore() 0 3 1
A can() 0 7 2
A getRepository() 0 3 1
A getMessageOnDestroy() 0 3 1
A __construct() 0 11 2
A fireFullEdit() 0 3 1
A getModel() 0 3 1
A getDeleteUrl() 0 5 1
A setRedirect() 0 5 1
A isEditable() 0 3 1
A disableAccessCheck() 0 5 1
A getEditUrl() 0 5 1
A hasCustomControllerClass() 0 5 2
A registerEvent() 0 4 2
A getMessageOnDelete() 0 3 1
A getCreateTitle() 0 3 1
A getNavigation() 0 3 1
A getAlias() 0 3 1
A getRedirect() 0 3 1
A getDefaultClassTitle() 0 3 1
A getStoreUrl() 0 5 1
A getEditTitle() 0 3 1
A setIcon() 0 5 1
A makePage() 0 14 3
A getDestroyUrl() 0 5 1
A getMessageOnCreate() 0 3 1
A fireEvent() 0 20 4
A getCreateUrl() 0 5 1
A isDestroyable() 0 3 2
A isRestorable() 0 3 2
A getNavigationPage() 0 3 1
A setControllerClass() 0 5 1
A isDisplayable() 0 3 1
A isCreatable() 0 3 1
A getTitle() 0 8 2
A getEventDispatcher() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ModelConfigurationManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ModelConfigurationManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SleepingOwl\Admin\Model;
4
5
use BadMethodCallException;
6
use SleepingOwl\Admin\Navigation;
7
use SleepingOwl\Admin\Navigation\Page;
8
use Illuminate\Database\Eloquent\Model;
9
use SleepingOwl\Admin\Navigation\Badge;
10
use Illuminate\Contracts\Events\Dispatcher;
11
use KodiComponents\Navigation\Contracts\BadgeInterface;
12
use SleepingOwl\Admin\Contracts\ModelConfigurationInterface;
13
use SleepingOwl\Admin\Contracts\Repositories\RepositoryInterface;
14
15
/**
16
 * @method bool creating(\Closure $callback)
17
 * @method void created(\Closure $callback)
18
 * @method bool updating(\Closure $callback)
19
 * @method void updated(\Closure $callback)
20
 * @method bool deleting(\Closure $callback)
21
 * @method void deleted(\Closure $callback)
22
 * @method bool restoring(\Closure $callback)
23
 * @method void restored(\Closure $callback)
24
 */
25
abstract class ModelConfigurationManager implements ModelConfigurationInterface
26
{
27
    /**
28
     * Get the event dispatcher instance.
29
     *
30
     * @return \Illuminate\Contracts\Events\Dispatcher
31
     */
32
    public static function getEventDispatcher()
33
    {
34
        return self::$dispatcher;
35
    }
36
37
    /**
38
     * Set the event dispatcher instance.
39
     *
40
     * @param  \Illuminate\Contracts\Events\Dispatcher  $dispatcher
41
     * @return void
42
     */
43 285
    public static function setEventDispatcher(Dispatcher $dispatcher)
44
    {
45 285
        self::$dispatcher = $dispatcher;
46 285
    }
47
48
    /**
49
     * The event dispatcher instance.
50
     *
51
     * @var \Illuminate\Contracts\Events\Dispatcher
52
     */
53
    protected static $dispatcher;
54
55
    /**
56
     * @var \Illuminate\Contracts\Foundation\Application
57
     */
58
    protected $app;
59
60
    /**
61
     * @var string
62
     */
63
    protected $class;
64
65
    /**
66
     * @var Model
67
     */
68
    protected $model;
69
70
    /**
71
     * @var string
72
     */
73
    protected $alias;
74
75
    /**
76
     * @var string|null
77
     */
78
    protected $controllerClass;
79
80
    /**
81
     * @var string
82
     */
83
    protected $title;
84
85
    /**
86
     * @var string
87
     */
88
    protected $icon;
89
90
    /**
91
     * @var bool
92
     */
93
    protected $checkAccess = false;
94
95
    /**
96
     * @var array
97
     */
98
    protected $redirect = ['edit' => 'edit', 'create' => 'edit'];
99
100
    /**
101
     * @var RepositoryInterface
102
     */
103
    private $repository;
104
105
    /**
106
     * ModelConfigurationManager constructor.
107
     * @param \Illuminate\Contracts\Foundation\Application $app
108
     * @param $class
109 54
     * @throws \SleepingOwl\Admin\Exceptions\RepositoryException
110
     */
111 54
    public function __construct(\Illuminate\Contracts\Foundation\Application $app, $class)
112 54
    {
113
        $this->app = $app;
114 54
        $this->class = $class;
115
116 54
        $this->model = $app->make($class);
117 54
118 54
        $this->repository = $app->make(RepositoryInterface::class);
119 54
        $this->repository->setClass($class);
120 54
        if (! $this->alias) {
121 54
            $this->setDefaultAlias();
122
        }
123
    }
124
125
    /**
126 54
     * @return string
127
     */
128 54
    public function getClass()
129
    {
130
        return $this->class;
131
    }
132
133
    /**
134 13
     * @return Model
135
     */
136 13
    public function getModel()
137
    {
138
        return $this->model;
139
    }
140
141
    /**
142 6
     * @return string
143
     */
144 6
    public function getTitle()
145 6
    {
146 6
        if (is_null($this->title)) {
0 ignored issues
show
introduced by
The condition is_null($this->title) is always false.
Loading history...
147 6
            $title = str_replace('_', ' ', $this->getDefaultClassTitle());
148
            $this->title = ucwords($title);
149 6
        }
150
151
        return $this->title;
152
    }
153
154
    /**
155 2
     * @return string
156
     */
157 2
    public function getIcon()
158
    {
159
        return $this->icon;
160
    }
161
162
    /**
163
     * @param string $icon
164
     *
165 1
     * @return $this
166
     */
167 1
    public function setIcon($icon)
168
    {
169 1
        $this->icon = $icon;
170
171
        return $this;
172
    }
173
174
    /**
175 12
     * @return string
176
     */
177 12
    public function getAlias()
178
    {
179
        return $this->alias;
180
    }
181
182
    /**
183 7
     * @return RepositoryInterface
184
     */
185 7
    public function getRepository()
186
    {
187
        return $this->repository;
188
    }
189
190
    /**
191 2
     * @return string|array|\Symfony\Component\Translation\TranslatorInterface
192
     */
193 2
    public function getCreateTitle()
194
    {
195
        return trans('sleeping_owl::lang.model.create', ['title' => $this->getTitle()]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o... => $this->getTitle())) also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...rface::getCreateTitle() of string|Symfony\Component...ion\TranslatorInterface.
Loading history...
196
    }
197
198
    /**
199 2
     * @return string|array|\Symfony\Component\Translation\TranslatorInterface
200
     */
201 2
    public function getEditTitle()
202
    {
203
        return trans('sleeping_owl::lang.model.edit', ['title' => $this->getTitle()]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o... => $this->getTitle())) also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...terface::getEditTitle() of string|Symfony\Component...ion\TranslatorInterface.
Loading history...
204
    }
205
206
    /**
207 1
     * @return bool
208
     */
209 1
    public function isDisplayable()
210
    {
211
        return $this->can('display', $this->getModel());
212
    }
213
214
    /**
215 1
     * @return bool
216
     */
217 1
    public function isCreatable()
218
    {
219
        return $this->can('create', $this->getModel());
220
    }
221
222
    /**
223
     * @param \Illuminate\Database\Eloquent\Model $model
224
     *
225 1
     * @return bool
226
     */
227 1
    public function isEditable(Model $model)
228
    {
229
        return $this->can('edit', $model);
230
    }
231
232
    /**
233
     * @param \Illuminate\Database\Eloquent\Model $model
234
     *
235 1
     * @return bool
236
     */
237 1
    public function isDeletable(Model $model)
238
    {
239
        return $this->can('delete', $model);
240
    }
241
242
    /**
243
     * @param Model $model
244
     *
245 3
     * @return bool
246
     */
247 3
    public function isDestroyable(Model $model)
248
    {
249
        return $this->isRestorableModel() && $this->can('destroy', $model);
250
    }
251
252
    /**
253
     * @param \Illuminate\Database\Eloquent\Model $model
254
     *
255 1
     * @return bool
256
     */
257 1
    public function isRestorable(Model $model)
258
    {
259
        return $this->isRestorableModel() && $this->can('restore', $model);
260
    }
261
262
    /**
263 6
     * @return bool
264
     */
265 6
    public function isRestorableModel()
266
    {
267
        return $this->getRepository()->isRestorable();
268
    }
269
270
    /**
271
     * @deprecated
272
     * @param int $id
273
     *
274
     * @return $this
275
     */
276
    public function fireFullEdit($id)
277
    {
278
        return $this->fireEdit($id);
279
    }
280
281
    /**
282 1
     * @return $this
283
     */
284 1
    public function enableAccessCheck()
285
    {
286 1
        $this->checkAccess = true;
287
288
        return $this;
289
    }
290
291
    /**
292 1
     * @return $this
293
     */
294 1
    public function disableAccessCheck()
295
    {
296 1
        $this->checkAccess = false;
297
298
        return $this;
299
    }
300
301
    /**
302
     * @param string $action
303
     * @param \Illuminate\Database\Eloquent\Model $model
304
     *
305 2
     * @return bool
306
     */
307 2
    public function can($action, Model $model)
308 2
    {
309
        if (! $this->checkAccess) {
310
            return true;
311 1
        }
312
313
        return \Gate::allows($action, [$this, $model]);
314
    }
315
316
    /**
317
     * @param string $controllerClass
318
     *
319 1
     * @return $this
320
     */
321 1
    public function setControllerClass($controllerClass)
322
    {
323 1
        $this->controllerClass = $controllerClass;
324
325
        return $this;
326
    }
327
328
    /**
329 1
     * @return null|string
330
     */
331 1
    public function getControllerClass()
332
    {
333
        return $this->controllerClass;
334
    }
335
336
    /**
337 1
     * @return null|string|bool
338
     */
339 1
    public function hasCustomControllerClass()
340
    {
341 1
        $controller = $this->getControllerClass();
342
343
        return ! is_null($controller) && class_exists($controller);
344
    }
345
346
    /**
347
     * @param array $parameters
348
     *
349 1
     * @return string
350
     */
351 1
    public function getDisplayUrl(array $parameters = [])
352
    {
353 1
        array_unshift($parameters, $this->getAlias());
354
355
        return route('admin.model', $parameters);
356
    }
357
358
    /**
359
     * @param array $parameters
360
     *
361
     * @return string
362
     */
363
    public function getCancelUrl(array $parameters = [])
364
    {
365
        return $this->getDisplayUrl($parameters);
366
    }
367
368
    /**
369
     * @param array $parameters
370
     *
371 1
     * @return string
372
     */
373 1
    public function getCreateUrl(array $parameters = [])
374
    {
375 1
        array_unshift($parameters, $this->getAlias());
376
377
        return route('admin.model.create', $parameters);
378
    }
379
380
    /**
381 2
     * @param array $parameters
382
     *
383 2
     * @return string
384
     */
385
    public function getStoreUrl(array $parameters = [])
386
    {
387
        array_unshift($parameters, $this->getAlias());
388
389
        return route('admin.model.store', $parameters);
390
    }
391 1
392
    /**
393 1
     * @param string|int $id
394
     * @param array $parameters
395
     *
396
     * @return string
397
     */
398
    public function getEditUrl($id, array $parameters = [])
399
    {
400
        array_unshift($parameters, $this->getAlias(), $id);
401 2
402
        return route('admin.model.edit', $parameters);
403 2
    }
404
405
    /**
406
     * @param string|int $id
407
     * @param array $parameters
408
     *
409
     * @return string
410
     */
411 1
    public function getUpdateUrl($id, array $parameters = [])
412
    {
413 1
        array_unshift($parameters, $this->getAlias(), $id);
414
415
        return route('admin.model.update', $parameters);
416
    }
417
418
    /**
419
     * @param string|int $id
420
     * @param array $parameters
421 1
     *
422
     * @return string
423 1
     */
424
    public function getDeleteUrl($id, array $parameters = [])
425
    {
426
        array_unshift($parameters, $this->getAlias(), $id);
427
428
        return route('admin.model.delete', $parameters);
429
    }
430
431 1
    /**
432
     * @param string|int $id
433 1
     * @param array $parameters
434
     *
435
     * @return string
436
     */
437
    public function getDestroyUrl($id, array $parameters = [])
438
    {
439 2
        array_unshift($parameters, $this->getAlias(), $id);
440
441 2
        return route('admin.model.destroy', $parameters);
442
    }
443
444
    /**
445
     * @param string|int $id
446
     * @param array $parameters
447 2
     *
448
     * @return string
449 2
     */
450
    public function getRestoreUrl($id, array $parameters = [])
451
    {
452
        array_unshift($parameters, $this->getAlias(), $id);
453
454
        return route('admin.model.restore', $parameters);
455 2
    }
456
457 2
    /**
458
     * @return string|array
459
     */
460
    public function getMessageOnCreate()
461
    {
462
        return trans('sleeping_owl::lang.message.created');
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o...:lang.message.created') also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...e::getMessageOnCreate() of string.
Loading history...
463 2
    }
464
465 2
    /**
466
     * @return string|array
467
     */
468
    public function getMessageOnUpdate()
469
    {
470
        return trans('sleeping_owl::lang.message.updated');
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o...:lang.message.updated') also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...e::getMessageOnUpdate() of string.
Loading history...
471 2
    }
472
473 2
    /**
474
     * @return string|array
475
     */
476
    public function getMessageOnDelete()
477
    {
478
        return trans('sleeping_owl::lang.message.deleted');
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o...:lang.message.deleted') also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...e::getMessageOnDelete() of string.
Loading history...
479 1
    }
480
481 1
    /**
482
     * @return string|array
483
     */
484
    public function getMessageOnRestore()
485
    {
486
        return trans('sleeping_owl::lang.message.restored');
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o...lang.message.restored') also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...::getMessageOnRestore() of string.
Loading history...
487
    }
488
489
    /**
490 1
     * @return string|array
491
     */
492 1
    public function getMessageOnDestroy()
493
    {
494 1
        return trans('sleeping_owl::lang.message.destroyed');
0 ignored issues
show
Bug Best Practice introduced by
The expression return trans('sleeping_o...ang.message.destroyed') also could return the type array which is incompatible with the return type mandated by SleepingOwl\Admin\Contra...::getMessageOnDestroy() of string.
Loading history...
495
    }
496 1
497
    /**
498
     * @return Navigation
499
     */
500
    public function getNavigation()
501
    {
502
        return $this->app['sleeping_owl.navigation'];
503
    }
504
505
    /**
506
     * @param int $priority
507
     * @param string|\Closure|BadgeInterface $badge
508
     *
509
     * @return Page
510
     */
511
    public function addToNavigation($priority = 100, $badge = null)
512
    {
513
        $page = $this->makePage($priority, $badge);
514 1
515
        $this->getNavigation()->addPage($page);
516 1
517 1
        return $page;
518
    }
519 1
520
    /**
521
     * @param $page_id
522
     * @return \KodiComponents\Navigation\Contracts\PageInterface|null
523
     */
524
    public function getNavigationPage($page_id)
525
    {
526
        return $this->getNavigation()->getPages()->findById($page_id);
527 1
    }
528
529
    /**
530
     * @param int $priority
531
     * @param string|\Closure|BadgeInterface $badge
532
     *
533
     * @return Page
534
     */
535
    protected function makePage($priority = 100, $badge = null)
536
    {
537
        $page = new Page($this->getClass());
538
        $page->setPriority($priority);
539
540
        if ($badge) {
541
            if (! ($badge instanceof BadgeInterface)) {
542
                $badge = new Badge($badge);
543
            }
544
545
            $page->setBadge($badge);
546
        }
547
548
        return $page;
549
    }
550
551
    /**
552
     * @param array $redirect
553
     * @return $this
554
     */
555
    public function setRedirect(array $redirect)
556
    {
557
        $this->redirect = $redirect;
558
559 3
        return $this;
560
    }
561 3
562
    /**
563
     * @return \Illuminate\Support\Collection
564
     */
565 3
    public function getRedirect()
566 2
    {
567 2
        return collect($this->redirect);
568
    }
569
570
    /**
571
     * Fire the given event for the model.
572 3
     *
573
     * @param string $event
574 3
     * @param bool $halt
575
     * @param Model|null $model
576 3
     * @param array $payload
577
     *
578 3
     * @return mixed
579
     */
580
    public function fireEvent($event, $halt = true, Model $model = null, ...$payload)
581
    {
582
        if (! isset(self::$dispatcher)) {
583
            return true;
584
        }
585
586
        if (is_null($model)) {
587
            $model = $this->getModel();
588
        }
589 3
590
        // We will append the names of the class to the event to distinguish it from
591 3
        // other model events that are fired, allowing us to listen on each model
592 3
        // event set individually instead of catching event for all the models.
593 3
        $event = "sleeping_owl.section.{$event}: ".$this->getClass();
594 3
595 2
        $method = $halt ? 'until' : 'fire';
596
597 2
        array_unshift($payload, $this, $model);
598
599
        return self::$dispatcher->$method($event, $payload);
600 1
    }
601
602
    /**
603
     * Handle dynamic method calls into the model.
604
     *
605
     * @param $method
606
     * @param $arguments
607
     *
608 2
     * @return mixed
609
     */
610 2
    public function __call($method, $arguments)
611 2
    {
612 2
        if (in_array($method, [
613 2
            'creating', 'created', 'updating', 'updated', 'saving', 'saved',
614
            'deleting', 'deleted', 'restoring', 'restored',
615 54
        ])) {
616
            array_unshift($arguments, $method);
617 54
618 54
            return call_user_func_array([$this, 'registerEvent'], $arguments);
619
        }
620
621
        throw new BadMethodCallException($method);
622
    }
623 54
624
    /**
625 54
     * @param     $event
626
     * @param     $callback
627
     * @param int $priority
628
     */
629
    protected function registerEvent($event, $callback, $priority = 0)
630
    {
631
        if (isset(self::$dispatcher)) {
632
            self::$dispatcher->listen("sleeping_owl.section.{$event}: ".$this->getClass(), $callback, $priority);
0 ignored issues
show
Unused Code introduced by
The call to Illuminate\Events\Dispatcher::listen() has too many arguments starting with $priority. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

632
            self::$dispatcher->/** @scrutinizer ignore-call */ 
633
                               listen("sleeping_owl.section.{$event}: ".$this->getClass(), $callback, $priority);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
633
        }
634
    }
635
636
    protected function setDefaultAlias()
637
    {
638
        $this->alias = $this->getDefaultClassTitle();
639
    }
640
641
    /**
642
     * @return string
643
     */
644
    protected function getDefaultClassTitle()
645
    {
646
        return snake_case(str_plural(class_basename($this->getClass())));
647
    }
648
}
649