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