diff --git a/UPGRADE-4.1.md b/UPGRADE-4.1.md index 4c20425c7c..2ceebd3dee 100644 --- a/UPGRADE-4.1.md +++ b/UPGRADE-4.1.md @@ -7,6 +7,11 @@ Config * Implementing `ParentNodeDefinitionInterface` without the `getChildNodeDefinitions()` method is deprecated and will be unsupported in 5.0. +Console +------- + + * Deprecated the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`. + EventDispatcher --------------- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index ddf6a96517..7186885b1c 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -6,6 +6,11 @@ Config * Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`. +Console +------- + + * Removed the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`. + EventDispatcher --------------- diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index d54f63684a..60a2d4cbc5 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -21,9 +21,14 @@ use Symfony\Component\Console\Exception\InvalidArgumentException; * @author Саша Стаменковић * @author Abdellatif Ait boudad * @author Max Grigorian + * @author Dany Maillard */ class Table { + private const SEPARATOR_TOP = 0; + private const SEPARATOR_MID = 1; + private const SEPARATOR_BOTTOM = 2; + /** * Table headers. */ @@ -300,7 +305,7 @@ class Table } if ($isHeader || $isFirstRow) { - $this->renderRowSeparator(); + $this->renderRowSeparator($isFirstRow ? self::SEPARATOR_MID : self::SEPARATOR_TOP); if ($isFirstRow) { $isFirstRow = false; } @@ -308,7 +313,7 @@ class Table $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); } - $this->renderRowSeparator(); + $this->renderRowSeparator(self::SEPARATOR_BOTTOM); $this->cleanup(); } @@ -318,7 +323,7 @@ class Table * * Example: +-----+-----------+-------+ */ - private function renderRowSeparator() + private function renderRowSeparator(int $type = self::SEPARATOR_MID) { if (0 === $count = $this->numberOfColumns) { return; @@ -328,9 +333,19 @@ class Table return; } - $markup = $this->style->getCrossingChar(); + $chars = $this->style->getCrossingChars(); + if (self::SEPARATOR_MID === $type) { + list($leftChar, $midChar, $rightChar) = array($chars[8], $chars[0], $chars[4]); + } elseif (self::SEPARATOR_TOP === $type) { + list($leftChar, $midChar, $rightChar) = array($chars[1], $chars[2], $chars[3]); + } else { + list($leftChar, $midChar, $rightChar) = array($chars[7], $chars[6], $chars[5]); + } + + $markup = $leftChar; for ($column = 0; $column < $count; ++$column) { - $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar(); + $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]); + $markup .= $column === $count - 1 ? $rightChar : $midChar; } $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); @@ -628,14 +643,14 @@ class Table $borderless ->setHorizontalBorderChar('=') ->setVerticalBorderChar(' ') - ->setCrossingChar(' ') + ->setDefaultCrossingChar(' ') ; $compact = new TableStyle(); $compact ->setHorizontalBorderChar('') ->setVerticalBorderChar(' ') - ->setCrossingChar('') + ->setDefaultCrossingChar('') ->setCellRowContentFormat('%s') ; @@ -643,14 +658,14 @@ class Table $styleGuide ->setHorizontalBorderChar('-') ->setVerticalBorderChar(' ') - ->setCrossingChar(' ') + ->setDefaultCrossingChar(' ') ->setCellHeaderFormat('%s') ; $box = (new TableStyle()) ->setHorizontalBorderChar('─') ->setVerticalBorderChar('│') - ->setCrossingChar('┼') + ->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├') ; return array( diff --git a/src/Symfony/Component/Console/Helper/TableStyle.php b/src/Symfony/Component/Console/Helper/TableStyle.php index 2999c76f86..0c5d13e9f7 100644 --- a/src/Symfony/Component/Console/Helper/TableStyle.php +++ b/src/Symfony/Component/Console/Helper/TableStyle.php @@ -19,6 +19,7 @@ use Symfony\Component\Console\Exception\LogicException; * * @author Fabien Potencier * @author Саша Стаменковић + * @author Dany Maillard */ class TableStyle { @@ -26,6 +27,14 @@ class TableStyle private $horizontalBorderChar = '-'; private $verticalBorderChar = '|'; private $crossingChar = '+'; + private $crossingTopRightChar = '+'; + private $crossingTopMidChar = '+'; + private $crossingTopLeftChar = '+'; + private $crossingMidRightChar = '+'; + private $crossingBottomRightChar = '+'; + private $crossingBottomMidChar = '+'; + private $crossingBottomLeftChar = '+'; + private $crossingMidLeftChar = '+'; private $cellHeaderFormat = '%s'; private $cellRowFormat = '%s'; private $cellRowContentFormat = ' %s '; @@ -108,18 +117,69 @@ class TableStyle return $this->verticalBorderChar; } + /** + * Sets crossing characters. + * + * Example: + * + * 1---------------2-----------------------2------------------3 + * | ISBN | Title | Author | + * 8---------------0-----------------------0------------------4 + * | 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 | + * 7---------------6-----------------------6------------------5 + * + * + * @param string $cross Crossing char (see #0 of example) + * @param string $topLeft Top left char (see #1 of example) + * @param string $topMid Top mid char (see #2 of example) + * @param string $topRight Top right char (see #3 of example) + * @param string $midRight Mid right char (see #4 of example) + * @param string $bottomRight Bottom right char (see #5 of example) + * @param string $bottomMid Bottom mid char (see #6 of example) + * @param string $bottomLeft Bottom left char (see #7 of example) + * @param string $midLeft Mid left char (see #8 of example) + */ + public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft): self + { + $this->crossingChar = $cross; + $this->crossingTopLeftChar = $topLeft; + $this->crossingTopMidChar = $topMid; + $this->crossingTopRightChar = $topRight; + $this->crossingMidRightChar = $midRight; + $this->crossingBottomRightChar = $bottomRight; + $this->crossingBottomMidChar = $bottomMid; + $this->crossingBottomLeftChar = $bottomLeft; + $this->crossingMidLeftChar = $midLeft; + + return $this; + } + + /** + * Sets default crossing character used for each cross. + * + * @see {@link setCrossingChars()} for setting each crossing individually. + */ + public function setDefaultCrossingChar(string $char): self + { + return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char); + } + /** * Sets crossing character. * * @param string $crossingChar * * @return $this + * + * @deprecated since Symfony 4.1. Use {@link setDefaultCrossingChar()} instead. */ public function setCrossingChar($crossingChar) { - $this->crossingChar = $crossingChar; + @trigger_error(sprintf('Method %s() is deprecated since Symfony 4.1. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED); - return $this; + return $this->setDefaultCrossingChar($crossingChar); } /** @@ -132,6 +192,26 @@ class TableStyle return $this->crossingChar; } + /** + * Gets crossing characters. + * + * @internal + */ + public function getCrossingChars(): array + { + return array( + $this->crossingChar, + $this->crossingTopLeftChar, + $this->crossingTopMidChar, + $this->crossingTopRightChar, + $this->crossingMidRightChar, + $this->crossingBottomRightChar, + $this->crossingBottomMidChar, + $this->crossingBottomLeftChar, + $this->crossingMidLeftChar, + ); + } + /** * Sets header cell format. * diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php index 380699528d..ab9e0e821a 100644 --- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php @@ -143,14 +143,14 @@ TABLE $books, 'box', <<<'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 ), @@ -628,7 +628,7 @@ TABLE; $style ->setHorizontalBorderChar('.') ->setVerticalBorderChar('.') - ->setCrossingChar('.') + ->setDefaultCrossingChar('.') ; Table::setStyleDefinition('dotfull', $style);