Passed
Push — 2.x ( 21558b...d42bdc )
by
unknown
06:07
created

HasCapsules::registerServiceProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
rs 10
1
<?php
2
3
namespace A17\Twill\Services\Capsules;
4
5
use Illuminate\Support\Facades\File;
6
use Illuminate\Support\Str;
7
8
trait HasCapsules
9
{
10
    protected function getAutoloader()
11
    {
12
        return app()->bound('autoloader')
13
            ? app('autoloader')
14
            : require base_path('vendor/autoload.php');
15
    }
16
17
    public function getCapsuleList()
18
    {
19
        $path = $this->getCapsulesPath();
20
21
        $list = collect(config('twill.capsules.list'));
22
23
        if (config('twill.capsules.loaded')) {
24
            return $list;
25
        }
26
27
        return $list
28
            ->where('enabled', true)
29
            ->map(function ($capsule) use ($path) {
30
                return $this->makeCapsule($capsule, $path);
31
            });
32
    }
33
34
    public function getCapsuleByModel($model)
35
    {
36
        return $this->getCapsuleList()
37
            ->where('singular', Str::studly($model))
38
            ->first();
39
    }
40
41
    public function getCapsuleByModule($module)
42
    {
43
        return $this->getCapsuleList()
44
            ->filter(function ($capsule) use ($module) {
45
                return Str::lower($capsule['plural']) == Str::lower($module);
46
            })
47
            ->first();
48
    }
49
50
    /**
51
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
52
     */
53
    public function getCapsulesPath()
54
    {
55
        return config('twill.capsules.path');
56
    }
57
58
    /**
59
     * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed
60
     */
61
    public function getCapsulesSubdir()
62
    {
63
        $subdir = config('twill.capsules.namespaces.subdir');
64
65
        return $subdir;
66
    }
67
68
    public function makeCapsule($capsule, $basePath = null)
69
    {
70
        $basePath = $basePath ?? $this->getCapsulesPath();
71
72
        $capsule['name'] = Str::studly($capsule['name']);
73
74
        $capsule['module'] = Str::camel($capsule['name']);
75
76
        $capsule['plural'] = $name = $capsule['name'];
77
78
        $capsule['singular'] = $singular =
79
            $capsule['singular'] ?? Str::singular($name);
80
81
        $twillNamespace = config('twill.namespace');
0 ignored issues
show
Unused Code introduced by
The assignment to $twillNamespace is dead and can be removed.
Loading history...
82
83
        $capsule['base_namespace'] = config('twill.capsules.namespaces.base');
84
85
        $capsule['namespace'] = $capsuleNamespace = $this->getManager()->capsuleNamespace(
0 ignored issues
show
Bug introduced by
The method capsuleNamespace() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

85
        $capsule['namespace'] = $capsuleNamespace = $this->getManager()->/** @scrutinizer ignore-call */ capsuleNamespace(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
86
            $capsule['name']
87
        );
88
89
        $capsule['database_namespace'] = "$capsuleNamespace\Database";
90
91
        $capsule['seeds_namespace'] = "{$capsule['database_namespace']}\Seeds";
92
93
        $capsule['model'] = $capsule['models'] = $models =
94
            "{$capsuleNamespace}\\" .
95
            config('twill.capsules.namespaces.models');
96
        $capsule['repositories'] = $repositories =
97
            "{$capsuleNamespace}\\" .
98
            config('twill.capsules.namespaces.repositories');
99
        $capsule['controllers'] = $controllers =
100
            "{$capsuleNamespace}\\" .
101
            config('twill.capsules.namespaces.controllers');
102
        $capsule['requests'] = $requests =
103
            "{$capsuleNamespace}\\" .
104
            config('twill.capsules.namespaces.requests');
105
106
        $capsule['psr4_path'] =
107
            "$basePath/{$name}" .
108
            (filled($this->getCapsulesSubdir())
109
                ? $this->getCapsulesSubdir() . '/'
0 ignored issues
show
Bug introduced by
Are you sure $this->getCapsulesSubdir() of type Illuminate\Config\Reposi...ation\Application|mixed can be used in concatenation? ( Ignorable by Annotation )

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

109
                ? /** @scrutinizer ignore-type */ $this->getCapsulesSubdir() . '/'
Loading history...
110
                : '');
111
112
        $capsule['base_path'] = $basePath;
113
114
        $capsule['database_psr4_path'] = "$basePath/{$name}/database";
115
116
        $capsule['seeds_psr4_path'] = "{$capsule['database_psr4_path']}/seeds";
117
118
        $capsule['root_path'] = $root = $this->capsuleRootPath($capsule);
0 ignored issues
show
Unused Code introduced by
The assignment to $root is dead and can be removed.
Loading history...
119
120
        $capsule['migrations_dir'] = "{$capsule['root_path']}/database/migrations";
121
122
        $capsule['lang_dir'] = "{$capsule['root_path']}/resources/lang";
123
124
        $capsule['views_dir'] = "{$capsule['root_path']}/resources/views";
125
126
        $capsule['view_prefix'] = "{$name}.resources.views.admin";
127
128
        $capsule['routes_file'] = "{$capsule['root_path']}/routes/admin.php";
129
130
        $capsule['model'] = "{$models}\\{$singular}";
131
132
        $capsule['models_dir'] = $this->namespaceToPath($capsule, $models);
133
134
        $capsule['translation'] = "{$models}\\{$singular}Translation";
135
136
        $capsule['slug'] = "{$models}\\{$singular}Slug";
137
138
        $capsule['revision'] = "{$models}\\{$singular}Revision";
139
140
        $capsule['repository'] = "{$repositories}\\{$singular}Repository";
141
142
        $capsule['repositories_dir'] = $this->namespaceToPath(
143
            $capsule,
144
            $repositories
145
        );
146
147
        $capsule['controller'] = "{$controllers}\\{$singular}Controller";
148
149
        $capsule['controllers_dir'] = $this->namespaceToPath(
150
            $capsule,
151
            $controllers
152
        );
153
154
        $capsule['formRequest'] = "{$requests}\\{$singular}Request";
155
156
        $capsule['requests_dir'] = $this->namespaceToPath($capsule, $requests);
157
158
        $capsule['config_file'] = "$basePath/{$name}/config.php";
159
160
        $capsule['config'] = $this->loadCapsuleConfig($capsule);
161
162
        $this->registerPsr4Autoloader($capsule);
163
164
        $this->autoloadConfigFiles($capsule);
165
166
        $this->registerServiceProvider($capsule);
167
168
        return $capsule;
169
    }
170
171
    public function registerPsr4Autoloader($capsule)
172
    {
173
        $this->getAutoloader()->setPsr4(
0 ignored issues
show
Bug introduced by
The method setPsr4() does not exist on Illuminate\Contracts\Foundation\Application. ( Ignorable by Annotation )

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

173
        $this->getAutoloader()->/** @scrutinizer ignore-call */ setPsr4(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174
            $capsule['namespace'] . '\\',
175
            $capsule['psr4_path']
176
        );
177
178
        $this->getAutoloader()->setPsr4(
179
            $capsule['database_namespace'] . '\\',
180
            $capsule['database_psr4_path']
181
        );
182
183
        $this->getAutoloader()->setPsr4(
184
            $capsule['database_namespace'] . '\\Seeds\\',
185
            $capsule['database_psr4_path'] . '/seeds'
186
        );
187
    }
188
189
    public function registerServiceProvider($capsule): void
190
    {
191
        $rootPath = $this->capsuleRootPath($capsule);
192
        $capsuleName = $capsule['name'];
193
194
        $serviceProviderName = $capsuleName . 'CapsuleServiceProvider';
195
196
        if (File::exists($rootPath . '/' . $serviceProviderName . '.php')) {
197
            $this->app->register($capsule['namespace'] . '\\' . $serviceProviderName);
198
        }
199
    }
200
201
    public function capsuleRootPath($capsule)
202
    {
203
        return config('twill.capsules.path') . '/' . $capsule['name'] ?? null;
204
    }
205
206
    public function getCapsuleRepositoryClass($model)
207
    {
208
        return $this->getCapsuleByModel($model)['repository'] ?? null;
209
    }
210
211
    public function getCapsuleTranslationClass($model)
212
    {
213
        return $this->getCapsuleByModel($model)['translation'] ?? null;
214
    }
215
216
    public function getCapsuleSlugClass($model)
217
    {
218
        return $this->getCapsuleByModel($model)['slug'] ?? null;
219
    }
220
221
    public function getCapsuleRevisionClass($model)
222
    {
223
        return $this->getCapsuleByModel($model)['revision'] ?? null;
224
    }
225
226
    public function getCapsuleFormRequestClass($model)
227
    {
228
        return $this->getCapsuleByModel($model)['formRequest'] ?? null;
229
    }
230
231
    public function getCapsuleViewPrefix($capsule)
232
    {
233
        return $this->getCapsuleByModule(Str::studly($capsule))['view_prefix'] ?? null;
234
    }
235
236
    public function namespaceToPath($capsule, $namespace)
237
    {
238
        return $this->capsuleNamespaceToPath(
239
            $namespace,
240
            $capsule['namespace'],
241
            $capsule['root_path']
242
        );
243
    }
244
245
    public function capsuleNamespaceToPath(
246
        $namespace,
247
        $capsuleNamespace,
248
        $rootPath
249
    ) {
250
        $namespace = Str::after($namespace, $capsuleNamespace . '\\');
251
252
        $subdir = $this->getCapsulesSubdir();
253
254
        $subdir = filled($subdir) ? "{$subdir}/" : '';
255
256
        return "{$rootPath}/{$subdir}" . str_replace('\\', '/', $namespace);
257
    }
258
259
    public function getManager()
260
    {
261
        return $this->manager = $this->manager ?? app('twill.capsules.manager');
0 ignored issues
show
Bug Best Practice introduced by
The property manager does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
262
    }
263
264
    public function seedCapsules($illuminateSeeder)
265
    {
266
        $twillSeeder = app(CapsuleSeeder::class);
267
268
        $this->getCapsuleList()->each(function ($capsule) use (
269
            $twillSeeder,
270
            $illuminateSeeder
271
        ) {
272
            if (filled($capsuleSeeder = $this->makeCapsuleSeeder($capsule))) {
273
                $twillSeeder->setCommand($illuminateSeeder->command);
274
275
                $twillSeeder->call($capsuleSeeder);
276
            }
277
        });
278
    }
279
280
    public function makeCapsuleSeeder($capsule)
281
    {
282
        $seeder = "{$capsule['database_namespace']}\\Seeds\DatabaseSeeder";
283
284
        if (class_exists($seeder)) {
285
            return $seeder;
286
        }
287
288
        return null;
289
    }
290
291
    public function capsuleExists($module)
292
    {
293
        return filled($this->getCapsuleByModule($module));
294
    }
295
296
    public function capsule($string)
297
    {
298
        if (file_exists($string)) {
299
            return $this->getCapsuleByPath($string);
300
        }
301
302
        if (class_exists($string)) {
303
            return $this->getCapsuleByClass($string);
304
        }
305
306
        return $this->getCapsuleByModule($string);
307
    }
308
309
    public function getCapsuleByPath($path)
310
    {
311
        $capsule = $this->getCapsuleList()->first();
312
313
        if (!Str::startsWith($path, $capsule['base_path'])) {
314
            return null;
315
        }
316
317
        $name = Str::before(
318
            Str::after(Str::after($path, $capsule['base_path']), '/'),
319
            '/'
320
        );
321
322
        $name = "{$capsule['base_path']}/$name";
323
324
        return $this->getCapsuleList()
325
            ->where('root_path', $name)
326
            ->first();
327
    }
328
329
    public function getCapsuleByClass($class)
330
    {
331
        $capsule = $this->getCapsuleList()->first();
332
333
        $namespace = Str::beforeLast($class, '\\');
0 ignored issues
show
Unused Code introduced by
The assignment to $namespace is dead and can be removed.
Loading history...
334
335
        if (!Str::startsWith($class, $capsule['base_namespace'])) {
336
            return null;
337
        }
338
339
        $name = Str::before(
340
            Str::after(Str::after($class, $capsule['base_namespace']), '\\'),
341
            '\\'
342
        );
343
344
        $name = "{$capsule['base_namespace']}\\$name";
345
346
        return $this->getCapsuleList()
347
            ->where('namespace', $name)
348
            ->first();
349
    }
350
351
    public function loadCapsuleConfig($capsule)
352
    {
353
        $config = file_exists($file = $capsule['config_file'] ?? 'MISSING-CONFIG-FILE')
354
            ? require $file
355
            : [];
356
357
        $key =
358
            config('twill.capsules.capsule_config_prefix') .
359
            ".{$capsule['module']}";
360
361
        config([
362
            $key => array_replace_recursive(
363
                $config ?? [],
364
                $capsule['config'] ?? []
365
            ),
366
        ]);
367
368
        return $config;
369
    }
370
371
    public function autoloadConfigFiles($capsule)
372
    {
373
        $files = $capsule['config']['autoload']['files'] ?? null;
374
375
        if (blank($files)) {
376
            return;
377
        }
378
379
        collect($files)->each(function ($file) {
380
            if (file_exists($file)) {
381
                require_once $file;
382
            }
383
        });
384
    }
385
}
386