Completed
Push — master ( d2aa29...f39b29 )
by Nicolas
03:46
created

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