[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/console/Symfony/Component/Console/ -> Shell.php (source)

   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;
  13  
  14  use Symfony\Component\Console\Input\StringInput;
  15  use Symfony\Component\Console\Output\ConsoleOutput;
  16  use Symfony\Component\Process\ProcessBuilder;
  17  use Symfony\Component\Process\PhpExecutableFinder;
  18  
  19  /**
  20   * A Shell wraps an Application to add shell capabilities to it.
  21   *
  22   * Support for history and completion only works with a PHP compiled
  23   * with readline support (either --with-readline or --with-libedit)
  24   *
  25   * @author Fabien Potencier <fabien@symfony.com>
  26   * @author Martin HasoĊˆ <martin.hason@gmail.com>
  27   */
  28  class Shell
  29  {
  30      private $application;
  31      private $history;
  32      private $output;
  33      private $hasReadline;
  34      private $processIsolation;
  35  
  36      /**
  37       * Constructor.
  38       *
  39       * If there is no readline support for the current PHP executable
  40       * a \RuntimeException exception is thrown.
  41       *
  42       * @param Application $application An application instance
  43       */
  44      public function __construct(Application $application)
  45      {
  46          $this->hasReadline = function_exists('readline');
  47          $this->application = $application;
  48          $this->history = getenv('HOME').'/.history_'.$application->getName();
  49          $this->output = new ConsoleOutput();
  50          $this->processIsolation = false;
  51      }
  52  
  53      /**
  54       * Runs the shell.
  55       */
  56      public function run()
  57      {
  58          $this->application->setAutoExit(false);
  59          $this->application->setCatchExceptions(true);
  60  
  61          if ($this->hasReadline) {
  62              readline_read_history($this->history);
  63              readline_completion_function(array($this, 'autocompleter'));
  64          }
  65  
  66          $this->output->writeln($this->getHeader());
  67          $php = null;
  68          if ($this->processIsolation) {
  69              $finder = new PhpExecutableFinder();
  70              $php = $finder->find();
  71              $this->output->writeln(<<<'EOF'
  72  <info>Running with process isolation, you should consider this:</info>
  73    * each command is executed as separate process,
  74    * commands don't support interactivity, all params must be passed explicitly,
  75    * commands output is not colorized.
  76  
  77  EOF
  78              );
  79          }
  80  
  81          while (true) {
  82              $command = $this->readline();
  83  
  84              if (false === $command) {
  85                  $this->output->writeln("\n");
  86  
  87                  break;
  88              }
  89  
  90              if ($this->hasReadline) {
  91                  readline_add_history($command);
  92                  readline_write_history($this->history);
  93              }
  94  
  95              if ($this->processIsolation) {
  96                  $pb = new ProcessBuilder();
  97  
  98                  $process = $pb
  99                      ->add($php)
 100                      ->add($_SERVER['argv'][0])
 101                      ->add($command)
 102                      ->inheritEnvironmentVariables(true)
 103                      ->getProcess()
 104                  ;
 105  
 106                  $output = $this->output;
 107                  $process->run(function ($type, $data) use ($output) {
 108                      $output->writeln($data);
 109                  });
 110  
 111                  $ret = $process->getExitCode();
 112              } else {
 113                  $ret = $this->application->run(new StringInput($command), $this->output);
 114              }
 115  
 116              if (0 !== $ret) {
 117                  $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
 118              }
 119          }
 120      }
 121  
 122      /**
 123       * Returns the shell header.
 124       *
 125       * @return string The header string
 126       */
 127      protected function getHeader()
 128      {
 129          return <<<EOF
 130  
 131  Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
 132  
 133  At the prompt, type <comment>help</comment> for some help,
 134  or <comment>list</comment> to get a list of available commands.
 135  
 136  To exit the shell, type <comment>^D</comment>.
 137  
 138  EOF;
 139      }
 140  
 141      /**
 142       * Renders a prompt.
 143       *
 144       * @return string The prompt
 145       */
 146      protected function getPrompt()
 147      {
 148          // using the formatter here is required when using readline
 149          return $this->output->getFormatter()->format($this->application->getName().' > ');
 150      }
 151  
 152      protected function getOutput()
 153      {
 154          return $this->output;
 155      }
 156  
 157      protected function getApplication()
 158      {
 159          return $this->application;
 160      }
 161  
 162      /**
 163       * Tries to return autocompletion for the current entered text.
 164       *
 165       * @param string $text The last segment of the entered text
 166       *
 167       * @return bool|array A list of guessed strings or true
 168       */
 169      private function autocompleter($text)
 170      {
 171          $info = readline_info();
 172          $text = substr($info['line_buffer'], 0, $info['end']);
 173  
 174          if ($info['point'] !== $info['end']) {
 175              return true;
 176          }
 177  
 178          // task name?
 179          if (false === strpos($text, ' ') || !$text) {
 180              return array_keys($this->application->all());
 181          }
 182  
 183          // options and arguments?
 184          try {
 185              $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
 186          } catch (\Exception $e) {
 187              return true;
 188          }
 189  
 190          $list = array('--help');
 191          foreach ($command->getDefinition()->getOptions() as $option) {
 192              $list[] = '--'.$option->getName();
 193          }
 194  
 195          return $list;
 196      }
 197  
 198      /**
 199       * Reads a single line from standard input.
 200       *
 201       * @return string The single line from standard input
 202       */
 203      private function readline()
 204      {
 205          if ($this->hasReadline) {
 206              $line = readline($this->getPrompt());
 207          } else {
 208              $this->output->write($this->getPrompt());
 209              $line = fgets(STDIN, 1024);
 210              $line = (false === $line || '' === $line) ? false : rtrim($line);
 211          }
 212  
 213          return $line;
 214      }
 215  
 216      public function getProcessIsolation()
 217      {
 218          return $this->processIsolation;
 219      }
 220  
 221      public function setProcessIsolation($processIsolation)
 222      {
 223          $this->processIsolation = (bool) $processIsolation;
 224  
 225          if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
 226              throw new \RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
 227          }
 228      }
 229  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1