Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Console\Input; Chris@0: Chris@0: use Symfony\Component\Console\Exception\InvalidArgumentException; Chris@0: use Symfony\Component\Console\Exception\LogicException; Chris@0: Chris@0: /** Chris@0: * A InputDefinition represents a set of valid command line arguments and options. Chris@0: * Chris@0: * Usage: Chris@0: * Chris@17: * $definition = new InputDefinition([ Chris@17: * new InputArgument('name', InputArgument::REQUIRED), Chris@17: * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED), Chris@17: * ]); Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: */ Chris@0: class InputDefinition Chris@0: { Chris@0: private $arguments; Chris@0: private $requiredCount; Chris@0: private $hasAnArrayArgument = false; Chris@0: private $hasOptional; Chris@0: private $options; Chris@0: private $shortcuts; Chris@0: Chris@0: /** Chris@0: * @param array $definition An array of InputArgument and InputOption instance Chris@0: */ Chris@17: public function __construct(array $definition = []) Chris@0: { Chris@0: $this->setDefinition($definition); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the definition of the input. Chris@0: */ Chris@0: public function setDefinition(array $definition) Chris@0: { Chris@17: $arguments = []; Chris@17: $options = []; Chris@0: foreach ($definition as $item) { Chris@0: if ($item instanceof InputOption) { Chris@0: $options[] = $item; Chris@0: } else { Chris@0: $arguments[] = $item; Chris@0: } Chris@0: } Chris@0: Chris@0: $this->setArguments($arguments); Chris@0: $this->setOptions($options); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the InputArgument objects. Chris@0: * Chris@0: * @param InputArgument[] $arguments An array of InputArgument objects Chris@0: */ Chris@17: public function setArguments($arguments = []) Chris@0: { Chris@17: $this->arguments = []; Chris@0: $this->requiredCount = 0; Chris@0: $this->hasOptional = false; Chris@0: $this->hasAnArrayArgument = false; Chris@0: $this->addArguments($arguments); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an array of InputArgument objects. Chris@0: * Chris@0: * @param InputArgument[] $arguments An array of InputArgument objects Chris@0: */ Chris@17: public function addArguments($arguments = []) Chris@0: { Chris@0: if (null !== $arguments) { Chris@0: foreach ($arguments as $argument) { Chris@0: $this->addArgument($argument); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * @throws LogicException When incorrect argument is given Chris@0: */ Chris@0: public function addArgument(InputArgument $argument) Chris@0: { Chris@0: if (isset($this->arguments[$argument->getName()])) { Chris@0: throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); Chris@0: } Chris@0: Chris@0: if ($this->hasAnArrayArgument) { Chris@0: throw new LogicException('Cannot add an argument after an array argument.'); Chris@0: } Chris@0: Chris@0: if ($argument->isRequired() && $this->hasOptional) { Chris@0: throw new LogicException('Cannot add a required argument after an optional one.'); Chris@0: } Chris@0: Chris@0: if ($argument->isArray()) { Chris@0: $this->hasAnArrayArgument = true; Chris@0: } Chris@0: Chris@0: if ($argument->isRequired()) { Chris@0: ++$this->requiredCount; Chris@0: } else { Chris@0: $this->hasOptional = true; Chris@0: } Chris@0: Chris@0: $this->arguments[$argument->getName()] = $argument; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns an InputArgument by name or by position. Chris@0: * Chris@0: * @param string|int $name The InputArgument name or position Chris@0: * Chris@0: * @return InputArgument An InputArgument object Chris@0: * Chris@0: * @throws InvalidArgumentException When argument given doesn't exist Chris@0: */ Chris@0: public function getArgument($name) Chris@0: { Chris@0: if (!$this->hasArgument($name)) { Chris@0: throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); Chris@0: } Chris@0: Chris@17: $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; Chris@0: Chris@0: return $arguments[$name]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns true if an InputArgument object exists by name or position. Chris@0: * Chris@0: * @param string|int $name The InputArgument name or position Chris@0: * Chris@0: * @return bool true if the InputArgument object exists, false otherwise Chris@0: */ Chris@0: public function hasArgument($name) Chris@0: { Chris@17: $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; Chris@0: Chris@0: return isset($arguments[$name]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the array of InputArgument objects. Chris@0: * Chris@0: * @return InputArgument[] An array of InputArgument objects Chris@0: */ Chris@0: public function getArguments() Chris@0: { Chris@0: return $this->arguments; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the number of InputArguments. Chris@0: * Chris@0: * @return int The number of InputArguments Chris@0: */ Chris@0: public function getArgumentCount() Chris@0: { Chris@17: return $this->hasAnArrayArgument ? PHP_INT_MAX : \count($this->arguments); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the number of required InputArguments. Chris@0: * Chris@0: * @return int The number of required InputArguments Chris@0: */ Chris@0: public function getArgumentRequiredCount() Chris@0: { Chris@0: return $this->requiredCount; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the default values. Chris@0: * Chris@0: * @return array An array of default values Chris@0: */ Chris@0: public function getArgumentDefaults() Chris@0: { Chris@17: $values = []; Chris@0: foreach ($this->arguments as $argument) { Chris@0: $values[$argument->getName()] = $argument->getDefault(); Chris@0: } Chris@0: Chris@0: return $values; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the InputOption objects. Chris@0: * Chris@0: * @param InputOption[] $options An array of InputOption objects Chris@0: */ Chris@17: public function setOptions($options = []) Chris@0: { Chris@17: $this->options = []; Chris@17: $this->shortcuts = []; Chris@0: $this->addOptions($options); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an array of InputOption objects. Chris@0: * Chris@0: * @param InputOption[] $options An array of InputOption objects Chris@0: */ Chris@17: public function addOptions($options = []) Chris@0: { Chris@0: foreach ($options as $option) { Chris@0: $this->addOption($option); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * @throws LogicException When option given already exist Chris@0: */ Chris@0: public function addOption(InputOption $option) Chris@0: { Chris@0: if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { Chris@0: throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName())); Chris@0: } Chris@0: Chris@0: if ($option->getShortcut()) { Chris@0: foreach (explode('|', $option->getShortcut()) as $shortcut) { Chris@0: if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { Chris@0: throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: $this->options[$option->getName()] = $option; Chris@0: if ($option->getShortcut()) { Chris@0: foreach (explode('|', $option->getShortcut()) as $shortcut) { Chris@0: $this->shortcuts[$shortcut] = $option->getName(); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns an InputOption by name. Chris@0: * Chris@0: * @param string $name The InputOption name Chris@0: * Chris@0: * @return InputOption A InputOption object Chris@0: * Chris@0: * @throws InvalidArgumentException When option given doesn't exist Chris@0: */ Chris@0: public function getOption($name) Chris@0: { Chris@0: if (!$this->hasOption($name)) { Chris@0: throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); Chris@0: } Chris@0: Chris@0: return $this->options[$name]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns true if an InputOption object exists by name. Chris@0: * Chris@0: * This method can't be used to check if the user included the option when Chris@0: * executing the command (use getOption() instead). Chris@0: * Chris@0: * @param string $name The InputOption name Chris@0: * Chris@0: * @return bool true if the InputOption object exists, false otherwise Chris@0: */ Chris@0: public function hasOption($name) Chris@0: { Chris@0: return isset($this->options[$name]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the array of InputOption objects. Chris@0: * Chris@0: * @return InputOption[] An array of InputOption objects Chris@0: */ Chris@0: public function getOptions() Chris@0: { Chris@0: return $this->options; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns true if an InputOption object exists by shortcut. Chris@0: * Chris@0: * @param string $name The InputOption shortcut Chris@0: * Chris@0: * @return bool true if the InputOption object exists, false otherwise Chris@0: */ Chris@0: public function hasShortcut($name) Chris@0: { Chris@0: return isset($this->shortcuts[$name]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets an InputOption by shortcut. Chris@0: * Chris@14: * @param string $shortcut The Shortcut name Chris@0: * Chris@0: * @return InputOption An InputOption object Chris@0: */ Chris@0: public function getOptionForShortcut($shortcut) Chris@0: { Chris@0: return $this->getOption($this->shortcutToName($shortcut)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets an array of default values. Chris@0: * Chris@0: * @return array An array of all default values Chris@0: */ Chris@0: public function getOptionDefaults() Chris@0: { Chris@17: $values = []; Chris@0: foreach ($this->options as $option) { Chris@0: $values[$option->getName()] = $option->getDefault(); Chris@0: } Chris@0: Chris@0: return $values; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the InputOption name given a shortcut. Chris@0: * Chris@0: * @param string $shortcut The shortcut Chris@0: * Chris@0: * @return string The InputOption name Chris@0: * Chris@0: * @throws InvalidArgumentException When option given does not exist Chris@18: * Chris@18: * @internal Chris@0: */ Chris@18: public function shortcutToName($shortcut) Chris@0: { Chris@0: if (!isset($this->shortcuts[$shortcut])) { Chris@0: throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); Chris@0: } Chris@0: Chris@0: return $this->shortcuts[$shortcut]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the synopsis. Chris@0: * Chris@0: * @param bool $short Whether to return the short version (with options folded) or not Chris@0: * Chris@0: * @return string The synopsis Chris@0: */ Chris@0: public function getSynopsis($short = false) Chris@0: { Chris@17: $elements = []; Chris@0: Chris@0: if ($short && $this->getOptions()) { Chris@0: $elements[] = '[options]'; Chris@0: } elseif (!$short) { Chris@0: foreach ($this->getOptions() as $option) { Chris@0: $value = ''; Chris@0: if ($option->acceptValue()) { Chris@0: $value = sprintf( Chris@0: ' %s%s%s', Chris@0: $option->isValueOptional() ? '[' : '', Chris@0: strtoupper($option->getName()), Chris@0: $option->isValueOptional() ? ']' : '' Chris@0: ); Chris@0: } Chris@0: Chris@0: $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; Chris@0: $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value); Chris@0: } Chris@0: } Chris@0: Chris@17: if (\count($elements) && $this->getArguments()) { Chris@0: $elements[] = '[--]'; Chris@0: } Chris@0: Chris@0: foreach ($this->getArguments() as $argument) { Chris@0: $element = '<'.$argument->getName().'>'; Chris@0: if (!$argument->isRequired()) { Chris@0: $element = '['.$element.']'; Chris@0: } elseif ($argument->isArray()) { Chris@17: $element .= ' ('.$element.')'; Chris@0: } Chris@0: Chris@0: if ($argument->isArray()) { Chris@0: $element .= '...'; Chris@0: } Chris@0: Chris@0: $elements[] = $element; Chris@0: } Chris@0: Chris@0: return implode(' ', $elements); Chris@0: } Chris@0: }