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

ModuleGenerator::getStubContents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 1
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
            $folder = GenerateConfigReader::read($key);
301
302 94
            if ($folder->generate() === false) {
303 3
                continue;
304
            }
305
306 94
            $path = $this->module->getModulePath($this->getName()) . '/' . $folder->getPath();
307
308 94
            $this->filesystem->makeDirectory($path, 0755, true);
309 94
            if (config('modules.stubs.gitkeep')) {
310 94
                $this->generateGitKeep($path);
311
            }
312
        }
313 94
    }
314
315
    /**
316
     * Generate git keep to the specified path.
317
     *
318
     * @param string $path
319
     */
320 94
    public function generateGitKeep($path)
321
    {
322 94
        $this->filesystem->put($path . '/.gitkeep', '');
323 94
    }
324
325
    /**
326
     * Generate the files.
327
     */
328 86
    public function generateFiles()
329
    {
330 86
        foreach ($this->getFiles() as $stub => $file) {
331 86
            if ($this->api === true) {
332
                if (in_array($stub, ['routes/web', 'views/index', 'views/master', 'assets/js/app', 'assets/sass/app', 'webpack'])) {
333
                    continue;
334
                }
335
            }
336
337 86
            $path = $this->module->getModulePath($this->getName()) . $file;
338
339 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...
340 86
                $this->filesystem->makeDirectory($dir, 0775, true);
341
            }
342
343 86
            $this->filesystem->put($path, $this->getStubContents($stub));
344
345 86
            $this->console->info("Created : {$path}");
346
        }
347 86
    }
348
349
    /**
350
     * Generate some resources.
351
     */
352 86
    public function generateResources()
353
    {
354 86
        $this->console->call('module:make-seed', $this->getMakeSeedArguments());
355
356 86
        $this->console->call('module:make-provider', $this->getMakeProviderArguments());
357
358 86
        $this->console->call('module:route-provider', $this->getMakeRouteProviderArguments());
359
360 86
        $this->console->call('module:make-controller', $this->getMakeControllerArguments());
361 86
    }
362
363
    /**
364
     * get Make Route Provider Arguments
365
     *
366
     * @since 2018/11/16
367
     * @return array
368
     */
369 86
    protected function getMakeRouteProviderArguments()
370
    {
371
        $arguments = [
372 86
            'module' => $this->getName(),
373
        ];
374 86
        if ($this->api === true) {
375
            $arguments['--api'] = true;
376
        }
377
378 86
        return $arguments;
379
    }
380
381
    /**
382
     * get Make Provider Arguments
383
     *
384
     * @since 2018/11/16
385
     * @return array
386
     */
387 86
    protected function getMakeProviderArguments()
388
    {
389
        $arguments = [
390 86
            'name' => $this->getName() . 'ServiceProvider',
391 86
            'module' => $this->getName(),
392
            '--master' => true,
393
        ];
394 86
        if ($this->api === true) {
395
            $arguments['--api'] = true;
396
        }
397
398 86
        return $arguments;
399
    }
400
401
    /**
402
     * get Make Controller Arguments
403
     *
404
     * @since 2018/11/16
405
     * @return array
406
     */
407 86
    protected function getMakeControllerArguments()
408
    {
409
        $arguments = [
410 86
            'controller' => $this->getName() . 'Controller',
411 86
            'module' => $this->getName(),
412
        ];
413 86
        if ($this->api === true) {
414
            $arguments['--plain'] = true;
415
        }
416
417 86
        return $arguments;
418
    }
419
420
    /**
421
     * get Make Seed Arguments
422
     *
423
     * @since 2018/11/16
424
     * @return array
425
     */
426 86
    protected function getMakeSeedArguments()
427
    {
428
        return  [
429 86
           'name' => $this->getName(),
430 86
           'module' => $this->getName(),
431
           '--master' => true,
432
       ];
433
    }
