[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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\Helper; 13 14 use Symfony\Component\Console\Exception\InvalidArgumentException; 15 use Symfony\Component\Console\Exception\RuntimeException; 16 use Symfony\Component\Console\Formatter\OutputFormatterStyle; 17 use Symfony\Component\Console\Output\ConsoleOutputInterface; 18 use Symfony\Component\Console\Output\OutputInterface; 19 20 /** 21 * The Dialog class provides helpers to interact with the user. 22 * 23 * @author Fabien Potencier <fabien@symfony.com> 24 * 25 * @deprecated since version 2.5, to be removed in 3.0. 26 * Use {@link \Symfony\Component\Console\Helper\QuestionHelper} instead. 27 */ 28 class DialogHelper extends InputAwareHelper 29 { 30 private $inputStream; 31 private static $shell; 32 private static $stty; 33 34 public function __construct($triggerDeprecationError = true) 35 { 36 if ($triggerDeprecationError) { 37 @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since Symfony 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED); 38 } 39 } 40 41 /** 42 * Asks the user to select a value. 43 * 44 * @param OutputInterface $output An Output instance 45 * @param string|array $question The question to ask 46 * @param array $choices List of choices to pick from 47 * @param bool|string $default The default answer if the user enters nothing 48 * @param bool|int $attempts Max number of times to ask before giving up (false by default, which means infinite) 49 * @param string $errorMessage Message which will be shown if invalid value from choice list would be picked 50 * @param bool $multiselect Select more than one value separated by comma 51 * 52 * @return int|string|array The selected value or values (the key of the choices array) 53 * 54 * @throws InvalidArgumentException 55 */ 56 public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false) 57 { 58 if ($output instanceof ConsoleOutputInterface) { 59 $output = $output->getErrorOutput(); 60 } 61 62 $width = max(array_map('strlen', array_keys($choices))); 63 64 $messages = (array) $question; 65 foreach ($choices as $key => $value) { 66 $messages[] = sprintf(" [<info>%-{$width}s</info>] %s", $key, $value); 67 } 68 69 $output->writeln($messages); 70 71 $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) { 72 // Collapse all spaces. 73 $selectedChoices = str_replace(' ', '', $picked); 74 75 if ($multiselect) { 76 // Check for a separated comma values 77 if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { 78 throw new InvalidArgumentException(sprintf($errorMessage, $picked)); 79 } 80 $selectedChoices = explode(',', $selectedChoices); 81 } else { 82 $selectedChoices = array($picked); 83 } 84 85 $multiselectChoices = array(); 86 87 foreach ($selectedChoices as $value) { 88 if (empty($choices[$value])) { 89 throw new InvalidArgumentException(sprintf($errorMessage, $value)); 90 } 91 $multiselectChoices[] = $value; 92 } 93 94 if ($multiselect) { 95 return $multiselectChoices; 96 } 97 98 return $picked; 99 }, $attempts, $default); 100 101 return $result; 102 } 103 104 /** 105 * Asks a question to the user. 106 * 107 * @param OutputInterface $output An Output instance 108 * @param string|array $question The question to ask 109 * @param string $default The default answer if none is given by the user 110 * @param array $autocomplete List of values to autocomplete 111 * 112 * @return string The user answer 113 * 114 * @throws RuntimeException If there is no data to read in the input stream 115 */ 116 public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) 117 { 118 if ($this->input && !$this->input->isInteractive()) { 119 return $default; 120 } 121 122 if ($output instanceof ConsoleOutputInterface) { 123 $output = $output->getErrorOutput(); 124 } 125 126 $output->write($question); 127 128 $inputStream = $this->inputStream ?: STDIN; 129 130 if (null === $autocomplete || !$this->hasSttyAvailable()) { 131 $ret = fgets($inputStream, 4096); 132 if (false === $ret) { 133 throw new RuntimeException('Aborted'); 134 } 135 $ret = trim($ret); 136 } else { 137 $ret = ''; 138 139 $i = 0; 140 $ofs = -1; 141 $matches = $autocomplete; 142 $numMatches = \count($matches); 143 144 $sttyMode = shell_exec('stty -g'); 145 146 // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) 147 shell_exec('stty -icanon -echo'); 148 149 // Add highlighted text style 150 $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); 151 152 // Read a keypress 153 while (!feof($inputStream)) { 154 $c = fread($inputStream, 1); 155 156 // Backspace Character 157 if ("\177" === $c) { 158 if (0 === $numMatches && 0 !== $i) { 159 --$i; 160 // Move cursor backwards 161 $output->write("\033[1D"); 162 } 163 164 if (0 === $i) { 165 $ofs = -1; 166 $matches = $autocomplete; 167 $numMatches = \count($matches); 168 } else { 169 $numMatches = 0; 170 } 171 172 // Pop the last character off the end of our string 173 $ret = substr($ret, 0, $i); 174 } elseif ("\033" === $c) { 175 // Did we read an escape sequence? 176 $c .= fread($inputStream, 2); 177 178 // A = Up Arrow. B = Down Arrow 179 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { 180 if ('A' === $c[2] && -1 === $ofs) { 181 $ofs = 0; 182 } 183 184 if (0 === $numMatches) { 185 continue; 186 } 187 188 $ofs += ('A' === $c[2]) ? -1 : 1; 189 $ofs = ($numMatches + $ofs) % $numMatches; 190 } 191 } elseif (\ord($c) < 32) { 192 if ("\t" === $c || "\n" === $c) { 193 if ($numMatches > 0 && -1 !== $ofs) { 194 $ret = $matches[$ofs]; 195 // Echo out remaining chars for current match 196 $output->write(substr($ret, $i)); 197 $i = \strlen($ret); 198 } 199 200 if ("\n" === $c) { 201 $output->write($c); 202 break; 203 } 204 205 $numMatches = 0; 206 } 207 208 continue; 209 } else { 210 $output->write($c); 211 $ret .= $c; 212 ++$i; 213 214 $numMatches = 0; 215 $ofs = 0; 216 217 foreach ($autocomplete as $value) { 218 // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) 219 if (0 === strpos($value, $ret) && $i !== \strlen($value)) { 220 $matches[$numMatches++] = $value; 221 } 222 } 223 } 224 225 // Erase characters from cursor to end of line 226 $output->write("\033[K"); 227 228 if ($numMatches > 0 && -1 !== $ofs) { 229 // Save cursor position 230 $output->write("\0337"); 231 // Write highlighted text 232 $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>'); 233 // Restore cursor position 234 $output->write("\0338"); 235 } 236 } 237 238 // Reset stty so it behaves normally again 239 shell_exec(sprintf('stty %s', $sttyMode)); 240 } 241 242 return \strlen($ret) > 0 ? $ret : $default; 243 } 244 245 /** 246 * Asks a confirmation to the user. 247 * 248 * The question will be asked until the user answers by nothing, yes, or no. 249 * 250 * @param OutputInterface $output An Output instance 251 * @param string|array $question The question to ask 252 * @param bool $default The default answer if the user enters nothing 253 * 254 * @return bool true if the user has confirmed, false otherwise 255 */ 256 public function askConfirmation(OutputInterface $output, $question, $default = true) 257 { 258 $answer = 'z'; 259 while ($answer && !\in_array(strtolower($answer[0]), array('y', 'n'))) { 260 $answer = $this->ask($output, $question); 261 } 262 263 if (false === $default) { 264 return $answer && 'y' == strtolower($answer[0]); 265 } 266 267 return !$answer || 'y' == strtolower($answer[0]); 268 } 269 270 /** 271 * Asks a question to the user, the response is hidden. 272 * 273 * @param OutputInterface $output An Output instance 274 * @param string|array $question The question 275 * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not 276 * 277 * @return string The answer 278 * 279 * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden 280 */ 281 public function askHiddenResponse(OutputInterface $output, $question, $fallback = true) 282 { 283 if ($output instanceof ConsoleOutputInterface) { 284 $output = $output->getErrorOutput(); 285 } 286 287 if ('\\' === \DIRECTORY_SEPARATOR) { 288 $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; 289 290 // handle code running from a phar 291 if ('phar:' === substr(__FILE__, 0, 5)) { 292 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; 293 copy($exe, $tmpExe); 294 $exe = $tmpExe; 295 } 296 297 $output->write($question); 298 $value = rtrim(shell_exec($exe)); 299 $output->writeln(''); 300 301 if (isset($tmpExe)) { 302 unlink($tmpExe); 303 } 304 305 return $value; 306 } 307 308 if ($this->hasSttyAvailable()) { 309 $output->write($question); 310 311 $sttyMode = shell_exec('stty -g'); 312 313 shell_exec('stty -echo'); 314 $value = fgets($this->inputStream ?: STDIN, 4096); 315 shell_exec(sprintf('stty %s', $sttyMode)); 316 317 if (false === $value) { 318 throw new RuntimeException('Aborted'); 319 } 320 321 $value = trim($value); 322 $output->writeln(''); 323 324 return $value; 325 } 326 327 if (false !== $shell = $this->getShell()) { 328 $output->write($question); 329 $readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword'; 330 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); 331 $value = rtrim(shell_exec($command)); 332 $output->writeln(''); 333 334 return $value; 335 } 336 337 if ($fallback) { 338 return $this->ask($output, $question); 339 } 340 341 throw new RuntimeException('Unable to hide the response'); 342 } 343 344 /** 345 * Asks for a value and validates the response. 346 * 347 * The validator receives the data to validate. It must return the 348 * validated data when the data is valid and throw an exception 349 * otherwise. 350 * 351 * @param OutputInterface $output An Output instance 352 * @param string|array $question The question to ask 353 * @param callable $validator A PHP callback 354 * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite) 355 * @param string $default The default answer if none is given by the user 356 * @param array $autocomplete List of values to autocomplete 357 * 358 * @return mixed 359 * 360 * @throws \Exception When any of the validators return an error 361 */ 362 public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null) 363 { 364 $that = $this; 365 366 $interviewer = function () use ($output, $question, $default, $autocomplete, $that) { 367 return $that->ask($output, $question, $default, $autocomplete); 368 }; 369 370 return $this->validateAttempts($interviewer, $output, $validator, $attempts); 371 } 372 373 /** 374 * Asks for a value, hide and validates the response. 375 * 376 * The validator receives the data to validate. It must return the 377 * validated data when the data is valid and throw an exception 378 * otherwise. 379 * 380 * @param OutputInterface $output An Output instance 381 * @param string|array $question The question to ask 382 * @param callable $validator A PHP callback 383 * @param int|false $attempts Max number of times to ask before giving up (false by default, which means infinite) 384 * @param bool $fallback In case the response can not be hidden, whether to fallback on non-hidden question or not 385 * 386 * @return string The response 387 * 388 * @throws \Exception When any of the validators return an error 389 * @throws RuntimeException In case the fallback is deactivated and the response can not be hidden 390 */ 391 public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true) 392 { 393 $that = $this; 394 395 $interviewer = function () use ($output, $question, $fallback, $that) { 396 return $that->askHiddenResponse($output, $question, $fallback); 397 }; 398 399 return $this->validateAttempts($interviewer, $output, $validator, $attempts); 400 } 401 402 /** 403 * Sets the input stream to read from when interacting with the user. 404 * 405 * This is mainly useful for testing purpose. 406 * 407 * @param resource $stream The input stream 408 */ 409 public function setInputStream($stream) 410 { 411 $this->inputStream = $stream; 412 } 413 414 /** 415 * Returns the helper's input stream. 416 * 417 * @return resource|null The input stream or null if the default STDIN is used 418 */ 419 public function getInputStream() 420 { 421 return $this->inputStream; 422 } 423 424 /** 425 * {@inheritdoc} 426 */ 427 public function getName() 428 { 429 return 'dialog'; 430 } 431 432 /** 433 * Return a valid Unix shell. 434 * 435 * @return string|bool The valid shell name, false in case no valid shell is found 436 */ 437 private function getShell() 438 { 439 if (null !== self::$shell) { 440 return self::$shell; 441 } 442 443 self::$shell = false; 444 445 if (file_exists('/usr/bin/env')) { 446 // handle other OSs with bash/zsh/ksh/csh if available to hide the answer 447 $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; 448 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) { 449 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { 450 self::$shell = $sh; 451 break; 452 } 453 } 454 } 455 456 return self::$shell; 457 } 458 459 private function hasSttyAvailable() 460 { 461 if (null !== self::$stty) { 462 return self::$stty; 463 } 464 465 exec('stty 2>&1', $output, $exitcode); 466 467 return self::$stty = 0 === $exitcode; 468 } 469 470 /** 471 * Validate an attempt. 472 * 473 * @param callable $interviewer A callable that will ask for a question and return the result 474 * @param OutputInterface $output An Output instance 475 * @param callable $validator A PHP callback 476 * @param int|false $attempts Max number of times to ask before giving up; false will ask infinitely 477 * 478 * @return string The validated response 479 * 480 * @throws \Exception In case the max number of attempts has been reached and no valid response has been given 481 */ 482 private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts) 483 { 484 if ($output instanceof ConsoleOutputInterface) { 485 $output = $output->getErrorOutput(); 486 } 487 488 $e = null; 489 while (false === $attempts || $attempts--) { 490 if (null !== $e) { 491 $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error')); 492 } 493 494 try { 495 return \call_user_func($validator, $interviewer()); 496 } catch (\Exception $e) { 497 } 498 } 499 500 throw $e; 501 } 502 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |