You are here

public function DialogHelper::ask in Zircon Profile 8.0

Same name and namespace in other branches
  1. 8 vendor/symfony/console/Helper/DialogHelper.php \Symfony\Component\Console\Helper\DialogHelper::ask()

Asks a question to the user.

Parameters

OutputInterface $output An Output instance:

string|array $question The question to ask:

string $default The default answer if none is given by the user:

array $autocomplete List of values to autocomplete:

Return value

string The user answer

Throws

\RuntimeException If there is no data to read in the input stream

2 calls to DialogHelper::ask()
DialogHelper::askConfirmation in vendor/symfony/console/Helper/DialogHelper.php
Asks a confirmation to the user.
DialogHelper::askHiddenResponse in vendor/symfony/console/Helper/DialogHelper.php
Asks a question to the user, the response is hidden.

File

vendor/symfony/console/Helper/DialogHelper.php, line 109

Class

DialogHelper
The Dialog class provides helpers to interact with the user.

Namespace

Symfony\Component\Console\Helper

Code

public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null) {
  if ($this->input && !$this->input
    ->isInteractive()) {
    return $default;
  }
  $output
    ->write($question);
  $inputStream = $this->inputStream ?: STDIN;
  if (null === $autocomplete || !$this
    ->hasSttyAvailable()) {
    $ret = fgets($inputStream, 4096);
    if (false === $ret) {
      throw new \RuntimeException('Aborted');
    }
    $ret = trim($ret);
  }
  else {
    $ret = '';
    $i = 0;
    $ofs = -1;
    $matches = $autocomplete;
    $numMatches = count($matches);
    $sttyMode = shell_exec('stty -g');

    // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
    shell_exec('stty -icanon -echo');

    // Add highlighted text style
    $output
      ->getFormatter()
      ->setStyle('hl', new OutputFormatterStyle('black', 'white'));

    // Read a keypress
    while (!feof($inputStream)) {
      $c = fread($inputStream, 1);

      // Backspace Character
      if ("" === $c) {
        if (0 === $numMatches && 0 !== $i) {
          --$i;

          // Move cursor backwards
          $output
            ->write("\33[1D");
        }
        if ($i === 0) {
          $ofs = -1;
          $matches = $autocomplete;
          $numMatches = count($matches);
        }
        else {
          $numMatches = 0;
        }

        // Pop the last character off the end of our string
        $ret = substr($ret, 0, $i);
      }
      elseif ("\33" === $c) {

        // Did we read an escape sequence?
        $c .= fread($inputStream, 2);

        // A = Up Arrow. B = Down Arrow
        if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
          if ('A' === $c[2] && -1 === $ofs) {
            $ofs = 0;
          }
          if (0 === $numMatches) {
            continue;
          }
          $ofs += 'A' === $c[2] ? -1 : 1;
          $ofs = ($numMatches + $ofs) % $numMatches;
        }
      }
      elseif (ord($c) < 32) {
        if ("\t" === $c || "\n" === $c) {
          if ($numMatches > 0 && -1 !== $ofs) {
            $ret = $matches[$ofs];

            // Echo out remaining chars for current match
            $output
              ->write(substr($ret, $i));
            $i = strlen($ret);
          }
          if ("\n" === $c) {
            $output
              ->write($c);
            break;
          }
          $numMatches = 0;
        }
        continue;
      }
      else {
        $output
          ->write($c);
        $ret .= $c;
        ++$i;
        $numMatches = 0;
        $ofs = 0;
        foreach ($autocomplete as $value) {

          // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
          if (0 === strpos($value, $ret) && $i !== strlen($value)) {
            $matches[$numMatches++] = $value;
          }
        }
      }

      // Erase characters from cursor to end of line
      $output
        ->write("\33[K");
      if ($numMatches > 0 && -1 !== $ofs) {

        // Save cursor position
        $output
          ->write("\0337");

        // Write highlighted text
        $output
          ->write('<hl>' . substr($matches[$ofs], $i) . '</hl>');

        // Restore cursor position
        $output
          ->write("\338");
      }
    }

    // Reset stty so it behaves normally again
    shell_exec(sprintf('stty %s', $sttyMode));
  }
  return strlen($ret) > 0 ? $ret : $default;
}