Completed
Push — develop ( d56149...badf6b )
by Andrea Marco
05:00
created

EnumMakeCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 110
ccs 29
cts 29
cp 1
rs 10
c 0
b 0
f 0
wmc 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A buildClass() 0 10 1
A parseEnums() 0 8 1
A getKeys() 0 11 3
A getStub() 0 3 1
A getDefaultNamespace() 0 14 2
1
<?php
2
3
namespace Cerbero\LaravelEnum\Console\Commands;
4
5
use Illuminate\Console\GeneratorCommand;
6
use Illuminate\Support\Str;
7
use Cerbero\LaravelEnum\StubAssembler;
8
use Cerbero\LaravelEnum\Parser;
9
use Cerbero\LaravelEnum\Keys;
10
use Rexlabs\Enum\Exceptions\InvalidKeyException;
11
use Symfony\Component\Console\Exception\InvalidArgumentException;
12
13
/**
14
 * The Artisan command to generate Enum classes.
15
 *
16
 */
17
class EnumMakeCommand extends GeneratorCommand
18
{
19
    /**
20
     * The name and signature of the console command.
21
     *
22
     * @var string
23
     */
24
    protected $signature = 'make:enum
25
                            {name : The name of the class}
26
                            {enum : The definition of the enum}
27
                            {--k|keys= : The type of keys to generate if not defined}
28
                            {--p|path= : The path to generate enums in}
29
                            {--f|force : Create the class even if the enum already exists}';
30
31
    /**
32
     * The console command description.
33
     *
34
     * @var string
35
     */
36
    protected $description = 'Create a new enum class';
37
38
    /**
39
     * The type of class being generated.
40
     *
41
     * @var string
42
     */
43
    protected $type = 'Enum';
44
45
    /**
46
     * Get the stub file for the generator.
47
     *
48
     * @return string
49
     */
50 15
    protected function getStub()
51
    {
52 15
        return __DIR__ . '/../../../stubs/enum.stub';
53
    }
54
55
    /**
56
     * Get the default namespace for the class.
57
     *
58
     * @param  string  $rootNamespace
59
     * @return string
60
     */
61 15
    protected function getDefaultNamespace($rootNamespace)
62
    {
63 15
        if ($path = $this->option('path')) {
64
            // Ensure the path starts with "app/"
65 3
            $path = Str::start(ltrim($path, '/'), 'app/');
66
            // Remove "app/" from the beginning of the path
67 3
            $path = preg_replace('#^app\/#', '', $path);
68
            // Convert the path into namespace
69 3
            $namespace = implode('\\', array_map('ucfirst', explode('/', $path)));
70
            // Prepend the root namespace
71 3
            return $rootNamespace . '\\' . $namespace;
72
        }
73
74 12
        return $rootNamespace . '\Enums';
75
    }
76
77
    /**
78
     * Build the class with the given name.
79
     *
80
     * @param  string  $name
81
     * @return string
82
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
83
     */
84 15
    protected function buildClass($name)
85
    {
86 15
        $stub = parent::buildClass($name);
87 15
        $enums = $this->parseEnums();
88
89 12
        return (new StubAssembler($stub, $enums))
90 12
            ->replaceMethodTags()
91 12
            ->replaceConstants()
92 12
            ->replaceMap()
93 12
            ->getStub();
94
    }
95
96
    /**
97
     * Parse the command syntax and retrieve the enums
98
     *
99
     * @return array
100
     */
101 15
    private function parseEnums() : array
102
    {
103
        // Normalise definition as argument() may return an array
104 15
        $enum = (array) $this->argument('enum');
105 15
        $definition = trim($enum[0]);
106 15
        $keys = $this->getKeys();
107
108 12
        return (new Parser)->parseDefinition($definition, $keys);
109
    }
110
111
    /**
112
     * Retrieve the keys to generate
113
     *
114
     * @return \Cerbero\LaravelEnum\Keys|null
115
     */
116 15
    private function getKeys() : ?Keys
117
    {
118 15
        if (null === $key = $this->option('keys')) {
119 9
            return null;
120
        }
121
122
        try {
123 6
            return Keys::instanceFromKey($key);
124 3
        } catch (InvalidKeyException $e) {
125 3
            $keys = implode(', ', Keys::keys());
126 3
            throw new InvalidArgumentException("Invalid type provided for keys. Allowed keys: {$keys}");
127
        }
128
    }
129
}
130