Completed
Push — master ( d56e51...35c738 )
by Nicolas
03:52
created

ModuleGenerator::getStubContents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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