Completed
Push — master ( 6e27f1...d5fec2 )
by Nicolas
03:36
created

ModuleGenerator::getReplacement()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 0
loc 22
ccs 11
cts 11
cp 1
crap 4
rs 9.568
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 92
    public function __construct(
73
        $name,
74
        FileRepository $module = null,
75
        Config $config = null,
76
        Filesystem $filesystem = null,
77
        Console $console = null
78
    ) {
79 92
        $this->name = $name;
80 92
        $this->config = $config;
81 92
        $this->filesystem = $filesystem;
82 92
        $this->console = $console;
83 92
        $this->module = $module;
84 92
    }
85
86
    /**
87
     * Set plain flag.
88
     *
89
     * @param bool $plain
90
     *
91
     * @return $this
92
     */
93 92
    public function setPlain($plain)
94
    {
95 92
        $this->plain = $plain;
96
97 92
        return $this;
98
    }
99
100
    /**
101
     * Get the name of module will created. By default in studly case.
102
     *
103
     * @return string
104
     */
105 92
    public function getName()
106
    {
107 92
        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 92
    public function setConfig($config)
128
    {
129 92
        $this->config = $config;
130
131 92
        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 92
    public function setFilesystem($filesystem)
152
    {
153 92
        $this->filesystem = $filesystem;
154
155 92
        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 92
    public function setConsole($console)
176
    {
177 92
        $this->console = $console;
178
179 92
        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 92
    public function setModule($module)
200
    {
201 92
        $this->module = $module;
202
203 92
        return $this;
204
    }
205
206
    /**
207
     * Get the list of folders will created.
208
     *
209
     * @return array
210
     */
211 92
    public function getFolders()
212
    {
213 92
        return $this->module->config('paths.generator');
214
    }
215
216
    /**
217
     * Get the list of files will created.
218
     *
219
     * @return array
220
     */
221 84
    public function getFiles()
222
    {
223 84
        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 92
    public function setForce($force)
234
    {
235 92
        $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 92
        return $this;
238
    }
239
240
    /**
241
     * Generate the module.
242
     */
243 92
    public function generate()
244
    {
245 92
        $name = $this->getName();
246
247 92
        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 92
        $this->generateFolders();
258
259 92
        $this->generateModuleJsonFile();
260
261 92
        if ($this->plain !== true) {
262 84
            $this->generateFiles();
263 84
            $this->generateResources();
264
        }
265
266 92
        if ($this->plain === true) {
267 8
            $this->cleanModuleJsonFile();
268
        }
269
270 92
        $this->console->info("Module [{$name}] created successfully.");
271 92
    }
272
273
    /**
274
     * Generate the folders.
275
     */
276 92
    public function generateFolders()
277
    {
278 92
        foreach ($this->getFolders() as $key => $folder) {
279 92
            $folder = GenerateConfigReader::read($key);
280
281 92
            if ($folder->generate() === false) {
282 3
                continue;
283
            }
284
285 92
            $path = $this->module->getModulePath($this->getName()) . '/' . $folder->getPath();
286
287 92
            $this->filesystem->makeDirectory($path, 0755, true);
288 92
            if (config('modules.stubs.gitkeep')) {
289 92
                $this->generateGitKeep($path);
290
            }
291
        }
292 92
    }
293
294
    /**
295
     * Generate git keep to the specified path.
296
     *
297
     * @param string $path
298
     */
299 92
    public function generateGitKeep($path)
300
    {
301 92
        $this->filesystem->put($path . '/.gitkeep', '');
302 92
    }
303
304
    /**
305
     * Generate the files.
306
     */
307 84
    public function generateFiles()
308
    {
309 84
        foreach ($this->getFiles() as $stub => $file) {
310 84
            $path = $this->module->getModulePath($this->getName()) . $file;
311
312 84 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 84
                $this->filesystem->makeDirectory($dir, 0775, true);
314
            }
315
316 84
            $this->filesystem->put($path, $this->getStubContents($stub));
317
318 84
            $this->console->info("Created : {$path}");
319
        }
320 84
    }
321
322
    /**
323
     * Generate some resources.
324
     */
325 84
    public function generateResources()
326
    {
327 84
        $this->console->call('module:make-seed', [
328 84
            'name' => $this->getName(),
329 84
            'module' => $this->getName(),
330
            '--master' => true,
331
        ]);
332
333 84
        $this->console->call('module:make-provider', [
334 84
            'name' => $this->getName() . 'ServiceProvider',
335 84
            'module' => $this->getName(),
336
            '--master' => true,
337
        ]);
338
339 84
        $this->console->call('module:make-controller', [
340 84
            'controller' => $this->getName() . 'Controller',
341 84
            'module' => $this->getName(),
342
        ]);
343 84
    }
344
345
    /**
346
     * Get the contents of the specified stub file by given stub name.
347
     *
348
     * @param $stub
349
     *
350
     * @return string
351
     */
352 92
    protected function getStubContents($stub)
353
    {
354 92
        return (new Stub(
355 92
            '/' . $stub . '.stub',
356 92
            $this->getReplacement($stub)
357
        )
358 92
        )->render();
359
    }
360
361
    /**
362
     * get the list for the replacements.
363
     */
364
    public function getReplacements()
365
    {
366
        return $this->module->config('stubs.replacements');
367
    }
368
369
    /**
370
     * Get array replacement for the specified stub.
371
     *
372
     * @param $stub
373
     *
374
     * @return array
375
     */
376 92
    protected function getReplacement($stub)
377
    {
378 92
        $replacements = $this->module->config('stubs.replacements');
379
380 92
        if (!isset($replacements[$stub])) {
381 84
            return [];
382
        }
383
384 92
        $keys = $replacements[$stub];
385
386 92
        $replaces = [];
387
388 92
        foreach ($keys as $key) {
389 92
            if (method_exists($this, $method = 'get' . ucfirst(studly_case(strtolower($key))) . 'Replacement')) {
390 92
                $replaces[$key] = $this->$method();
391
            } else {
392 92
                $replaces[$key] = null;
393
            }
394
        }
395
396 92
        return $replaces;
397
    }
398
399
    /**
400
     * Generate the module.json file
401
     */
402 92
    private function generateModuleJsonFile()
403
    {
404 92
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
405
406 92 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...
407
            $this->filesystem->makeDirectory($dir, 0775, true);
408
        }
409
410 92
        $this->filesystem->put($path, $this->getStubContents('json'));
411
412 92
        $this->console->info("Created : {$path}");
413 92
    }
414
415
    /**
416
     * Remove the default service provider that was added in the module.json file
417
     * This is needed when a --plain module was created
418
     */
419 8
    private function cleanModuleJsonFile()
420
    {
421 8
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
422
423 8
        $content = $this->filesystem->get($path);
424 8
        $namespace = $this->getModuleNamespaceReplacement();
425 8
        $studlyName = $this->getStudlyNameReplacement();
426
427 8
        $provider = '"' . $namespace . '\\\\' . $studlyName . '\\\\Providers\\\\' . $studlyName . 'ServiceProvider"';
428
429 8
        $content = str_replace($provider, '', $content);
430
431 8
        $this->filesystem->put($path, $content);
432 8
    }
433
434
    /**
435
     * Get the module name in lower case.
436
     *
437
     * @return string
438
     */
439 92
    protected function getLowerNameReplacement()
440
    {
441 92
        return strtolower($this->getName());
442
    }
443
444
    /**
445
     * Get the module name in studly case.
446
     *
447
     * @return string
448
     */
449 92
    protected function getStudlyNameReplacement()
450
    {
451 92
        return $this->getName();
452
    }
453
454
    /**
455
     * Get replacement for $VENDOR$.
456
     *
457
     * @return string
458
     */
459 84
    protected function getVendorReplacement()
460
    {
461 84
        return $this->module->config('composer.vendor');
462
    }
463
464
    /**
465
     * Get replacement for $MODULE_NAMESPACE$.
466
     *
467
     * @return string
468
     */
469 92
    protected function getModuleNamespaceReplacement()
470
    {
471 92
        return str_replace('\\', '\\\\', $this->module->config('namespace'));
472
    }
473
474
    /**
475
     * Get replacement for $AUTHOR_NAME$.
476
     *
477
     * @return string
478
     */
479 84
    protected function getAuthorNameReplacement()
480
    {
481 84
        return $this->module->config('composer.author.name');
482
    }
483
484
    /**
485
     * Get replacement for $AUTHOR_EMAIL$.
486
     *
487
     * @return string
488
     */
489 84
    protected function getAuthorEmailReplacement()
490
    {
491 84
        return $this->module->config('composer.author.email');
492
    }
493
494 84
    protected function getRoutesLocationReplacement()
495
    {
496 84
        return '/' . $this->module->config('stubs.files.routes');
497
    }
498
}
499