ComponentGenerator   B
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 435
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 37
lcom 1
cbo 5
dl 0
loc 435
rs 8.6
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A setPlain() 0 6 1
A getName() 0 4 1
A getConfig() 0 4 1
A setConfig() 0 6 1
A getFilesystem() 0 4 1
A setFilesystem() 0 6 1
A getConsole() 0 4 1
A setConsole() 0 6 1
A getComponent() 0 4 1
A setComponent() 0 6 1
A getFolders() 0 4 1
A getFiles() 0 4 1
A setForce() 0 6 1
B generate() 0 24 4
A generateFolders() 0 10 2
A generateGitKeep() 0 4 1
A generateFiles() 0 14 3
A generateResources() 0 19 1
A getStubContents() 0 7 1
A getReplacements() 0 4 1
B getReplacement() 0 22 4
A getLowerNameReplacement() 0 4 1
A getStudlyNameReplacement() 0 4 1
A getVendorReplacement() 0 4 1
A getComponentNamespaceReplacement() 0 4 1
A getAuthorNameReplacement() 0 4 1
A getAuthorEmailReplacement() 0 4 1
1
<?php
2
3
namespace Consigliere\Components\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 Consigliere\Components\Repository;
10
use Consigliere\Components\Support\Stub;
11
12
class ComponentGenerator extends Generator
13
{
14
    /**
15
     * The component name will created.
16
     *
17
     * @var string
18
     */
19
    protected $name;
20
21
    /**
22
     * The laravel config instance.
23
     *
24
     * @var Config
25
     */
26
    protected $config;
27
28
    /**
29
     * The laravel filesystem instance.
30
     *
31
     * @var Filesystem
32
     */
33
    protected $filesystem;
34
35
    /**
36
     * The laravel console instance.
37
     *
38
     * @var Console
39
     */
40
    protected $console;
41
42
    /**
43
     * The pingpong component instance.
44
     *
45
     * @var Component
46
     */
47
    protected $component;
48
49
    /**
50
     * Force status.
51
     *
52
     * @var bool
53
     */
54
    protected $force = false;
55
56
    /**
57
     * Generate a plain component.
58
     *
59
     * @var bool
60
     */
61
    protected $plain = false;
62
63
    /**
64
     * The constructor.
65
     *
66
     * @param            $name
67
     * @param Repository $component
68
     * @param Config $config
69
     * @param Filesystem $filesystem
70
     * @param Console $console
71
     */
72
    public function __construct(
73
        $name,
74
        Repository $component = null,
75
        Config $config = null,
76
        Filesystem $filesystem = null,
77
        Console $console = null
78
    )
79
    {
80
        $this->name       = $name;
81
        $this->config     = $config;
82
        $this->filesystem = $filesystem;
83
        $this->console    = $console;
84
        $this->component  = $component;
0 ignored issues
show
Documentation Bug introduced by
It seems like $component can also be of type object<Consigliere\Components\Repository>. However, the property $component is declared as type object<Consigliere\Compo...s\Generators\Component>. 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...
85
    }
86
87
    /**
88
     * Set plain flag.
89
     *
90
     * @param bool $plain
91
     *
92
     * @return $this
93
     */
94
    public function setPlain($plain)
95
    {
96
        $this->plain = $plain;
97
98
        return $this;
99
    }
100
101
    /**
102
     * Get the name of component will created. By default in studly case.
103
     *
104
     * @return string
105
     */
106
    public function getName()
107
    {
108
        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
    public function setConfig($config)
129
    {
130
        $this->config = $config;
131
132
        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
    public function setFilesystem($filesystem)
153
    {
154
        $this->filesystem = $filesystem;
155
156
        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
    public function setConsole($console)
177
    {
178
        $this->console = $console;
179
180
        return $this;
181
    }
182
183
    /**
184
     * Get the pingpong component instance.
185
     *
186
     * @return Component
187
     */
188
    public function getComponent()
189
    {
190
        return $this->component;
191
    }
192
193
    /**
194
     * Set the pingpong component instance.
195
     *
196
     * @param mixed $component
197
     *
198
     * @return $this
199
     */
200
    public function setComponent($component)
201
    {
202
        $this->component = $component;
203
204
        return $this;
205
    }
206
207
    /**
208
     * Get the list of folders will created.
209
     *
210
     * @return array
211
     */
212
    public function getFolders()
213
    {
214
        return array_values($this->component->config('paths.generator'));
215
    }
216
217
    /**
218
     * Get the list of files will created.
219
     *
220
     * @return array
221
     */
222
    public function getFiles()
223
    {
224
        return $this->component->config('stubs.files');
225
    }
226
227
    /**
228
     * Set force status.
229
     *
230
     * @param bool|int $force
231
     *
232
     * @return $this
233
     */
234
    public function setForce($force)
235
    {
236
        $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
        return $this;
239
    }
240
241
    /**
242
     * Generate the component.
243
     */
244
    public function generate()
245
    {
246
        $name = $this->getName();
247
248
        if ($this->component->has($name)) {
249
            if ($this->force) {
250
                $this->component->delete($name);
251
            } else {
252
                $this->console->error("Component [{$name}] already exist!");
253
254
                return;
255
            }
256
        }
257
258
        $this->generateFolders();
259
260
        $this->generateFiles();
261
262
        if (!$this->plain) {
263
            $this->generateResources();
264
        }
265
266
        $this->console->info("Component [{$name}] created successfully.");
267
    }
268
269
    /**
270
     * Generate the folders.
271
     */
272
    public function generateFolders()
273
    {
274
        foreach ($this->getFolders() as $folder) {
275
            $path = $this->component->getComponentPath($this->getName()) . '/' . $folder;
276
277
            $this->filesystem->makeDirectory($path, 0755, true);
278
279
            $this->generateGitKeep($path);
280
        }
281
    }
282
283
    /**
284
     * Generate git keep to the specified path.
285
     *
286
     * @param string $path
287
     */
288
    public function generateGitKeep($path)
289
    {
290
        $this->filesystem->put($path . '/.gitkeep', '');
291
    }
292
293
    /**
294
     * Generate the files.
295
     */
296
    public function generateFiles()
297
    {
298
        foreach ($this->getFiles() as $stub => $file) {
299
            $path = $this->component->getComponentPath($this->getName()) . $file;
300
301
            if (!$this->filesystem->isDirectory($dir = dirname($path))) {
302
                $this->filesystem->makeDirectory($dir, 0775, true);
303
            }
304
305
            $this->filesystem->put($path, $this->getStubContents($stub));
306
307
            $this->console->info("Created : {$path}");
308
        }
309
    }
310
311
    /**
312
     * Generate some resources.
313
     */
314
    public function generateResources()
315
    {
316
        $this->console->call('component:make-seed', [
317
            'name'      => $this->getName(),
318
            'component' => $this->getName(),
319
            '--master'  => true,
320
        ]);
321
322
        $this->console->call('component:make-provider', [
323
            'name'      => $this->getName() . 'ServiceProvider',
324
            'component' => $this->getName(),
325
            '--master'  => true,
326
        ]);
327
328
        $this->console->call('component:make-controller', [
329
            'controller' => $this->getName() . 'Controller',
330
            'component'  => $this->getName(),
331
        ]);
332
    }
333
334
    /**
335
     * Get the contents of the specified stub file by given stub name.
336
     *
337
     * @param $stub
338
     *
339
     * @return Stub
340
     */
341
    protected function getStubContents($stub)
342
    {
343
        return (new Stub(
344
            '/' . $stub . '.stub',
345
            $this->getReplacement($stub))
346
        )->render();
347
    }
348
349
    /**
350
     * get the list for the replacements.
351
     */
352
    public function getReplacements()
353
    {
354
        return $this->component->config('stubs.replacements');
355
    }
356
357
    /**
358
     * Get array replacement for the specified stub.
359
     *
360
     * @param $stub
361
     *
362
     * @return array
363
     */
364
    protected function getReplacement($stub)
365
    {
366
        $replacements = $this->component->config('stubs.replacements');
367
368
        if (!isset($replacements[$stub])) {
369
            return [];
370
        }
371
372
        $keys = $replacements[$stub];
373
374
        $replaces = [];
375
376
        foreach ($keys as $key) {
377
            if (method_exists($this, $method = 'get' . ucfirst(studly_case(strtolower($key))) . 'Replacement')) {
378
                $replaces[$key] = call_user_func([$this, $method]);
379
            } else {
380
                $replaces[$key] = null;
381
            }
382
        }
383
384
        return $replaces;
385
    }
386
387
    /**
388
     * Get the component name in lower case.
389
     *
390
     * @return string
391
     */
392
    protected function getLowerNameReplacement()
393
    {
394
        return strtolower($this->getName());
395
    }
396
397
    /**
398
     * Get the component name in studly case.
399
     *
400
     * @return string
401
     */
402
    protected function getStudlyNameReplacement()
403
    {
404
        return $this->getName();
405
    }
406
407
    /**
408
     * Get replacement for $VENDOR$.
409
     *
410
     * @return string
411
     */
412
    protected function getVendorReplacement()
413
    {
414
        return $this->component->config('composer.vendor');
415
    }
416
417
    /**
418
     * Get replacement for $COMPONENT_NAMESPACE$.
419
     *
420
     * @return string
421
     */
422
    protected function getComponentNamespaceReplacement()
423
    {
424
        return str_replace('\\', '\\\\', $this->component->config('namespace'));
425
    }
426
427
    /**
428
     * Get replacement for $AUTHOR_NAME$.
429
     *
430
     * @return string
431
     */
432
    protected function getAuthorNameReplacement()
433
    {
434
        return $this->component->config('composer.author.name');
435
    }
436
437
    /**
438
     * Get replacement for $AUTHOR_EMAIL$.
439
     *
440
     * @return string
441
     */
442
    protected function getAuthorEmailReplacement()
443
    {
444
        return $this->component->config('composer.author.email');
445
    }
446
}
447