InputDefinition.php 12 KB

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