Completed
Pull Request — master (#666)
by reallyli
03:08
created

ModuleGenerator::getFilesystem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\Generators;
4
5
use Illuminate\Config\Repository as Config;
6
use Illuminate\Console\Command as Console;
7
use Illuminate\Filesystem\Filesystem;
8
use Illuminate\Support\Str;
9
use Nwidart\Modules\FileRepository;
10
use Nwidart\Modules\Support\Config\GenerateConfigReader;
11
use Nwidart\Modules\Support\Stub;
12
13
class ModuleGenerator extends Generator
14
{
15
    /**
16
     * The module name will created.
17
     *
18
     * @var string
19
     */
20
    protected $name;
21
22
    /**
23
     * The laravel config instance.
24
     *
25
     * @var Config
26
     */
27
    protected $config;
28
29
    /**
30
     * The laravel filesystem instance.
31
     *
32
     * @var Filesystem
33
     */
34
    protected $filesystem;
35
36
    /**
37
     * The laravel console instance.
38
     *
39
     * @var Console
40
     */
41
    protected $console;
42
43
    /**
44
     * The pingpong module instance.
45
     *
46
     * @var \Nwidart\Modules\Module
47
     */
48
    protected $module;
49
50
    /**
51
     * Force status.
52
     *
53
     * @var bool
54
     */
55
    protected $force = false;
56
57
    /**
58
     * Generate a plain module.
59
     *
60
     * @var bool
61
     */
62
    protected $plain = false;
63
64
    /**
65
     * Generate a api module.
66
     *
67
     * @var bool
68
     */
69
    protected $api = false;
70
71
    /**
72
     * The constructor.
73
     * @param $name
74
     * @param FileRepository $module
75
     * @param Config     $config
76
     * @param Filesystem $filesystem
77
     * @param Console    $console
78
     */
79 94
    public function __construct(
80
        $name,
81
        FileRepository $module = null,
82
        Config $config = null,
83
        Filesystem $filesystem = null,
84
        Console $console = null
85
    ) {
86 94
        $this->name = $name;
87 94
        $this->config = $config;
88 94
        $this->filesystem = $filesystem;
89 94
        $this->console = $console;
90 94
        $this->module = $module;
91 94
    }
92
93
    /**
94
     * Set plain flag.
95
     *
96
     * @param bool $plain
97
     *
98
     * @return $this
99
     */
100 94
    public function setPlain($plain)
101
    {
102 94
        $this->plain = $plain;
103
104 94
        return $this;
105
    }
106
107
    /**
108
     * Get the name of module will created. By default in studly case.
109
     *
110
     * @return string
111
     */
112 94
    public function getName()
113
    {
114 94
        return Str::studly($this->name);
115
    }
116
117
    /**
118
     * Get the laravel config instance.
119
     *
120
     * @return Config
121
     */
122
    public function getConfig()
123
    {
124
        return $this->config;
125
    }
126
127
    /**
128
     * Set the laravel config instance.
129
     *
130
     * @param Config $config
131
     *
132
     * @return $this
133
     */
134 94
    public function setConfig($config)
135
    {
136 94
        $this->config = $config;
137
138 94
        return $this;
139
    }
140
141
    /**
142
     * Get the laravel filesystem instance.
143
     *
144
     * @return Filesystem
145
     */
146
    public function getFilesystem()
147
    {
148
        return $this->filesystem;
149
    }
150
151
    /**
152
     * Set the laravel filesystem instance.
153
     *
154
     * @param Filesystem $filesystem
155
     *
156
     * @return $this
157
     */
158 94
    public function setFilesystem($filesystem)
159
    {
160 94
        $this->filesystem = $filesystem;
161
162 94
        return $this;
163
    }
164
165
    /**
166
     * Get the laravel console instance.
167
     *
168
     * @return Console
169
     */
170
    public function getConsole()
171
    {
172
        return $this->console;
173
    }
174
175
    /**
176
     * Set the laravel console instance.
177
     *
178
     * @param Console $console
179
     *
180
     * @return $this
181
     */
182 94
    public function setConsole($console)
183
    {
184 94
        $this->console = $console;
185
186 94
        return $this;
187
    }
188
189
    /**
190
     * Get the module instance.
191
     *
192
     * @return \Nwidart\Modules\Module
193
     */
194
    public function getModule()
195
    {
196
        return $this->module;
197
    }
198
199
    /**
200
     * Set the pingpong module instance.
201
     *
202
     * @param mixed $module
203
     *
204
     * @return $this
205
     */
206 94
    public function setModule($module)
207
    {
208 94
        $this->module = $module;
209
210 94
        return $this;
211
    }
212
213
    /**
214
     * Get the list of folders will created.
215
     *
216
     * @return array
217
     */
218 94
    public function getFolders()
219
    {
220 94
        return $this->module->config('paths.generator');
221
    }
222
223
    /**
224
     * Get the list of files will created.
225
     *
226
     * @return array
227
     */
228 86
    public function getFiles()
229
    {
230 86
        return $this->module->config('stubs.files');
231
    }
232
233
    /**
234
     * Set force status.
235
     *
236
     * @param bool|int $force
237
     *
238
     * @return $this
239
     */
240 94
    public function setForce($force)
241
    {
242 94
        $this->force = $force;
0 ignored issues
show
Documentation Bug introduced by
It seems like $force can also be of type integer. However, the property $force is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
243
244 94
        return $this;
245
    }
246
247
    /**
248
     * Set Api Flog.
249
     *
250
     * @param bool $api
251
     *
252
     * @return $this
253
     */
254 94
    public function setApi($api)
255
    {
256 94
        $this->api = $api;
257
258 94
        return $this;
259
    }
260
261
    /**
262
     * Generate the module.
263
     */
264 94
    public function generate()
265
    {
266 94
        $name = $this->getName();
267
268 94
        if ($this->module->has($name)) {
269 2
            if ($this->force) {
270 1
                $this->module->delete($name);
271
            } else {
272 1
                $this->console->error("Module [{$name}] already exist!");
273
274 1
                return;
275
            }
276
        }
277
278 94
        $this->generateFolders();
279
280 94
        $this->generateModuleJsonFile();
281
282 94
        if ($this->plain !== true) {
283 86
            $this->generateFiles();
284 86
            $this->generateResources();
285
        }
286
287 94
        if ($this->plain === true) {
288 8
            $this->cleanModuleJsonFile();
289
        }
290
291 94
        $this->console->info("Module [{$name}] created successfully.");
292 94
    }
293
294
    /**
295
     * Generate the folders.
296
     */
297 94
    public function generateFolders()
298
    {
299 94
        foreach ($this->getFolders() as $key => $folder) {
300 94
            if ($this->api === true) {
301
                if (in_array($key, ['assets', 'views'])) {
302
                    continue;
303
                }
304
            }
305 94
            $folder = GenerateConfigReader::read($key);
306
307 94
            if ($folder->generate() === false) {
308 3
                continue;
309
            }
310
311 94
            $path = $this->module->getModulePath($this->getName()) . '/' . $folder->getPath();
312
313 94
            $this->filesystem->makeDirectory($path, 0755, true);
314 94
            if (config('modules.stubs.gitkeep')) {
315 94
                $this->generateGitKeep($path);
316
            }
317
        }
318 94
    }
319
320
    /**
321
     * Generate git keep to the specified path.
322
     *
323
     * @param string $path
324
     */
325 94
    public function generateGitKeep($path)
326
    {
327 94
        $this->filesystem->put($path . '/.gitkeep', '');
328 94
    }
329
330
    /**
331
     * Generate the files.
332
     */
333 86
    public function generateFiles()
334
    {
335 86
        foreach ($this->getFiles() as $stub => $file) {
336 86
            if ($this->api === true) {
337
                if (in_array($stub, ['routes/web', 'views/index', 'views/master', 'assets/js/app', 'assets/sass/app', 'webpack'])) {
338
                    continue;
339
                }
340
            }
341
342 86
            $path = $this->module->getModulePath($this->getName()) . $file;
343
344 86 View Code Duplication
            if (!$this->filesystem->isDirectory($dir = dirname($path))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345 86
                $this->filesystem->makeDirectory($dir, 0775, true);
346
            }
347
348 86
            $this->filesystem->put($path, $this->getStubContents($stub));
349
350 86
            $this->console->info("Created : {$path}");
351
        }
352 86
    }
353
354
    /**
355
     * Generate some resources.
356
     */
357 86
    public function generateResources()
358
    {
359 86
        $this->console->call('module:make-seed', $this->getMakeSeedArguments());
360
361 86
        $this->console->call('module:make-provider', $this->getMakeProviderArguments());
362
363 86
        $this->console->call('module:route-provider', $this->getMakeRouteProviderArguments());
364
365 86
        $this->console->call('module:make-controller', $this->getMakeControllerArguments());
366 86
    }
367
368
    /**
369
     * get Make Route Provider Arguments
370
     *
371
     * @since 2018/11/16
372
     * @return array
373
     */
374 86
    protected function getMakeRouteProviderArguments()
375
    {
376
        $arguments = [
377 86
            'module' => $this->getName(),
378
        ];
379 86
        if ($this->api === true) {
380
            $arguments['--api'] = true;
381
        }
382
383 86
        return $arguments;
384
    }
385
386
    /**
387
     * get Make Provider Arguments
388
     *
389
     * @since 2018/11/16
390
     * @return array
391
     */
392 86
    protected function getMakeProviderArguments()
393
    {
394
        $arguments = [
395 86
            'name' => $this->getName() . 'ServiceProvider',
396 86
            'module' => $this->getName(),
397
            '--master' => true,
398
        ];
399 86
        if ($this->api === true) {
400
            $arguments['--api'] = true;
401
        }
402
403 86
        return $arguments;
404
    }
405
406
    /**
407
     * get Make Controller Arguments
408
     *
409
     * @since 2018/11/16
410
     * @return array
411
     */
412 86
    protected function getMakeControllerArguments()
413
    {
414
        $arguments = [
415 86
            'controller' => $this->getName() . 'Controller',
416 86
            'module' => $this->getName(),
417
        ];
418 86
        if ($this->api === true) {
419
            $arguments['--plain'] = true;
420
        }
421
422 86
        return $arguments;
423
    }
424
425
    /**
426
     * get Make Seed Arguments
427
     *
428
     * @since 2018/11/16
429
     * @return array
430
     */
431 86
    protected function getMakeSeedArguments()
432
    {
433
        return  [
434 86
           'name' => $this->getName(),
435 86
           'module' => $this->getName(),
436
           '--master' => true,
437
       ];
438
    }
439
440
    /**
441
     * Get the contents of the specified stub file by given stub name.
442
     *
443
     * @param $stub
444
     *
445
     * @return string
446
     */
447 94
    protected function getStubContents($stub)
448
    {
449 94
        return (new Stub(
450 94
            '/' . $stub . '.stub',
451 94
            $this->getReplacement($stub)
452
        )
453 94
        )->render();
454
    }
455
456
    /**
457
     * get the list for the replacements.
458
     */
459
    public function getReplacements()
460
    {
461
        return $this->module->config('stubs.replacements');
462
    }
463
464
    /**
465
     * Get array replacement for the specified stub.
466
     *
467
     * @param $stub
468
     *
469
     * @return array
470
     */
471 94
    protected function getReplacement($stub)
472
    {
473 94
        $replacements = $this->module->config('stubs.replacements');
474
475 94
        if (!isset($replacements[$stub])) {
476 86
            return [];
477
        }
478
479 94
        $keys = $replacements[$stub];
480
481 94
        $replaces = [];
482
483 94
        foreach ($keys as $key) {
484 94
            if (method_exists($this, $method = 'get' . ucfirst(studly_case(strtolower($key))) . 'Replacement')) {
485 94
                $replaces[$key] = $this->$method();
486
            } else {
487 94
                $replaces[$key] = null;
488
            }
489
        }
490
491 94
        return $replaces;
492
    }
493
494
    /**
495
     * Generate the module.json file
496
     */
497 94
    private function generateModuleJsonFile()
498
    {
499 94
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
500
501 94 View Code Duplication
        if (!$this->filesystem->isDirectory($dir = dirname($path))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
502
            $this->filesystem->makeDirectory($dir, 0775, true);
503
        }
504
505 94
        $this->filesystem->put($path, $this->getStubContents('json'));
506
507 94
        $this->console->info("Created : {$path}");
508 94
    }
509
510
    /**
511
     * Remove the default service provider that was added in the module.json file
512
     * This is needed when a --plain module was created
513
     */
514 8
    private function cleanModuleJsonFile()
515
    {
516 8
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
517
518 8
        $content = $this->filesystem->get($path);
519 8
        $namespace = $this->getModuleNamespaceReplacement();
520 8
        $studlyName = $this->getStudlyNameReplacement();
521
522 8
        $provider = '"' . $namespace . '\\\\' . $studlyName . '\\\\Providers\\\\' . $studlyName . 'ServiceProvider"';
523
524 8
        $content = str_replace($provider, '', $content);
525
526 8
        $this->filesystem->put($path, $content);
527 8
    }
528
529
    /**
530
     * Get the module name in lower case.
531
     *
532
     * @return string
533
     */
534 94
    protected function getLowerNameReplacement()
535
    {
536 94
        return strtolower($this->getName());
537
    }
538
539
    /**
540
     * Get the module name in studly case.
541
     *
542
     * @return string
543
     */
544 94
    protected function getStudlyNameReplacement()
545
    {
546 94
        return $this->getName();
547
    }
548
549
    /**
550
     * Get replacement for $VENDOR$.
551
     *
552
     * @return string
553
     */
554 86
    protected function getVendorReplacement()
555
    {
556 86
        return $this->module->config('composer.vendor');
557
    }
558
559
    /**
560
     * Get replacement for $MODULE_NAMESPACE$.
561
     *
562
     * @return string
563
     */
564 94
    protected function getModuleNamespaceReplacement()
565
    {
566 94
        return str_replace('\\', '\\\\', $this->module->config('namespace'));
567
    }
568
569
    /**
570
     * Get replacement for $AUTHOR_NAME$.
571
     *
572
     * @return string
573
     */
574 86
    protected function getAuthorNameReplacement()
575
    {
576 86
        return $this->module->config('composer.author.name');
577
    }
578
579
    /**
580
     * Get replacement for $AUTHOR_EMAIL$.
581
     *
582
     * @return string
583
     */
584 86
    protected function getAuthorEmailReplacement()
585
    {
586 86
        return $this->module->config('composer.author.email');
587
    }
588
}
589