Passed
Pull Request — 2.x (#729)
by Quentin
08:04
created

ModuleMake   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 667
Duplicated Lines 0 %

Test Coverage

Coverage 96.57%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 279
dl 0
loc 667
ccs 169
cts 175
cp 0.9657
rs 2.88
c 3
b 0
f 0
wmc 69

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 20 1
B checkCapsuleDirectory() 0 21 7
A databasePath() 0 7 3
A checkOption() 0 17 4
A createController() 0 17 2
A createRequest() 0 17 2
A createViews() 0 11 2
A createMigration() 0 41 3
A renderStubForOption() 0 12 2
F createModels() 0 90 15
B handle() 0 93 4
A namespace() 0 8 3
B createRepository() 0 31 9
A createCapsulePath() 0 13 2
A viewPath() 0 9 2
A makeDir() 0 14 4
A createRoutes() 0 13 1
A createSeed() 0 11 1
A makeTwillDirectory() 0 3 1
A createCapsuleNamespace() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like ModuleMake 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 ModuleMake, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace A17\Twill\Commands;
4
5
use Illuminate\Config\Repository as Config;
6
use Illuminate\Filesystem\Filesystem;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Composer;
9
use Illuminate\Support\Facades\File;
10
use Illuminate\Support\Str;
11
12
class ModuleMake extends Command
13
{
14
    /**
15
     * The name and signature of the console command.
16
     *
17
     * @var string
18
     */
19
    protected $signature = 'twill:make:module {moduleName}
20
        {--B|hasBlocks}
21
        {--T|hasTranslation}
22
        {--S|hasSlug}
23
        {--M|hasMedias}
24
        {--F|hasFiles}
25
        {--P|hasPosition}
26
        {--R|hasRevisions}
27
        {--all}';
28
29
    /**
30
     * The console command description.
31
     *
32
     * @var string
33
     */
34
    protected $description = 'Create a new Twill Module';
35
36
    /**
37
     * @var Filesystem
38
     */
39
    protected $files;
40
41
    /**
42
     * @var Composer
43
     */
44
    protected $composer;
45
46
    /**
47
     * @var string[]
48
     */
49
    protected $modelTraits;
50
51
    /**
52
     * @var string[]
53
     */
54
    protected $repositoryTraits;
55
56
    /**
57
     * @var Config
58
     */
59
    protected $config;
60
61
    /**
62
     * @var bool
63
     */
64
    protected $blockable;
65
66
    /**
67
     * @var bool
68
     */
69
    protected $translatable;
70
71
    /**
72
     * @var bool
73
     */
74
    protected $sluggable;
75
76
    /**
77
     * @var bool
78
     */
79
    protected $mediable;
80
81
    /**
82
     * @var bool
83
     */
84
    protected $fileable;
85
86
    /**
87
     * @var bool
88
     */
89
    protected $sortable;
90
91
    /**
92
     * @var bool
93
     */
94
    protected $revisionable;
95
96
    /**
97
     * @var bool
98
     */
99
    protected $defaultsAnswserToNo;
100
101
    /**
102
     * @var bool
103
     */
104
    protected $isCapsule = false;
105 69
106
    /**
107 69
     * @var string
108
     */
109 69
    protected $moduleBasePath;
110 69
111 69
    /**
112
     * @var string
113 69
     */
114 69
    protected $capsule;
115 69
116 69
    /**
117 69
     * @param Filesystem $files
118 69
     * @param Composer $composer
119 69
     * @param Config $config
120
     */
121 69
    public function __construct(Filesystem $files, Composer $composer, Config $config)
122
    {
123 69
        parent::__construct();
124 69
125 69
        $this->files = $files;
126
        $this->composer = $composer;
127
        $this->config = $config;
128
129
        $this->blockable = false;
130
        $this->translatable = false;
131
        $this->sluggable = false;
132 1
        $this->mediable = false;
133
        $this->fileable = false;
134 1
        $this->sortable = false;
135
        $this->revisionable = false;
136 1
137 1
        $this->defaultsAnswserToNo = false;
138
139
        $this->modelTraits = ['HasBlocks', 'HasTranslation', 'HasSlug', 'HasMedias', 'HasFiles', 'HasRevisions', 'HasPosition'];
140
        $this->repositoryTraits = ['HandleBlocks', 'HandleTranslations', 'HandleSlugs', 'HandleMedias', 'HandleFiles', 'HandleRevisions'];
141
    }
142
143
    protected function checkCapsuleDirectory($dir)
144 1
    {
145 1
        if (file_exists($dir)) {
146 1
            if (!$this->option('force')) {
147
                $answer = $this->choice("Capsule path exists ({$dir}). Erase and overwrite?",
148 1
                    ['no', 'yes'], $this->defaultsAnswserToNo
149 1
                    ? 0
150
                    : 1);
151
            }
152 1
153 1
            if ('yes' === ($answer ?? 'no') || $this->option('force')) {
154 1
                File::deleteDirectory($dir);
155 1
156 1
                if (file_exists($dir)) {
157 1
                    $this->info("Directory could not be deleted. Aborted.");
158 1
                    die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
159
                }
160
            } else {
161 1
                $this->info("Aborted");
162 1
163 1
                die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
164 1
            }
165 1
        }
166 1
    }
167 1
168
    /**
169
     * Executes the console command.
170 1
     *
171
     * @return mixed
172 1
     */
173 1
    public function handle()
174 1
    {
175 1
        $moduleName = Str::camel(Str::plural(lcfirst($this->argument('moduleName'))));
0 ignored issues
show
Bug introduced by
It seems like $this->argument('moduleName') can also be of type null and string[]; however, parameter $string of lcfirst() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

175
        $moduleName = Str::camel(Str::plural(lcfirst(/** @scrutinizer ignore-type */ $this->argument('moduleName'))));
Loading history...
176 1
177 1
        $this->capsule = app('twill.capsules.manager')->makeCapsule(['name' => $moduleName], config("twill.capsules.path"));
0 ignored issues
show
Bug introduced by
The method makeCapsule() 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

177
        $this->capsule = app('twill.capsules.manager')->/** @scrutinizer ignore-call */ makeCapsule(['name' => $moduleName], config("twill.capsules.path"));

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...
178
179 1
        $enabledOptions = Collection::make($this->options())->only([
180 1
            'hasBlocks',
181
            'hasTranslation',
182 1
            'hasSlug',
183 1
            'hasMedias',
184 1
            'hasFiles',
185 1
            'hasPosition',
186
            'hasRevisions',
187
        ])->filter(function ($enabled) {
188
            return $enabled;
189
        });
190 1
191
        if (count($enabledOptions) > 0) {
192 1
            $this->defaultsAnswserToNo = true;
193
        }
194 1
195 1
        $this->blockable = $this->checkOption('hasBlocks');
196
        $this->translatable = $this->checkOption('hasTranslation');
197
        $this->sluggable = $this->checkOption('hasSlug');
198
        $this->mediable = $this->checkOption('hasMedias');
199
        $this->fileable = $this->checkOption('hasFiles');
200
        $this->sortable = $this->checkOption('hasPosition');
201
        $this->revisionable = $this->checkOption('hasRevisions');
202
203
        $activeTraits = [
204 1
            $this->blockable,
205
            $this->translatable,
206 1
            $this->sluggable,
207 1
            $this->mediable,
208
            $this->fileable,
209 1
            $this->revisionable,
210
            $this->sortable,
211 1
        ];
212
213 1
        $modelName = Str::studly(Str::singular($moduleName));
214 1
215
        $this->createCapsuleNamespace(Str::studly($moduleName), $modelName);
216 1
217
        $this->createCapsulePath(Str::studly($moduleName), $modelName);
218 1
219 1
        $this->createMigration($moduleName);
220 1
        $this->createModels($modelName, $activeTraits);
221 1
        $this->createRepository($modelName, $activeTraits);
222
        $this->createController($moduleName, $modelName);
223
        $this->createRequest($modelName);
224 1
        $this->createViews($moduleName);
225 1
226
        if ($this->isCapsule) {
227
            $this->createRoutes($moduleName);
0 ignored issues
show
Unused Code introduced by
The call to A17\Twill\Commands\ModuleMake::createRoutes() has too many arguments starting with $moduleName. ( Ignorable by Annotation )

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

227
            $this->/** @scrutinizer ignore-call */ 
228
                   createRoutes($moduleName);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
228
            $this->createSeed($moduleName);
229
        } else {
230
            $this->info("Add Route::module('{$moduleName}'); to your admin routes file.");
231
        }
232
233 1
        $this->info("Setup a new CMS menu item in config/twill-navigation.php:");
234 1
235 1
        $navTitle = Str::studly($moduleName);
236 1
237
        $this->info("
238 1
            '{$moduleName}' => [
239
                'title' => '{$navTitle}',
240 1
                'module' => true
241
            ]
242 1
        ");
243
244 1
        if ($this->isCapsule) {
245
            $this->info("Setup your new Capsule on config/twill.php:");
246
247
            $navTitle = Str::studly($moduleName);
0 ignored issues
show
Unused Code introduced by
The assignment to $navTitle is dead and can be removed.
Loading history...
248
249
            $this->info("
250
                'capsules' => [
251
                    'list' => [
252
                        [
253 1
                            'name' => '{$this->capsule['name']}',
254
                            'enabled' => true
255 1
                        ]
256
                    ]
257 1
                ]
258
            ");
259 1
        }
260 1
261
        $this->info("Migrate your database.\n");
262 1
263
        $this->info("Enjoy.");
264 1
265 1
        $this->composer->dumpAutoloads();
266 1
    }
267 1
268
    /**
269
     * Creates a new module database migration file.
270 1
     *
271
     * @param string $moduleName
272
     * @return void
273 1
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
274 1
     */
275
    private function createMigration($moduleName = 'items')
276 1
    {
277
        $table = Str::snake($moduleName);
278 1
        $tableClassName = Str::studly($table);
279
280 1
        $className = "Create{$tableClassName}Tables";
0 ignored issues
show
Unused Code introduced by
The assignment to $className is dead and can be removed.
Loading history...
281
282
        $migrationName = 'create_' . $table . '_tables';
283 1
284 1
        if (!count(glob($this->databasePath('migrations/*' . $migrationName . '.php')))) {
285
            $migrationPath = $this->databasePath() . '/migrations';
286 1
287
            $this->makeDir($migrationPath);
288 1
289
            $fullPath = $this->laravel['migration.creator']->create($migrationName, $migrationPath);
290 1
291
            $stub = str_replace(
292
                ['{{table}}', '{{singularTableName}}', '{{tableClassName}}'],
293 1
                [$table, Str::singular($table), $tableClassName],
294
                $this->files->get(__DIR__ . '/stubs/migration.stub')
295 1
            );
296 1
297 1
            if ($this->translatable) {
298
                $stub = preg_replace('/{{!hasTranslation}}[\s\S]+?{{\/!hasTranslation}}/', '', $stub);
299
            } else {
300
                $stub = str_replace([
301 1
                    '{{!hasTranslation}}',
302
                    '{{/!hasTranslation}}',
303 1
                ], '', $stub);
304
            }
305 1
306
            $stub = $this->renderStubForOption($stub, 'hasTranslation', $this->translatable);
307 1
            $stub = $this->renderStubForOption($stub, 'hasSlug', $this->sluggable);
308 1
            $stub = $this->renderStubForOption($stub, 'hasRevisions', $this->revisionable);
309
            $stub = $this->renderStubForOption($stub, 'hasPosition', $this->sortable);
310
311 1
            $stub = preg_replace('/\}\);[\s\S]+?Schema::create/', "});\n\n        Schema::create", $stub);
312 1
313
            $this->files->put($fullPath, $stub);
314
315
            $this->info("Migration created successfully! Add some fields!");
316
        }
317 1
    }
318 1
319 1
    /**
320 1
     * Creates new model class files for the given model name and traits.
321 1
     *
322
     * @param string $modelName
323 1
     * @param array $activeTraits
324 1
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
325 1
     */
326 1
    private function createModels($modelName = 'Item', $activeTraits = [])
327
    {
328 1
        $modelClassName = $this->namespace('models', 'Models', $modelName);
329
330 1
        $modelsDir = $this->isCapsule ? $this->capsule['models_dir'] : 'Models';
331 1
332
        $this->makeTwillDirectory($modelsDir);
333 1
334
        if ($this->translatable) {
335 1
            $this->makeTwillDirectory($baseDir = $this->isCapsule ? $modelsDir : "{$modelsDir}/Translations");
336 1
337 1
            $modelTranslationClassName = $modelName . 'Translation';
338 1
339 1
            $stub = str_replace(
340
                ['{{modelTranslationClassName}}', '{{modelClassWithNamespace}}', '{{modelClassName}}', '{{namespace}}'],
341
                [$modelTranslationClassName, $modelClassName, $modelName, $this->namespace('models', 'Models\Translations')],
342
                $this->files->get(__DIR__ . '/stubs/model_translation.stub')
343
            );
344 1
345
            twill_put_stub(twill_path("{$baseDir}/" . $modelTranslationClassName . '.php'), $stub);
346
        }
347
348
        if ($this->sluggable) {
349
            $this->makeTwillDirectory($baseDir = $this->isCapsule ? $modelsDir : "{$modelsDir}/Slugs");
350
351
            $modelSlugClassName = $modelName . 'Slug';
352
353
            $stub = str_replace(
354
                ['{{modelSlugClassName}}', '{{modelClassWithNamespace}}', '{{modelName}}', '{{namespace}}'],
355 1
                [$modelSlugClassName, $modelClassName, Str::snake($modelName), $this->namespace('models', 'Models\Slugs')],
356
                $this->files->get(__DIR__ . '/stubs/model_slug.stub')
357 1
            );
358
359 1
            twill_put_stub(twill_path("{$baseDir}/" . $modelSlugClassName . '.php'), $stub);
360
        }
361 1
362
        if ($this->revisionable) {
363 1
            $this->makeTwillDirectory($baseDir = $this->isCapsule ? $modelsDir : "{$modelsDir}/Revisions");
364 1
365 1
            $modelRevisionClassName = $modelName . 'Revision';
366
367
            $stub = str_replace(
368
                ['{{modelRevisionClassName}}', '{{modelClassWithNamespace}}', '{{modelName}}', '{{namespace}}'],
369 1
                [$modelRevisionClassName, $modelClassName, Str::snake($modelName), $this->namespace('models', 'Models\Revisions')],
370
                $this->files->get(__DIR__ . '/stubs/model_revision.stub')
371 1
            );
372
373 1
            twill_put_stub(twill_path("{$baseDir}/" . $modelRevisionClassName . '.php'), $stub);
374
        }
375 1
376
        $activeModelTraits = [];
377 1
378 1
        foreach ($activeTraits as $index => $traitIsActive) {
379
            if ($traitIsActive) {
380
                !isset($this->modelTraits[$index]) ?: $activeModelTraits[] = $this->modelTraits[$index];
381
            }
382
        }
383
384
        $activeModelTraitsString = empty($activeModelTraits) ? '' : 'use ' . rtrim(implode(', ', $activeModelTraits), ', ') . ';';
385
386
        $activeModelTraitsImports = empty($activeModelTraits) ? '' : "use A17\Twill\Models\Behaviors\\" . implode(";\nuse A17\Twill\Models\Behaviors\\", $activeModelTraits) . ";";
387
388 1
        $activeModelImplements = $this->sortable ? 'implements Sortable' : '';
389
390 1
        if ($this->sortable) {
391
            $activeModelTraitsImports .= "\nuse A17\Twill\Models\Behaviors\Sortable;";
392 1
        }
393
394 1
        $stub = str_replace([
395 1
            '{{modelClassName}}',
396 1
            '{{modelTraits}}',
397 1
            '{{modelImports}}',
398
            '{{modelImplements}}',
399
            '{{namespace}}',
400 1
        ], [
401
            $modelName,
402 1
            $activeModelTraitsString,
403 1
            $activeModelTraitsImports,
404
            $activeModelImplements,
405
            $this->namespace('models', 'Models'),
406
        ], $this->files->get(__DIR__ . '/stubs/model.stub'));
407
408
        $stub = $this->renderStubForOption($stub, 'hasTranslation', $this->translatable);
409
        $stub = $this->renderStubForOption($stub, 'hasSlug', $this->sluggable);
410
        $stub = $this->renderStubForOption($stub, 'hasMedias', $this->mediable);
411
        $stub = $this->renderStubForOption($stub, 'hasPosition', $this->sortable);
412 1
413
        twill_put_stub(twill_path("{$modelsDir}/" . $modelName . '.php'), $stub);
414 1
415
        $this->info("Models created successfully! Fill your fillables!");
416 1
    }
417
418 1
    private function renderStubForOption($stub, $option, $enabled)
419
    {
420 1
        if ($enabled) {
421
            $stub = str_replace([
422 1
                '{{' . $option . '}}',
423 1
                '{{/' . $option . '}}',
424
            ], '', $stub);
425
        } else {
426
            $stub = preg_replace('/{{' . $option . '}}[\s\S]+?{{\/' . $option . '}}/', '', $stub);
427
        }
428
429
        return $stub;
430
    }
431
432 1
    /**
433
     * Creates new repository class file for the given model name.
434 1
     *
435
     * @param string $modelName
436 1
     * @param array $activeTraits
437
     * @return void
438 1
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
439
     */
440 1
    private function createRepository($modelName = 'Item', $activeTraits = [])
441
    {
442 1
        $modelsDir = $this->isCapsule ? $this->capsule['repositories_dir'] : 'Repositories';
443 1
444
        $modelClass = $this->isCapsule ? $this->capsule['model'] : "App\Models\\{$this->capsule['singular']}";
445 1
446
        $this->makeTwillDirectory($modelsDir);
447 1
448 1
        $repositoryClassName = $modelName . 'Repository';
449
450
        $activeRepositoryTraits = [];
451
452
        foreach ($activeTraits as $index => $traitIsActive) {
453
            if ($traitIsActive) {
454
                !isset($this->repositoryTraits[$index]) ?: $activeRepositoryTraits[] = $this->repositoryTraits[$index];
455
            }
456
        }
457
458
        $activeRepositoryTraitsString = empty($activeRepositoryTraits) ? '' : 'use ' . (empty($activeRepositoryTraits) ? "" : rtrim(implode(', ', $activeRepositoryTraits), ', ') . ';');
459
460
        $activeRepositoryTraitsImports = empty($activeRepositoryTraits) ? '' : "use A17\Twill\Repositories\Behaviors\\" . implode(";\nuse A17\Twill\Repositories\Behaviors\\", $activeRepositoryTraits) . ";";
461
462
        $stub = str_replace(
463
            ['{{repositoryClassName}}', '{{modelName}}', '{{repositoryTraits}}', '{{repositoryImports}}', '{{namespace}}', '{{modelClass}}'],
464
            [$repositoryClassName, $modelName, $activeRepositoryTraitsString, $activeRepositoryTraitsImports, $this->namespace('repositories', 'Repositories'), $modelClass],
465
            $this->files->get(__DIR__ . '/stubs/repository.stub')
466
        );
467
468
        twill_put_stub(twill_path("{$modelsDir}/" . $repositoryClassName . '.php'), $stub);
469
470
        $this->info("Repository created successfully! Control all the things!");
471
    }
472
473
    /**
474
     * Create a new controller class file for the given module name and model name.
475
     *
476
     * @param string $moduleName
477
     * @param string $modelName
478
     * @return void
479
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
480
     */
481
    private function createController($moduleName = 'items', $modelName = 'Item')
482
    {
483
        $controllerClassName = $modelName . 'Controller';
484
485
        $dir = $this->isCapsule ? $this->capsule['controllers_dir'] : 'Http/Controllers/Admin';
486
487
        $this->makeTwillDirectory($dir);
488
489
        $stub = str_replace(
490
            ['{{moduleName}}', '{{controllerClassName}}', '{{namespace}}'],
491
            [$moduleName, $controllerClassName, $this->namespace('controllers', 'Http\Controllers\Admin')],
492
            $this->files->get(__DIR__ . '/stubs/controller.stub')
493
        );
494
495
        twill_put_stub(twill_path("{$dir}/" . $controllerClassName . '.php'), $stub);
496
497
        $this->info("Controller created successfully! Define your index/browser/form endpoints options!");
498
    }
499
500
    /**
501
     * Creates a new request class file for the given model name.
502
     *
503
     * @param string $modelName
504
     * @return void
505
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
506
     */
507
    private function createRequest($modelName = 'Item')
508
    {
509
        $dir = $this->isCapsule ? $this->capsule['requests_dir'] : 'Http/Requests/Admin';
510
511
        $this->makeTwillDirectory($dir);
512
513
        $requestClassName = $modelName . 'Request';
514
515
        $stub = str_replace(
516
            ['{{requestClassName}}', '{{namespace}}'],
517
            [$requestClassName, $this->namespace('requests', 'Http\Requests\Admin')],
518
            $this->files->get(__DIR__ . '/stubs/request.stub')
519
        );
520
521
        twill_put_stub(twill_path("{$dir}/" . $requestClassName . '.php'), $stub);
522
523
        $this->info("Form request created successfully! Add some validation rules!");
524
    }
525
526
    /**
527
     * Creates appropriate module Blade view files.
528
     *
529
     * @param string $moduleName
530
     * @return void
531
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
532
     */
533
    private function createViews($moduleName = 'items')
534
    {
535
        $viewsPath = $this->viewPath($moduleName);
536
537
        $this->makeTwillDirectory($viewsPath);
538
539
        $formView = $this->translatable ? 'form_translatable' : 'form';
540
541
        twill_put_stub($viewsPath . '/form.blade.php', $this->files->get(__DIR__ . '/stubs/' . $formView . '.blade.stub'));
542
543
        $this->info("Form view created successfully! Include your form fields using @formField directives!");
544
    }
545
546
    /**
547
     * Creates a basic routes file for the Capsule.
548
     *
549
     * @param string $moduleName
550
     * @return void
551
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
552
     */
553
    public function createRoutes()
554
    {
555
        $this->makeDir($this->capsule['routes_file']);
556
557
        $contents = str_replace(
558
            '{{moduleName}}',
559
            $this->capsule['module'],
560
            $this->files->get(__DIR__ . '/stubs/routes_admin.stub')
561
        );
562
563
        twill_put_stub($this->capsule['routes_file'], $contents);
564
565
        $this->info("Routes file created successfully!");
566
    }
567
568
    /**
569
     * Creates a new module database seed file.
570
     *
571
     * @param string $moduleName
572
     * @return void
573
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
574
     */
575
    private function createSeed($moduleName = 'items')
576
    {
577
        $this->makeTwillDirectory($this->capsule['seeds_psr4_path']);
578
579
        $stub = $this->files->get(__DIR__ . '/stubs/database_seeder.stub');
580
581
        $stub = str_replace('{moduleName}', $this->capsule['plural'], $stub);
582
583
        $this->files->put("{$this->capsule['seeds_psr4_path']}/DatabaseSeeder.php", $stub);
584
585
        $this->info("Seed created successfully!");
586
    }
587
588
    private function checkOption($option)
589
    {
590
        if ($this->option($option) || $this->option('all')) {
591
            return true;
592
        }
593
594
        $questions = [
595
            'hasBlocks' => 'Do you need to use the block editor on this module?',
596
            'hasTranslation' => 'Do you need to translate content on this module?',
597
            'hasSlug' => 'Do you need to generate slugs on this module?',
598
            'hasMedias' => 'Do you need to attach images on this module?',
599
            'hasFiles' => 'Do you need to attach files on this module?',
600
            'hasPosition' => 'Do you need to manage the position of records on this module?',
601
            'hasRevisions' => 'Do you need to enable revisions on this module?',
602
        ];
603
604
        return 'yes' === $this->choice($questions[$option], ['no', 'yes'], $this->defaultsAnswserToNo ? 0 : 1);
605
    }
606
607
    public function createCapsulePath($moduleName, $modelName)
608
    {
609
        if (!$this->isCapsule) {
610
            $this->moduleBasePath = base_path();
611
612
            return;
613
        }
614
615
        $this->checkCapsuleDirectory(
616
            $this->moduleBasePath = config('twill.capsules.path') . "/{$moduleName}"
617
        );
618
619
        $this->makeDir($this->moduleBasePath);
620
    }
621
622
    public function createCapsuleNamespace($module, $model)
623
    {
624
        $base = config('twill.capsules.namespace');
625
626
        $this->capsuleNamespace = "{$base}\\{$module}";
0 ignored issues
show
Bug Best Practice introduced by
The property capsuleNamespace does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
627
    }
628
629
    public function databasePath($path = '')
630
    {
631
        if (!$this->isCapsule) {
632
            return database_path($path);
633
        }
634
635
        return "{$this->moduleBasePath}/database" . (filled($path) ? "/{$path}" : '');
636
    }
637
638
    public function makeDir($dir)
639
    {
640
        $info = pathinfo($dir);
641
642
        $dir = isset($info['extension']) ? $info['dirname'] : $dir;
643
644
        if (!is_dir($dir)) {
645
            mkdir($dir, 0755, true);
646
        }
647
648
        if (!is_dir($dir)) {
649
            $this->info("It wasn't possible to create capsule directory {$dir}");
650
651
            die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
652
        }
653
    }
654
655
    public function makeTwillDirectory($path)
656
    {
657
        make_twill_directory($path);
658
    }
659
660
    public function namespace ($type, $suffix, $class = null) {
661
        $class = (filled($class) ? "\\$class" : '');
662
663
        if (!$this->isCapsule) {
664
            return "App\\{$suffix}{$class}";
665
        }
666
667
        return $this->capsule[$type] . $class;
668
    }
669
670
    public function viewPath($moduleName)
671
    {
672
        if (!$this->isCapsule) {
673
            return $viewsPath = $this->config->get('view.paths')[0] . '/admin/' . $moduleName;
0 ignored issues
show
Unused Code introduced by
The assignment to $viewsPath is dead and can be removed.
Loading history...
674
        }
675
676
        $this->makeDir($dir = "{$this->moduleBasePath}/resources/views/admin");
677
678
        return $dir;
679
    }
680
}
681