[Console] deprecated TableHelper in favor of Table
This commit is contained in:
parent
554b28d975
commit
39c495f814
@ -48,6 +48,42 @@ UPGRADE FROM 2.x to 3.0
|
||||
}
|
||||
```
|
||||
|
||||
* `TableHelper` has been removed in favor of `Table`.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
$table = $app->getHelperSet()->get('table');
|
||||
$table
|
||||
->setHeaders(array('ISBN', 'Title', 'Author'))
|
||||
->setRows(array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
|
||||
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
|
||||
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
|
||||
))
|
||||
;
|
||||
$table->render($output);
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
|
||||
$table = new Table($output);
|
||||
$table
|
||||
->setHeaders(array('ISBN', 'Title', 'Author'))
|
||||
->setRows(array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
|
||||
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
|
||||
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
|
||||
))
|
||||
;
|
||||
$table->render();
|
||||
```
|
||||
|
||||
### EventDispatcher
|
||||
|
||||
* The interface `Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface`
|
||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
* deprecated TableHelper in favor of Table
|
||||
* deprecated ProgressHelper in favor of ProgressBar
|
||||
* added a way to set a default command instead of `ListCommand`
|
||||
* added a way to set the process name of a command
|
||||
|
391
src/Symfony/Component/Console/Helper/Table.php
Normal file
391
src/Symfony/Component/Console/Helper/Table.php
Normal file
@ -0,0 +1,391 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Helper;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Provides helpers to display a table.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Саша Стаменковић <umpirsky@gmail.com>
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
/**
|
||||
* Table headers.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array();
|
||||
|
||||
/**
|
||||
* Table rows.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $rows = array();
|
||||
|
||||
/**
|
||||
* Column widths cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $columnWidths = array();
|
||||
|
||||
/**
|
||||
* Number of columns cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $numberOfColumns;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
|
||||
/**
|
||||
* @var TableStyle
|
||||
*/
|
||||
private $style;
|
||||
|
||||
private static $styles;
|
||||
|
||||
public function __construct(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
|
||||
$this->setStyle('default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a style definition.
|
||||
*
|
||||
* @param string $name The style name
|
||||
* @param TableStyle $style A TableStyle instance
|
||||
*/
|
||||
public static function setStyleDefinition($name, TableStyle $style)
|
||||
{
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
|
||||
self::$styles[$name] = $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a style definition by name.
|
||||
*
|
||||
* @param string $name The style name
|
||||
*
|
||||
* @return TableStyle A TableStyle instance
|
||||
*/
|
||||
public static function getStyleDefinition($name)
|
||||
{
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
|
||||
if (!self::$styles[$name]) {
|
||||
throw new \InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
return self::$styles[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets table style.
|
||||
*
|
||||
* @param string $name The style name
|
||||
*
|
||||
* @return Table
|
||||
*/
|
||||
public function setStyle($name)
|
||||
{
|
||||
if (isset(self::$styles[$name])) {
|
||||
$this->style = self::$styles[$name];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current table style.
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function getStyle()
|
||||
{
|
||||
return $this->style;
|
||||
}
|
||||
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = array_values($headers);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRows(array $rows)
|
||||
{
|
||||
$this->rows = array();
|
||||
|
||||
return $this->addRows($rows);
|
||||
}
|
||||
|
||||
public function addRows(array $rows)
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
$this->addRow($row);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addRow(array $row)
|
||||
{
|
||||
$this->rows[] = array_values($row);
|
||||
|
||||
$keys = array_keys($this->rows);
|
||||
$rowKey = array_pop($keys);
|
||||
|
||||
foreach ($row as $key => $cellValue) {
|
||||
if (!strstr($cellValue, "\n")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lines = explode("\n", $cellValue);
|
||||
$this->rows[$rowKey][$key] = $lines[0];
|
||||
unset($lines[0]);
|
||||
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
$nextRowKey = $rowKey + $lineKey + 1;
|
||||
|
||||
if (isset($this->rows[$nextRowKey])) {
|
||||
$this->rows[$nextRowKey][$key] = $line;
|
||||
} else {
|
||||
$this->rows[$nextRowKey] = array($key => $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRow($column, array $row)
|
||||
{
|
||||
$this->rows[$column] = $row;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders table to output.
|
||||
*
|
||||
* Example:
|
||||
* +---------------+-----------------------+------------------+
|
||||
* | ISBN | Title | Author |
|
||||
* +---------------+-----------------------+------------------+
|
||||
* | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
* +---------------+-----------------------+------------------+
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->renderRowSeparator();
|
||||
$this->renderRow($this->headers, $this->style->getCellHeaderFormat());
|
||||
if (!empty($this->headers)) {
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
foreach ($this->rows as $row) {
|
||||
$this->renderRow($row, $this->style->getCellRowFormat());
|
||||
}
|
||||
if (!empty($this->rows)) {
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
|
||||
$this->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders horizontal header separator.
|
||||
*
|
||||
* Example: +-----+-----------+-------+
|
||||
*/
|
||||
private function renderRowSeparator()
|
||||
{
|
||||
if (0 === $count = $this->getNumberOfColumns()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$markup = $this->style->getCrossingChar();
|
||||
for ($column = 0; $column < $count; $column++) {
|
||||
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->getColumnWidth($column)).$this->style->getCrossingChar();
|
||||
}
|
||||
|
||||
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders vertical column separator.
|
||||
*/
|
||||
private function renderColumnSeparator()
|
||||
{
|
||||
$this->output->write(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders table row.
|
||||
*
|
||||
* Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
*
|
||||
* @param array $row
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderRow(array $row, $cellFormat)
|
||||
{
|
||||
if (empty($row)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->renderColumnSeparator();
|
||||
for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
|
||||
$this->renderCell($row, $column, $cellFormat);
|
||||
$this->renderColumnSeparator();
|
||||
}
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders table cell with padding.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderCell(array $row, $column, $cellFormat)
|
||||
{
|
||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||
$width = $this->getColumnWidth($column);
|
||||
|
||||
// str_pad won't work properly with multi-byte strings, we need to fix the padding
|
||||
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($cell)) {
|
||||
$width += strlen($cell) - mb_strlen($cell, $encoding);
|
||||
}
|
||||
|
||||
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
|
||||
|
||||
$content = sprintf($this->style->getCellRowContentFormat(), $cell);
|
||||
|
||||
$this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of columns for this table.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getNumberOfColumns()
|
||||
{
|
||||
if (null !== $this->numberOfColumns) {
|
||||
return $this->numberOfColumns;
|
||||
}
|
||||
|
||||
$columns = array(count($this->headers));
|
||||
foreach ($this->rows as $row) {
|
||||
$columns[] = count($row);
|
||||
}
|
||||
|
||||
return $this->numberOfColumns = max($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets column width.
|
||||
*
|
||||
* @param integer $column
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getColumnWidth($column)
|
||||
{
|
||||
if (isset($this->columnWidths[$column])) {
|
||||
return $this->columnWidths[$column];
|
||||
}
|
||||
|
||||
$lengths = array($this->getCellWidth($this->headers, $column));
|
||||
foreach ($this->rows as $row) {
|
||||
$lengths[] = $this->getCellWidth($row, $column);
|
||||
}
|
||||
|
||||
return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cell width.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getCellWidth(array $row, $column)
|
||||
{
|
||||
return isset($row[$column]) ? Helper::strlenWithoutDecoration($this->output->getFormatter(), $row[$column]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after rendering to cleanup cache data.
|
||||
*/
|
||||
private function cleanup()
|
||||
{
|
||||
$this->columnWidths = array();
|
||||
$this->numberOfColumns = null;
|
||||
}
|
||||
|
||||
private static function initStyles()
|
||||
{
|
||||
$borderless = new TableStyle();
|
||||
$borderless
|
||||
->setHorizontalBorderChar('=')
|
||||
->setVerticalBorderChar(' ')
|
||||
->setCrossingChar(' ')
|
||||
;
|
||||
|
||||
$compact = new TableStyle();
|
||||
$compact
|
||||
->setHorizontalBorderChar('')
|
||||
->setVerticalBorderChar(' ')
|
||||
->setCrossingChar('')
|
||||
->setCellRowContentFormat('%s')
|
||||
;
|
||||
|
||||
return array(
|
||||
'default' => new TableStyle(),
|
||||
'borderless' => $borderless,
|
||||
'compact' => $compact,
|
||||
);
|
||||
}
|
||||
}
|
@ -12,12 +12,15 @@
|
||||
namespace Symfony\Component\Console\Helper;
|
||||
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
|
||||
/**
|
||||
* Provides helpers to display table output.
|
||||
*
|
||||
* @author Саша Стаменковић <umpirsky@gmail.com>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated Deprecated since 2.5, to be removed in 3.0; use Table instead.
|
||||
*/
|
||||
class TableHelper extends Helper
|
||||
{
|
||||
@ -26,52 +29,13 @@ class TableHelper extends Helper
|
||||
const LAYOUT_COMPACT = 2;
|
||||
|
||||
/**
|
||||
* Table headers.
|
||||
*
|
||||
* @var array
|
||||
* @var Table
|
||||
*/
|
||||
private $headers = array();
|
||||
|
||||
/**
|
||||
* Table rows.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $rows = array();
|
||||
|
||||
// Rendering options
|
||||
private $paddingChar;
|
||||
private $horizontalBorderChar;
|
||||
private $verticalBorderChar;
|
||||
private $crossingChar;
|
||||
private $cellHeaderFormat;
|
||||
private $cellRowFormat;
|
||||
private $cellRowContentFormat;
|
||||
private $borderFormat;
|
||||
private $padType;
|
||||
|
||||
/**
|
||||
* Column widths cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $columnWidths = array();
|
||||
|
||||
/**
|
||||
* Number of columns cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $numberOfColumns;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
private $table;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setLayout(self::LAYOUT_DEFAULT);
|
||||
$this->table = new Table(new NullOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,49 +49,19 @@ class TableHelper extends Helper
|
||||
{
|
||||
switch ($layout) {
|
||||
case self::LAYOUT_BORDERLESS:
|
||||
$this
|
||||
->setPaddingChar(' ')
|
||||
->setHorizontalBorderChar('=')
|
||||
->setVerticalBorderChar(' ')
|
||||
->setCrossingChar(' ')
|
||||
->setCellHeaderFormat('<info>%s</info>')
|
||||
->setCellRowFormat('%s')
|
||||
->setCellRowContentFormat(' %s ')
|
||||
->setBorderFormat('%s')
|
||||
->setPadType(STR_PAD_RIGHT)
|
||||
;
|
||||
$this->table->setStyle('borderless');
|
||||
break;
|
||||
|
||||
case self::LAYOUT_COMPACT:
|
||||
$this
|
||||
->setPaddingChar(' ')
|
||||
->setHorizontalBorderChar('')
|
||||
->setVerticalBorderChar(' ')
|
||||
->setCrossingChar('')
|
||||
->setCellHeaderFormat('<info>%s</info>')
|
||||
->setCellRowFormat('%s')
|
||||
->setCellRowContentFormat('%s')
|
||||
->setBorderFormat('%s')
|
||||
->setPadType(STR_PAD_RIGHT)
|
||||
;
|
||||
$this->table->setStyle('compact');
|
||||
break;
|
||||
|
||||
case self::LAYOUT_DEFAULT:
|
||||
$this
|
||||
->setPaddingChar(' ')
|
||||
->setHorizontalBorderChar('-')
|
||||
->setVerticalBorderChar('|')
|
||||
->setCrossingChar('+')
|
||||
->setCellHeaderFormat('<info>%s</info>')
|
||||
->setCellRowFormat('%s')
|
||||
->setCellRowContentFormat(' %s ')
|
||||
->setBorderFormat('%s')
|
||||
->setPadType(STR_PAD_RIGHT)
|
||||
;
|
||||
$this->table->setStyle('default');
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
|
||||
throw new \InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
|
||||
break;
|
||||
};
|
||||
|
||||
@ -136,60 +70,35 @@ class TableHelper extends Helper
|
||||
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = array_values($headers);
|
||||
$this->table->setHeaders($headers);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRows(array $rows)
|
||||
{
|
||||
$this->rows = array();
|
||||
$this->table->setRows($rows);
|
||||
|
||||
return $this->addRows($rows);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addRows(array $rows)
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
$this->addRow($row);
|
||||
}
|
||||
$this->table->addRows($rows);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addRow(array $row)
|
||||
{
|
||||
$this->rows[] = array_values($row);
|
||||
|
||||
$keys = array_keys($this->rows);
|
||||
$rowKey = array_pop($keys);
|
||||
|
||||
foreach ($row as $key => $cellValue) {
|
||||
if (!strstr($cellValue, "\n")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lines = explode("\n", $cellValue);
|
||||
$this->rows[$rowKey][$key] = $lines[0];
|
||||
unset($lines[0]);
|
||||
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
$nextRowKey = $rowKey + $lineKey + 1;
|
||||
|
||||
if (isset($this->rows[$nextRowKey])) {
|
||||
$this->rows[$nextRowKey][$key] = $line;
|
||||
} else {
|
||||
$this->rows[$nextRowKey] = array($key => $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->table->addRow($row);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRow($column, array $row)
|
||||
{
|
||||
$this->rows[$column] = $row;
|
||||
$this->table->setRow($column, $row);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -203,11 +112,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setPaddingChar($paddingChar)
|
||||
{
|
||||
if (!$paddingChar) {
|
||||
throw new \LogicException('The padding char must not be empty');
|
||||
}
|
||||
|
||||
$this->paddingChar = $paddingChar;
|
||||
$this->table->getStyle()->setPaddingChar($paddingChar);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -221,7 +126,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setHorizontalBorderChar($horizontalBorderChar)
|
||||
{
|
||||
$this->horizontalBorderChar = $horizontalBorderChar;
|
||||
$this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -235,7 +140,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setVerticalBorderChar($verticalBorderChar)
|
||||
{
|
||||
$this->verticalBorderChar = $verticalBorderChar;
|
||||
$this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -249,7 +154,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setCrossingChar($crossingChar)
|
||||
{
|
||||
$this->crossingChar = $crossingChar;
|
||||
$this->table->getStyle()->setCrossingChar($crossingChar);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -263,7 +168,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setCellHeaderFormat($cellHeaderFormat)
|
||||
{
|
||||
$this->cellHeaderFormat = $cellHeaderFormat;
|
||||
$this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -277,7 +182,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setCellRowFormat($cellRowFormat)
|
||||
{
|
||||
$this->cellRowFormat = $cellRowFormat;
|
||||
$this->table->getStyle()->setCellHeaderFormat($cellRowFormat);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -291,7 +196,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setCellRowContentFormat($cellRowContentFormat)
|
||||
{
|
||||
$this->cellRowContentFormat = $cellRowContentFormat;
|
||||
$this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -305,7 +210,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setBorderFormat($borderFormat)
|
||||
{
|
||||
$this->borderFormat = $borderFormat;
|
||||
$this->table->getStyle()->setBorderFormat($borderFormat);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -319,7 +224,7 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function setPadType($padType)
|
||||
{
|
||||
$this->padType = $padType;
|
||||
$this->table->getStyle()->setPadType($padType);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -340,162 +245,11 @@ class TableHelper extends Helper
|
||||
*/
|
||||
public function render(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
$p = new \ReflectionProperty($this->table, 'output');
|
||||
$p->setAccessible(true);
|
||||
$p->setValue($this->table, $output);
|
||||
|
||||
$this->renderRowSeparator();
|
||||
$this->renderRow($this->headers, $this->cellHeaderFormat);
|
||||
if (!empty($this->headers)) {
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
foreach ($this->rows as $row) {
|
||||
$this->renderRow($row, $this->cellRowFormat);
|
||||
}
|
||||
if (!empty($this->rows)) {
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
|
||||
$this->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders horizontal header separator.
|
||||
*
|
||||
* Example: +-----+-----------+-------+
|
||||
*/
|
||||
private function renderRowSeparator()
|
||||
{
|
||||
if (0 === $count = $this->getNumberOfColumns()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->horizontalBorderChar && !$this->crossingChar) {
|
||||
return;
|
||||
}
|
||||
|
||||
$markup = $this->crossingChar;
|
||||
for ($column = 0; $column < $count; $column++) {
|
||||
$markup .= str_repeat($this->horizontalBorderChar, $this->getColumnWidth($column)).$this->crossingChar;
|
||||
}
|
||||
|
||||
$this->output->writeln(sprintf($this->borderFormat, $markup));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders vertical column separator.
|
||||
*/
|
||||
private function renderColumnSeparator()
|
||||
{
|
||||
$this->output->write(sprintf($this->borderFormat, $this->verticalBorderChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders table row.
|
||||
*
|
||||
* Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
*
|
||||
* @param array $row
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderRow(array $row, $cellFormat)
|
||||
{
|
||||
if (empty($row)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->renderColumnSeparator();
|
||||
for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
|
||||
$this->renderCell($row, $column, $cellFormat);
|
||||
$this->renderColumnSeparator();
|
||||
}
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders table cell with padding.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
* @param string $cellFormat
|
||||
*/
|
||||
private function renderCell(array $row, $column, $cellFormat)
|
||||
{
|
||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||
$width = $this->getColumnWidth($column);
|
||||
|
||||
// str_pad won't work properly with multi-byte strings, we need to fix the padding
|
||||
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($cell)) {
|
||||
$width += strlen($cell) - mb_strlen($cell, $encoding);
|
||||
}
|
||||
|
||||
$width += $this->strlen($cell) - self::strlenWithoutDecoration($this->output->getFormatter(), $cell);
|
||||
|
||||
$content = sprintf($this->cellRowContentFormat, $cell);
|
||||
|
||||
$this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->paddingChar, $this->padType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of columns for this table.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNumberOfColumns()
|
||||
{
|
||||
if (null !== $this->numberOfColumns) {
|
||||
return $this->numberOfColumns;
|
||||
}
|
||||
|
||||
$columns = array(0);
|
||||
$columns[] = count($this->headers);
|
||||
foreach ($this->rows as $row) {
|
||||
$columns[] = count($row);
|
||||
}
|
||||
|
||||
return $this->numberOfColumns = max($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets column width.
|
||||
*
|
||||
* @param integer $column
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getColumnWidth($column)
|
||||
{
|
||||
if (isset($this->columnWidths[$column])) {
|
||||
return $this->columnWidths[$column];
|
||||
}
|
||||
|
||||
$lengths = array(0);
|
||||
$lengths[] = $this->getCellWidth($this->headers, $column);
|
||||
foreach ($this->rows as $row) {
|
||||
$lengths[] = $this->getCellWidth($row, $column);
|
||||
}
|
||||
|
||||
return $this->columnWidths[$column] = max($lengths) + strlen($this->cellRowContentFormat) - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cell width.
|
||||
*
|
||||
* @param array $row
|
||||
* @param integer $column
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getCellWidth(array $row, $column)
|
||||
{
|
||||
return isset($row[$column]) ? self::strlenWithoutDecoration($this->output->getFormatter(), $row[$column]) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after rendering to cleanup cache data.
|
||||
*/
|
||||
private function cleanup()
|
||||
{
|
||||
$this->columnWidths = array();
|
||||
$this->numberOfColumns = null;
|
||||
$this->table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
|
251
src/Symfony/Component/Console/Helper/TableStyle.php
Normal file
251
src/Symfony/Component/Console/Helper/TableStyle.php
Normal file
@ -0,0 +1,251 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Helper;
|
||||
|
||||
/**
|
||||
* Defines the styles for a Table.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Саша Стаменковић <umpirsky@gmail.com>
|
||||
*/
|
||||
class TableStyle
|
||||
{
|
||||
private $paddingChar = ' ';
|
||||
private $horizontalBorderChar = '-';
|
||||
private $verticalBorderChar = '|';
|
||||
private $crossingChar = '+';
|
||||
private $cellHeaderFormat = '<info>%s</info>';
|
||||
private $cellRowFormat = '%s';
|
||||
private $cellRowContentFormat = ' %s ';
|
||||
private $borderFormat = '%s';
|
||||
private $padType = STR_PAD_RIGHT;
|
||||
|
||||
/**
|
||||
* Sets padding character, used for cell padding.
|
||||
*
|
||||
* @param string $paddingChar
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setPaddingChar($paddingChar)
|
||||
{
|
||||
if (!$paddingChar) {
|
||||
throw new \LogicException('The padding char must not be empty');
|
||||
}
|
||||
|
||||
$this->paddingChar = $paddingChar;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets padding character, used for cell padding.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPaddingChar()
|
||||
{
|
||||
return $this->paddingChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets horizontal border character.
|
||||
*
|
||||
* @param string $horizontalBorderChar
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setHorizontalBorderChar($horizontalBorderChar)
|
||||
{
|
||||
$this->horizontalBorderChar = $horizontalBorderChar;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets horizontal border character.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHorizontalBorderChar()
|
||||
{
|
||||
return $this->horizontalBorderChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets vertical border character.
|
||||
*
|
||||
* @param string $verticalBorderChar
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setVerticalBorderChar($verticalBorderChar)
|
||||
{
|
||||
$this->verticalBorderChar = $verticalBorderChar;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets vertical border character.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVerticalBorderChar()
|
||||
{
|
||||
return $this->verticalBorderChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets crossing character.
|
||||
*
|
||||
* @param string $crossingChar
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setCrossingChar($crossingChar)
|
||||
{
|
||||
$this->crossingChar = $crossingChar;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets crossing character.
|
||||
*
|
||||
* @return string $crossingChar
|
||||
*/
|
||||
public function getCrossingChar()
|
||||
{
|
||||
return $this->crossingChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets header cell format.
|
||||
*
|
||||
* @param string $cellHeaderFormat
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setCellHeaderFormat($cellHeaderFormat)
|
||||
{
|
||||
$this->cellHeaderFormat = $cellHeaderFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets header cell format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCellHeaderFormat()
|
||||
{
|
||||
return $this->cellHeaderFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets row cell format.
|
||||
*
|
||||
* @param string $cellRowFormat
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setCellRowFormat($cellRowFormat)
|
||||
{
|
||||
$this->cellRowFormat = $cellRowFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets row cell format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCellRowFormat()
|
||||
{
|
||||
return $this->cellRowFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets row cell content format.
|
||||
*
|
||||
* @param string $cellRowContentFormat
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setCellRowContentFormat($cellRowContentFormat)
|
||||
{
|
||||
$this->cellRowContentFormat = $cellRowContentFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets row cell content format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCellRowContentFormat()
|
||||
{
|
||||
return $this->cellRowContentFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets table border format.
|
||||
*
|
||||
* @param string $borderFormat
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setBorderFormat($borderFormat)
|
||||
{
|
||||
$this->borderFormat = $borderFormat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets table border format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBorderFormat()
|
||||
{
|
||||
return $this->borderFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cell padding type.
|
||||
*
|
||||
* @param integer $padType STR_PAD_*
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function setPadType($padType)
|
||||
{
|
||||
$this->padType = $padType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cell padding type.
|
||||
*
|
||||
* @param integer
|
||||
*/
|
||||
public function getPadType()
|
||||
{
|
||||
return $this->padType;
|
||||
}
|
||||
}
|
325
src/Symfony/Component/Console/Tests/Helper/TableTest.php
Normal file
325
src/Symfony/Component/Console/Tests/Helper/TableTest.php
Normal file
@ -0,0 +1,325 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Tests\Helper;
|
||||
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Helper\TableStyle;
|
||||
use Symfony\Component\Console\Output\StreamOutput;
|
||||
|
||||
class TableTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $stream;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->stream = fopen('php://memory', 'r+');
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
fclose($this->stream);
|
||||
$this->stream = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider testRenderProvider
|
||||
*/
|
||||
public function testRender($headers, $rows, $style, $expected)
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table
|
||||
->setHeaders($headers)
|
||||
->setRows($rows)
|
||||
->setStyle($style)
|
||||
;
|
||||
$table->render();
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider testRenderProvider
|
||||
*/
|
||||
public function testRenderAddRows($headers, $rows, $style, $expected)
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table
|
||||
->setHeaders($headers)
|
||||
->addRows($rows)
|
||||
->setStyle($style)
|
||||
;
|
||||
$table->render();
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider testRenderProvider
|
||||
*/
|
||||
public function testRenderAddRowsOneByOne($headers, $rows, $style, $expected)
|
||||
{
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table
|
||||
->setHeaders($headers)
|
||||
->setStyle($style)
|
||||
;
|
||||
foreach ($rows as $row) {
|
||||
$table->addRow($row);
|
||||
}
|
||||
$table->render();
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
public function testRenderProvider()
|
||||
{
|
||||
$books = array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
|
||||
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
|
||||
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
|
||||
);
|
||||
|
||||
return array(
|
||||
array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
$books,
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+--------------------------+------------------+
|
||||
| ISBN | Title | Author |
|
||||
+---------------+--------------------------+------------------+
|
||||
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
|
||||
+---------------+--------------------------+------------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
$books,
|
||||
'compact',
|
||||
<<<TABLE
|
||||
ISBN Title Author
|
||||
99921-58-10-7 Divine Comedy Dante Alighieri
|
||||
9971-5-0210-0 A Tale of Two Cities Charles Dickens
|
||||
960-425-059-0 The Lord of the Rings J. R. R. Tolkien
|
||||
80-902734-1-6 And Then There Were None Agatha Christie
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
$books,
|
||||
'borderless',
|
||||
<<<TABLE
|
||||
=============== ========================== ==================
|
||||
ISBN Title Author
|
||||
=============== ========================== ==================
|
||||
99921-58-10-7 Divine Comedy Dante Alighieri
|
||||
9971-5-0210-0 A Tale of Two Cities Charles Dickens
|
||||
960-425-059-0 The Lord of the Rings J. R. R. Tolkien
|
||||
80-902734-1-6 And Then There Were None Agatha Christie
|
||||
=============== ========================== ==================
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array('ISBN', 'Title'),
|
||||
array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0'),
|
||||
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
|
||||
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+--------------------------+------------------+
|
||||
| ISBN | Title | |
|
||||
+---------------+--------------------------+------------------+
|
||||
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
| 9971-5-0210-0 | | |
|
||||
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
|
||||
+---------------+--------------------------+------------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array(),
|
||||
array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0'),
|
||||
array('960-425-059-0', 'The Lord of the Rings', 'J. R. R. Tolkien'),
|
||||
array('80-902734-1-6', 'And Then There Were None', 'Agatha Christie'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+--------------------------+------------------+
|
||||
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
| 9971-5-0210-0 | | |
|
||||
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
|
||||
| 80-902734-1-6 | And Then There Were None | Agatha Christie |
|
||||
+---------------+--------------------------+------------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array("99921-58-10-7", "Divine\nComedy", "Dante Alighieri"),
|
||||
array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
|
||||
array("9971-5-0210-2", "Harry Potter\nand the Chamber of Secrets", "Rowling\nJoanne K."),
|
||||
array("960-425-059-0", "The Lord of the Rings", "J. R. R.\nTolkien"),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+----------------------------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+---------------+----------------------------+-----------------+
|
||||
| 99921-58-10-7 | Divine | Dante Alighieri |
|
||||
| | Comedy | |
|
||||
| 9971-5-0210-2 | Harry Potter | Rowling |
|
||||
| | and the Chamber of Secrets | Joanne K. |
|
||||
| 9971-5-0210-2 | Harry Potter | Rowling |
|
||||
| | and the Chamber of Secrets | Joanne K. |
|
||||
| 960-425-059-0 | The Lord of the Rings | J. R. R. |
|
||||
| | | Tolkien |
|
||||
+---------------+----------------------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array('ISBN', 'Title'),
|
||||
array(),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+------+-------+
|
||||
| ISBN | Title |
|
||||
+------+-------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
array(
|
||||
array(),
|
||||
array(),
|
||||
'default',
|
||||
'',
|
||||
),
|
||||
'Cell text with tags used for Output styling' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array('<info>99921-58-10-7</info>', '<error>Divine Comedy</error>', '<fg=blue;bg=white>Dante Alighieri</fg=blue;bg=white>'),
|
||||
array('9971-5-0210-0', 'A Tale of Two Cities', '<info>Charles Dickens</>'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+----------------------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+---------------+----------------------+-----------------+
|
||||
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
+---------------+----------------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell text with tags not used for Output styling' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array('<strong>99921-58-10-700</strong>', '<f>Divine Com</f>', 'Dante Alighieri'),
|
||||
array('9971-5-0210-0', 'A Tale of Two Cities', 'Charles Dickens'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+----------------------------------+----------------------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+----------------------------------+----------------------+-----------------+
|
||||
| <strong>99921-58-10-700</strong> | <f>Divine Com</f> | Dante Alighieri |
|
||||
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
+----------------------------------+----------------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testRenderMultiByte()
|
||||
{
|
||||
if (!function_exists('mb_strlen')) {
|
||||
$this->markTestSkipped('The "mbstring" extension is not available');
|
||||
}
|
||||
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table
|
||||
->setHeaders(array('■■'))
|
||||
->setRows(array(array(1234)))
|
||||
->setStyle('default')
|
||||
;
|
||||
$table->render();
|
||||
|
||||
$expected =
|
||||
<<<TABLE
|
||||
+------+
|
||||
| ■■ |
|
||||
+------+
|
||||
| 1234 |
|
||||
+------+
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
public function testStyle()
|
||||
{
|
||||
$style = new TableStyle();
|
||||
$style
|
||||
->setHorizontalBorderChar('.')
|
||||
->setVerticalBorderChar('.')
|
||||
->setCrossingChar('.')
|
||||
;
|
||||
|
||||
Table::setStyleDefinition('dotfull', $style);
|
||||
$table = new Table($output = $this->getOutputStream());
|
||||
$table
|
||||
->setHeaders(array('Foo'))
|
||||
->setRows(array(array('Bar')))
|
||||
->setStyle('dotfull');
|
||||
$table->render();
|
||||
|
||||
$expected =
|
||||
<<<TABLE
|
||||
.......
|
||||
. Foo .
|
||||
.......
|
||||
. Bar .
|
||||
.......
|
||||
|
||||
TABLE;
|
||||
|
||||
$this->assertEquals($expected, $this->getOutputContent($output));
|
||||
}
|
||||
|
||||
protected function getOutputStream()
|
||||
{
|
||||
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);
|
||||
}
|
||||
|
||||
protected function getOutputContent(StreamOutput $output)
|
||||
{
|
||||
rewind($output->getStream());
|
||||
|
||||
return str_replace(PHP_EOL, "\n", stream_get_contents($output->getStream()));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user