Passed
Pull Request — 2.x (#947)
by Antonio Carlos
05:30
created

HasCapsules::getCapsuleSlugClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

86
        ] = $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...
87
            $capsule['name']
88
        );
89
90
        $capsule['database_namespace'] = "$capsuleNamespace\Database";
91
92
        $capsule['seeds_namespace'] = "{$capsule['database_namespace']}\Seeds";
93
94
        $capsule['model'] = $capsule['models'] = $models =
95
        "{$capsuleNamespace}\\" .
96
        config('twill.capsules.namespaces.models');
97
        $capsule['repositories'] = $repositories =
98
        "{$capsuleNamespace}\\" .
99
        config('twill.capsules.namespaces.repositories');
100
        $capsule['controllers'] = $controllers =
101
        "{$capsuleNamespace}\\" .
102
        config('twill.capsules.namespaces.controllers');
103
        $capsule['requests'] = $requests =
104
        "{$capsuleNamespace}\\" .
105
        config('twill.capsules.namespaces.requests');
106
107
        $capsule['psr4_path'] =
108
            "$basePath/{$name}" .
109
            (filled($this->getCapsulesSubdir())
110
            ? $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

110
            ? /** @scrutinizer ignore-type */ $this->getCapsulesSubdir() . '/'
Loading history...
111
            : '');
112
113
        $capsule['base_path'] = $basePath;
114
115
        $capsule['database_psr4_path'] = "$basePath/{$name}/database";
116
117
        $capsule['seeds_psr4_path'] = "{$capsule['database_psr4_path']}/seeds";
118
119
        $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...
120
121
        $capsule[
122
            'migrations_dir'
123
        ] = "{$capsule['root_path']}/database/migrations";
124
125
        $capsule['views_dir'] = "{$capsule['root_path']}/resources/views";
126
127
        $capsule['view_prefix'] = "{$name}.resources.views.admin";
128
129
        $capsule['routes_file'] = "{$capsule['root_path']}/routes/admin.php";
130
131
        $capsule['model'] = "{$models}\\{$singular}";
132
133
        $capsule['models_dir'] = $this->namespaceToPath($capsule, $models);
134
135
        $capsule['translation'] = "{$models}\\{$singular}Translation";
136
137
        $capsule['slug'] = "{$models}\\{$singular}Slug";
138
139
        $capsule['revision'] = "{$models}\\{$singular}Revision";
140
141
        $capsule['repository'] = "{$repositories}\\{$singular}Repository";
142
143
        $capsule['repositories_dir'] = $this->namespaceToPath(
144
            $capsule,
145
            $repositories
146
        );
147
148
        $capsule['controller'] = "{$controllers}\\{$singular}Controller";
149
150
        $capsule['controllers_dir'] = $this->namespaceToPath(
151
            $capsule,
152
            $controllers
153
        );
154
155
        $capsule['formRequest'] = "{$requests}\\{$singular}Request";
156
157
        $capsule['requests_dir'] = $this->namespaceToPath($capsule, $requests);
158
159
        $capsule['config_file'] = "$basePath/{$name}/config.php";
160
161
        $capsule['config'] = $this->loadCapsuleConfig($capsule);
162
163
        $this->registerPsr4Autoloader($capsule);
164
165
        $this->autoloadConfigFiles($capsule);
166
167
        return $capsule;
168
    }
169
170
    public function registerPsr4Autoloader($capsule)
171
    {
172
        $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

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