Passed
Push — master ( cf340d...4e06a8 )
by Arthur
06:10
created

buildEmptyBootstrapArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 2
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\ListenerContract;
12
use Illuminate\Console\Command;
13
use Nwidart\Modules\Module;
14
use ReflectionClass;
15
16
class BootstrapRegistrarService
17
{
18
19
    /**
20
     * @var array
21
     */
22
    protected $moduleEntityDirectories = [
23
        'commands' => 'Console',
24
        'routes' => 'Routes',
25
        'configs' => 'Config',
26
        'factories' => 'Database/factories',
27
        'migrations' => 'Database/Migrations',
28
        'seeders' => 'Database/Seeders',
29
        'models' => 'Entities',
30
        'policies' => 'Policies',
31
        'providers' => 'Providers',
32
        'events' => 'Events'
33
    ];
34
35
    /**
36
     * @var string
37
     */
38
    protected $cacheFile = 'bootstrap.php';
39
40
    /**
41
     * @var
42
     */
43
    protected $bootstrap;
44
45
46 2
    public function recache()
47
    {
48 2
        $this->buildBootstrapData();
49 2
        $this->storeInCache($this->bootstrap);
50 2
    }
51
52
    /**
53
     * @param $data
54
     */
55 2
    private function storeInCache($data)
56
    {
57 2
        file_put_contents($this->getCachePath(), '<?php return ' . var_export($data, true) . ';');
58 2
    }
59
60
    /**
61
     * @return mixed
62
     */
63 22
    public function readFromCache()
64
    {
65 22
        return include $this->getCachePath();
66
    }
67
68 3
    public function clearCache()
69
    {
70 3
        unlink($this->getCachePath());
71 3
    }
72
73
    /**
74
     * @return bool
75
     */
76 22
    public function cacheExists()
77
    {
78 22
        return file_exists($this->getCachePath());
79
    }
80
81
    /**
82
     * @return string
83
     */
84 22
    private function getCachePath(): string
85
    {
86 22
        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

86
        return app()->/** @scrutinizer ignore-call */ bootstrapPath() . '/cache/' . $this->cacheFile;
Loading history...
87
    }
88
89
    /**
90
     * @return array
91
     */
92 2
    private function buildEmptyBootstrapArray()
93
    {
94 2
        $bootstrapArray = [];
95 2
        foreach ($this->moduleEntityDirectories as $key => $directory) {
96 2
            $bootstrapArray[$key] = [];
97
        }
98
99 2
        return $bootstrapArray;
100
    }
101
102
    /**
103
     * @return string[]
104
     */
105 2
    private function getModules(): array
106
    {
107 2
        $path = base_path('src/Modules');
108 2
        $moduleNames = array_diff(scandir($path), array('..', '.'));
109 2
        $modules = array();
110 2
        foreach ($moduleNames as $moduleName) {
111 2
            $modules[$moduleName] = $path . '/' . $moduleName;
112
        }
113 2
        return $modules;
114
    }
115
116
    /**
117
     * @return void
118
     */
119 2
    private function buildBootstrapData()
120
    {
121 2
        $bootstrap = $this->buildEmptyBootstrapArray();
122 2
        $moduleNames = $this->getModules();
123 2
        foreach ($moduleNames as $moduleName => $modulePath) {
124 2
            if (is_dir($modulePath)) {
125 2
                foreach ($this->moduleEntityDirectories as $key => $directory) {
126 2
                    $directory = ucfirst($directory);
127 2
                    $directoryPath = $modulePath . '/' . $directory;
128 2
                    $namespace = 'Modules' . '\\' . $moduleName;
129 2
                    if (is_dir($directoryPath)) {
130 2
                        $files = scandir($directoryPath);
131 2
                        foreach ($files as $fileName) {
132 2
                            if ($this->hasPhpExtension($fileName)) {
133 2
                                $className = basename($fileName, '.php');
134 2
                                $class = $namespace . '\\' . str_replace('/', '\\', $directory) . '\\' . $className;
135 2
                                switch ($key) {
136 2
                                    case 'commands':
137
                                        try {
138 2
                                            $command = new $class();
139 2
                                            if ($command instanceof Command) {
140 2
                                                $bootstrap[$key][] = $class;
141
                                            }
142
                                        } catch (\Exception $e) {
143
                                            break;
144
                                        }
145 2
                                        break;
146 2
                                    case 'routes':
147 2
                                        $bootstrap[$key][] = $this->buildRouteArray($directoryPath . '/' . $fileName, $namespace);
148 2
                                        break;
149 2
                                    case 'configs':
150 2
                                        $bootstrap[$key][] = $this->buildConfigArray($directoryPath . '/' . $fileName, $moduleName, $fileName);
151 2
                                        break;
152 2
                                    case 'factories':
153 2
                                        $bootstrap[$key][] = $this->buildDirectoryPathArray($directoryPath);
154 2
                                        break;
155 2
                                    case 'migrations':
156 2
                                        $bootstrap[$key][] = $this->buildDirectoryPathArray($directoryPath);
157 2
                                        break;
158 2
                                    case 'seeders':
159 2
                                        $bootstrap[$key][] = $class;
160 2
                                        break;
161 2
                                    case 'models':
162 2
                                        $bootstrap[$key][] = $class;
163 2
                                        break;
164 2
                                    case 'policies':
165 2
                                        $bootstrap[$key][] = $this->buildPolicyArray($class, $namespace);
166 2
                                        break;
167 2
                                    case 'providers':
168 2
                                        $bootstrap[$key][] = $class;
169 2
                                        break;
170 2
                                    case 'events':
171 2
                                        $bootstrap[$key][] = $this->buildEventsArray($class);
172 2
                                        break;
173
                                    default:
174 2
                                        break;
175
                                }
176
                            }
177
                        }
178
                    }
179
                }
180
            }
181
        }
182
183 2
        $this->bootstrap = $bootstrap;
184 2
    }
185
186
    /**
187
     * @param string $fileName
188
     *
189
     * @return bool
190
     */
191 2
    private function hasPhpExtension(string $fileName): bool
192
    {
193 2
        return strlen($fileName) > 4 && '.php' === ($fileName[-4] . $fileName[-3] . $fileName[-2] . $fileName[-1]);
194
    }
195
196
    /**
197
     * @return mixed
198
     */
199 22
    public function loadBootstrapFromCache()
200
    {
201 22
        if (!isset($this->bootstrap)) {
202 22
            if ($this->cacheExists()) {
203 22
                $this->bootstrap = $this->readFromCache();
204
            } else {
205 1
                $this->recache();
206
            }
207
        }
208
209 22
        return $this->bootstrap;
210
    }
211
212
    /**
213
     * @param $path
214
     * @param $namespace
215
     *
216
     * @return array
217
     */
218 2
    private function buildRouteArray($path, $namespace)
219
    {
220 2
        $apiDomain = strtolower(env('API_URL'));
221 2
        $apiDomain = str_replace('http://', '', $apiDomain);
222 2
        $apiDomain = str_replace('https://', '', $apiDomain);
223 2
        $moduleNamespace = $namespace;
224 2
        $moduleName = explode('\\', $moduleNamespace)[1];
225 2
        $controllerNamespace = $moduleNamespace . '\\' . 'Http\\Controllers';
226 2
        $modelNameSpace = $moduleNamespace . '\\' . 'Entities\\' . $moduleName;
227
228
        return [
229 2
            'path' => $path,
230 2
            'namespace' => $namespace,
231 2
            'module' => strtolower($moduleName),
232 2
            'domain' => $apiDomain,
233 2
            'controller' => $controllerNamespace,
234 2
            'model' => $modelNameSpace,
235
        ];
236
    }
237
238
    /**
239
     * @param $class
240
     * @param $namespace
241
     *
242
     * @return array
243
     */
244 2
    private function buildPolicyArray($class, $namespace)
245
    {
246 2
        $moduleNamespace = $namespace;
247 2
        $moduleName = explode('\\', $moduleNamespace)[1];
248 2
        $modelNameSpace = $moduleNamespace . '\\' . 'Entities\\' . $moduleName;
249
250
        return [
251 2
            'class' => $class,
252 2
            'model' => $modelNameSpace,
253
        ];
254
    }
255
256
    /**
257
     * @param $path
258
     * @param $module
259
     *
260
     * @return array
261
     */
262 2
    private function buildConfigArray($path, $module, $filename)
263
    {
264
        return [
265 2
            'path' => $path,
266 2
            'filename' => $filename,
267 2
            'module' => strtolower($module),
268
        ];
269
    }
270
271
    /**
272
     * @param $path
273
     *
274
     * @return array
275
     */
276 2
    private function buildDirectoryPathArray($path)
277
    {
278
        return [
279 2
            'path' => $path,
280
        ];
281
    }
282
283 2
    private function buildEventsArray($class)
284
    {
285 2
        $listenerProperties = get_class_property($class, 'listeners');
286 2
        $listeners = array();
287 2
        foreach ($listenerProperties as $listener) {
288 2
            if (class_implements_interface($listener, ListenerContract::class)) {
289 2
                $listeners[] = $listener;
290
            }
291
        }
292
293
        return [
294 2
            'class' => $class,
295 2
            'listeners' => $listeners
296
        ];
297
    }
298
299
    /**
300
     * @return array
301
     */
302 22
    public function getCommands(): array
303
    {
304 22
        return $this->loadBootstrapFromCache()['commands'] ?? [];
305
    }
306
307
    /**
308
     * @return array
309
     */
310 22
    public function getRoutes(): array
311
    {
312 22
        return $this->loadBootstrapFromCache()['routes'] ?? [];
313
    }
314
315
    /**
316
     * @return array
317
     */
318 22
    public function getConfigs(): array
319
    {
320 22
        return $this->loadBootstrapFromCache()['configs'] ?? [];
321
    }
322
323
    /**
324
     * @return array
325
     */
326 22
    public function getFactories(): array
327
    {
328 22
        return $this->loadBootstrapFromCache()['factories'] ?? [];
329
    }
330
331
    /**
332
     * @return array
333
     */
334 22
    public function getMigrations(): array
335
    {
336 22
        return $this->loadBootstrapFromCache()['migrations'] ?? [];
337
    }
338
339
    /**
340
     * @return array
341
     */
342 22
    public function getSeeders(): array
343
    {
344 22
        return $this->loadBootstrapFromCache()['seeders'] ?? [];
345
    }
346
347
    /**
348
     * @return array
349
     */
350 22
    public function getModels(): array
351
    {
352 22
        return $this->loadBootstrapFromCache()['models'] ?? [];
353
    }
354
355
    /**
356
     * @return array
357
     */
358 22
    public function getPolicies(): array
359
    {
360 22
        return $this->loadBootstrapFromCache()['policies'] ?? [];
361
    }
362
363
    /**
364
     * @return array
365
     */
366 22
    public function getProviders(): array
367
    {
368 22
        return $this->loadBootstrapFromCache()['providers'] ?? [];
369
    }
370
371
    /**
372
     * @return array
373
     */
374 22
    public function getEvents(): array
375
    {
376 22
        return $this->loadBootstrapFromCache()['events'] ?? [];
377
    }
378
}
379