Passed
Push — master ( 67253e...1a1f73 )
by Arthur
04:53 queued 11s
created

BootstrapRegistrarService   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 324
Duplicated Lines 0 %

Test Coverage

Coverage 97.5%

Importance

Changes 0
Metric Value
eloc 111
dl 0
loc 324
ccs 117
cts 120
cp 0.975
rs 8.96
c 0
b 0
f 0
wmc 43

24 Methods

Rating   Name   Duplication   Size   Complexity  
A getSeeders() 0 3 1
A buildRouteArray() 0 17 1
A getConfigs() 0 3 1
A __construct() 0 3 1
A clearCache() 0 3 1
A buildEmptyBootstrapArray() 0 8 2
A storeInCache() 0 3 1
A buildConfigArray() 0 5 1
A getMigrations() 0 3 1
A getModels() 0 3 1
A buildDirectoryPathArray() 0 4 1
A getCommands() 0 3 1
A getModules() 0 3 1
A getCachePath() 0 3 1
A getPolicies() 0 3 1
A getFactories() 0 3 1
A buildPolicyArray() 0 9 1
A recache() 0 4 1
A cacheExists() 0 3 1
C buildBootstrapData() 0 56 16
A getRoutes() 0 3 1
A loadBootstrapFromCache() 0 11 3
A readFromCache() 0 3 1
A hasPhpExtension() 0 3 2

How to fix   Complexity   

Complex Class

Complex classes like BootstrapRegistrarService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BootstrapRegistrarService, and based on these observations, apply Extract Interface, too.

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 Illuminate\Console\Command;
12
use Nwidart\Modules\Module;
13
14
class BootstrapRegistrarService
15
{
16
    /**
17
     * @var \Illuminate\Filesystem\Filesystem
18
     */
19
    protected $files;
20
21
    /**
22
     * @var array
23
     */
24
    protected $moduleEntityDirectories = [
25
        'commands' => 'Console',
26
        'routes' => 'Routes',
27
        'configs' => 'Config',
28
        'factories' => 'Database/factories',
29
        'migrations' => 'Database/Migrations',
30
        'seeders' => 'Database/Seeders',
31
        'models' => 'Entities',
32
        'policies' => 'Policies'
33
    ];
34
35
    /**
36
     * @var string
37
     */
38
    protected $cacheFile = 'bootstrap.php';
39
40
    /**
41
     * @var
42
     */
43
    protected $bootstrap;
44
45
    /**
46
     * BootstrapRegistrarService constructor.
47
     */
48 17
    public function __construct()
49
    {
50 17
        $this->files = new \Illuminate\Filesystem\Filesystem();
51 17
    }
52
53
    /**
54
     *
55
     */
56 17
    public function recache()
57
    {
58 17
        $this->buildBootstrapData();
59 17
        $this->storeInCache($this->bootstrap);
60 17
    }
61
62
    /**
63
     * @param $data
64
     */
65 17
    private function storeInCache($data)
66
    {
67 17
        file_put_contents($this->getCachePath(), '<?php return ' . var_export($data, true) . ';');
68 17
    }
69
70
    /**
71
     * @return mixed
72
     */
73 17
    public function readFromCache()
74
    {
75 17
        return include $this->getCachePath();
76
    }
77
78
    /**
79
     *
80
     */
81 3
    public function clearCache()
82
    {
83 3
        unlink($this->getCachePath());
84 3
    }
85
86
    /**
87
     * @return bool
88
     */
89 17
    public function cacheExists()
90
    {
91 17
        return file_exists($this->getCachePath());
92
    }
93
94
    /**
95
     * @return string
96
     */
97 17
    private function getCachePath(): string
98
    {
99 17
        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

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