Completed
Push — master ( 9620dc...f09c52 )
by Nicolas
04:04 queued 12s
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\Contracts\ActivatorInterface;
10
use Nwidart\Modules\FileRepository;
11
use Nwidart\Modules\Support\Config\GenerateConfigReader;
12
use Nwidart\Modules\Support\Stub;
13
14
class ModuleGenerator extends Generator
15
{
16
    /**
17
     * The module name will created.
18
     *
19
     * @var string
20
     */
21
    protected $name;
22
23
    /**
24
     * The laravel config instance.
25
     *
26
     * @var Config
27
     */
28
    protected $config;
29
30
    /**
31
     * The laravel filesystem instance.
32
     *
33
     * @var Filesystem
34
     */
35
    protected $filesystem;
36
37
    /**
38
     * The laravel console instance.
39
     *
40
     * @var Console
41
     */
42
    protected $console;
43
44
    /**
45
     * The activator instance
46
     * 
47
     * @var ActivatorInterface
48
     */
49
    protected $activator;
50
51
    /**
52
     * The pingpong module instance.
53
     *
54
     * @var \Nwidart\Modules\Module
55
     */
56
    protected $module;
57
58
    /**
59
     * Force status.
60
     *
61
     * @var bool
62
     */
63
    protected $force = false;
64
65
    /**
66
     * Generate a plain module.
67
     *
68
     * @var bool
69
     */
70
    protected $plain = false;
71
72
    /**
73
     * Enables the module.
74
     *
75
     * @var bool
76
     */
77
    protected $isActive = false;
78
79
    /**
80
     * The constructor.
81
     * @param $name
82
     * @param FileRepository $module
83
     * @param Config     $config
84
     * @param Filesystem $filesystem
85
     * @param Console    $console
86
     */
87 118
    public function __construct(
88
        $name,
89
        FileRepository $module = null,
90
        Config $config = null,
91
        Filesystem $filesystem = null,
92
        Console $console = null,
93
        ActivatorInterface $activator = null
94
    ) {
95 118
        $this->name = $name;
96 118
        $this->config = $config;
97 118
        $this->filesystem = $filesystem;
98 118
        $this->console = $console;
99 118
        $this->module = $module;
100 118
        $this->activator = $activator;
101 118
    }
102
103
    /**
104
     * Set plain flag.
105
     *
106
     * @param bool $plain
107
     *
108
     * @return $this
109
     */
110 118
    public function setPlain($plain)
111
    {
112 118
        $this->plain = $plain;
113
114 118
        return $this;
115
    }
116
117
    /**
118
     * Set active flag.
119
     *
120
     * @param bool $active
121
     *
122
     * @return $this
123
     */
124 118
    public function setActive(bool $active)
125
    {
126 118
        $this->isActive = $active;
127
128 118
        return $this;
129
    }
130
131
    /**
132
     * Get the name of module will created. By default in studly case.
133
     *
134
     * @return string
135
     */
136 118
    public function getName()
137
    {
138 118
        return Str::studly($this->name);
139
    }
140
141
    /**
142
     * Get the laravel config instance.
143
     *
144
     * @return Config
145
     */
146
    public function getConfig()
147
    {
148
        return $this->config;
149
    }
150
151
    /**
152
     * Set the laravel config instance.
153
     *
154
     * @param Config $config
155
     *
156
     * @return $this
157
     */
158 118
    public function setConfig($config)
159
    {
160 118
        $this->config = $config;
161
162 118
        return $this;
163
    }
164
165
    /**
166
     * Set the modules activator
167
     *
168
     * @param ActivatorInterface $activator
169
     *
170
     * @return $this
171
     */
172 118
    public function setActivator(ActivatorInterface $activator)
173
    {
174 118
        $this->activator = $activator;
175
176 118
        return $this;
177
    }
178
179
    /**
180
     * Get the laravel filesystem instance.
181
     *
182
     * @return Filesystem
183
     */
184
    public function getFilesystem()
185
    {
186
        return $this->filesystem;
187
    }
188
189
    /**
190
     * Set the laravel filesystem instance.
191
     *
192
     * @param Filesystem $filesystem
193
     *
194
     * @return $this
195
     */
196 118
    public function setFilesystem($filesystem)
197
    {
198 118
        $this->filesystem = $filesystem;
199
200 118
        return $this;
201
    }
202
203
    /**
204
     * Get the laravel console instance.
205
     *
206
     * @return Console
207
     */
208
    public function getConsole()
209
    {
210
        return $this->console;
211
    }
212
213
    /**
214
     * Set the laravel console instance.
215
     *
216
     * @param Console $console
217
     *
218
     * @return $this
219
     */
220 118
    public function setConsole($console)
221
    {
222 118
        $this->console = $console;
223
224 118
        return $this;
225
    }
226
227
    /**
228
     * Get the module instance.
229
     *
230
     * @return \Nwidart\Modules\Module
231
     */
232
    public function getModule()
233
    {
234
        return $this->module;
235
    }
236
237
    /**
238
     * Set the pingpong module instance.
239
     *
240
     * @param mixed $module
241
     *
242
     * @return $this
243
     */
244 118
    public function setModule($module)
245
    {
246 118
        $this->module = $module;
247
248 118
        return $this;
249
    }
250
251
    /**
252
     * Get the list of folders will created.
253
     *
254
     * @return array
255
     */
256 118
    public function getFolders()
257
    {
258 118
        return $this->module->config('paths.generator');
259
    }
260
261
    /**
262
     * Get the list of files will created.
263
     *
264
     * @return array
265
     */
266 109
    public function getFiles()
267
    {
268 109
        return $this->module->config('stubs.files');
269
    }
270
271
    /**
272
     * Set force status.
273
     *
274
     * @param bool|int $force
275
     *
276
     * @return $this
277
     */
278 118
    public function setForce($force)
279
    {
280 118
        $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...
281
282 118
        return $this;
283
    }
284
285
    /**
286
     * Generate the module.
287
     */
288 118
    public function generate()
289
    {
290 118
        $name = $this->getName();
291
292 118
        if ($this->module->has($name)) {
293 2
            if ($this->force) {
294 1
                $this->module->delete($name);
295
            } else {
296 1
                $this->console->error("Module [{$name}] already exist!");
297
298 1
                return;
299
            }
300
        }
301
302 118
        $this->generateFolders();
303
304 118
        $this->generateModuleJsonFile();
305
306 118
        if ($this->plain !== true) {
307 109
            $this->generateFiles();
308 109
            $this->generateResources();
309
        }
310
311 118
        if ($this->plain === true) {
312 9
            $this->cleanModuleJsonFile();
313
        }
314
315 118
        $this->activator->setActiveByName($name, $this->isActive);
316
317 118
        $this->console->info("Module [{$name}] created successfully.");
318 118
    }
319
320
    /**
321
     * Generate the folders.
322
     */
323 118
    public function generateFolders()
324
    {
325 118
        foreach ($this->getFolders() as $key => $folder) {
326 118
            $folder = GenerateConfigReader::read($key);
327
328 118
            if ($folder->generate() === false) {
329 3
                continue;
330
            }
331
332 118
            $path = $this->module->getModulePath($this->getName()) . '/' . $folder->getPath();
333
334 118
            $this->filesystem->makeDirectory($path, 0755, true);
335 118
            if (config('modules.stubs.gitkeep')) {
336 118
                $this->generateGitKeep($path);
337
            }
338
        }
339 118
    }
340
341
    /**
342
     * Generate git keep to the specified path.
343
     *
344
     * @param string $path
345
     */
346 118
    public function generateGitKeep($path)
347
    {
348 118
        $this->filesystem->put($path . '/.gitkeep', '');
349 118
    }
350
351
    /**
352
     * Generate the files.
353
     */
354 109
    public function generateFiles()
355
    {
356 109
        foreach ($this->getFiles() as $stub => $file) {
357 109
            $path = $this->module->getModulePath($this->getName()) . $file;
358
359 109 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...
360 109
                $this->filesystem->makeDirectory($dir, 0775, true);
361
            }
362
363 109
            $this->filesystem->put($path, $this->getStubContents($stub));
364
365 109
            $this->console->info("Created : {$path}");
366
        }
367 109
    }
