4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Console\Input;
15 * A InputDefinition represents a set of valid command line arguments and options.
19 * $definition = new InputDefinition(array(
20 * new InputArgument('name', InputArgument::REQUIRED),
21 * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
24 * @author Fabien Potencier <fabien@symfony.com>
31 private $requiredCount;
32 private $hasAnArrayArgument = false;
40 * @param array $definition An array of InputArgument and InputOption instance
44 public function __construct(array $definition = array())
46 $this->setDefinition($definition);
50 * Sets the definition of the input.
52 * @param array $definition The definition array
56 public function setDefinition(array $definition)
60 foreach ($definition as $item) {
61 if ($item instanceof InputOption) {
68 $this->setArguments($arguments);
69 $this->setOptions($options);
73 * Sets the InputArgument objects.
75 * @param array $arguments An array of InputArgument objects
79 public function setArguments($arguments = array())
81 $this->arguments = array();
82 $this->requiredCount = 0;
83 $this->hasOptional = false;
84 $this->hasAnArrayArgument = false;
85 $this->addArguments($arguments);
89 * Adds an array of InputArgument objects.
91 * @param InputArgument[] $arguments An array of InputArgument objects
95 public function addArguments($arguments = array())
97 if (null !== $arguments) {
98 foreach ($arguments as $argument) {
99 $this->addArgument($argument);
105 * Adds an InputArgument object.
107 * @param InputArgument $argument An InputArgument object
109 * @throws \LogicException When incorrect argument is given
113 public function addArgument(InputArgument $argument)
115 if (isset($this->arguments[$argument->getName()])) {
116 throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
119 if ($this->hasAnArrayArgument) {
120 throw new \LogicException('Cannot add an argument after an array argument.');
123 if ($argument->isRequired() && $this->hasOptional) {
124 throw new \LogicException('Cannot add a required argument after an optional one.');
127 if ($argument->isArray()) {
128 $this->hasAnArrayArgument = true;
131 if ($argument->isRequired()) {
132 ++$this->requiredCount;
134 $this->hasOptional = true;
137 $this->arguments[$argument->getName()] = $argument;
141 * Returns an InputArgument by name or by position.
143 * @param string|integer $name The InputArgument name or position
145 * @return InputArgument An InputArgument object
147 * @throws \InvalidArgumentException When argument given doesn't exist
151 public function getArgument($name)
153 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
155 if (!$this->hasArgument($name)) {
156 throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
159 return $arguments[$name];
163 * Returns true if an InputArgument object exists by name or position.
165 * @param string|integer $name The InputArgument name or position
167 * @return Boolean true if the InputArgument object exists, false otherwise
171 public function hasArgument($name)
173 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
175 return isset($arguments[$name]);
179 * Gets the array of InputArgument objects.
181 * @return array An array of InputArgument objects
185 public function getArguments()
187 return $this->arguments;
191 * Returns the number of InputArguments.
193 * @return integer The number of InputArguments
195 public function getArgumentCount()
197 return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
201 * Returns the number of required InputArguments.
203 * @return integer The number of required InputArguments
205 public function getArgumentRequiredCount()
207 return $this->requiredCount;
211 * Gets the default values.
213 * @return array An array of default values
215 public function getArgumentDefaults()
218 foreach ($this->arguments as $argument) {
219 $values[$argument->getName()] = $argument->getDefault();
226 * Sets the InputOption objects.
228 * @param array $options An array of InputOption objects
232 public function setOptions($options = array())
234 $this->options = array();
235 $this->shortcuts = array();
236 $this->addOptions($options);
240 * Adds an array of InputOption objects.
242 * @param InputOption[] $options An array of InputOption objects
246 public function addOptions($options = array())
248 foreach ($options as $option) {
249 $this->addOption($option);
254 * Adds an InputOption object.
256 * @param InputOption $option An InputOption object
258 * @throws \LogicException When option given already exist
262 public function addOption(InputOption $option)
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()));
270 $this->options[$option->getName()] = $option;
271 if ($option->getShortcut()) {
272 $this->shortcuts[$option->getShortcut()] = $option->getName();
277 * Returns an InputOption by name.
279 * @param string $name The InputOption name
281 * @return InputOption A InputOption object
283 * @throws \InvalidArgumentException When option given doesn't exist
287 public function getOption($name)
289 if (!$this->hasOption($name)) {
290 throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
293 return $this->options[$name];
297 * Returns true if an InputOption object exists by name.
299 * @param string $name The InputOption name
301 * @return Boolean true if the InputOption object exists, false otherwise
305 public function hasOption($name)
307 return isset($this->options[$name]);
311 * Gets the array of InputOption objects.
313 * @return array An array of InputOption objects
317 public function getOptions()
319 return $this->options;
323 * Returns true if an InputOption object exists by shortcut.
325 * @param string $name The InputOption shortcut
327 * @return Boolean true if the InputOption object exists, false otherwise
329 public function hasShortcut($name)
331 return isset($this->shortcuts[$name]);
335 * Gets an InputOption by shortcut.
337 * @param string $shortcut the Shortcut name
339 * @return InputOption An InputOption object
341 public function getOptionForShortcut($shortcut)
343 return $this->getOption($this->shortcutToName($shortcut));
347 * Gets an array of default values.
349 * @return array An array of all default values
351 public function getOptionDefaults()
354 foreach ($this->options as $option) {
355 $values[$option->getName()] = $option->getDefault();
362 * Returns the InputOption name given a shortcut.
364 * @param string $shortcut The shortcut
366 * @return string The InputOption name
368 * @throws \InvalidArgumentException When option given does not exist
370 private function shortcutToName($shortcut)
372 if (!isset($this->shortcuts[$shortcut])) {
373 throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
376 return $this->shortcuts[$shortcut];
382 * @return string The synopsis
384 public function getSynopsis()
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());
392 foreach ($this->getArguments() as $argument) {
393 $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
395 if ($argument->isArray()) {
396 $elements[] = sprintf('... [%sN]', $argument->getName());
400 return implode(' ', $elements);
404 * Returns a textual representation of the InputDefinition.
406 * @return string A string representing the InputDefinition
408 public function asText()
410 // find the largest option or argument name
412 foreach ($this->getOptions() as $option) {
413 $nameLength = strlen($option->getName()) + 2;
414 if ($option->getShortcut()) {
415 $nameLength += strlen($option->getShortcut()) + 3;
418 $max = max($max, $nameLength);
420 foreach ($this->getArguments() as $argument) {
421 $max = max($max, strlen($argument->getName()));
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()));
436 $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription());
438 $text[] = sprintf(" <info>%-${max}s</info> %s%s", $argument->getName(), $description, $default);
444 if ($this->getOptions()) {
445 $text[] = '<comment>Options:</comment>';
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()));
454 $multiple = $option->isArray() ? '<comment> (multiple values allowed)</comment>' : '';
455 $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription());
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()) : '',
470 return implode("\n", $text);
474 * Returns an XML representation of the InputDefinition.
476 * @param Boolean $asDom Whether to return a DOM or an XML string
478 * @return string|DOMDocument An XML string representing the InputDefinition
480 public function asXml($asDom = false)
482 $dom = new \DOMDocument('1.0', 'UTF-8');
483 $dom->formatOutput = true;
484 $dom->appendChild($definitionXML = $dom->createElement('definition'));
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()));
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));
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()));
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));
524 return $asDom ? $dom : $dom->saveXml();
527 private function formatDefaultValue($default)
529 return json_encode($default);