Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\Console\Input;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\Console\Exception\InvalidArgumentException;
|
Chris@0
|
15 use Symfony\Component\Console\Exception\LogicException;
|
Chris@0
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * A InputDefinition represents a set of valid command line arguments and options.
|
Chris@0
|
19 *
|
Chris@0
|
20 * Usage:
|
Chris@0
|
21 *
|
Chris@17
|
22 * $definition = new InputDefinition([
|
Chris@17
|
23 * new InputArgument('name', InputArgument::REQUIRED),
|
Chris@17
|
24 * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
|
Chris@17
|
25 * ]);
|
Chris@0
|
26 *
|
Chris@0
|
27 * @author Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
28 */
|
Chris@0
|
29 class InputDefinition
|
Chris@0
|
30 {
|
Chris@0
|
31 private $arguments;
|
Chris@0
|
32 private $requiredCount;
|
Chris@0
|
33 private $hasAnArrayArgument = false;
|
Chris@0
|
34 private $hasOptional;
|
Chris@0
|
35 private $options;
|
Chris@0
|
36 private $shortcuts;
|
Chris@0
|
37
|
Chris@0
|
38 /**
|
Chris@0
|
39 * @param array $definition An array of InputArgument and InputOption instance
|
Chris@0
|
40 */
|
Chris@17
|
41 public function __construct(array $definition = [])
|
Chris@0
|
42 {
|
Chris@0
|
43 $this->setDefinition($definition);
|
Chris@0
|
44 }
|
Chris@0
|
45
|
Chris@0
|
46 /**
|
Chris@0
|
47 * Sets the definition of the input.
|
Chris@0
|
48 */
|
Chris@0
|
49 public function setDefinition(array $definition)
|
Chris@0
|
50 {
|
Chris@17
|
51 $arguments = [];
|
Chris@17
|
52 $options = [];
|
Chris@0
|
53 foreach ($definition as $item) {
|
Chris@0
|
54 if ($item instanceof InputOption) {
|
Chris@0
|
55 $options[] = $item;
|
Chris@0
|
56 } else {
|
Chris@0
|
57 $arguments[] = $item;
|
Chris@0
|
58 }
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 $this->setArguments($arguments);
|
Chris@0
|
62 $this->setOptions($options);
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@0
|
65 /**
|
Chris@0
|
66 * Sets the InputArgument objects.
|
Chris@0
|
67 *
|
Chris@0
|
68 * @param InputArgument[] $arguments An array of InputArgument objects
|
Chris@0
|
69 */
|
Chris@17
|
70 public function setArguments($arguments = [])
|
Chris@0
|
71 {
|
Chris@17
|
72 $this->arguments = [];
|
Chris@0
|
73 $this->requiredCount = 0;
|
Chris@0
|
74 $this->hasOptional = false;
|
Chris@0
|
75 $this->hasAnArrayArgument = false;
|
Chris@0
|
76 $this->addArguments($arguments);
|
Chris@0
|
77 }
|
Chris@0
|
78
|
Chris@0
|
79 /**
|
Chris@0
|
80 * Adds an array of InputArgument objects.
|
Chris@0
|
81 *
|
Chris@0
|
82 * @param InputArgument[] $arguments An array of InputArgument objects
|
Chris@0
|
83 */
|
Chris@17
|
84 public function addArguments($arguments = [])
|
Chris@0
|
85 {
|
Chris@0
|
86 if (null !== $arguments) {
|
Chris@0
|
87 foreach ($arguments as $argument) {
|
Chris@0
|
88 $this->addArgument($argument);
|
Chris@0
|
89 }
|
Chris@0
|
90 }
|
Chris@0
|
91 }
|
Chris@0
|
92
|
Chris@0
|
93 /**
|
Chris@0
|
94 * @throws LogicException When incorrect argument is given
|
Chris@0
|
95 */
|
Chris@0
|
96 public function addArgument(InputArgument $argument)
|
Chris@0
|
97 {
|
Chris@0
|
98 if (isset($this->arguments[$argument->getName()])) {
|
Chris@0
|
99 throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
|
Chris@0
|
100 }
|
Chris@0
|
101
|
Chris@0
|
102 if ($this->hasAnArrayArgument) {
|
Chris@0
|
103 throw new LogicException('Cannot add an argument after an array argument.');
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 if ($argument->isRequired() && $this->hasOptional) {
|
Chris@0
|
107 throw new LogicException('Cannot add a required argument after an optional one.');
|
Chris@0
|
108 }
|
Chris@0
|
109
|
Chris@0
|
110 if ($argument->isArray()) {
|
Chris@0
|
111 $this->hasAnArrayArgument = true;
|
Chris@0
|
112 }
|
Chris@0
|
113
|
Chris@0
|
114 if ($argument->isRequired()) {
|
Chris@0
|
115 ++$this->requiredCount;
|
Chris@0
|
116 } else {
|
Chris@0
|
117 $this->hasOptional = true;
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 $this->arguments[$argument->getName()] = $argument;
|
Chris@0
|
121 }
|
Chris@0
|
122
|
Chris@0
|
123 /**
|
Chris@0
|
124 * Returns an InputArgument by name or by position.
|
Chris@0
|
125 *
|
Chris@0
|
126 * @param string|int $name The InputArgument name or position
|
Chris@0
|
127 *
|
Chris@0
|
128 * @return InputArgument An InputArgument object
|
Chris@0
|
129 *
|
Chris@0
|
130 * @throws InvalidArgumentException When argument given doesn't exist
|
Chris@0
|
131 */
|
Chris@0
|
132 public function getArgument($name)
|
Chris@0
|
133 {
|
Chris@0
|
134 if (!$this->hasArgument($name)) {
|
Chris@0
|
135 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@17
|
138 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
|
Chris@0
|
139
|
Chris@0
|
140 return $arguments[$name];
|
Chris@0
|
141 }
|
Chris@0
|
142
|
Chris@0
|
143 /**
|
Chris@0
|
144 * Returns true if an InputArgument object exists by name or position.
|
Chris@0
|
145 *
|
Chris@0
|
146 * @param string|int $name The InputArgument name or position
|
Chris@0
|
147 *
|
Chris@0
|
148 * @return bool true if the InputArgument object exists, false otherwise
|
Chris@0
|
149 */
|
Chris@0
|
150 public function hasArgument($name)
|
Chris@0
|
151 {
|
Chris@17
|
152 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
|
Chris@0
|
153
|
Chris@0
|
154 return isset($arguments[$name]);
|
Chris@0
|
155 }
|
Chris@0
|
156
|
Chris@0
|
157 /**
|
Chris@0
|
158 * Gets the array of InputArgument objects.
|
Chris@0
|
159 *
|
Chris@0
|
160 * @return InputArgument[] An array of InputArgument objects
|
Chris@0
|
161 */
|
Chris@0
|
162 public function getArguments()
|
Chris@0
|
163 {
|
Chris@0
|
164 return $this->arguments;
|
Chris@0
|
165 }
|
Chris@0
|
166
|
Chris@0
|
167 /**
|
Chris@0
|
168 * Returns the number of InputArguments.
|
Chris@0
|
169 *
|
Chris@0
|
170 * @return int The number of InputArguments
|
Chris@0
|
171 */
|
Chris@0
|
172 public function getArgumentCount()
|
Chris@0
|
173 {
|
Chris@17
|
174 return $this->hasAnArrayArgument ? PHP_INT_MAX : \count($this->arguments);
|
Chris@0
|
175 }
|
Chris@0
|
176
|
Chris@0
|
177 /**
|
Chris@0
|
178 * Returns the number of required InputArguments.
|
Chris@0
|
179 *
|
Chris@0
|
180 * @return int The number of required InputArguments
|
Chris@0
|
181 */
|
Chris@0
|
182 public function getArgumentRequiredCount()
|
Chris@0
|
183 {
|
Chris@0
|
184 return $this->requiredCount;
|
Chris@0
|
185 }
|
Chris@0
|
186
|
Chris@0
|
187 /**
|
Chris@0
|
188 * Gets the default values.
|
Chris@0
|
189 *
|
Chris@0
|
190 * @return array An array of default values
|
Chris@0
|
191 */
|
Chris@0
|
192 public function getArgumentDefaults()
|
Chris@0
|
193 {
|
Chris@17
|
194 $values = [];
|
Chris@0
|
195 foreach ($this->arguments as $argument) {
|
Chris@0
|
196 $values[$argument->getName()] = $argument->getDefault();
|
Chris@0
|
197 }
|
Chris@0
|
198
|
Chris@0
|
199 return $values;
|
Chris@0
|
200 }
|
Chris@0
|
201
|
Chris@0
|
202 /**
|
Chris@0
|
203 * Sets the InputOption objects.
|
Chris@0
|
204 *
|
Chris@0
|
205 * @param InputOption[] $options An array of InputOption objects
|
Chris@0
|
206 */
|
Chris@17
|
207 public function setOptions($options = [])
|
Chris@0
|
208 {
|
Chris@17
|
209 $this->options = [];
|
Chris@17
|
210 $this->shortcuts = [];
|
Chris@0
|
211 $this->addOptions($options);
|
Chris@0
|
212 }
|
Chris@0
|
213
|
Chris@0
|
214 /**
|
Chris@0
|
215 * Adds an array of InputOption objects.
|
Chris@0
|
216 *
|
Chris@0
|
217 * @param InputOption[] $options An array of InputOption objects
|
Chris@0
|
218 */
|
Chris@17
|
219 public function addOptions($options = [])
|
Chris@0
|
220 {
|
Chris@0
|
221 foreach ($options as $option) {
|
Chris@0
|
222 $this->addOption($option);
|
Chris@0
|
223 }
|
Chris@0
|
224 }
|
Chris@0
|
225
|
Chris@0
|
226 /**
|
Chris@0
|
227 * @throws LogicException When option given already exist
|
Chris@0
|
228 */
|
Chris@0
|
229 public function addOption(InputOption $option)
|
Chris@0
|
230 {
|
Chris@0
|
231 if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
|
Chris@0
|
232 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
|
Chris@0
|
233 }
|
Chris@0
|
234
|
Chris@0
|
235 if ($option->getShortcut()) {
|
Chris@0
|
236 foreach (explode('|', $option->getShortcut()) as $shortcut) {
|
Chris@0
|
237 if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
|
Chris@0
|
238 throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
|
Chris@0
|
239 }
|
Chris@0
|
240 }
|
Chris@0
|
241 }
|
Chris@0
|
242
|
Chris@0
|
243 $this->options[$option->getName()] = $option;
|
Chris@0
|
244 if ($option->getShortcut()) {
|
Chris@0
|
245 foreach (explode('|', $option->getShortcut()) as $shortcut) {
|
Chris@0
|
246 $this->shortcuts[$shortcut] = $option->getName();
|
Chris@0
|
247 }
|
Chris@0
|
248 }
|
Chris@0
|
249 }
|
Chris@0
|
250
|
Chris@0
|
251 /**
|
Chris@0
|
252 * Returns an InputOption by name.
|
Chris@0
|
253 *
|
Chris@0
|
254 * @param string $name The InputOption name
|
Chris@0
|
255 *
|
Chris@0
|
256 * @return InputOption A InputOption object
|
Chris@0
|
257 *
|
Chris@0
|
258 * @throws InvalidArgumentException When option given doesn't exist
|
Chris@0
|
259 */
|
Chris@0
|
260 public function getOption($name)
|
Chris@0
|
261 {
|
Chris@0
|
262 if (!$this->hasOption($name)) {
|
Chris@0
|
263 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
|
Chris@0
|
264 }
|
Chris@0
|
265
|
Chris@0
|
266 return $this->options[$name];
|
Chris@0
|
267 }
|
Chris@0
|
268
|
Chris@0
|
269 /**
|
Chris@0
|
270 * Returns true if an InputOption object exists by name.
|
Chris@0
|
271 *
|
Chris@0
|
272 * This method can't be used to check if the user included the option when
|
Chris@0
|
273 * executing the command (use getOption() instead).
|
Chris@0
|
274 *
|
Chris@0
|
275 * @param string $name The InputOption name
|
Chris@0
|
276 *
|
Chris@0
|
277 * @return bool true if the InputOption object exists, false otherwise
|
Chris@0
|
278 */
|
Chris@0
|
279 public function hasOption($name)
|
Chris@0
|
280 {
|
Chris@0
|
281 return isset($this->options[$name]);
|
Chris@0
|
282 }
|
Chris@0
|
283
|
Chris@0
|
284 /**
|
Chris@0
|
285 * Gets the array of InputOption objects.
|
Chris@0
|
286 *
|
Chris@0
|
287 * @return InputOption[] An array of InputOption objects
|
Chris@0
|
288 */
|
Chris@0
|
289 public function getOptions()
|
Chris@0
|
290 {
|
Chris@0
|
291 return $this->options;
|
Chris@0
|
292 }
|
Chris@0
|
293
|
Chris@0
|
294 /**
|
Chris@0
|
295 * Returns true if an InputOption object exists by shortcut.
|
Chris@0
|
296 *
|
Chris@0
|
297 * @param string $name The InputOption shortcut
|
Chris@0
|
298 *
|
Chris@0
|
299 * @return bool true if the InputOption object exists, false otherwise
|
Chris@0
|
300 */
|
Chris@0
|
301 public function hasShortcut($name)
|
Chris@0
|
302 {
|
Chris@0
|
303 return isset($this->shortcuts[$name]);
|
Chris@0
|
304 }
|
Chris@0
|
305
|
Chris@0
|
306 /**
|
Chris@0
|
307 * Gets an InputOption by shortcut.
|
Chris@0
|
308 *
|
Chris@14
|
309 * @param string $shortcut The Shortcut name
|
Chris@0
|
310 *
|
Chris@0
|
311 * @return InputOption An InputOption object
|
Chris@0
|
312 */
|
Chris@0
|
313 public function getOptionForShortcut($shortcut)
|
Chris@0
|
314 {
|
Chris@0
|
315 return $this->getOption($this->shortcutToName($shortcut));
|
Chris@0
|
316 }
|
Chris@0
|
317
|
Chris@0
|
318 /**
|
Chris@0
|
319 * Gets an array of default values.
|
Chris@0
|
320 *
|
Chris@0
|
321 * @return array An array of all default values
|
Chris@0
|
322 */
|
Chris@0
|
323 public function getOptionDefaults()
|
Chris@0
|
324 {
|
Chris@17
|
325 $values = [];
|
Chris@0
|
326 foreach ($this->options as $option) {
|
Chris@0
|
327 $values[$option->getName()] = $option->getDefault();
|
Chris@0
|
328 }
|
Chris@0
|
329
|
Chris@0
|
330 return $values;
|
Chris@0
|
331 }
|
Chris@0
|
332
|
Chris@0
|
333 /**
|
Chris@0
|
334 * Returns the InputOption name given a shortcut.
|
Chris@0
|
335 *
|
Chris@0
|
336 * @param string $shortcut The shortcut
|
Chris@0
|
337 *
|
Chris@0
|
338 * @return string The InputOption name
|
Chris@0
|
339 *
|
Chris@0
|
340 * @throws InvalidArgumentException When option given does not exist
|
Chris@18
|
341 *
|
Chris@18
|
342 * @internal
|
Chris@0
|
343 */
|
Chris@18
|
344 public function shortcutToName($shortcut)
|
Chris@0
|
345 {
|
Chris@0
|
346 if (!isset($this->shortcuts[$shortcut])) {
|
Chris@0
|
347 throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
|
Chris@0
|
348 }
|
Chris@0
|
349
|
Chris@0
|
350 return $this->shortcuts[$shortcut];
|
Chris@0
|
351 }
|
Chris@0
|
352
|
Chris@0
|
353 /**
|
Chris@0
|
354 * Gets the synopsis.
|
Chris@0
|
355 *
|
Chris@0
|
356 * @param bool $short Whether to return the short version (with options folded) or not
|
Chris@0
|
357 *
|
Chris@0
|
358 * @return string The synopsis
|
Chris@0
|
359 */
|
Chris@0
|
360 public function getSynopsis($short = false)
|
Chris@0
|
361 {
|
Chris@17
|
362 $elements = [];
|
Chris@0
|
363
|
Chris@0
|
364 if ($short && $this->getOptions()) {
|
Chris@0
|
365 $elements[] = '[options]';
|
Chris@0
|
366 } elseif (!$short) {
|
Chris@0
|
367 foreach ($this->getOptions() as $option) {
|
Chris@0
|
368 $value = '';
|
Chris@0
|
369 if ($option->acceptValue()) {
|
Chris@0
|
370 $value = sprintf(
|
Chris@0
|
371 ' %s%s%s',
|
Chris@0
|
372 $option->isValueOptional() ? '[' : '',
|
Chris@0
|
373 strtoupper($option->getName()),
|
Chris@0
|
374 $option->isValueOptional() ? ']' : ''
|
Chris@0
|
375 );
|
Chris@0
|
376 }
|
Chris@0
|
377
|
Chris@0
|
378 $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
|
Chris@0
|
379 $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
|
Chris@0
|
380 }
|
Chris@0
|
381 }
|
Chris@0
|
382
|
Chris@17
|
383 if (\count($elements) && $this->getArguments()) {
|
Chris@0
|
384 $elements[] = '[--]';
|
Chris@0
|
385 }
|
Chris@0
|
386
|
Chris@0
|
387 foreach ($this->getArguments() as $argument) {
|
Chris@0
|
388 $element = '<'.$argument->getName().'>';
|
Chris@0
|
389 if (!$argument->isRequired()) {
|
Chris@0
|
390 $element = '['.$element.']';
|
Chris@0
|
391 } elseif ($argument->isArray()) {
|
Chris@17
|
392 $element .= ' ('.$element.')';
|
Chris@0
|
393 }
|
Chris@0
|
394
|
Chris@0
|
395 if ($argument->isArray()) {
|
Chris@0
|
396 $element .= '...';
|
Chris@0
|
397 }
|
Chris@0
|
398
|
Chris@0
|
399 $elements[] = $element;
|
Chris@0
|
400 }
|
Chris@0
|
401
|
Chris@0
|
402 return implode(' ', $elements);
|
Chris@0
|
403 }
|
Chris@0
|
404 }
|