Passed
Push — master ( 07ff08...756a96 )
by Arthur
05:20
created

BootstrapServiceProvider::loadBootstrapService()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 0
dl 0
loc 6
ccs 0
cts 3
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Foundation\Providers;
4
5
use Foundation\Console\SeedCommand;
6
use Foundation\Contracts\ConditionalAutoRegistration;
7
use Foundation\Contracts\ModelPolicyContract;
8
use Foundation\Contracts\Ownable;
9
use Foundation\Observers\CacheObserver;
10
use Foundation\Policies\OwnershipPolicy;
11
use Foundation\Services\BootstrapRegistrarService;
12
use Foundation\Traits\Cacheable;
13
use Illuminate\Database\Eloquent\Factory;
14
use Illuminate\Support\Facades\Event;
15
use Illuminate\Support\Facades\Gate;
16
use Illuminate\Support\ServiceProvider;
17
use Route;
18
19
/**
20
 * Class BootstrapServiceProvider.
21
 */
22
class BootstrapServiceProvider extends ServiceProvider
23
{
24
    /**
25
     * @var BootstrapRegistrarService
26
     */
27
    protected $bootstrapService;
28
29
    public function boot()
30
    {
31
        /* Load cache observers only when caching is enabled */
32
        if (config('model.caching')) {
33
            $this->loadCacheObservers();
34
        }
35
    }
36
37
    public function register()
38
    {
39
        /* Load BootstrapService here because of the dependencies needed in BootstrapRegistrarService */
40
        $this->loadBootstrapService();
41
42
        $this->loadCommands();
43
        $this->loadRoutes();
44
        $this->loadConfigs();
45
        $this->loadFactories();
46
        $this->loadMigrations();
47
        $this->loadListeners();
48
49
        /* Override the seed command with the larapi custom one */
50
        $this->overrideSeedCommand();
51
52
53
54
        $this->loadOwnershipPolicies();
55
56
        /* Register Policies after ownership policies otherwise they would not get overriden */
57
        $this->loadPolicies();
58
59
        /* Register all Module Service providers.
60
        ** Always load at the end so the user has the ability to override certain functionality
61
         * */
62
        $this->loadServiceProviders();
63
    }
64
65
    private function loadBootstrapService()
66
    {
67
        $this->bootstrapService = new BootstrapRegistrarService();
68
69
        if (!($this->app->environment('production') || $this->app->environment('testing'))) {
70
            $this->bootstrapService->recache();
71
        }
72
    }
73
74
    private function loadCommands()
75
    {
76
        $this->commands($this->bootstrapService->getCommands());
77
    }
78
79
    private function loadRoutes()
80
    {
81
        foreach ($this->bootstrapService->getRoutes() as $route) {
82
            $path = $route['path'];
83
            Route::group([
84
                'prefix' => 'v1/' . str_plural($route['module']),
85
                'namespace' => $route['controller'],
86
                'domain' => $route['domain'],
87
                'middleware' => ['api'],
88
            ], function () use ($path) {
89
                require $path;
90
            });
91
            Route::model($route['module'], $route['model']);
92
        }
93
    }
94
95
    /**
96
     * Register config.
97
     *
98
     * @return void
99
     */
100
    protected function loadConfigs()
101
    {
102
        foreach ($this->bootstrapService->getConfigs() as $config) {
103
            if (isset($config['filename']) && is_string($config['filename'])) {
104
                $fileName = $config['filename'];
105
                $configName = strtolower(explode('.',$fileName)[0]);
106
                $this->mergeConfigFrom(
107
                    $config['path'], $configName
108
                );
109
            }
110
        }
111
    }
112
113
    /**
114
     * Register additional directories of factories.
115
     *
116
     * @return void
117
     */
118
    public function loadFactories()
119
    {
120
        foreach ($this->bootstrapService->getFactories() as $factory) {
121
            if (!$this->app->environment('production')) {
122
                app(Factory::class)->load($factory['path']);
123
            }
124
        }
125
    }
126
127
    /**
128
     * Register additional directories of migrations.
129
     *
130
     * @return void
131
     */
132
    public function loadMigrations()
133
    {
134
        foreach ($this->bootstrapService->getMigrations() as $migration) {
135
            $this->loadMigrationsFrom($migration['path']);
136
        }
137
    }
138
139
    private function loadPolicies()
140
    {
141
        foreach ($this->bootstrapService->getPolicies() as $policy) {
142
            if (class_implements_interface($policy['class'], ModelPolicyContract::class)) {
143
                Gate::policy($policy['model'], $policy['class']);
144
            }
145
        }
146
    }
147
148
    private function overrideSeedCommand()
149
    {
150
        $app = $this->app;
151
        $service = $this->bootstrapService;
152
        $this->app->extend('command.seed', function () use ($app, $service) {
153
            return new SeedCommand($app['db'], $service);
154
        });
155
    }
156
157
    private function loadCacheObservers()
158
    {
159
        foreach ($this->bootstrapService->getModels() as $model) {
160
            if (class_uses_trait($model, Cacheable::class)) {
161
                $model::observe(CacheObserver::class);
162
            }
163
        }
164
    }
165
166
    private function loadOwnershipPolicies()
167
    {
168
        foreach ($this->bootstrapService->getModels() as $model) {
169
            if (class_implements_interface($model, Ownable::class)) {
170
                Gate::policy($model, OwnershipPolicy::class);
171
                Gate::define('access', OwnershipPolicy::class . '@access');
172
            }
173
        }
174
    }
175
176
    private function loadServiceProviders()
177
    {
178
        foreach ($this->bootstrapService->getProviders() as $provider) {
179
            if ($this->passedRegistrationCondition($provider))
180
                $this->app->register($provider);
181
        }
182
    }
183
184
    private function loadListeners()
185
    {
186
        foreach ($this->bootstrapService->getEvents() as $event) {
187
            foreach ($event['listeners'] as $listener) {
188
                Event::listen($event['class'], $listener);
189
            }
190
        }
191
    }
192
193
    private function passedRegistrationCondition($class)
194
    {
195
        if (!class_implements_interface($class, ConditionalAutoRegistration::class))
196
            return true;
197
        return run_class_function($class, 'registrationCondition');
198
    }
199
}
200