Completed
Push — master ( 4fafa1...e65f27 )
by Nicolas
12:12
created

src/Generators/ModuleGenerator.php (14 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 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 120
    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 120
        $this->name = $name;
96 120
        $this->config = $config;
97 120
        $this->filesystem = $filesystem;
98 120
        $this->console = $console;
99 120
        $this->module = $module;
0 ignored issues
show
Documentation Bug introduced by
It seems like $module can also be of type object<Nwidart\Modules\FileRepository>. However, the property $module is declared as type object<Nwidart\Modules\Module>. 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...
100 120
        $this->activator = $activator;
101 120
    }
102
103
    /**
104
     * Set plain flag.
105
     *
106
     * @param bool $plain
107
     *
108
     * @return $this
109
     */
110 120
    public function setPlain($plain)
111
    {
112 120
        $this->plain = $plain;
113
114 120
        return $this;
115
    }
116
117
    /**
118
     * Set active flag.
119
     *
120
     * @param bool $active
121
     *
122
     * @return $this
123
     */
124 120
    public function setActive(bool $active)
125
    {
126 120
        $this->isActive = $active;
127
128 120
        return $this;
129
    }
130
131
    /**
132
     * Get the name of module will created. By default in studly case.
133
     *
134
     * @return string
135
     */
136 120
    public function getName()
