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;
14 use Symfony\Component\Console\Exception\InvalidArgumentException;
15 use Symfony\Component\Console\Exception\LogicException;
18 * A InputDefinition represents a set of valid command line arguments and options.
22 * $definition = new InputDefinition(array(
23 * new InputArgument('name', InputArgument::REQUIRED),
24 * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
27 * @author Fabien Potencier <fabien@symfony.com>
32 private $requiredCount;
33 private $hasAnArrayArgument = false;
41 * @param array $definition An array of InputArgument and InputOption instance
43 public function __construct(array $definition = array())
45 $this->setDefinition($definition);
49 * Sets the definition of the input.
51 * @param array $definition The definition array
53 public function setDefinition(array $definition)
57 foreach ($definition as $item) {
58 if ($item instanceof InputOption) {
65 $this->setArguments($arguments);
66 $this->setOptions($options);
70 * Sets the InputArgument objects.
72 * @param InputArgument[] $arguments An array of InputArgument objects
74 public function setArguments($arguments = array())
76 $this->arguments = array();
77 $this->requiredCount = 0;
78 $this->hasOptional = false;
79 $this->hasAnArrayArgument = false;
80 $this->addArguments($arguments);
84 * Adds an array of InputArgument objects.
86 * @param InputArgument[] $arguments An array of InputArgument objects
88 public function addArguments($arguments = array())
90 if (null !== $arguments) {
91 foreach ($arguments as $argument) {
92 $this->addArgument($argument);
98 * Adds an InputArgument object.
100 * @param InputArgument $argument An InputArgument object
102 * @throws LogicException When incorrect argument is given
104 public function addArgument(InputArgument $argument)
106 if (isset($this->arguments[$argument->getName()])) {
107 throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
110 if ($this->hasAnArrayArgument) {
111 throw new LogicException('Cannot add an argument after an array argument.');
114 if ($argument->isRequired() && $this->hasOptional) {
115 throw new LogicException('Cannot add a required argument after an optional one.');
118 if ($argument->isArray()) {
119 $this->hasAnArrayArgument = true;
122 if ($argument->isRequired()) {
123 ++$this->requiredCount;
125 $this->hasOptional = true;
128 $this->arguments[$argument->getName()] = $argument;
132 * Returns an InputArgument by name or by position.
134 * @param string|int $name The InputArgument name or position
136 * @return InputArgument An InputArgument object
138 * @throws InvalidArgumentException When argument given doesn't exist
140 public function getArgument($name)
142 if (!$this->hasArgument($name)) {
143 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
146 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
148 return $arguments[$name];
152 * Returns true if an InputArgument object exists by name or position.
154 * @param string|int $name The InputArgument name or position
156 * @return bool true if the InputArgument object exists, false otherwise
158 public function hasArgument($name)
160 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
162 return isset($arguments[$name]);
166 * Gets the array of InputArgument objects.
168 * @return InputArgument[] An array of InputArgument objects
170 public function getArguments()
172 return $this->arguments;
176 * Returns the number of InputArguments.
178 * @return int The number of InputArguments
180 public function getArgumentCount()
182 return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
186 * Returns the number of required InputArguments.
188 * @return int The number of required InputArguments
190 public function getArgumentRequiredCount()
192 return $this->requiredCount;
196 * Gets the default values.
198 * @return array An array of default values
200 public function getArgumentDefaults()
203 foreach ($this->arguments as $argument) {
204 $values[$argument->getName()] = $argument->getDefault();
211 * Sets the InputOption objects.
213 * @param InputOption[] $options An array of InputOption objects
215 public function setOptions($options = array())
217 $this->options = array();
218 $this->shortcuts = array();
219 $this->addOptions($options);
223 * Adds an array of InputOption objects.
225 * @param InputOption[] $options An array of InputOption objects
227 public function addOptions($options = array())
229 foreach ($options as $option) {
230 $this->addOption($option);
235 * Adds an InputOption object.
237 * @param InputOption $option An InputOption object
239 * @throws LogicException When option given already exist
241 public function addOption(InputOption $option)
243 if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
244 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
247 if ($option->getShortcut()) {
248 foreach (explode('|', $option->getShortcut()) as $shortcut) {
249 if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
250 throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
255 $this->options[$option->getName()] = $option;
256 if ($option->getShortcut()) {
257 foreach (explode('|', $option->getShortcut()) as $shortcut) {
258 $this->shortcuts[$shortcut] = $option->getName();
264 * Returns an InputOption by name.
266 * @param string $name The InputOption name
268 * @return InputOption A InputOption object
270 * @throws InvalidArgumentException When option given doesn't exist
272 public function getOption($name)
274 if (!$this->hasOption($name)) {
275 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
278 return $this->options[$name];
282 * Returns true if an InputOption object exists by name.
284 * This method can't be used to check if the user included the option when
285 * executing the command (use getOption() instead).
287 * @param string $name The InputOption name
289 * @return bool true if the InputOption object exists, false otherwise
291 public function hasOption($name)
293 return isset($this->options[$name]);
297 * Gets the array of InputOption objects.
299 * @return InputOption[] An array of InputOption objects
301 public function getOptions()
303 return $this->options;
307 * Returns true if an InputOption object exists by shortcut.
309 * @param string $name The InputOption shortcut
311 * @return bool true if the InputOption object exists, false otherwise
313 public function hasShortcut($name)
315 return isset($this->shortcuts[$name]);
319 * Gets an InputOption by shortcut.
321 * @param string $shortcut the Shortcut name
323 * @return InputOption An InputOption object
325 public function getOptionForShortcut($shortcut)
327 return $this->getOption($this->shortcutToName($shortcut));
331 * Gets an array of default values.
333 * @return array An array of all default values
335 public function getOptionDefaults()
338 foreach ($this->options as $option) {
339 $values[$option->getName()] = $option->getDefault();
346 * Returns the InputOption name given a shortcut.
348 * @param string $shortcut The shortcut
350 * @return string The InputOption name
352 * @throws InvalidArgumentException When option given does not exist
354 private function shortcutToName($shortcut)
356 if (!isset($this->shortcuts[$shortcut])) {
357 throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
360 return $this->shortcuts[$shortcut];
366 * @param bool $short Whether to return the short version (with options folded) or not
368 * @return string The synopsis
370 public function getSynopsis($short = false)
374 if ($short && $this->getOptions()) {
375 $elements[] = '[options]';
377 foreach ($this->getOptions() as $option) {
379 if ($option->acceptValue()) {
382 $option->isValueOptional() ? '[' : '',
383 strtoupper($option->getName()),
384 $option->isValueOptional() ? ']' : ''
388 $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
389 $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
393 if (count($elements) && $this->getArguments()) {
394 $elements[] = '[--]';
397 foreach ($this->getArguments() as $argument) {
398 $element = '<'.$argument->getName().'>';
399 if (!$argument->isRequired()) {
400 $element = '['.$element.']';
401 } elseif ($argument->isArray()) {
402 $element = $element.' ('.$element.')';
405 if ($argument->isArray()) {
409 $elements[] = $element;
412 return implode(' ', $elements);