368
369
    /**
370
     * Generate some resources.
371
     */
372 109
    public function generateResources()
373
    {
374 109
        $this->console->call('module:make-seed', [
375 109
            'name' => $this->getName(),
376 109
            'module' => $this->getName(),
377
            '--master' => true,
378
        ]);
379
380 109
        $this->console->call('module:make-provider', [
381 109
            'name' => $this->getName() . 'ServiceProvider',
382 109
            'module' => $this->getName(),
383
            '--master' => true,
384
        ]);
385
386 109
        $this->console->call('module:route-provider', [
387 109
            'module' => $this->getName(),
388
        ]);
389
390 109
        $this->console->call('module:make-controller', [
391 109
            'controller' => $this->getName() . 'Controller',
392 109
            'module' => $this->getName(),
393
        ]);
394 109
    }
395
396
    /**
397
     * Get the contents of the specified stub file by given stub name.
398
     *
399
     * @param $stub
400
     *
401
     * @return string
402
     */
403 118
    protected function getStubContents($stub)
404
    {
405 118
        return (new Stub(
406 118
            '/' . $stub . '.stub',
407 118
            $this->getReplacement($stub)
408
        )
409 118
        )->render();
410
    }
411
412
    /**
413
     * get the list for the replacements.
414
     */
415
    public function getReplacements()
