From b93bcc1153f00e7078987690bb3b628fe4445c7e Mon Sep 17 00:00:00 2001 From: Joshua Thijssen Date: Sun, 14 Jun 2015 20:11:27 +0200 Subject: [PATCH] Fixed colspan issues with multiple render() calls --- .../Component/Console/Helper/Table.php | 39 ++++++++++--------- .../Console/Tests/Helper/TableTest.php | 37 +++++++++++++++--- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index 392d4652ef..d480774630 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -205,24 +205,26 @@ class Table public function render() { $this->calculateNumberOfColumns(); - $this->rows = $this->buildTableRows($this->rows); - $this->headers = $this->buildTableRows($this->headers); + $rows = $this->buildTableRows($this->rows); + $headers = $this->buildTableRows($this->headers); + + $this->calculateColumnsWidth(array_merge($headers, $rows)); $this->renderRowSeparator(); - if (!empty($this->headers)) { - foreach ($this->headers as $header) { + if (!empty($headers)) { + foreach ($headers as $header) { $this->renderRow($header, $this->style->getCellHeaderFormat()); $this->renderRowSeparator(); } } - foreach ($this->rows as $row) { + foreach ($rows as $row) { if ($row instanceof TableSeparator) { $this->renderRowSeparator(); } else { $this->renderRow($row, $this->style->getCellRowFormat()); } } - if (!empty($this->rows)) { + if (!empty($rows)) { $this->renderRowSeparator(); } @@ -246,7 +248,7 @@ class Table $markup = $this->style->getCrossingChar(); 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)); @@ -292,11 +294,11 @@ class Table private function renderCell(array $row, $column, $cellFormat) { $cell = isset($row[$column]) ? $row[$column] : ''; - $width = $this->getColumnWidth($column); + $width = $this->columnWidths[$column]; if ($cell instanceof TableCell && $cell->getColspan() > 1) { // add the width of the following columns(numbers of colspan). foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { - $width += $this->getColumnSeparatorWidth() + $this->getColumnWidth($nextColumn); + $width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn]; } } @@ -509,21 +511,20 @@ class Table * * @return int */ - private function getColumnWidth($column) + private function calculateColumnsWidth($rows) { - if (isset($this->columnWidths[$column])) { - return $this->columnWidths[$column]; - } + for ($column = 0; $column < $this->numberOfColumns; $column++) { + $lengths = array(); + foreach ($rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } - foreach (array_merge($this->headers, $this->rows) as $row) { - if ($row instanceof TableSeparator) { - continue; + $lengths[] = $this->getCellWidth($row, $column); } - $lengths[] = $this->getCellWidth($row, $column); + $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; } - - return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2; } /** diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php index 3db51f45b0..973b066561 100644 --- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php @@ -180,10 +180,10 @@ 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"), + 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', << 3, 'colspan' => 1)), + new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 1)), 'Dante Alighieri', ), array(new TableSeparator()), @@ -547,6 +547,33 @@ TABLE; | Bar3 | +------+ +TABLE; + + $this->assertEquals($expected, $this->getOutputContent($output)); + } + + 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 = +<<
assertEquals($expected, $this->getOutputContent($output));