summaryrefslogtreecommitdiff
path: root/vendor/symfony/console/Question
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
committerpolo <ordipolo@gmx.fr>2024-08-13 23:45:21 +0200
commitbf6655a534a6775d30cafa67bd801276bda1d98d (patch)
treec6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/symfony/console/Question
parent94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff)
downloadAppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/symfony/console/Question')
-rw-r--r--vendor/symfony/console/Question/ChoiceQuestion.php178
-rw-r--r--vendor/symfony/console/Question/ConfirmationQuestion.php57
-rw-r--r--vendor/symfony/console/Question/Question.php280
3 files changed, 515 insertions, 0 deletions
diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php
new file mode 100644
index 0000000..0ccad05
--- /dev/null
+++ b/vendor/symfony/console/Question/ChoiceQuestion.php
@@ -0,0 +1,178 @@
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;
15
16/**
17 * Represents a choice question.
18 *
19 * @author Fabien Potencier <fabien@symfony.com>
20 */
21class ChoiceQuestion extends Question
22{
23 private bool $multiselect = false;
24 private string $prompt = ' > ';
25 private string $errorMessage = 'Value "%s" is invalid';
26
27 /**
28 * @param string $question The question to ask to the user
29 * @param array $choices The list of available choices
30 * @param mixed $default The default answer to return
31 */
32 public function __construct(
33 string $question,
34 private array $choices,
35 mixed $default = null,
36 ) {
37 if (!$choices) {
38 throw new \LogicException('Choice question must have at least 1 choice available.');
39 }
40
41 parent::__construct($question, $default);
42
43 $this->setValidator($this->getDefaultValidator());
44 $this->setAutocompleterValues($choices);
45 }
46
47 /**
48 * Returns available choices.
49 */
50 public function getChoices(): array
51 {
52 return $this->choices;
53 }
54
55 /**
56 * Sets multiselect option.
57 *
58 * When multiselect is set to true, multiple choices can be answered.
59 *
60 * @return $this
61 */
62 public function setMultiselect(bool $multiselect): static
63 {
64 $this->multiselect = $multiselect;
65 $this->setValidator($this->getDefaultValidator());
66
67 return $this;
68 }
69
70 /**
71 * Returns whether the choices are multiselect.
72 */
73 public function isMultiselect(): bool
74 {
75 return $this->multiselect;
76 }
77
78 /**
79 * Gets the prompt for choices.
80 */
81 public function getPrompt(): string
82 {
83 return $this->prompt;
84 }
85
86 /**
87 * Sets the prompt for choices.
88 *
89 * @return $this
90 */
91 public function setPrompt(string $prompt): static
92 {
93 $this->prompt = $prompt;
94
95 return $this;
96 }
97
98 /**
99 * Sets the error message for invalid values.
100 *
101 * The error message has a string placeholder (%s) for the invalid value.
102 *
103 * @return $this
104 */
105 public function setErrorMessage(string $errorMessage): static
106 {
107 $this->errorMessage = $errorMessage;
108 $this->setValidator($this->getDefaultValidator());
109
110 return $this;
111 }
112
113 private function getDefaultValidator(): callable
114 {
115 $choices = $this->choices;
116 $errorMessage = $this->errorMessage;
117 $multiselect = $this->multiselect;
118 $isAssoc = $this->isAssoc($choices);
119
120 return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
121 if ($multiselect) {
122 // Check for a separated comma values
123 if (!preg_match('/^[^,]+(?:,[^,]+)*$/', (string) $selected, $matches)) {
124 throw new InvalidArgumentException(sprintf($errorMessage, $selected));
125 }
126
127 $selectedChoices = explode(',', (string) $selected);
128 } else {
129 $selectedChoices = [$selected];
130 }
131
132 if ($this->isTrimmable()) {
133 foreach ($selectedChoices as $k => $v) {
134 $selectedChoices[$k] = trim((string) $v);
135 }
136 }
137
138 $multiselectChoices = [];
139 foreach ($selectedChoices as $value) {
140 $results = [];
141 foreach ($choices as $key => $choice) {
142 if ($choice === $value) {
143 $results[] = $key;
144 }
145 }
146
147 if (\count($results) > 1) {
148 throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of "%s".', implode('" or "', $results)));
149 }
150
151 $result = array_search($value, $choices);
152
153 if (!$isAssoc) {
154 if (false !== $result) {
155 $result = $choices[$result];
156 } elseif (isset($choices[$value])) {
157 $result = $choices[$value];
158 }
159 } elseif (false === $result && isset($choices[$value])) {
160 $result = $value;
161 }
162
163 if (false === $result) {
164 throw new InvalidArgumentException(sprintf($errorMessage, $value));
165 }
166
167 // For associative choices, consistently return the key as string:
168 $multiselectChoices[] = $isAssoc ? (string) $result : $result;
169 }
170
171 if ($multiselect) {
172 return $multiselectChoices;
173 }
174
175 return current($multiselectChoices);
176 };
177 }
178}
diff --git a/vendor/symfony/console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Question/ConfirmationQuestion.php
new file mode 100644
index 0000000..951d681
--- /dev/null
+++ b/vendor/symfony/console/Question/ConfirmationQuestion.php
@@ -0,0 +1,57 @@
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
14/**
15 * Represents a yes/no question.
16 *
17 * @author Fabien Potencier <fabien@symfony.com>
18 */
19class ConfirmationQuestion extends Question
20{
21 /**
22 * @param string $question The question to ask to the user
23 * @param bool $default The default answer to return, true or false
24 * @param string $trueAnswerRegex A regex to match the "yes" answer
25 */
26 public function __construct(
27 string $question,
28 bool $default = true,
29 private string $trueAnswerRegex = '/^y/i',
30 ) {
31 parent::__construct($question, $default);
32
33 $this->setNormalizer($this->getDefaultNormalizer());
34 }
35
36 /**
37 * Returns the default answer normalizer.
38 */
39 private function getDefaultNormalizer(): callable
40 {
41 $default = $this->getDefault();
42 $regex = $this->trueAnswerRegex;
43
44 return function ($answer) use ($default, $regex) {
45 if (\is_bool($answer)) {
46 return $answer;
47 }
48
49 $answerIsTrue = (bool) preg_match($regex, $answer);
50 if (false === $default) {
51 return $answer && $answerIsTrue;
52 }
53
54 return '' === $answer || $answerIsTrue;
55 };
56 }
57}
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}