You are here

class SymfonyStyle in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/symfony/console/Style/SymfonyStyle.php \Symfony\Component\Console\Style\SymfonyStyle

Output decorator helpers for the Symfony Style Guide.

@author Kevin Bond <kevinbond@gmail.com>

Hierarchy

Expanded class hierarchy of SymfonyStyle

10 files declare their use of SymfonyStyle
command_0.php in vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php
command_1.php in vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php
command_2.php in vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php
command_3.php in vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php
command_4.php in vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php

... See full list

File

vendor/symfony/console/Style/SymfonyStyle.php, line 32

Namespace

Symfony\Component\Console\Style
View source
class SymfonyStyle extends OutputStyle {
  const MAX_LINE_LENGTH = 120;
  private $input;
  private $questionHelper;
  private $progressBar;
  private $lineLength;
  private $bufferedOutput;

  /**
   * @param InputInterface  $input
   * @param OutputInterface $output
   */
  public function __construct(InputInterface $input, OutputInterface $output) {
    $this->input = $input;
    $this->bufferedOutput = new BufferedOutput($output
      ->getVerbosity(), false, clone $output
      ->getFormatter());

    // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
    $this->lineLength = min($this
      ->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
    parent::__construct($output);
  }

  /**
   * Formats a message as a block of text.
   *
   * @param string|array $messages The message to write in the block
   * @param string|null  $type     The block type (added in [] on first line)
   * @param string|null  $style    The style to apply to the whole block
   * @param string       $prefix   The prefix for the block
   * @param bool         $padding  Whether to add vertical padding
   */
  public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false) {
    $this
      ->autoPrependBlock();
    $messages = is_array($messages) ? array_values($messages) : array(
      $messages,
    );
    $lines = array();

    // add type
    if (null !== $type) {
      $messages[0] = sprintf('[%s] %s', $type, $messages[0]);
    }

    // wrap and add newlines for each element
    foreach ($messages as $key => $message) {
      $message = OutputFormatter::escape($message);
      $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - Helper::strlen($prefix), PHP_EOL, true)));
      if (count($messages) > 1 && $key < count($messages) - 1) {
        $lines[] = '';
      }
    }
    if ($padding && $this
      ->isDecorated()) {
      array_unshift($lines, '');
      $lines[] = '';
    }
    foreach ($lines as &$line) {
      $line = sprintf('%s%s', $prefix, $line);
      $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this
        ->getFormatter(), $line));
      if ($style) {
        $line = sprintf('<%s>%s</>', $style, $line);
      }
    }
    $this
      ->writeln($lines);
    $this
      ->newLine();
  }

  /**
   * {@inheritdoc}
   */
  public function title($message) {
    $this
      ->autoPrependBlock();
    $this
      ->writeln(array(
      sprintf('<comment>%s</>', $message),
      sprintf('<comment>%s</>', str_repeat('=', strlen($message))),
    ));
    $this
      ->newLine();
  }

  /**
   * {@inheritdoc}
   */
  public function section($message) {
    $this
      ->autoPrependBlock();
    $this
      ->writeln(array(
      sprintf('<comment>%s</>', $message),
      sprintf('<comment>%s</>', str_repeat('-', strlen($message))),
    ));
    $this
      ->newLine();
  }

  /**
   * {@inheritdoc}
   */
  public function listing(array $elements) {
    $this
      ->autoPrependText();
    $elements = array_map(function ($element) {
      return sprintf(' * %s', $element);
    }, $elements);
    $this
      ->writeln($elements);
    $this
      ->newLine();
  }

  /**
   * {@inheritdoc}
   */
  public function text($message) {
    $this
      ->autoPrependText();
    if (!is_array($message)) {
      $this
        ->writeln(sprintf(' // %s', $message));
      return;
    }
    foreach ($message as $element) {
      $this
        ->text($element);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function success($message) {
    $this
      ->block($message, 'OK', 'fg=black;bg=green', ' ', true);
  }

  /**
   * {@inheritdoc}
   */
  public function error($message) {
    $this
      ->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
  }

  /**
   * {@inheritdoc}
   */
  public function warning($message) {
    $this
      ->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
  }

  /**
   * {@inheritdoc}
   */
  public function note($message) {
    $this
      ->block($message, 'NOTE', 'fg=yellow', ' ! ');
  }

  /**
   * {@inheritdoc}
   */
  public function caution($message) {
    $this
      ->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
  }

  /**
   * {@inheritdoc}
   */
  public function table(array $headers, array $rows) {
    $headers = array_map(function ($value) {
      return sprintf('<info>%s</>', $value);
    }, $headers);
    $table = new Table($this);
    $table
      ->setHeaders($headers);
    $table
      ->setRows($rows);
    $table
      ->setStyle('symfony-style-guide');
    $table
      ->render();
    $this
      ->newLine();
  }

  /**
   * {@inheritdoc}
   */
  public function ask($question, $default = null, $validator = null) {
    $question = new Question($question, $default);
    $question
      ->setValidator($validator);
    return $this
      ->askQuestion($question);
  }

  /**
   * {@inheritdoc}
   */
  public function askHidden($question, $validator = null) {
    $question = new Question($question);
    $question
      ->setHidden(true);
    $question
      ->setValidator($validator);
    return $this
      ->askQuestion($question);
  }

  /**
   * {@inheritdoc}
   */
  public function confirm($question, $default = true) {
    return $this
      ->askQuestion(new ConfirmationQuestion($question, $default));
  }

  /**
   * {@inheritdoc}
   */
  public function choice($question, array $choices, $default = null) {
    if (null !== $default) {
      $values = array_flip($choices);
      $default = $values[$default];
    }
    return $this
      ->askQuestion(new ChoiceQuestion($question, $choices, $default));
  }

  /**
   * {@inheritdoc}
   */
  public function progressStart($max = 0) {
    $this->progressBar = $this
      ->createProgressBar($max);
    $this->progressBar
      ->start();
  }

  /**
   * {@inheritdoc}
   */
  public function progressAdvance($step = 1) {
    $this
      ->getProgressBar()
      ->advance($step);
  }

  /**
   * {@inheritdoc}
   */
  public function progressFinish() {
    $this
      ->getProgressBar()
      ->finish();
    $this
      ->newLine(2);
    $this->progressBar = null;
  }

  /**
   * {@inheritdoc}
   */
  public function createProgressBar($max = 0) {
    $progressBar = parent::createProgressBar($max);
    if ('\\' === DIRECTORY_SEPARATOR) {
      $progressBar
        ->setEmptyBarCharacter('░');

      // light shade character \u2591
      $progressBar
        ->setProgressCharacter('');
      $progressBar
        ->setBarCharacter('▓');

      // dark shade character \u2593
    }
    return $progressBar;
  }

  /**
   * @param Question $question
   *
   * @return string
   */
  public function askQuestion(Question $question) {
    if ($this->input
      ->isInteractive()) {
      $this
        ->autoPrependBlock();
    }
    if (!$this->questionHelper) {
      $this->questionHelper = new SymfonyQuestionHelper();
    }
    $answer = $this->questionHelper
      ->ask($this->input, $this, $question);
    if ($this->input
      ->isInteractive()) {
      $this
        ->newLine();
      $this->bufferedOutput
        ->write("\n");
    }
    return $answer;
  }

  /**
   * {@inheritdoc}
   */
  public function writeln($messages, $type = self::OUTPUT_NORMAL) {
    parent::writeln($messages, $type);
    $this->bufferedOutput
      ->writeln($this
      ->reduceBuffer($messages), $type);
  }

  /**
   * {@inheritdoc}
   */
  public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) {
    parent::write($messages, $newline, $type);
    $this->bufferedOutput
      ->write($this
      ->reduceBuffer($messages), $newline, $type);
  }

  /**
   * {@inheritdoc}
   */
  public function newLine($count = 1) {
    parent::newLine($count);
    $this->bufferedOutput
      ->write(str_repeat("\n", $count));
  }

  /**
   * @return ProgressBar
   */
  private function getProgressBar() {
    if (!$this->progressBar) {
      throw new \RuntimeException('The ProgressBar is not started.');
    }
    return $this->progressBar;
  }
  private function getTerminalWidth() {
    $application = new Application();
    $dimensions = $application
      ->getTerminalDimensions();
    return $dimensions[0] ?: self::MAX_LINE_LENGTH;
  }
  private function autoPrependBlock() {
    $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput
      ->fetch()), -2);
    if (!isset($chars[0])) {
      return $this
        ->newLine();

      //empty history, so we should start with a new line.
    }

    //Prepend new line for each non LF chars (This means no blank line was output before)
    $this
      ->newLine(2 - substr_count($chars, "\n"));
  }
  private function autoPrependText() {
    $fetched = $this->bufferedOutput
      ->fetch();

    //Prepend new line if last char isn't EOL:
    if ("\n" !== substr($fetched, -1)) {
      $this
        ->newLine();
    }
  }
  private function reduceBuffer($messages) {

    // We need to know if the two last chars are PHP_EOL
    // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
    return array_map(function ($value) {
      return substr($value, -4);
    }, array_merge(array(
      $this->bufferedOutput
        ->fetch(),
    ), (array) $messages));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
OutputInterface::OUTPUT_NORMAL constant
OutputInterface::OUTPUT_PLAIN constant
OutputInterface::OUTPUT_RAW constant
OutputInterface::VERBOSITY_DEBUG constant
OutputInterface::VERBOSITY_NORMAL constant
OutputInterface::VERBOSITY_QUIET constant
OutputInterface::VERBOSITY_VERBOSE constant
OutputInterface::VERBOSITY_VERY_VERBOSE constant
OutputStyle::$output private property
OutputStyle::getFormatter public function Returns current output formatter instance. Overrides OutputInterface::getFormatter
OutputStyle::getVerbosity public function Gets the current verbosity of the output. Overrides OutputInterface::getVerbosity
OutputStyle::isDecorated public function Gets the decorated flag. Overrides OutputInterface::isDecorated
OutputStyle::setDecorated public function Sets the decorated flag. Overrides OutputInterface::setDecorated
OutputStyle::setFormatter public function Sets output formatter. Overrides OutputInterface::setFormatter
OutputStyle::setVerbosity public function Sets the verbosity of the output. Overrides OutputInterface::setVerbosity
SymfonyStyle::$bufferedOutput private property
SymfonyStyle::$input private property
SymfonyStyle::$lineLength private property
SymfonyStyle::$progressBar private property
SymfonyStyle::$questionHelper private property
SymfonyStyle::ask public function Asks a question. Overrides StyleInterface::ask
SymfonyStyle::askHidden public function Asks a question with the user input hidden. Overrides StyleInterface::askHidden
SymfonyStyle::askQuestion public function
SymfonyStyle::autoPrependBlock private function
SymfonyStyle::autoPrependText private function
SymfonyStyle::block public function Formats a message as a block of text.
SymfonyStyle::caution public function Formats a caution admonition. Overrides StyleInterface::caution
SymfonyStyle::choice public function Asks a choice question. Overrides StyleInterface::choice
SymfonyStyle::confirm public function Asks for confirmation. Overrides StyleInterface::confirm
SymfonyStyle::createProgressBar public function Overrides OutputStyle::createProgressBar
SymfonyStyle::error public function Formats an error result bar. Overrides StyleInterface::error
SymfonyStyle::getProgressBar private function
SymfonyStyle::getTerminalWidth private function
SymfonyStyle::listing public function Formats a list. Overrides StyleInterface::listing
SymfonyStyle::MAX_LINE_LENGTH constant
SymfonyStyle::newLine public function Add newline(s). Overrides OutputStyle::newLine
SymfonyStyle::note public function Formats a note admonition. Overrides StyleInterface::note
SymfonyStyle::progressAdvance public function Advances the progress output X steps. Overrides StyleInterface::progressAdvance
SymfonyStyle::progressFinish public function Finishes the progress output. Overrides StyleInterface::progressFinish
SymfonyStyle::progressStart public function Starts the progress output. Overrides StyleInterface::progressStart
SymfonyStyle::reduceBuffer private function
SymfonyStyle::section public function Formats a section title. Overrides StyleInterface::section
SymfonyStyle::success public function Formats a success result bar. Overrides StyleInterface::success
SymfonyStyle::table public function Formats a table. Overrides StyleInterface::table
SymfonyStyle::text public function Formats informational text. Overrides StyleInterface::text
SymfonyStyle::title public function Formats a command title. Overrides StyleInterface::title
SymfonyStyle::warning public function Formats an warning result bar. Overrides StyleInterface::warning
SymfonyStyle::write public function Writes a message to the output. Overrides OutputStyle::write
SymfonyStyle::writeln public function Writes a message to the output and adds a newline at the end. Overrides OutputStyle::writeln
SymfonyStyle::__construct public function Overrides OutputStyle::__construct