InputArgument.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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\Command\Command;
  12. use Symfony\Component\Console\Completion\CompletionInput;
  13. use Symfony\Component\Console\Completion\CompletionSuggestions;
  14. use Symfony\Component\Console\Completion\Suggestion;
  15. use Symfony\Component\Console\Exception\InvalidArgumentException;
  16. use Symfony\Component\Console\Exception\LogicException;
  17. /**
  18. * Represents a command line argument.
  19. *
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. */
  22. class InputArgument
  23. {
  24. public const REQUIRED = 1;
  25. public const OPTIONAL = 2;
  26. public const IS_ARRAY = 4;
  27. /**
  28. * @var string
  29. */
  30. private $name;
  31. /**
  32. * @var int
  33. */
  34. private $mode;
  35. /**
  36. * @var string|int|bool|mixed[]|null|float
  37. */
  38. private $default;
  39. /**
  40. * @var mixed[]|\Closure
  41. */
  42. private $suggestedValues;
  43. /**
  44. * @var string
  45. */
  46. private $description;
  47. /**
  48. * @param string $name The argument name
  49. * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
  50. * @param string $description A description text
  51. * @param string|bool|int|float|mixed[] $default The default value (for self::OPTIONAL mode only)
  52. * @param array|\Closure(CompletionInput,CompletionSuggestions):list<string|Suggestion> $suggestedValues The values used for input completion
  53. *
  54. * @throws InvalidArgumentException When argument mode is not valid
  55. */
  56. public function __construct($name, $mode = null, $description = '', $default = null, $suggestedValues = [])
  57. {
  58. if (null === $mode) {
  59. $mode = self::OPTIONAL;
  60. } elseif ($mode > 7 || $mode < 1) {
  61. throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
  62. }
  63. $this->name = $name;
  64. $this->mode = $mode;
  65. $this->description = $description;
  66. $this->suggestedValues = $suggestedValues;
  67. $this->setDefault($default);
  68. }
  69. /**
  70. * Returns the argument name.
  71. */
  72. public function getName()
  73. {
  74. return $this->name;
  75. }
  76. /**
  77. * Returns true if the argument is required.
  78. *
  79. * @return bool true if parameter mode is self::REQUIRED, false otherwise
  80. */
  81. public function isRequired()
  82. {
  83. return self::REQUIRED === (self::REQUIRED & $this->mode);
  84. }
  85. /**
  86. * Returns true if the argument can take multiple values.
  87. *
  88. * @return bool true if mode is self::IS_ARRAY, false otherwise
  89. */
  90. public function isArray()
  91. {
  92. return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
  93. }
  94. /**
  95. * Sets the default value.
  96. *
  97. * @return void
  98. *
  99. * @throws LogicException When incorrect default value is given
  100. * @param string|bool|int|float|mixed[] $default
  101. */
  102. public function setDefault($default = null)
  103. {
  104. if (1 > \func_num_args()) {
  105. trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
  106. }
  107. if ($this->isRequired() && null !== $default) {
  108. throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
  109. }
  110. if ($this->isArray()) {
  111. if (null === $default) {
  112. $default = [];
  113. } elseif (!\is_array($default)) {
  114. throw new LogicException('A default value for an array argument must be an array.');
  115. }
  116. }
  117. $this->default = $default;
  118. }
  119. /**
  120. * Returns the default value.
  121. * @return string|bool|int|float|mixed[]|null
  122. */
  123. public function getDefault()
  124. {
  125. return $this->default;
  126. }
  127. public function hasCompletion()
  128. {
  129. return [] !== $this->suggestedValues;
  130. }
  131. /**
  132. * Adds suggestions to $suggestions for the current completion input.
  133. *
  134. * @see Command::complete()
  135. * @param \Symfony\Component\Console\Completion\CompletionInput $input
  136. * @param \Symfony\Component\Console\Completion\CompletionSuggestions $suggestions
  137. */
  138. public function complete($input, $suggestions)
  139. {
  140. $values = $this->suggestedValues;
  141. if ($values instanceof \Closure && !\is_array($values = $values($input))) {
  142. throw new LogicException(sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->name, get_debug_type($values)));
  143. }
  144. if ($values) {
  145. $suggestions->suggestValues($values);
  146. }
  147. }
  148. /**
  149. * Returns the description text.
  150. */
  151. public function getDescription()
  152. {
  153. return $this->description;
  154. }
  155. }