434
435
    /**
436
     * Get the contents of the specified stub file by given stub name.
437
     *
438
     * @param $stub
439
     *
440
     * @return string
441
     */
442 94
    protected function getStubContents($stub)
443
    {
444 94
        return (new Stub(
445 94
            '/' . $stub . '.stub',
446 94
            $this->getReplacement($stub)
447
        )
448 94
        )->render();
449
    }
450
451
    /**
452
     * get the list for the replacements.
453
     */
454
    public function getReplacements()
455
    {
456
        return $this->module->config('stubs.replacements');
457
    }
458
459
    /**
460
     * Get array replacement for the specified stub.
461
     *
462
     * @param $stub
463
     *
464
     * @return array
465
     */
466 94
    protected function getReplacement($stub)
467
    {
468 94
        $replacements = $this->module->config('stubs.replacements');
469
470 94
        if (!isset($replacements[$stub])) {
471 86
            return [];
472
        }
473
474 94
        $keys = $replacements[$stub];
475
476 94
        $replaces = [];
477
478 94
        foreach ($keys as $key) {
479 94
            if (method_exists($this, $method = 'get' . ucfirst(studly_case(strtolower($key))) . 'Replacement')) {
480 94
                $replaces[$key] = $this->$method();
481
            } else {
482 94
                $replaces[$key] = null;
483
            }
484
        }
485
486 94
        return $replaces;
487
    }
488
489
    /**
490
     * Generate the module.json file
491
     */
492 94
    private function generateModuleJsonFile()
493
    {
494 94
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
495
496 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...
497
            $this->filesystem->makeDirectory($dir, 0775, true);
498
        }
499
500 94
        $this->filesystem->put($path, $this->getStubContents('json'));
501
502 94
        $this->console->info("Created : {$path}");
503 94
    }
504
505
    /**
506
     * Remove the default service provider that was added in the module.json file
507
     * This is needed when a --plain module was created
508
     */
509 8
    private function cleanModuleJsonFile()
510
    {
511 8
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
512
513 8
        $content = $this->filesystem->get($path);
514 8
        $namespace = $this->getModuleNamespaceReplacement();
515 8
        $studlyName = $this->getStudlyNameReplacement();
516
517 8
        $provider = '"' . $namespace . '\\\\' . $studlyName . '\\\\Providers\\\\' . $studlyName . 'ServiceProvider"';
518
519 8
        $content = str_replace($provider, '', $content);
520
521 8
        $this->filesystem->put($path, $content);
522 8
    }
523
524
    /**
525
     * Get the module name in lower case.
526
     *
527
     * @return string
528
     */
529 94
    protected function getLowerNameReplacement()
530
    {
531 94
        return strtolower($this->getName());
532
    }
533
534
    /**
535
     * Get the module name in studly case.
536
     *
537
     * @return string
538
     */
539 94
    protected function getStudlyNameReplacement()
540
    {
541 94
        return $this->getName();
542
    }
543
544
    /**
545
     * Get replacement for $VENDOR$.
546
     *
547
     * @return string
548
     */
549 86
    protected function getVendorReplacement()
550
    {
551 86
        return $this->module->config('composer.vendor');
552
    }
553
554
    /**
555
     * Get replacement for $MODULE_NAMESPACE$.
556
     *
557
     * @return string
558
     */
559 94
    protected function getModuleNamespaceReplacement()
560
    {
561 94
        return str_replace('\\', '\\\\', $this->module->config('namespace'));
562
    }
563
564
    /**
565
     * Get replacement for $AUTHOR_NAME$.
566
     *
567
     * @return string
568
     */
569 86
    protected function getAuthorNameReplacement()
570
    {
571 86
        return $this->module->config('composer.author.name');
572
    }
573
574
    /**
575
     * Get replacement for $AUTHOR_EMAIL$.
576
     *
577
     * @return string
578
     */
579 86
    protected function getAuthorEmailReplacement()
580
    {
581 86
        return $this->module->config('composer.author.email');
582
    }
583
}
584