feature #14991 [Console][Table] allow multiple render() calls. (jaytaph)

This PR was merged into the 2.8 branch.

Discussion
----------

[Console][Table] allow multiple render() calls.

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Fixed tickets  | ~
| Tests pass?   | yes
| License       | MIT

This is a cherry-pick of #14983.

Commits
-------

b93bcc1 Fixed colspan issues with multiple render() calls
This commit is contained in:
Fabien Potencier 2015-06-22 18:34:55 +02:00
commit 9f86195158
2 changed files with 48 additions and 20 deletions

View File

@ -205,24 +205,26 @@ class Table
public function render() public function render()
{ {
$this->calculateNumberOfColumns(); $this->calculateNumberOfColumns();
$this->rows = $this->buildTableRows($this->rows); $rows = $this->buildTableRows($this->rows);
$this->headers = $this->buildTableRows($this->headers); $headers = $this->buildTableRows($this->headers);
$this->calculateColumnsWidth(array_merge($headers, $rows));
$this->renderRowSeparator(); $this->renderRowSeparator();
if (!empty($this->headers)) { if (!empty($headers)) {
foreach ($this->headers as $header) { foreach ($headers as $header) {
$this->renderRow($header, $this->style->getCellHeaderFormat()); $this->renderRow($header, $this->style->getCellHeaderFormat());
$this->renderRowSeparator(); $this->renderRowSeparator();
} }
} }
foreach ($this->rows as $row) { foreach ($rows as $row) {
if ($row instanceof TableSeparator) { if ($row instanceof TableSeparator) {
$this->renderRowSeparator(); $this->renderRowSeparator();
} else { } else {
$this->renderRow($row, $this->style->getCellRowFormat()); $this->renderRow($row, $this->style->getCellRowFormat());
} }
} }
if (!empty($this->rows)) { if (!empty($rows)) {
$this->renderRowSeparator(); $this->renderRowSeparator();
} }
@ -246,7 +248,7 @@ class Table
$markup = $this->style->getCrossingChar(); $markup = $this->style->getCrossingChar();
for ($column = 0; $column < $count; $column++) { for ($column = 0; $column < $count; $column++) {
$markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->getColumnWidth($column)).$this->style->getCrossingChar(); $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
} }
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
@ -292,11 +294,11 @@ class Table
private function renderCell(array $row, $column, $cellFormat) private function renderCell(array $row, $column, $cellFormat)
{ {
$cell = isset($row[$column]) ? $row[$column] : ''; $cell = isset($row[$column]) ? $row[$column] : '';
$width = $this->getColumnWidth($column); $width = $this->columnWidths[$column];
if ($cell instanceof TableCell && $cell->getColspan() > 1) { if ($cell instanceof TableCell && $cell->getColspan() > 1) {
// add the width of the following columns(numbers of colspan). // add the width of the following columns(numbers of colspan).
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
$width += $this->getColumnSeparatorWidth() + $this->getColumnWidth($nextColumn); $width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
} }
} }
@ -509,13 +511,11 @@ class Table
* *
* @return int * @return int
*/ */
private function getColumnWidth($column) private function calculateColumnsWidth($rows)
{ {
if (isset($this->columnWidths[$column])) { for ($column = 0; $column < $this->numberOfColumns; $column++) {
return $this->columnWidths[$column]; $lengths = array();
} foreach ($rows as $row) {
foreach (array_merge($this->headers, $this->rows) as $row) {
if ($row instanceof TableSeparator) { if ($row instanceof TableSeparator) {
continue; continue;
} }
@ -523,7 +523,8 @@ class Table
$lengths[] = $this->getCellWidth($row, $column); $lengths[] = $this->getCellWidth($row, $column);
} }
return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
}
} }
/** /**

View File

@ -427,7 +427,7 @@ TABLE
array('ISBN', 'Author'), array('ISBN', 'Author'),
array( array(
array( array(
new TableCell("9971-5-0210-0", array('rowspan' => 3, 'colspan' => 1)), new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)),
'Dante Alighieri', 'Dante Alighieri',
), ),
array(new TableSeparator()), array(new TableSeparator()),
@ -554,6 +554,33 @@ TABLE;
$this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works'); $this->assertEquals($table, $table->addRow(new TableSeparator()), 'fluent interface on addRow() with a single TableSeparator() works');
} }
public function testRenderMultiCalls()
{
$table = new Table($output = $this->getOutputStream());
$table->setRows(array(
array(new TableCell('foo', array('colspan' => 2))),
));
$table->render();
$table->render();
$table->render();
$expected =
<<<TABLE
+---+--+
| foo |
+---+--+
+---+--+
| foo |
+---+--+
+---+--+
| foo |
+---+--+
TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
protected function getOutputStream() protected function getOutputStream()
{ {
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false); return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, false);