View file vendor/symfony/console/Question/Question.php

File size: 6.92Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\Console\Question;
  13.  
  14. use Symfony\Component\Console\Exception\InvalidArgumentException;
  15. use Symfony\Component\Console\Exception\LogicException;
  16.  
  17. /**
  18. * Represents a Question.
  19. *
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. */
  22. class Question
  23. {
  24. private $question;
  25. private $attempts;
  26. private $hidden = false;
  27. private $hiddenFallback = true;
  28. private $autocompleterCallback;
  29. private $validator;
  30. private $default;
  31. private $normalizer;
  32. private $trimmable = true;
  33. private $multiline = false;
  34.  
  35. /**
  36. * @param string $question The question to ask to the user
  37. * @param mixed $default The default answer to return if the user enters nothing
  38. */
  39. public function __construct(string $question, $default = null)
  40. {
  41. $this->question = $question;
  42. $this->default = $default;
  43. }
  44.  
  45. /**
  46. * Returns the question.
  47. *
  48. * @return string
  49. */
  50. public function getQuestion()
  51. {
  52. return $this->question;
  53. }
  54.  
  55. /**
  56. * Returns the default answer.
  57. *
  58. * @return mixed
  59. */
  60. public function getDefault()
  61. {
  62. return $this->default;
  63. }
  64.  
  65. /**
  66. * Returns whether the user response accepts newline characters.
  67. */
  68. public function isMultiline(): bool
  69. {
  70. return $this->multiline;
  71. }
  72.  
  73. /**
  74. * Sets whether the user response should accept newline characters.
  75. *
  76. * @return $this
  77. */
  78. public function setMultiline(bool $multiline): self
  79. {
  80. $this->multiline = $multiline;
  81.  
  82. return $this;
  83. }
  84.  
  85. /**
  86. * Returns whether the user response must be hidden.
  87. *
  88. * @return bool
  89. */
  90. public function isHidden()
  91. {
  92. return $this->hidden;
  93. }
  94.  
  95. /**
  96. * Sets whether the user response must be hidden or not.
  97. *
  98. * @param bool $hidden
  99. *
  100. * @return $this
  101. *
  102. * @throws LogicException In case the autocompleter is also used
  103. */
  104. public function setHidden($hidden)
  105. {
  106. if ($this->autocompleterCallback) {
  107. throw new LogicException('A hidden question cannot use the autocompleter.');
  108. }
  109.  
  110. $this->hidden = (bool) $hidden;
  111.  
  112. return $this;
  113. }
  114.  
  115. /**
  116. * In case the response can not be hidden, whether to fallback on non-hidden question or not.
  117. *
  118. * @return bool
  119. */
  120. public function isHiddenFallback()
  121. {
  122. return $this->hiddenFallback;
  123. }
  124.  
  125. /**
  126. * Sets whether to fallback on non-hidden question if the response can not be hidden.
  127. *
  128. * @param bool $fallback
  129. *
  130. * @return $this
  131. */
  132. public function setHiddenFallback($fallback)
  133. {
  134. $this->hiddenFallback = (bool) $fallback;
  135.  
  136. return $this;
  137. }
  138.  
  139. /**
  140. * Gets values for the autocompleter.
  141. *
  142. * @return iterable|null
  143. */
  144. public function getAutocompleterValues()
  145. {
  146. $callback = $this->getAutocompleterCallback();
  147.  
  148. return $callback ? $callback('') : null;
  149. }
  150.  
  151. /**
  152. * Sets values for the autocompleter.
  153. *
  154. * @return $this
  155. *
  156. * @throws LogicException
  157. */
  158. public function setAutocompleterValues(?iterable $values)
  159. {
  160. if (\is_array($values)) {
  161. $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
  162.  
  163. $callback = static function () use ($values) {
  164. return $values;
  165. };
  166. } elseif ($values instanceof \Traversable) {
  167. $valueCache = null;
  168. $callback = static function () use ($values, &$valueCache) {
  169. return $valueCache ?? $valueCache = iterator_to_array($values, false);
  170. };
  171. } else {
  172. $callback = null;
  173. }
  174.  
  175. return $this->setAutocompleterCallback($callback);
  176. }
  177.  
  178. /**
  179. * Gets the callback function used for the autocompleter.
  180. */
  181. public function getAutocompleterCallback(): ?callable
  182. {
  183. return $this->autocompleterCallback;
  184. }
  185.  
  186. /**
  187. * Sets the callback function used for the autocompleter.
  188. *
  189. * The callback is passed the user input as argument and should return an iterable of corresponding suggestions.
  190. *
  191. * @return $this
  192. */
  193. public function setAutocompleterCallback(callable $callback = null): self
  194. {
  195. if ($this->hidden && null !== $callback) {
  196. throw new LogicException('A hidden question cannot use the autocompleter.');
  197. }
  198.  
  199. $this->autocompleterCallback = $callback;
  200.  
  201. return $this;
  202. }
  203.  
  204. /**
  205. * Sets a validator for the question.
  206. *
  207. * @return $this
  208. */
  209. public function setValidator(callable $validator = null)
  210. {
  211. $this->validator = $validator;
  212.  
  213. return $this;
  214. }
  215.  
  216. /**
  217. * Gets the validator for the question.
  218. *
  219. * @return callable|null
  220. */
  221. public function getValidator()
  222. {
  223. return $this->validator;
  224. }
  225.  
  226. /**
  227. * Sets the maximum number of attempts.
  228. *
  229. * Null means an unlimited number of attempts.
  230. *
  231. * @return $this
  232. *
  233. * @throws InvalidArgumentException in case the number of attempts is invalid
  234. */
  235. public function setMaxAttempts(?int $attempts)
  236. {
  237. if (null !== $attempts) {
  238. $attempts = (int) $attempts;
  239. if ($attempts < 1) {
  240. throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
  241. }
  242. }
  243.  
  244. $this->attempts = $attempts;
  245.  
  246. return $this;
  247. }
  248.  
  249. /**
  250. * Gets the maximum number of attempts.
  251. *
  252. * Null means an unlimited number of attempts.
  253. *
  254. * @return int|null
  255. */
  256. public function getMaxAttempts()
  257. {
  258. return $this->attempts;
  259. }
  260.  
  261. /**
  262. * Sets a normalizer for the response.
  263. *
  264. * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
  265. *
  266. * @return $this
  267. */
  268. public function setNormalizer(callable $normalizer)
  269. {
  270. $this->normalizer = $normalizer;
  271.  
  272. return $this;
  273. }
  274.  
  275. /**
  276. * Gets the normalizer for the response.
  277. *
  278. * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
  279. *
  280. * @return callable|null
  281. */
  282. public function getNormalizer()
  283. {
  284. return $this->normalizer;
  285. }
  286.  
  287. protected function isAssoc(array $array)
  288. {
  289. return (bool) \count(array_filter(array_keys($array), 'is_string'));
  290. }
  291.  
  292. public function isTrimmable(): bool
  293. {
  294. return $this->trimmable;
  295. }
  296.  
  297. /**
  298. * @return $this
  299. */
  300. public function setTrimmable(bool $trimmable): self
  301. {
  302. $this->trimmable = $trimmable;
  303.  
  304. return $this;
  305. }
  306. }