[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/console/Symfony/Component/Console/Helper/ -> TableHelper.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\Helper;
  13  
  14  use Symfony\Component\Console\Output\OutputInterface;
  15  
  16  /**
  17   * Provides helpers to display table output.
  18   *
  19   * @author Саша Стаменковић <umpirsky@gmail.com>
  20   */
  21  class TableHelper extends Helper
  22  {
  23      const LAYOUT_DEFAULT = 0;
  24      const LAYOUT_BORDERLESS = 1;
  25  
  26      /**
  27       * Table headers.
  28       *
  29       * @var array
  30       */
  31      private $headers = array();
  32  
  33      /**
  34       * Table rows.
  35       *
  36       * @var array
  37       */
  38      private $rows = array();
  39  
  40      // Rendering options
  41      private $paddingChar;
  42      private $horizontalBorderChar;
  43      private $verticalBorderChar;
  44      private $crossingChar;
  45      private $cellHeaderFormat;
  46      private $cellRowFormat;
  47      private $borderFormat;
  48      private $padType;
  49  
  50      /**
  51       * Column widths cache.
  52       *
  53       * @var array
  54       */
  55      private $columnWidths = array();
  56  
  57      /**
  58       * Number of columns cache.
  59       *
  60       * @var array
  61       */
  62      private $numberOfColumns;
  63  
  64      /**
  65       * @var OutputInterface
  66       */
  67      private $output;
  68  
  69      public function __construct()
  70      {
  71          $this->setLayout(self::LAYOUT_DEFAULT);
  72      }
  73  
  74      /**
  75       * Sets table layout type.
  76       *
  77       * @param int $layout self::LAYOUT_*
  78       *
  79       * @return TableHelper
  80       *
  81       * @throws \InvalidArgumentException when the table layout is not known
  82       */
  83      public function setLayout($layout)
  84      {
  85          switch ($layout) {
  86              case self::LAYOUT_BORDERLESS:
  87                  $this
  88                      ->setPaddingChar(' ')
  89                      ->setHorizontalBorderChar('=')
  90                      ->setVerticalBorderChar(' ')
  91                      ->setCrossingChar(' ')
  92                      ->setCellHeaderFormat('<info>%s</info>')
  93                      ->setCellRowFormat('<comment>%s</comment>')
  94                      ->setBorderFormat('%s')
  95                      ->setPadType(STR_PAD_RIGHT)
  96                  ;
  97                  break;
  98  
  99              case self::LAYOUT_DEFAULT:
 100                  $this
 101                      ->setPaddingChar(' ')
 102                      ->setHorizontalBorderChar('-')
 103                      ->setVerticalBorderChar('|')
 104                      ->setCrossingChar('+')
 105                      ->setCellHeaderFormat('<info>%s</info>')
 106                      ->setCellRowFormat('<comment>%s</comment>')
 107                      ->setBorderFormat('%s')
 108                      ->setPadType(STR_PAD_RIGHT)
 109                  ;
 110                  break;
 111  
 112              default:
 113                  throw new \InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
 114          }
 115  
 116          return $this;
 117      }
 118  
 119      public function setHeaders(array $headers)
 120      {
 121          $this->headers = array_values($headers);
 122  
 123          return $this;
 124      }
 125  
 126      public function setRows(array $rows)
 127      {
 128          $this->rows = array();
 129  
 130          return $this->addRows($rows);
 131      }
 132  
 133      public function addRows(array $rows)
 134      {
 135          foreach ($rows as $row) {
 136              $this->addRow($row);
 137          }
 138  
 139          return $this;
 140      }
 141  
 142      public function addRow(array $row)
 143      {
 144          $this->rows[] = array_values($row);
 145  
 146          end($this->rows);
 147          $rowKey = key($this->rows);
 148          reset($this->rows);
 149  
 150          foreach ($row as $key => $cellValue) {
 151              if (false === strpos($cellValue, "\n")) {
 152                  continue;
 153              }
 154  
 155              $lines = explode("\n", $cellValue);
 156              $this->rows[$rowKey][$key] = $lines[0];
 157              unset($lines[0]);
 158  
 159              foreach ($lines as $lineKey => $line) {
 160                  $nextRowKey = $rowKey + $lineKey + 1;
 161  
 162                  if (isset($this->rows[$nextRowKey])) {
 163                      $this->rows[$nextRowKey][$key] = $line;
 164                  } else {
 165                      $this->rows[$nextRowKey] = array($key => $line);
 166                  }
 167              }
 168          }
 169  
 170          return $this;
 171      }
 172  
 173      public function setRow($column, array $row)
 174      {
 175          $this->rows[$column] = $row;
 176  
 177          return $this;
 178      }
 179  
 180      /**
 181       * Sets padding character, used for cell padding.
 182       *
 183       * @param string $paddingChar
 184       *
 185       * @return TableHelper
 186       */
 187      public function setPaddingChar($paddingChar)
 188      {
 189          $this->paddingChar = $paddingChar;
 190  
 191          return $this;
 192      }
 193  
 194      /**
 195       * Sets horizontal border character.
 196       *
 197       * @param string $horizontalBorderChar
 198       *
 199       * @return TableHelper
 200       */
 201      public function setHorizontalBorderChar($horizontalBorderChar)
 202      {
 203          $this->horizontalBorderChar = $horizontalBorderChar;
 204  
 205          return $this;
 206      }
 207  
 208      /**
 209       * Sets vertical border character.
 210       *
 211       * @param string $verticalBorderChar
 212       *
 213       * @return TableHelper
 214       */
 215      public function setVerticalBorderChar($verticalBorderChar)
 216      {
 217          $this->verticalBorderChar = $verticalBorderChar;
 218  
 219          return $this;
 220      }
 221  
 222      /**
 223       * Sets crossing character.
 224       *
 225       * @param string $crossingChar
 226       *
 227       * @return TableHelper
 228       */
 229      public function setCrossingChar($crossingChar)
 230      {
 231          $this->crossingChar = $crossingChar;
 232  
 233          return $this;
 234      }
 235  
 236      /**
 237       * Sets header cell format.
 238       *
 239       * @param string $cellHeaderFormat
 240       *
 241       * @return TableHelper
 242       */
 243      public function setCellHeaderFormat($cellHeaderFormat)
 244      {
 245          $this->cellHeaderFormat = $cellHeaderFormat;
 246  
 247          return $this;
 248      }
 249  
 250      /**
 251       * Sets row cell format.
 252       *
 253       * @param string $cellRowFormat
 254       *
 255       * @return TableHelper
 256       */
 257      public function setCellRowFormat($cellRowFormat)
 258      {
 259          $this->cellRowFormat = $cellRowFormat;
 260  
 261          return $this;
 262      }
 263  
 264      /**
 265       * Sets table border format.
 266       *
 267       * @param string $borderFormat
 268       *
 269       * @return TableHelper
 270       */
 271      public function setBorderFormat($borderFormat)
 272      {
 273          $this->borderFormat = $borderFormat;
 274  
 275          return $this;
 276      }
 277  
 278      /**
 279       * Sets cell padding type.
 280       *
 281       * @param int $padType STR_PAD_*
 282       *
 283       * @return TableHelper
 284       */
 285      public function setPadType($padType)
 286      {
 287          $this->padType = $padType;
 288  
 289          return $this;
 290      }
 291  
 292      /**
 293       * Renders table to output.
 294       *
 295       * Example:
 296       * +---------------+-----------------------+------------------+
 297       * | ISBN          | Title                 | Author           |
 298       * +---------------+-----------------------+------------------+
 299       * | 99921-58-10-7 | Divine Comedy         | Dante Alighieri  |
 300       * | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
 301       * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
 302       * +---------------+-----------------------+------------------+
 303       *
 304       * @param OutputInterface $output
 305       */
 306      public function render(OutputInterface $output)
 307      {
 308          $this->output = $output;
 309  
 310          $this->renderRowSeparator();
 311          $this->renderRow($this->headers, $this->cellHeaderFormat);
 312          if (!empty($this->headers)) {
 313              $this->renderRowSeparator();
 314          }
 315          foreach ($this->rows as $row) {
 316              $this->renderRow($row, $this->cellRowFormat);
 317          }
 318          if (!empty($this->rows)) {
 319              $this->renderRowSeparator();
 320          }
 321  
 322          $this->cleanup();
 323      }
 324  
 325      /**
 326       * Renders horizontal header separator.
 327       *
 328       * Example: +-----+-----------+-------+
 329       */
 330      private function renderRowSeparator()
 331      {
 332          if (0 === $count = $this->getNumberOfColumns()) {
 333              return;
 334          }
 335  
 336          $markup = $this->crossingChar;
 337          for ($column = 0; $column < $count; ++$column) {
 338              $markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column))
 339                      .$this->crossingChar
 340              ;
 341          }
 342  
 343          $this->output->writeln(sprintf($this->borderFormat, $markup));
 344      }
 345  
 346      /**
 347       * Renders vertical column separator.
 348       */
 349      private function renderColumnSeparator()
 350      {
 351          $this->output->write(sprintf($this->borderFormat, $this->verticalBorderChar));
 352      }
 353  
 354      /**
 355       * Renders table row.
 356       *
 357       * Example: | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
 358       *
 359       * @param array  $row
 360       * @param string $cellFormat
 361       */
 362      private function renderRow(array $row, $cellFormat)
 363      {
 364          if (empty($row)) {
 365              return;
 366          }
 367  
 368          $this->renderColumnSeparator();
 369          for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; ++$column) {
 370              $this->renderCell($row, $column, $cellFormat);
 371              $this->renderColumnSeparator();
 372          }
 373          $this->output->writeln('');
 374      }
 375  
 376      /**
 377       * Renders table cell with padding.
 378       *
 379       * @param array  $row
 380       * @param int    $column
 381       * @param string $cellFormat
 382       */
 383      private function renderCell(array $row, $column, $cellFormat)
 384      {
 385          $cell = isset($row[$column]) ? $row[$column] : '';
 386          $width = $this->getColumnWidth($column);
 387  
 388          // str_pad won't work properly with multi-byte strings, we need to fix the padding
 389          if (function_exists('mb_strwidth') && false !== $encoding = mb_detect_encoding($cell, null, true)) {
 390              $width += strlen($cell) - mb_strwidth($cell, $encoding);
 391          }
 392  
 393          $width += $this->strlen($cell) - $this->computeLengthWithoutDecoration($cell);
 394  
 395          $this->output->write(sprintf(
 396              $cellFormat,
 397              str_pad(
 398                  $this->paddingChar.$cell.$this->paddingChar,
 399                  $width,
 400                  $this->paddingChar,
 401                  $this->padType
 402              )
 403          ));
 404      }
 405  
 406      /**
 407       * Gets number of columns for this table.
 408       *
 409       * @return int
 410       */
 411      private function getNumberOfColumns()
 412      {
 413          if (null !== $this->numberOfColumns) {
 414              return $this->numberOfColumns;
 415          }
 416  
 417          $columns = array(0);
 418          $columns[] = count($this->headers);
 419          foreach ($this->rows as $row) {
 420              $columns[] = count($row);
 421          }
 422  
 423          return $this->numberOfColumns = max($columns);
 424      }
 425  
 426      /**
 427       * Gets column width.
 428       *
 429       * @param int $column
 430       *
 431       * @return int
 432       */
 433      private function getColumnWidth($column)
 434      {
 435          if (isset($this->columnWidths[$column])) {
 436              return $this->columnWidths[$column];
 437          }
 438  
 439          $lengths = array(0);
 440          $lengths[] = $this->getCellWidth($this->headers, $column);
 441          foreach ($this->rows as $row) {
 442              $lengths[] = $this->getCellWidth($row, $column);
 443          }
 444  
 445          return $this->columnWidths[$column] = max($lengths) + 2;
 446      }
 447  
 448      /**
 449       * Gets cell width.
 450       *
 451       * @param array $row
 452       * @param int   $column
 453       *
 454       * @return int
 455       */
 456      private function getCellWidth(array $row, $column)
 457      {
 458          return isset($row[$column]) ? $this->computeLengthWithoutDecoration($row[$column]) : 0;
 459      }
 460  
 461      /**
 462       * Called after rendering to cleanup cache data.
 463       */
 464      private function cleanup()
 465      {
 466          $this->columnWidths = array();
 467          $this->numberOfColumns = null;
 468      }
 469  
 470      private function computeLengthWithoutDecoration($string)
 471      {
 472          $formatter = $this->output->getFormatter();
 473          $isDecorated = $formatter->isDecorated();
 474          $formatter->setDecorated(false);
 475  
 476          $string = $formatter->format($string);
 477          $formatter->setDecorated($isDecorated);
 478  
 479          return $this->strlen($string);
 480      }
 481  
 482      /**
 483       * {@inheritdoc}
 484       */
 485      public function getName()
 486      {
 487          return 'table';
 488      }
 489  }


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