ComponentServiceProvider::loadComponents()   B
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 15.8865

Importance

Changes 0
Metric Value
dl 0
loc 32
c 0
b 0
f 0
ccs 7
cts 20
cp 0.35
rs 8.439
cc 6
eloc 18
nc 4
nop 1
crap 15.8865
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 Symfony\Component\Finder\Finder;
13
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14
15
class ComponentServiceProvider extends ServiceProvider
16
{
17 48
    public function boot()
18
    {
19 48
        Component::setEventDispatcher($this->app['events']);
20
21 48
        $this->loadComponents(config('admin.components'));
22
23 48
        $this->bindRouteModel();
24 48
    }
25
26 48
    public function register()
27
    {
28 48
        $this->app->instance('admin.components', new Collection());
29 48
    }
30
31
    protected function registerInstanceComponent(ComponentInterface $component)
32
    {
33
        $this->app->instance('admin.instance.component', $component);
34
    }
35
36 48
    protected function bindRouteModel()
37
    {
38 48
        $aliases = $this->app['admin.components']
39 48
            ->keyBy(function (ComponentInterface $component) {
40
                return $component->getName();
41 48
            });
42
43 48
        $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...
44
            if (! $aliases->has($value)) {
45
                throw new NotFoundHttpException(
46
                    sprintf(
47
                        'Not Found model(%s) component.',
48
                        $value
49
                    )
50
                );
51
            }
52
53
            $this->registerInstanceComponent(($component = $aliases->get($value)));
54
55
            return $component;
56 48
        });
57 48
    }
58
59
    /**
60
     * Load component class from the paths
61
     *
62
     * @param mixed $paths
63
     * @throws \ReflectionException
64
     */
65 48
    protected function loadComponents($paths)
66
    {
67 48
        $paths = array_unique(is_array($paths) ? $paths : (array) $paths);
68
69 48
        $paths = array_filter($paths, function ($path) {
70 48
            return is_dir($path);
71 48
        });
72
73 48
        if (empty($paths)) {
74 48
            return;
75
        }
76
77
        $namespace = $this->app->getNamespace();
78
79
        foreach ((new Finder())->in($paths)->exclude('Observers')->files() as $file) {
80
            $class = trim($namespace, '\\') . '\\'
81
                . str_replace(
82
                    ['/', '.php'],
83
                    ['\\', ''],
84
                    Str::after(
85
                        realpath($file->getPathname()),
86
                        app_path() . DIRECTORY_SEPARATOR
87
                    )
88
                );
89
90
            if (is_subclass_of($class, Component::class)
91
                && ! (new \ReflectionClass($class))->isAbstract()
92
            ) {
93
                $this->registerComponent($class);
94
            }
95
        }
96
    }
97
98
    /**
99
     * register the component class
100
     *
101
     * @param string $class
102
     */
103
    protected function registerComponent($class)
104
    {
105
        $component = $this->app->make($class);
106
        if (! ($component instanceof ComponentInterface)) {
107
            throw new InvalidArgumentException(
108
                sprintf(
109
                    'Class "%s" must be instanced of "%s".',
110
                    $component,
111
                    ComponentInterface::class
112
                )
113
            );
114
        }
115
116
        if ($component instanceof Initializable) {
117
            $component->initialize();
118
        }
119
120
        $component->addToNavigation();
121
122
        $this->app['admin.components']->put($component->getName(), $component);
123
    }
124
}
125