12 namespace Symfony\Component\Console\Helper;
33 if ($triggerDeprecationError) {
34 @trigger_error(
'"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
53 public function select(
OutputInterface $output, $question, $choices, $default = null, $attempts =
false, $errorMessage =
'Value "%s" is invalid', $multiselect =
false)
55 $width = max(array_map(
'strlen', array_keys($choices)));
57 $messages = (array) $question;
58 foreach ($choices as $key => $value) {
59 $messages[] = sprintf(
" [<info>%-${width}s</info>] %s", $key, $value);
64 $result = $this->
askAndValidate($output,
'> ',
function ($picked) use ($choices, $errorMessage, $multiselect) {
66 $selectedChoices = str_replace(
' ',
'', $picked);
70 if (!preg_match(
'/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
71 throw new \InvalidArgumentException(sprintf($errorMessage, $picked));
73 $selectedChoices = explode(
',', $selectedChoices);
75 $selectedChoices = array($picked);
78 $multiselectChoices = array();
80 foreach ($selectedChoices as $value) {
81 if (empty($choices[$value])) {
82 throw new \InvalidArgumentException(sprintf($errorMessage, $value));
84 $multiselectChoices[] = $value;
88 return $multiselectChoices;
92 }, $attempts, $default);
111 if ($this->input && !$this->input->isInteractive()) {
115 $output->
write($question);
121 if (
false === $ret) {
122 throw new \RuntimeException(
'Aborted');
130 $matches = $autocomplete;
131 $numMatches = count($matches);
133 $sttyMode = shell_exec(
'stty -g');
136 shell_exec(
'stty -icanon -echo');
147 if (0 === $numMatches && 0 !== $i) {
150 $output->
write(
"\033[1D");
155 $matches = $autocomplete;
156 $numMatches = count($matches);
162 $ret = substr($ret, 0, $i);
163 }
elseif (
"\033" === $c) {
168 if (isset($c[2]) && (
'A' === $c[2] ||
'B' === $c[2])) {
169 if (
'A' === $c[2] && -1 === $ofs) {
173 if (0 === $numMatches) {
177 $ofs += (
'A' === $c[2]) ? -1 : 1;
178 $ofs = ($numMatches + $ofs) % $numMatches;
181 if (
"\t" === $c ||
"\n" === $c) {
182 if ($numMatches > 0 && -1 !== $ofs) {
183 $ret = $matches[$ofs];
185 $output->
write(substr($ret, $i));
206 foreach ($autocomplete as $value) {
208 if (0 === strpos($value, $ret) && $i !==
strlen($value)) {
209 $matches[$numMatches++] = $value;
215 $output->
write(
"\033[K");
217 if ($numMatches > 0 && -1 !== $ofs) {
219 $output->
write(
"\0337");
221 $output->
write(
'<hl>'.substr($matches[$ofs], $i).
'</hl>');
223 $output->
write(
"\0338");
228 shell_exec(sprintf(
'stty %s', $sttyMode));
231 return strlen($ret) > 0 ? $ret : $default;
248 while ($answer && !in_array(strtolower($answer[0]), array(
'y',
'n'))) {
249 $answer = $this->
ask($output, $question);
252 if (
false === $default) {
253 return $answer &&
'y' == strtolower($answer[0]);
256 return !$answer ||
'y' == strtolower($answer[0]);
272 if (
'\\' === DIRECTORY_SEPARATOR) {
273 $exe = __DIR__.
'/../Resources/bin/hiddeninput.exe';
276 if (
'phar:' === substr(__FILE__, 0, 5)) {
277 $tmpExe = sys_get_temp_dir().
'/hiddeninput.exe';
282 $output->
write($question);
283 $value = rtrim(shell_exec($exe));
286 if (isset($tmpExe)) {
294 $output->
write($question);
296 $sttyMode = shell_exec(
'stty -g');
298 shell_exec(
'stty -echo');
299 $value = fgets($this->inputStream ?: STDIN, 4096);
300 shell_exec(sprintf(
'stty %s', $sttyMode));
302 if (
false === $value) {
303 throw new \RuntimeException(
'Aborted');
306 $value = trim($value);
313 $output->
write($question);
314 $readCmd =
$shell ===
'csh' ?
'set mypassword = $<' :
'read -r mypassword';
315 $command = sprintf(
"/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'",
$shell, $readCmd);
316 $value = rtrim(shell_exec($command));
323 return $this->
ask($output, $question);
326 throw new \RuntimeException(
'Unable to hide the response');
351 $interviewer =
function () use ($output, $question, $default, $autocomplete, $that) {
352 return $that->ask($output, $question, $default, $autocomplete);
355 return $this->
validateAttempts($interviewer, $output, $validator, $attempts);
380 $interviewer =
function () use ($output, $question, $fallback, $that) {
381 return $that->askHiddenResponse($output, $question, $fallback);
384 return $this->
validateAttempts($interviewer, $output, $validator, $attempts);
396 $this->inputStream = $stream;
424 if (null !== self::$shell) {
428 self::$shell =
false;
430 if (file_exists(
'/usr/bin/env')) {
432 $test =
"/usr/bin/env %s -c 'echo OK' 2> /dev/null";
433 foreach (array(
'bash',
'zsh',
'ksh',
'csh') as $sh) {
434 if (
'OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
446 if (null !== self::$stty) {
450 exec(
'stty 2>&1', $output, $exitcode);
452 return self::$stty = $exitcode === 0;
470 while (
false === $attempts || $attempts--) {
472 $output->
writeln($this->
getHelperSet()->
get(
'formatter')->formatBlock($e->getMessage(),
'error'));
476 return call_user_func($validator, $interviewer());
477 }
catch (\Exception $e) {