Passed
Push — master ( 139939...b4b8e8 )
by Arthur
21:54 queued 17s
created

BootstrapRegistrarService::buildRouteArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 3
dl 0
loc 18
ccs 15
cts 15
cp 1
crap 1
rs 9.7666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: arthur
5
 * Date: 04.10.18
6
 * Time: 02:13.
7
 */
8
9
namespace Foundation\Services;
10
11
use Foundation\Abstracts\Listeners\Listener;
12
use Foundation\Abstracts\Observers\Observer;
13
use Foundation\Abstracts\Policies\Policy;
14
use Foundation\Contracts\ConditionalAutoRegistration;
15
use Foundation\Contracts\Ownable;
16
use Foundation\Core\Larapi;
17
use Foundation\Traits\Cacheable;
18
19
class BootstrapRegistrarService
20
{
21
22
    /**
23
     * @var string
24
     */
25
    protected $cacheFile = 'bootstrap.php';
26
27
    /**
28
     * @var
29
     */
30
    protected $bootstrap;
31
32
    public function recache()
33
    {
34
        $this->bootstrap();
35
36
        $this->storeInCache($this->bootstrap);
37
    }
38
39
    /**
40
     * @param $data
41
     */
42
    private function storeInCache($data)
43 62
    {
44
        file_put_contents($this->getCachePath(), '<?php return ' . var_export($data, true) . ';');
45 62
    }
46 62
47 62
    /**
48
     * @return mixed
49
     */
50
    public function readFromCache()
51
    {
52 62
        return include $this->getCachePath();
53
    }
54 62
55 62
    public function clearCache()
56
    {
57
        unlink($this->getCachePath());
58
    }
59
60 62
    /**
61
     * @return bool
62 62
     */
63
    public function cacheExists()
64
    {
65 3
        return file_exists($this->getCachePath());
66
    }
67 3
68 3
    /**
69
     * @return string
70
     */
71
    private function getCachePath(): string
72
    {
73 62
        return app()->bootstrapPath() . '/cache/' . $this->cacheFile;
1 ignored issue
show
introduced by
The method bootstrapPath() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

73
        return app()->/** @scrutinizer ignore-call */ bootstrapPath() . '/cache/' . $this->cacheFile;
Loading history...
74
    }
75 62
76
    public function bootstrap()
77
    {
78
        foreach (Larapi::getModules() as $module) {
79
            $this->bootstrapCommands($module);
80
            $this->bootstrapRoutes($module);
81 62
            $this->bootstrapConfigs($module);
82
            $this->bootstrapFactories($module);
83 62
            $this->bootstrapMigrations($module);
84
            $this->bootstrapModels($module);
85
            $this->bootstrapSeeders($module);
86
            $this->bootstrapProviders($module);
87
            $this->bootstrapEvents($module);
88
        }
89 62
    }
90
91 62
    private function bootstrapCommands(\Foundation\Core\Module $module)
92 62
    {
93 62
        foreach ($module->getCommands()->getClasses() as $commandClass) {
94
            $this->bootstrap['commands'][] = [
95
                'class' => $commandClass
96 62
            ];
97
        }
98
    }
99
100
    private function bootstrapRoutes(\Foundation\Core\Module $module)
101
    {
102 62
        foreach ($module->getRoutes()->getFiles() as $file) {
103
            $this->bootstrap['routes'][] = [
104 62
                'prefix' => $this->generateRoutePrefixFromFileName($file->getFileName()),
105 62
                'controller_namespace' => $module->getControllers()->getNamespace(),
106 62
                'domain' => Larapi::getApiDomainName(),
107 62
                'path' => $file->getPath(),
108 62
                'module_model' => $module->getMainModel()
109
            ];
110
        }
111 62
    }
112
113
    private function generateRoutePrefixFromFileName(string $fileName)
114
    {
115
        $prefixArray = explode('.', $fileName);
116
        $prefixVersion = $prefixArray[1];
117 62
        $prefixRoute = $prefixArray[0];
118
        return $prefixVersion . '/' . $prefixRoute;
119 62
    }
120 62
121 62
    private function bootstrapConfigs(\Foundation\Core\Module $module)
122 62
    {
123 62
        foreach ($module->getConfigs()->getFiles() as $file) {
124 62
            $this->bootstrap['configs'][] = [
125 62
                'name' => $file->getName(),
126 62
                'path' => $file->getPath()
127 62
            ];
128 62
        }
129 62
    }
130 62
131 62
    private function bootstrapFactories(\Foundation\Core\Module $module)
132 62
    {
133 62
        $this->bootstrap['factories'][] = [
134 62
            'path' => $module->getFactories()->getPath()
135
        ];
136 62
    }
137 62
138 62
    private function bootstrapMigrations(\Foundation\Core\Module $module)
139
    {
140
        $this->bootstrap['migrations'][] = [
141
            'path' => $module->getMigrations()->getPath()
142
        ];
143 62
    }
144 62
145 62
    private function bootstrapSeeders(\Foundation\Core\Module $module)
146 62
    {
147 62
        foreach ($module->getSeeders()->getClasses() as $seederClass) {
148 62
            $this->bootstrap['seeders'][] = [
149 62
                'class' => $seederClass,
150 62
            ];
151 62
        }
152 62
    }
153 62
154 62
    private function bootstrapModels(\Foundation\Core\Module $module)
155 62
    {
156 62
        foreach ($module->getModels()->getClasses() as $modelClass) {
157 62
            $this->bootstrap['models'][] = [
158 62
                'class' => $modelClass,
159 62
                'observers' => $this->extractObserversFromModel($modelClass),
160 62
                'policies' => $this->extractPoliciesFromModel($modelClass),
161 62
                'cacheable' => class_uses_trait($modelClass, Cacheable::class),
162 62
                'ownable' => class_implements_interface($modelClass, Ownable::class)
163 62
            ];
164 62
        }
165 62
    }
166 62
167 62
    private function extractObserversFromModel(string $modelClass)
168 62
    {
169 62
        $observers = [];
170 62
        foreach (get_class_property($modelClass, 'observers') ?? [] as $observerClass) {
171
            if (instance_without_constructor($observerClass) instanceof Observer) {
172
                $observers[] = $observerClass;
173
            }
174
        }
175
        return $observers;
176
    }
177
178
    private function extractPoliciesFromModel(string $modelClass)
179
    {
180
        $policies = [];
181 62
        foreach (get_class_property($modelClass, 'policies') ?? [] as $policyClass) {
182 62
            if (instance_without_constructor($policyClass) instanceof Policy) {
183
                $policies[] = $policyClass;
184
            }
185
        }
186
        return $policies;
187
    }
188
189 62
190
    private function bootstrapProviders(\Foundation\Core\Module $module)
191 62
    {
192
        foreach ($module->getServiceProviders()->getClasses() as $serviceProviderClass) {
193
            if ($this->passedRegistrationCondition($serviceProviderClass)) {
194
                $this->bootstrap['providers'][] = [
195
                    'class' => $serviceProviderClass
196
                ];
197 62
            }
198
        }
199 62
    }
200 62
201 62
    private function passedRegistrationCondition($class)
202
    {
203
        if (!class_implements_interface($class, ConditionalAutoRegistration::class)) {
204
            return true;
205
        }
206
207 62
        return call_class_function($class, 'registrationCondition');
208
    }
209
210
    private function bootstrapEvents(\Foundation\Core\Module $module)
211
    {
212
        foreach ($module->getEvents()->getClasses() as $eventClass) {
213
            $listeners = [];
214
            foreach (get_class_property($eventClass, 'listeners') ?? [] as $listenerClass) {
215
                if (instance_without_constructor($listenerClass) instanceof Listener) {
216 62
                    $listeners[] = $listenerClass;
217
                }
218 62
            }
219 62
            $this->bootstrap['events'][] = [
220 62
                'class' => $eventClass,
221 62
                'listeners' => $listeners
222 62
            ];
223 62
        }
224 62
    }
225
226
    /**
227 62
     * @return mixed
228 62
     */
229 62
    public function loadBootstrapFromCache()
230 62
    {
231 62
        if (!isset($this->bootstrap)) {
232 62
            if ($this->cacheExists()) {
233 62
                $this->bootstrap = $this->readFromCache();
234
            } else {
235
                $this->recache();
236
            }
237
        }
238
239
        return $this->bootstrap;
240
    }
241
242
    public function loadNewBootstrap()
243 62
    {
244
        $this->bootstrap();
245 62
        return $this->bootstrap;
246 62
    }
247 62
248
    /**
249
     * @return array
250 62
     */
251 62
    public function getCommands(): array
252
    {
253
        return $this->loadBootstrapFromCache()['commands'] ?? [];
254
    }
255
256
    /**
257
     * @return array
258
     */
259
    public function getRoutes(): array
260
    {
261 62
        return $this->loadBootstrapFromCache()['routes'] ?? [];
262
    }
263
264 62
    /**
265 62
     * @return array
266 62
     */
267
    public function getConfigs(): array
268
    {
269
        return $this->loadBootstrapFromCache()['configs'] ?? [];
270
    }
271
272
    /**
273
     * @return array
274
     */
275 62
    public function getFactories(): array
276
    {
277
        return $this->loadBootstrapFromCache()['factories'] ?? [];
278 62
    }
279
280
    /**
281
     * @return array
282 62
     */
283
    public function getMigrations(): array
284 62
    {
285 62
        return $this->loadBootstrapFromCache()['migrations'] ?? [];
286 62
    }
287 62
288 62
    /**
289
     * @return array
290
     */
291
    public function getSeeders(): array
292
    {
293 62
        return $this->loadBootstrapFromCache()['seeders'] ?? [];
294 62
    }
295
296
    /**
297
     * @return array
298
     */
299
    public function getModels(): array
300
    {
301 62
        return $this->loadBootstrapFromCache()['models'] ?? [];
302
    }
303 62
304
    /**
305
     * @return array
306
     */
307
    public function getPolicies(): array
308
    {
309 62
        return $this->loadBootstrapFromCache()['policies'] ?? [];
310
    }
311 62
312
    /**
313
     * @return array
314
     */
315
    public function getProviders(): array
316
    {
317 62
        return $this->loadBootstrapFromCache()['providers'] ?? [];
318
    }
319 62
320
    /**
321
     * @return array
322
     */
323
    public function getEvents(): array
324
    {
325 62
        return $this->loadBootstrapFromCache()['events'] ?? [];
326
    }
327
}
328