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