137
    {
138 120
        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 120
    public function setConfig($config)
159
    {
160 120
        $this->config = $config;
161
162 120
        return $this;
163
    }
164
165
    /**
166
     * Set the modules activator
167
     *
168
     * @param ActivatorInterface $activator
169
     *
170
     * @return $this
171
     */
172 120
    public function setActivator(ActivatorInterface $activator)
173
    {
174 120
        $this->activator = $activator;
175
176 120
        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 120
    public function setFilesystem($filesystem)
197
    {
198 120
        $this->filesystem = $filesystem;
199
200 120
        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 120
    public function setConsole($console)
221
    {
222 120
        $this->console = $console;
223
224 120
        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 module instance.
239
     *
240
     * @param mixed $module
241
     *
242
     * @return $this
243
     */
244 120
    public function setModule($module)
245
    {
246 120
        $this->module = $module;
247
248 120
        return $this;
249
    }
250
251
    /**
252
     * Get the list of folders will created.
253
     *
254
     * @return array
255
     */
256 120
    public function getFolders()
257
    {
258 120
        return $this->module->config('paths.generator');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
259
    }
260
261
    /**
262
     * Get the list of files will created.
263
     *
264
     * @return array
265
     */
266 111
    public function getFiles()
267
    {
268 111
        return $this->module->config('stubs.files');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
269
    }
270
271
    /**
272
     * Set force status.
273
     *
274
     * @param bool|int $force
275
     *
276
     * @return $this
277
     */
278 120
    public function setForce($force)
279
    {
280 120
        $this->force = $force;
281
282 120
        return $this;
283
    }
284
285
    /**
286
     * Generate the module.
287
     */
288 120
    public function generate()
289
    {
290 120
        $name = $this->getName();
291
292 120
        if ($this->module->has($name)) {
0 ignored issues
show
Documentation Bug introduced by
The method has does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
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 120
        $this->generateFolders();
303
304 120
        $this->generateModuleJsonFile();
305
306 120
        if ($this->plain !== true) {
307 111
            $this->generateFiles();
308 111
            $this->generateResources();
309
        }
310
311 120
        if ($this->plain === true) {
312 9
            $this->cleanModuleJsonFile();
313
        }
314
315 120
        $this->activator->setActiveByName($name, $this->isActive);
316
317 120
        $this->console->info("Module [{$name}] created successfully.");
318 120
    }
319
320
    /**
321
     * Generate the folders.
322
     */
323 120
    public function generateFolders()
324
    {
325 120
        foreach ($this->getFolders() as $key => $folder) {
326 120
            $folder = GenerateConfigReader::read($key);
327
328 120
            if ($folder->generate() === false) {
329 3
                continue;
330
            }
331
332 120
            $path = $this->module->getModulePath($this->getName()) . '/' . $folder->getPath();
0 ignored issues
show
Documentation Bug introduced by
The method getModulePath does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
333
334 120
            $this->filesystem->makeDirectory($path, 0755, true);
335 120
            if (config('modules.stubs.gitkeep')) {
336 120
                $this->generateGitKeep($path);
337
            }
338
        }
339 120
    }
340
341
    /**
342
     * Generate git keep to the specified path.
343
     *
344
     * @param string $path
345
     */
346 120
    public function generateGitKeep($path)
347
    {
348 120
        $this->filesystem->put($path . '/.gitkeep', '');
349 120
    }
350
351
    /**
352
     * Generate the files.
353
     */
354 111
    public function generateFiles()
355
    {
356 111
        foreach ($this->getFiles() as $stub => $file) {
357 111
            $path = $this->module->getModulePath($this->getName()) . $file;
0 ignored issues
show
Documentation Bug introduced by
The method getModulePath does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
358
359 111 View Code Duplication
            if (!$this->filesystem->isDirectory($dir = dirname($path))) {
360 111
                $this->filesystem->makeDirectory($dir, 0775, true);
361
            }
362
363 111
            $this->filesystem->put($path, $this->getStubContents($stub));
364
365 111
            $this->console->info("Created : {$path}");
366
        }
367 111
    }
368
369
    /**
370
     * Generate some resources.
371
     */
372 111
    public function generateResources()
373
    {
374 111
        $this->console->call('module:make-seed', [
375 111
            'name' => $this->getName(),
376 111
            'module' => $this->getName(),
377
            '--master' => true,
378
        ]);
379
380 111
        $this->console->call('module:make-provider', [
381 111
            'name' => $this->getName() . 'ServiceProvider',
382 111
            'module' => $this->getName(),
383
            '--master' => true,
384
        ]);
385
386 111
        $this->console->call('module:route-provider', [
387 111
            'module' => $this->getName(),
388
        ]);
389
390 111
        $this->console->call('module:make-controller', [
391 111
            'controller' => $this->getName() . 'Controller',
392 111
            'module' => $this->getName(),
393
        ]);
394 111
    }
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 120
    protected function getStubContents($stub)
404
    {
405 120
        return (new Stub(
406 120
            '/' . $stub . '.stub',
407 120
            $this->getReplacement($stub)
408
        )
409 120
        )->render();
410
    }
411
412
    /**
413
     * get the list for the replacements.
414
     */
415
    public function getReplacements()
416
    {
417
        return $this->module->config('stubs.replacements');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
418
    }
419
420
    /**
421
     * Get array replacement for the specified stub.
422
     *
423
     * @param $stub
424
     *
425
     * @return array
426
     */
427 120
    protected function getReplacement($stub)
428
    {
429 120
        $replacements = $this->module->config('stubs.replacements');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
430
431 120
        if (!isset($replacements[$stub])) {
432 111
            return [];
433
        }
434
435 120
        $keys = $replacements[$stub];
436
437 120
        $replaces = [];
438
439 120
        foreach ($keys as $key) {
440 120
            if (method_exists($this, $method = 'get' . ucfirst(Str::studly(strtolower($key))) . 'Replacement')) {
441 120
                $replaces[$key] = $this->$method();
442
            } else {
443
                $replaces[$key] = null;
444
            }
445
        }
446
447 120
        return $replaces;
448
    }
449
450
    /**
451
     * Generate the module.json file
452
     */
453 120
    private function generateModuleJsonFile()
454
    {
455 120
        $path = $this->module->getModulePath($this->getName()) . 'module.json';
0 ignored issues
show
Documentation Bug introduced by
The method getModulePath does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
456
457 120 View Code Duplication
        if (!$this->filesystem->isDirectory($dir = dirname($path))) {
458
            $this->filesystem->makeDirectory($dir, 0775, true);
459
        }
460
461 120
        $this->filesystem->put($path, $this->getStubContents('json'));
462
463 120
        $this->console->info("Created : {$path}");
464 120
    }
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';
0 ignored issues
show
Documentation Bug introduced by
The method getModulePath does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
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 120
    protected function getLowerNameReplacement()
491
    {
492 120
        return strtolower($this->getName());
493
    }
494
495
    /**
496
     * Get the module name in studly case.
497
     *
498
     * @return string
499
     */
500 120
    protected function getStudlyNameReplacement()
501
    {
502 120
        return $this->getName();
503
    }
504
505
    /**
506
     * Get replacement for $VENDOR$.
507
     *
508
     * @return string
509
     */
510 111
    protected function getVendorReplacement()
511
    {
512 111
        return $this->module->config('composer.vendor');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
513
    }
514
515
    /**
516
     * Get replacement for $MODULE_NAMESPACE$.
517
     *
518
     * @return string
519
     */
520 120
    protected function getModuleNamespaceReplacement()
521
    {
522 120
        return str_replace('\\', '\\\\', $this->module->config('namespace'));
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
523
    }
524
525
    /**
526
     * Get replacement for $AUTHOR_NAME$.
527
     *
528
     * @return string
529
     */
530 111
    protected function getAuthorNameReplacement()
531
    {
532 111
        return $this->module->config('composer.author.name');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
533
    }
534
535
    /**
536
     * Get replacement for $AUTHOR_EMAIL$.
537
     *
538
     * @return string
539
     */
540 111
    protected function getAuthorEmailReplacement()
541
    {
542 111
        return $this->module->config('composer.author.email');
0 ignored issues
show
Documentation Bug introduced by
The method config does not exist on object<Nwidart\Modules\Module>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
543
    }
544
}
545