Completed
Push — master ( 93b4ca...ada3e7 )
by wen
10:31
created

ComponentServiceProvider   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 8
dl 0
loc 89
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A boot() 0 8 1
A register() 0 4 1
A bindRouteModel() 0 19 2
B loadComponents() 0 28 6
B registerComponent() 0 23 4
1
<?php
2
3
namespace Sco\Admin\Providers;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\ServiceProvider;
7
use Illuminate\Support\Str;
8
use InvalidArgumentException;
9
use Sco\Admin\Component\Component;
10
use Sco\Admin\Contracts\ComponentInterface;
11
use Sco\Admin\Contracts\Initializable;
12
use Sco\Admin\Contracts\WithNavigation;
13
use Symfony\Component\Finder\Finder;
14
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
15
16
class ComponentServiceProvider extends ServiceProvider
17
{
18
    public function boot()
19
    {
20
        Component::setEventDispatcher($this->app['events']);
21
22
        $this->loadComponents(config('admin.components'));
23
24
        $this->bindRouteModel();
25
    }
26
27
    public function register()
28
    {
29
        $this->app->instance('admin.components', new Collection());
30
    }
31
32
    protected function bindRouteModel()
33
    {
34
        $aliases = $this->app['admin.components']
35
            ->keyBy(function (ComponentInterface $component) {
36
                return $component->getName();
37
            });
38
39
        $this->app['router']->bind('model', function ($value, $route) use ($aliases) {
0 ignored issues
show
Unused Code introduced by
The parameter $route 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...
40
            if (!$aliases->has($value)) {
41
                throw new NotFoundHttpException(
42
                    sprintf(
43
                        'Not Found model(%s) component.',
44
                        $value
45
                    )
46
                );
47
            }
48
            return $aliases->get($value);
49
        });
50
    }
51
52
    protected function loadComponents($paths)
53
    {
54
        $paths = array_unique(is_array($paths) ? $paths : (array)$paths);
55
56
        $paths = array_filter($paths, function ($path) {
57
            return is_dir($path);
58
        });
59
60
        if (empty($paths)) {
61
            return;
62
        }
63
64
        $namespace = $this->app->getNamespace();
65
66
        foreach ((new Finder())->in($paths)->files() as $file) {
67
            $class = $namespace . str_replace(
68
                    ['/', '.php'],
69
                    ['\\', ''],
70
                    Str::after(realpath($file->getPathname()),
71
                        app_path() . DIRECTORY_SEPARATOR)
72
                );
73
74
            if (is_subclass_of($class, Component::class)
75
                && !(new \ReflectionClass($class))->isAbstract()) {
76
                $this->registerComponent($class);
77
            }
78
        }
79
    }
80
81
    protected function registerComponent($class)
82
    {
83
        $component = $this->app->make($class);
84
        if (!($component instanceof ComponentInterface)) {
85
            throw new InvalidArgumentException(
86
                sprintf(
87
                    'Class "%s" must be instanced of "%s".',
88
                    $component,
89
                    ComponentInterface::class
90
                )
91
            );
92
        }
93
94
        if ($component instanceof Initializable) {
95
            $component->initialize();
96
        }
97
98
        if ($component instanceof WithNavigation) {
99
            $component->addToNavigation();
100
        }
101
102
        $this->app['admin.components']->put($component->model(), $component);
103
    }
104
}
105