416
    {
417
        return $this->module->config('stubs.replacements');
418
    }
419
420
    /**
421
     * Get array replacement for the specified stub.
422
     *
423
     * @param $stub
424
     *
425
     * @return array
426
     */
427 118
    protected function getReplacement($stub)
428
    {
429 118
        $replacements = $this->module->config('stubs.replacements');
430
431 118
        if (!isset($replacements[$stub])) {
432 109
            return [];
433
        }
434
435 118
        $keys = $replacements[$stub];
436
437 118
        $replaces = [];
438
439 118
        foreach ($keys as $key) {
440 118
            if (method_exists($this, $method = 'get' . ucfirst(Str::studly(strtolower($key))) . 'Replacement')) {
441 118
                $replaces[$key] = $this->$method();
442
            } else {
443
                $replaces[$key] = null;
444
            }
445
        }
446
447 118
        return $replaces;
448
    }
449
450
    /**
451
     * Generate the module.json file
452
     */
453 118
    private function generateModuleJsonFile()
454
    {
455 118
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
456
457 118 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...
458
            $this->filesystem->makeDirectory($dir, 0775, true);
459
        }
460
461 118
        $this->filesystem->put($path, $this->getStubContents('json'));
462
463 118
        $this->console->info("Created : {$path}");
464 118
    }
465
466
    /**
467
     * Remove the default service provider that was added in the module.json file
468
     * This is needed when a --plain module was created
469
     */
470 9
    private function cleanModuleJsonFile()
471
    {
472 9
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
473
474 9
        $content = $this->filesystem->get($path);
475 9
        $namespace = $this->getModuleNamespaceReplacement();
476 9
        $studlyName = $this->getStudlyNameReplacement();
477
478 9
        $provider = '"' . $namespace . '\\\\' . $studlyName . '\\\\Providers\\\\' . $studlyName . 'ServiceProvider"';
479
480 9
        $content = str_replace($provider, '', $content);
481
482 9
        $this->filesystem->put($path, $content);
483 9
    }
484
485
    /**
486
     * Get the module name in lower case.
487
     *
488
     * @return string
489
     */
490 118
    protected function getLowerNameReplacement()
491
    {
492 118
        return strtolower($this->getName());
493
    }
494
495
    /**
496
     * Get the module name in studly case.
497
     *
498
     * @return string
499
     */
500 118
    protected function getStudlyNameReplacement()
501
    {
502 118
        return $this->getName();
503
    }
504
505
    /**
506
     * Get replacement for $VENDOR$.
507
     *
508
     * @return string
509
     */
510 109
    protected function getVendorReplacement()
511
    {
512 109
        return $this->module->config('composer.vendor');
513
    }
514
515
    /**
516
     * Get replacement for $MODULE_NAMESPACE$.
517
     *
518
     * @return string
519
     */
520 118
    protected function getModuleNamespaceReplacement()
521
    {
522 118
        return str_replace('\\', '\\\\', $this->module->config('namespace'));
523
    }
524
525
    /**
526
     * Get replacement for $AUTHOR_NAME$.
527
     *
528
     * @return string
529
     */
530 109
    protected function getAuthorNameReplacement()
531
    {
532 109
        return $this->module->config('composer.author.name');
533
    }
534
535
    /**
536
     * Get replacement for $AUTHOR_EMAIL$.
537
     *
538
     * @return string
539
     */
540 109
    protected function getAuthorEmailReplacement()
541
    {
542 109
        return $this->module->config('composer.author.email');
543
    }
544
}
545