InputOption.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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\Exception\InvalidArgumentException;
  12. use Symfony\Component\Console\Exception\LogicException;
  13. /**
  14. * Represents a command line option.
  15. *
  16. * @author Fabien Potencier <fabien@symfony.com>
  17. */
  18. class InputOption
  19. {
  20. public const VALUE_NONE = 1;
  21. public const VALUE_REQUIRED = 2;
  22. public const VALUE_OPTIONAL = 4;
  23. public const VALUE_IS_ARRAY = 8;
  24. private $name;
  25. private $shortcut;
  26. private $mode;
  27. private $default;
  28. private $description;
  29. /**
  30. * @param string $name The option name
  31. * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
  32. * @param int|null $mode The option mode: One of the VALUE_* constants
  33. * @param string $description A description text
  34. * @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
  35. *
  36. * @throws InvalidArgumentException If option mode is invalid or incompatible
  37. */
  38. public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
  39. {
  40. if (0 === strpos($name, '--')) {
  41. $name = substr($name, 2);
  42. }
  43. if (empty($name)) {
  44. throw new InvalidArgumentException('An option name cannot be empty.');
  45. }
  46. if (empty($shortcut)) {
  47. $shortcut = null;
  48. }
  49. if (null !== $shortcut) {
  50. if (\is_array($shortcut)) {
  51. $shortcut = implode('|', $shortcut);
  52. }
  53. $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
  54. $shortcuts = array_filter($shortcuts);
  55. $shortcut = implode('|', $shortcuts);
  56. if (empty($shortcut)) {
  57. throw new InvalidArgumentException('An option shortcut cannot be empty.');
  58. }
  59. }
  60. if (null === $mode) {
  61. $mode = self::VALUE_NONE;
  62. } elseif ($mode > 15 || $mode < 1) {
  63. throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
  64. }
  65. $this->name = $name;
  66. $this->shortcut = $shortcut;
  67. $this->mode = $mode;
  68. $this->description = $description;
  69. if ($this->isArray() && !$this->acceptValue()) {
  70. throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
  71. }
  72. $this->setDefault($default);
  73. }
  74. /**
  75. * Returns the option shortcut.
  76. *
  77. * @return string|null The shortcut
  78. */
  79. public function getShortcut()
  80. {
  81. return $this->shortcut;
  82. }
  83. /**
  84. * Returns the option name.
  85. *
  86. * @return string The name
  87. */
  88. public function getName()
  89. {
  90. return $this->name;
  91. }
  92. /**
  93. * Returns true if the option accepts a value.
  94. *
  95. * @return bool true if value mode is not self::VALUE_NONE, false otherwise
  96. */
  97. public function acceptValue()
  98. {
  99. return $this->isValueRequired() || $this->isValueOptional();
  100. }
  101. /**
  102. * Returns true if the option requires a value.
  103. *
  104. * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
  105. */
  106. public function isValueRequired()
  107. {
  108. return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
  109. }
  110. /**
  111. * Returns true if the option takes an optional value.
  112. *
  113. * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
  114. */
  115. public function isValueOptional()
  116. {
  117. return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
  118. }
  119. /**
  120. * Returns true if the option can take multiple values.
  121. *
  122. * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
  123. */
  124. public function isArray()
  125. {
  126. return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
  127. }
  128. /**
  129. * Sets the default value.
  130. *
  131. * @param string|string[]|bool|null $default The default value
  132. *
  133. * @throws LogicException When incorrect default value is given
  134. */
  135. public function setDefault($default = null)
  136. {
  137. if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
  138. throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
  139. }
  140. if ($this->isArray()) {
  141. if (null === $default) {
  142. $default = [];
  143. } elseif (!\is_array($default)) {
  144. throw new LogicException('A default value for an array option must be an array.');
  145. }
  146. }
  147. $this->default = $this->acceptValue() ? $default : false;
  148. }
  149. /**
  150. * Returns the default value.
  151. *
  152. * @return string|string[]|bool|null The default value
  153. */
  154. public function getDefault()
  155. {
  156. return $this->default;
  157. }
  158. /**
  159. * Returns the description text.
  160. *
  161. * @return string The description text
  162. */
  163. public function getDescription()
  164. {
  165. return $this->description;
  166. }
  167. /**
  168. * Checks whether the given option equals this one.
  169. *
  170. * @return bool
  171. */
  172. public function equals(self $option)
  173. {
  174. return $option->getName() === $this->getName()
  175. && $option->getShortcut() === $this->getShortcut()
  176. && $option->getDefault() === $this->getDefault()
  177. && $option->isArray() === $this->isArray()
  178. && $option->isValueRequired() === $this->isValueRequired()
  179. && $option->isValueOptional() === $this->isValueOptional()
  180. ;
  181. }
  182. }