Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / symfony / console / Symfony / Component / 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 /**
15  * A InputDefinition represents a set of valid command line arguments and options.
16  *
17  * Usage:
18  *
19  *     $definition = new InputDefinition(array(
20  *       new InputArgument('name', InputArgument::REQUIRED),
21  *       new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
22  *     ));
23  *
24  * @author Fabien Potencier <fabien@symfony.com>
25  *
26  * @api
27  */
28 class InputDefinition
29 {
30     private $arguments;
31     private $requiredCount;
32     private $hasAnArrayArgument = false;
33     private $hasOptional;
34     private $options;
35     private $shortcuts;
36
37     /**
38      * Constructor.
39      *
40      * @param array $definition An array of InputArgument and InputOption instance
41      *
42      * @api
43      */
44     public function __construct(array $definition = array())
45     {
46         $this->setDefinition($definition);
47     }
48
49     /**
50      * Sets the definition of the input.
51      *
52      * @param array $definition The definition array
53      *
54      * @api
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 array $arguments An array of InputArgument objects
76      *
77      * @api
78      */
79     public function setArguments($arguments = array())
80     {
81         $this->arguments          = array();
82         $this->requiredCount      = 0;
83         $this->hasOptional        = false;
84         $this->hasAnArrayArgument = false;
85         $this->addArguments($arguments);
86     }
87
88     /**
89      * Adds an array of InputArgument objects.
90      *
91      * @param InputArgument[] $arguments An array of InputArgument objects
92      *
93      * @api
94      */
95     public function addArguments($arguments = array())
96     {
97         if (null !== $arguments) {
98             foreach ($arguments as $argument) {
99                 $this->addArgument($argument);
100             }
101         }
102     }
103
104     /**
105      * Adds an InputArgument object.
106      *
107      * @param InputArgument $argument An InputArgument object
108      *
109      * @throws \LogicException When incorrect argument is given
110      *
111      * @api
112      */
113     public function addArgument(InputArgument $argument)
114     {
115         if (isset($this->arguments[$argument->getName()])) {
116             throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
117         }
118
119         if ($this->hasAnArrayArgument) {
120             throw new \LogicException('Cannot add an argument after an array argument.');
121         }
122
123         if ($argument->isRequired() && $this->hasOptional) {
124             throw new \LogicException('Cannot add a required argument after an optional one.');
125         }
126
127         if ($argument->isArray()) {
128             $this->hasAnArrayArgument = true;
129         }
130
131         if ($argument->isRequired()) {
132             ++$this->requiredCount;
133         } else {
134             $this->hasOptional = true;
135         }
136
137         $this->arguments[$argument->getName()] = $argument;
138     }
139
140     /**
141      * Returns an InputArgument by name or by position.
142      *
143      * @param string|integer $name The InputArgument name or position
144      *
145      * @return InputArgument An InputArgument object
146      *
147      * @throws \InvalidArgumentException When argument given doesn't exist
148      *
149      * @api
150      */
151     public function getArgument($name)
152     {
153         $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
154
155         if (!$this->hasArgument($name)) {
156             throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
157         }
158
159         return $arguments[$name];
160     }
161
162     /**
163      * Returns true if an InputArgument object exists by name or position.
164      *
165      * @param string|integer $name The InputArgument name or position
166      *
167      * @return Boolean true if the InputArgument object exists, false otherwise
168      *
169      * @api
170      */
171     public function hasArgument($name)
172     {
173         $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
174
175         return isset($arguments[$name]);
176     }
177
178     /**
179      * Gets the array of InputArgument objects.
180      *
181      * @return array An array of InputArgument objects
182      *
183      * @api
184      */
185     public function getArguments()
186     {
187         return $this->arguments;
188     }
189
190     /**
191      * Returns the number of InputArguments.
192      *
193      * @return integer The number of InputArguments
194      */
195     public function getArgumentCount()
196     {
197         return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
198     }
199
200     /**
201      * Returns the number of required InputArguments.
202      *
203      * @return integer The number of required InputArguments
204      */
205     public function getArgumentRequiredCount()
206     {
207         return $this->requiredCount;
208     }
209
210     /**
211      * Gets the default values.
212      *
213      * @return array An array of default values
214      */
215     public function getArgumentDefaults()
216     {
217         $values = array();
218         foreach ($this->arguments as $argument) {
219             $values[$argument->getName()] = $argument->getDefault();
220         }
221
222         return $values;
223     }
224
225     /**
226      * Sets the InputOption objects.
227      *
228      * @param array $options An array of InputOption objects
229      *
230      * @api
231      */
232     public function setOptions($options = array())
233     {
234         $this->options = array();
235         $this->shortcuts = array();
236         $this->addOptions($options);
237     }
238
239     /**
240      * Adds an array of InputOption objects.
241      *
242      * @param InputOption[] $options An array of InputOption objects
243      *
244      * @api
245      */
246     public function addOptions($options = array())
247     {
248         foreach ($options as $option) {
249             $this->addOption($option);
250         }
251     }
252
253     /**
254      * Adds an InputOption object.
255      *
256      * @param InputOption $option An InputOption object
257      *
258      * @throws \LogicException When option given already exist
259      *
260      * @api
261      */
262     public function addOption(InputOption $option)
263     {
264         if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
265             throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
266         } elseif (isset($this->shortcuts[$option->getShortcut()]) && !$option->equals($this->options[$this->shortcuts[$option->getShortcut()]])) {
267             throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $option->getShortcut()));
268         }
269
270         $this->options[$option->getName()] = $option;
271         if ($option->getShortcut()) {
272             $this->shortcuts[$option->getShortcut()] = $option->getName();
273         }
274     }
275
276     /**
277      * Returns an InputOption by name.
278      *
279      * @param string $name The InputOption name
280      *
281      * @return InputOption A InputOption object
282      *
283      * @throws \InvalidArgumentException When option given doesn't exist
284      *
285      * @api
286      */
287     public function getOption($name)
288     {
289         if (!$this->hasOption($name)) {
290             throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
291         }
292
293         return $this->options[$name];
294     }
295
296     /**
297      * Returns true if an InputOption object exists by name.
298      *
299      * @param string $name The InputOption name
300      *
301      * @return Boolean true if the InputOption object exists, false otherwise
302      *
303      * @api
304      */
305     public function hasOption($name)
306     {
307         return isset($this->options[$name]);
308     }
309
310     /**
311      * Gets the array of InputOption objects.
312      *
313      * @return array An array of InputOption objects
314      *
315      * @api
316      */
317     public function getOptions()
318     {
319         return $this->options;
320     }
321
322     /**
323      * Returns true if an InputOption object exists by shortcut.
324      *
325      * @param string $name The InputOption shortcut
326      *
327      * @return Boolean true if the InputOption object exists, false otherwise
328      */
329     public function hasShortcut($name)
330     {
331         return isset($this->shortcuts[$name]);
332     }
333
334     /**
335      * Gets an InputOption by shortcut.
336      *
337      * @param string $shortcut the Shortcut name
338      *
339      * @return InputOption An InputOption object
340      */
341     public function getOptionForShortcut($shortcut)
342     {
343         return $this->getOption($this->shortcutToName($shortcut));
344     }
345
346     /**
347      * Gets an array of default values.
348      *
349      * @return array An array of all default values
350      */
351     public function getOptionDefaults()
352     {
353         $values = array();
354         foreach ($this->options as $option) {
355             $values[$option->getName()] = $option->getDefault();
356         }
357
358         return $values;
359     }
360
361     /**
362      * Returns the InputOption name given a shortcut.
363      *
364      * @param string $shortcut The shortcut
365      *
366      * @return string The InputOption name
367      *
368      * @throws \InvalidArgumentException When option given does not exist
369      */
370     private function shortcutToName($shortcut)
371     {
372         if (!isset($this->shortcuts[$shortcut])) {
373             throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
374         }
375
376         return $this->shortcuts[$shortcut];
377     }
378
379     /**
380      * Gets the synopsis.
381      *
382      * @return string The synopsis
383      */
384     public function getSynopsis()
385     {
386         $elements = array();
387         foreach ($this->getOptions() as $option) {
388             $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
389             $elements[] = sprintf('['.($option->isValueRequired() ? '%s--%s="..."' : ($option->isValueOptional() ? '%s--%s[="..."]' : '%s--%s')).']', $shortcut, $option->getName());
390         }
391
392         foreach ($this->getArguments() as $argument) {
393             $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
394
395             if ($argument->isArray()) {
396                 $elements[] = sprintf('... [%sN]', $argument->getName());
397             }
398         }
399
400         return implode(' ', $elements);
401     }
402
403     /**
404      * Returns a textual representation of the InputDefinition.
405      *
406      * @return string A string representing the InputDefinition
407      */
408     public function asText()
409     {
410         // find the largest option or argument name
411         $max = 0;
412         foreach ($this->getOptions() as $option) {
413             $nameLength = strlen($option->getName()) + 2;
414             if ($option->getShortcut()) {
415                 $nameLength += strlen($option->getShortcut()) + 3;
416             }
417
418             $max = max($max, $nameLength);
419         }
420         foreach ($this->getArguments() as $argument) {
421             $max = max($max, strlen($argument->getName()));
422         }
423         ++$max;
424
425         $text = array();
426
427         if ($this->getArguments()) {
428             $text[] = '<comment>Arguments:</comment>';
429             foreach ($this->getArguments() as $argument) {
430                 if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
431                     $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($argument->getDefault()));
432                 } else {
433                     $default = '';
434                 }
435
436                 $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription());
437
438                 $text[] = sprintf(" <info>%-${max}s</info> %s%s", $argument->getName(), $description, $default);
439             }
440
441             $text[] = '';
442         }
443
444         if ($this->getOptions()) {
445             $text[] = '<comment>Options:</comment>';
446
447             foreach ($this->getOptions() as $option) {
448                 if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
449                     $default = sprintf('<comment> (default: %s)</comment>', $this->formatDefaultValue($option->getDefault()));
450                 } else {
451                     $default = '';
452                 }
453
454                 $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
455                 $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription());
456
457                 $optionMax = $max - strlen($option->getName()) - 2;
458                 $text[] = sprintf(" <info>%s</info> %-${optionMax}s%s%s%s",
459                     '--'.$option->getName(),
460                     $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
461                     $description,
462                     $default,
463                     $multiple
464                 );
465             }
466
467             $text[] = '';
468         }
469
470         return implode("\n", $text);
471     }
472
473     /**
474      * Returns an XML representation of the InputDefinition.
475      *
476      * @param Boolean $asDom Whether to return a DOM or an XML string
477      *
478      * @return string|DOMDocument An XML string representing the InputDefinition
479      */
480     public function asXml($asDom = false)
481     {
482         $dom = new \DOMDocument('1.0', 'UTF-8');
483         $dom->formatOutput = true;
484         $dom->appendChild($definitionXML = $dom->createElement('definition'));
485
486         $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
487         foreach ($this->getArguments() as $argument) {
488             $argumentsXML->appendChild($argumentXML = $dom->createElement('argument'));
489             $argumentXML->setAttribute('name', $argument->getName());
490             $argumentXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
491             $argumentXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
492             $argumentXML->appendChild($descriptionXML = $dom->createElement('description'));
493             $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
494
495             $argumentXML->appendChild($defaultsXML = $dom->createElement('defaults'));
496             $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
497             foreach ($defaults as $default) {
498                 $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
499                 $defaultXML->appendChild($dom->createTextNode($default));
500             }
501         }
502
503         $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
504         foreach ($this->getOptions() as $option) {
505             $optionsXML->appendChild($optionXML = $dom->createElement('option'));
506             $optionXML->setAttribute('name', '--'.$option->getName());
507             $optionXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
508             $optionXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
509             $optionXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
510             $optionXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
511             $optionXML->appendChild($descriptionXML = $dom->createElement('description'));
512             $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
513
514             if ($option->acceptValue()) {
515                 $optionXML->appendChild($defaultsXML = $dom->createElement('defaults'));
516                 $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
517                 foreach ($defaults as $default) {
518                     $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
519                     $defaultXML->appendChild($dom->createTextNode($default));
520                 }
521             }
522         }
523
524         return $asDom ? $dom : $dom->saveXml();
525     }
526
527     private function formatDefaultValue($default)
528     {
529         return json_encode($default);
530     }
531 }