Passed
Push — master ( ad5a85...40ce26 )
by Arthur
23:10
created

AbstractGeneratorCommand::handleArguments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 20
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: arthur
5
 * Date: 09.03.19
6
 * Time: 17:15.
7
 */
8
9
namespace Foundation\Generator\Abstracts;
10
11
use Foundation\Core\Larapi;
12
use Foundation\Core\Module;
13
use Foundation\Exceptions\Exception;
14
use Foundation\Generator\Support\InputOption;
15
use Foundation\Generator\Support\Stub;
16
use Illuminate\Console\Command;
17
use Illuminate\Contracts\Filesystem\FileExistsException;
18
use ReflectionClass;
19
use Symfony\Component\Console\Input\InputArgument;
20
21
abstract class AbstractGeneratorCommand extends Command
22
{
23
    /**
24
     * The name of the generated resource.
25
     *
26
     * @var string
27
     */
28
    protected $generatorName;
29
30
    /**
31
     * The stub name.
32
     *
33
     * @var string
34
     */
35
    protected $stub;
36
37
    /**
38
     * The file path.
39
     *
40
     * @var string
41
     */
42
    protected $filePath;
43
44
    /**
45 10
     * The event that will fire when the file is created.
46
     *
47 10
     * @var string
48
     */
49
    protected $event;
50
51
52
    /**
53
     * The data that is inputted from the options.
54 12
     *
55
     * @var array
56 12
     */
57 12
    protected $optionData = [];
58
59 12
    /**
60 1
     * The data that is inputted from the arguments.
61
     *
62
     * @var array
63 12
     */
64 2
    protected $argumentData = [];
65
66
    public function handle()
67 12
    {
68
        $this->handleArguments();
69 12
70
        $path = str_replace('\\', '/', $this->getDestinationFilePath());
71 12
72 12
        if (file_exists($path) && !$this->isOverwriteable()) {
73
            $this->error("File : {$path} already exists.");
74
            throw new FileExistsException();
75
        }
76
77 10
        $this->handleOptions();
78
79 10
        $stub = new Stub($this->stubName(), array_merge($this->defaultStubOptions(), $this->stubOptions()));
80
81
82 12
        $this->beforeGeneration();
83
84
        if ($this->event === null)
85 12
            throw new Exception("No Generator event specified on " . static::class);
86 12
87
        event(new $this->event($path, $stub));
88
        $this->info("Created : {$path}");
89 12
90
        $this->afterGeneration();
91
    }
92 12
93 12
    /**
94
     * @return string
95
     */
96 12
    protected function getDestinationFilePath(): string
97
    {
98 12
        return $this->getModule()->getPath() . $this->filePath . '/' . $this->getFileName();
99
    }
100 12
101
    /**
102
     * @return string
103
     */
104 12
    protected abstract function getFileName(): string;
105
106
    protected function isOverwriteable(): bool
107
    {
108
        return $this->option('overwrite') ??false;
109
    }
110
111
    protected function getModule(): Module
112
    {
113 11
        return Larapi::getModule($this->getModuleName());
114
    }
115 11
116
    protected function beforeGeneration(): void
117
    {
118
    }
119
120 12
    protected function afterGeneration(): void
121
    {
122 12
    }
123
124 10
    abstract protected function stubOptions(): array;
125
126 10
    protected final function defaultStubOptions(): array
127
    {
128
        return [
129
            "MODULE" => $this->getModuleName()
130 11
        ];
131
    }
132
133 11
    /**
134 11
     * Get the console command options.
135
     *
136
     * @return array
137 11
     */
138
    final protected function getOptions()
139 11
    {
140
        $options = $this->setOptions();
141 11
        $options[] = ['overwrite', null, InputOption::VALUE_NONE, 'Overwrite this file if it already exists?'];
142
        return $options;
143
    }
144
145 11
    /**
146
     * Get the console command arguments.
147
     *
148
     * @return array
149
     */
150
    final protected function getArguments()
151
    {
152
        return array_merge([
153 87
            ['module', InputArgument::OPTIONAL, 'The name of module will be used.'],
154
        ],
155
            $this->setArguments());
156 87
    }
157 87
158
    /**
159
     * Set the console command arguments.
160
     *
161
     * @return array
162
     */
163
    protected abstract function setArguments(): array;
164
165
    /**
166 87
     * Set the console command options.
167
     *
168 87
     * @return array
169
     */
170
    protected abstract function setOptions(): array;
171 87
172
173 87
    protected function getGeneratorName(): string
174
    {
175
        return $this->generatorName ?? 'class';
176
    }
177
178
    /**
179
     * Get the stub file name.
180 6
     * @return string
181
     */
182 6
    protected function stubName()
183
    {
184
        return $this->stub;
185
    }
186
187
    protected function handleOptions()
188
    {
189
        foreach ($this->getOptions() as $option) {
190
            $method = 'handle' . ucfirst(strtolower($option[0])) . 'Option';
191
            $originalInput = $this->getOriginalOptionInput();
192
            if (isset($originalInput[$option[0]])) {
193
                $this->optionData[$option[0]] = $originalInput[$option[0]];
194
            } else {
195
                $this->optionData[$option[0]] = method_exists($this, $method) ? $this->$method($option[1], $option[2], $option[3], $option[4] ?? null) : $this->option($option[0]);
196
            }
197
        }
198
    }
199
200
    protected function handleModuleArgument()
201
    {
202
        return $this->anticipate('For what module would you like to generate a ' . $this->getGeneratorName() . '.', Larapi::getModuleNames());
203
    }
204
205
    protected function getModuleName(){
206
        $moduleName = $this->getArgument('module');
207
        if($moduleName===null){
208
            $this->error('module not specified');
209
            throw new \Exception('Name of module not specified.');
210
        }
211
        return $moduleName;
212
    }
213
214
    protected function handleArguments()
215
    {
216
        foreach ($this->getArguments() as $argument) {
217
            $method = 'handle' . ucfirst(strtolower($argument[0])) . 'Argument';
218
            $originalInput = $this->getOriginalArgumentInput();
219
            if (isset($originalInput[$argument[0]])) {
220
                $this->argumentData[$argument[0]] = $originalInput[$argument[0]];
221
            } else {
222
                $this->argumentData[$argument[0]] = method_exists($this, $method) ? $this->$method($argument[1], $argument[2], $argument[3] ?? null) : $this->option($argument[0]);
223
            }
224
        }
225
    }
226
227
    protected function getArgument(string $argument)
228
    {
229
        return $this->argumentData[$argument];
230
    }
231
232
    protected function getOption(string $name)
233
    {
234
        return $this->optionData[$name];
235
    }
236
237
    private function getOriginalOptionInput()
238
    {
239
        $reflection = new ReflectionClass($this->input);
240
        $property = $reflection->getProperty('options');
241
        $property->setAccessible(true);
242
        return $property->getValue($this->input);
243
    }
244
245
    private function getOriginalArgumentInput()
246
    {
247
        $reflection = new ReflectionClass($this->input);
248
        $property = $reflection->getProperty('arguments');
249
        $property->setAccessible(true);
250
        return $property->getValue($this->input);
251
    }
252
253
    public function __call($method, $parameters)
254
    {
255
        $key = str_replace('get', '', $method);
256
        if (array_key_exists(strtolower($method), $this->optionData))
257
            return $this->optionData[$key];
258
    }
259
}
260