Passed
Push — master ( b4b8e8...3089dd )
by Arthur
26:17 queued 02:28
created

loadBootstrapFromCache()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

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