1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Weew\ConsoleArguments; |
4
|
|
|
|
5
|
|
|
use Weew\ConsoleArguments\Exceptions\ArgumentNotFoundException; |
6
|
|
|
use Weew\ConsoleArguments\Exceptions\OptionNotFoundException; |
7
|
|
|
|
8
|
|
|
class Command implements ICommand { |
9
|
|
|
/** |
10
|
|
|
* @var string |
11
|
|
|
*/ |
12
|
|
|
protected $name; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @var string |
16
|
|
|
*/ |
17
|
|
|
protected $description; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var string |
21
|
|
|
*/ |
22
|
|
|
protected $help; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var bool |
26
|
|
|
*/ |
27
|
|
|
protected $hidden = false; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var bool |
31
|
|
|
*/ |
32
|
|
|
protected $parallel = true; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var bool |
36
|
|
|
*/ |
37
|
|
|
protected $global = false; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var IArgument[] |
41
|
|
|
*/ |
42
|
|
|
protected $arguments = []; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var IOption[] |
46
|
|
|
*/ |
47
|
|
|
protected $options = []; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var mixed |
51
|
|
|
*/ |
52
|
|
|
protected $handler; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Command constructor. |
56
|
|
|
* |
57
|
|
|
* @param string $name |
58
|
|
|
* @param null $description |
59
|
|
|
*/ |
60
|
|
|
public function __construct($name = null, $description = null) { |
61
|
|
|
$this->setName($name); |
62
|
|
|
$this->setDescription($description); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @return string |
67
|
|
|
*/ |
68
|
|
|
public function getName() { |
69
|
|
|
return $this->name; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @param string $name |
74
|
|
|
* |
75
|
|
|
* @return ICommand |
76
|
|
|
*/ |
77
|
|
|
public function setName($name) { |
78
|
|
|
$this->name = $name; |
79
|
|
|
|
80
|
|
|
return $this; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @return string |
85
|
|
|
*/ |
86
|
|
|
public function getDescription() { |
87
|
|
|
return $this->description; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* @param string $description |
92
|
|
|
* |
93
|
|
|
* @return ICommand |
94
|
|
|
*/ |
95
|
|
|
public function setDescription($description) { |
96
|
|
|
$this->description = $description; |
97
|
|
|
|
98
|
|
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @return string |
103
|
|
|
*/ |
104
|
|
|
public function getHelp() { |
105
|
|
|
return $this->help; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @param string $help |
110
|
|
|
* |
111
|
|
|
* @return ICommand |
112
|
|
|
*/ |
113
|
|
|
public function setHelp($help) { |
114
|
|
|
$this->help = $help; |
115
|
|
|
|
116
|
|
|
return $this; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* @return bool |
121
|
|
|
*/ |
122
|
|
|
public function isParallel() { |
123
|
|
|
return $this->parallel; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @param bool $parallel |
128
|
|
|
* |
129
|
|
|
* @return ICommand |
130
|
|
|
*/ |
131
|
|
|
public function setParallel($parallel) { |
132
|
|
|
$this->parallel = $parallel; |
133
|
|
|
|
134
|
|
|
return $this; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @return bool |
139
|
|
|
*/ |
140
|
|
|
public function isHidden() { |
141
|
|
|
return $this->hidden; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* @param bool $hidden |
146
|
|
|
* |
147
|
|
|
* @return ICommand |
148
|
|
|
*/ |
149
|
|
|
public function setHidden($hidden) { |
150
|
|
|
$this->hidden = $hidden; |
151
|
|
|
|
152
|
|
|
return $this; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* @return bool |
157
|
|
|
*/ |
158
|
|
|
public function isGlobal() { |
159
|
|
|
return $this->global; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* @param bool $global |
164
|
|
|
* |
165
|
|
|
* @return $this |
166
|
|
|
*/ |
167
|
|
|
public function setGlobal($global) { |
168
|
|
|
$this->global = $global; |
169
|
|
|
|
170
|
|
|
return $this; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param int $type |
175
|
|
|
* @param string $name |
176
|
|
|
* |
177
|
|
|
* @return IArgument |
178
|
|
|
*/ |
179
|
|
|
public function argument($type, $name) { |
180
|
|
|
$argument = new Argument($type, $name); |
181
|
|
|
$this->addArgument($argument); |
182
|
|
|
|
183
|
|
|
return $argument; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* @param IArgument $argument |
188
|
|
|
*/ |
189
|
|
|
public function addArgument(IArgument $argument) { |
190
|
|
|
$this->arguments[] = $argument; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @param IArgument[] $arguments |
195
|
|
|
*/ |
196
|
|
|
public function addArguments(array $arguments) { |
197
|
|
|
foreach ($arguments as $argument) { |
198
|
|
|
$this->addArgument($argument); |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @return IArgument[] |
204
|
|
|
*/ |
205
|
|
|
public function getArguments() { |
206
|
|
|
return $this->arguments; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* @param IArgument[] $arguments |
211
|
|
|
*/ |
212
|
|
|
public function setArguments(array $arguments) { |
213
|
|
|
$this->arguments = []; |
214
|
|
|
$this->addArguments($arguments); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* @param int $type |
219
|
|
|
* @param string $name |
220
|
|
|
* @param string $alias |
221
|
|
|
* |
222
|
|
|
* @return IOption |
223
|
|
|
*/ |
224
|
|
|
public function option($type, $name = null, $alias = null) { |
225
|
|
|
$option = new Option($type, $name, $alias); |
226
|
|
|
$this->addOption($option); |
227
|
|
|
|
228
|
|
|
return $option; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* @param IOption $option |
233
|
|
|
*/ |
234
|
|
|
public function addOption(IOption $option) { |
235
|
|
|
$this->options[] = $option; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* @param IOption[] $options |
240
|
|
|
*/ |
241
|
|
|
public function addOptions(array $options) { |
242
|
|
|
foreach ($options as $option) { |
243
|
|
|
$this->addOption($option); |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* @return IOption[] |
249
|
|
|
*/ |
250
|
|
|
public function getOptions() { |
251
|
|
|
return $this->options; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* @param IOption[] $options |
256
|
|
|
*/ |
257
|
|
|
public function setOptions(array $options) { |
258
|
|
|
$this->options = []; |
259
|
|
|
$this->addOptions($options); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param string $name |
264
|
|
|
* |
265
|
|
|
* @return IArgument |
266
|
|
|
* @throws ArgumentNotFoundException |
267
|
|
|
*/ |
268
|
|
|
public function findArgument($name) { |
269
|
|
|
foreach ($this->getArguments() as $argument) { |
270
|
|
|
if ($argument->getName() === $name) { |
271
|
|
|
return $argument; |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
throw new ArgumentNotFoundException(s( |
276
|
|
|
'Argument "%s" does not exist.', |
277
|
|
|
$name |
278
|
|
|
)); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* @param $nameOrOption |
283
|
|
|
* |
284
|
|
|
* @return IOption |
285
|
|
|
* @throws OptionNotFoundException |
286
|
|
|
*/ |
287
|
|
|
public function findOption($nameOrOption) { |
288
|
|
|
foreach ($this->getOptions() as $option) { |
289
|
|
|
if ($option->hasNameOrAlias($nameOrOption)) { |
290
|
|
|
return $option; |
291
|
|
|
} |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
throw new OptionNotFoundException(s( |
295
|
|
|
'Option "%s" does not exist.', |
296
|
|
|
$nameOrOption |
297
|
|
|
)); |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* @return mixed |
302
|
|
|
*/ |
303
|
|
|
public function getHandler() { |
304
|
|
|
return $this->handler; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* @param $handler |
309
|
|
|
* |
310
|
|
|
* @return ICommand |
311
|
|
|
*/ |
312
|
|
|
public function setHandler($handler) { |
313
|
|
|
$this->handler = $handler; |
314
|
|
|
|
315
|
|
|
return $this; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* @param array|null $argv |
320
|
|
|
* @param bool $strict |
321
|
|
|
* |
322
|
|
|
* @return array |
323
|
|
|
*/ |
324
|
|
View Code Duplication |
public function parseArgv(array $argv = null, $strict = true) { |
|
|
|
|
325
|
|
|
if ( ! is_array($argv)) { |
326
|
|
|
global $argv; |
|
|
|
|
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
return $this->parseArgs(array_slice($argv, 1), $strict); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* @param array $args |
334
|
|
|
* @param bool $strict |
335
|
|
|
* |
336
|
|
|
* @return array |
337
|
|
|
*/ |
338
|
|
|
public function parseArgs(array $args, $strict = true) { |
339
|
|
|
return $this->parseString(implode(' ', $args), $strict); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* @param $string |
344
|
|
|
* @param bool $strict |
345
|
|
|
* |
346
|
|
|
* @return array |
347
|
|
|
* @throws Exceptions\TooManyArgumentValuesException |
348
|
|
|
*/ |
349
|
|
View Code Duplication |
public function parseString($string, $strict = true) { |
|
|
|
|
350
|
|
|
$parser = new ArgumentsParser(); |
351
|
|
|
$matcher = new ArgumentsMatcher($parser); |
352
|
|
|
$args = $parser->parse($string); |
353
|
|
|
$args = $parser->group($args); |
354
|
|
|
|
355
|
|
|
return $matcher->matchCommand($this, $args, $strict); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Clone command and all of its arguments and options. |
360
|
|
|
*/ |
361
|
|
|
public function __clone() { |
362
|
|
|
$arguments = []; |
363
|
|
|
$options = []; |
364
|
|
|
|
365
|
|
|
foreach ($this->arguments as $key => $argument) { |
366
|
|
|
$arguments[$key] = clone $argument; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
foreach ($this->options as $key => $option) { |
370
|
|
|
$options[$key] = clone $option; |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
$this->arguments = $arguments; |
374
|
|
|
$this->options = $options; |
375
|
|
|
} |
376
|
|
|
} |
377
|
|
|
|
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.