From 6df3b2d2b6e8db9827d840770f6a432b3ea2897f Mon Sep 17 00:00:00 2001 From: Vladimir Valikayev Date: Wed, 26 Mar 2025 15:33:23 +0700 Subject: [PATCH] [Console] Table counts wrong column width when using colspan and `setColumnMaxWidth()` --- .../Component/Console/Helper/Table.php | 44 ++++++++++++++++++- .../Console/Tests/Helper/TableTest.php | 16 +++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Console/Helper/Table.php b/src/Symfony/Component/Console/Helper/Table.php index 809c659283d4..0ef771dd4bd5 100644 --- a/src/Symfony/Component/Console/Helper/Table.php +++ b/src/Symfony/Component/Console/Helper/Table.php @@ -629,8 +629,48 @@ private function buildTableRows(array $rows): TableRows foreach ($rows[$rowKey] as $column => $cell) { $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1; - if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) { - $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan); + $minWrappedWidth = 0; + $widthApplied = []; + $lengthColumnBorder = $this->getColumnSeparatorWidth() + Helper::width($this->style->getCellRowContentFormat()) - 2; + for ($i = $column; $i < ($column + $colspan); ++$i) { + if (isset($this->columnMaxWidths[$i])) { + $minWrappedWidth += $this->columnMaxWidths[$i]; + $widthApplied[] = ['type' => 'max', 'column' => $i]; + } elseif (($this->columnWidths[$i] ?? 0) > 0 && $colspan > 1) { + $minWrappedWidth += $this->columnWidths[$i]; + $widthApplied[] = ['type' => 'min', 'column' => $i]; + } + } + if (1 === \count($widthApplied)) { + if ($colspan > 1) { + $minWrappedWidth *= $colspan; // previous logic + } + } elseif (\count($widthApplied) > 1) { + $minWrappedWidth += (\count($widthApplied) - 1) * $lengthColumnBorder; + } + + $cellWidth = Helper::width(Helper::removeDecoration($formatter, $cell)); + if ($minWrappedWidth && $cellWidth > $minWrappedWidth) { + $cell = $formatter->formatAndWrap($cell, $minWrappedWidth); + } + // update minimal columnWidths for spanned columns + if ($colspan > 1 && $minWrappedWidth > 0) { + $columnsMinWidthProcessed = []; + $cellWidth = min($cellWidth, $minWrappedWidth); + foreach ($widthApplied as $item) { + if ('max' === $item['type'] && $cellWidth >= $this->columnMaxWidths[$item['column']]) { + $minWidthColumn = $this->columnMaxWidths[$item['column']]; + $this->columnWidths[$item['column']] = $minWidthColumn; + $columnsMinWidthProcessed[$item['column']] = true; + $cellWidth -= $minWidthColumn + $lengthColumnBorder; + } + } + for ($i = $column; $i < ($column + $colspan); ++$i) { + if (isset($columnsMinWidthProcessed[$i])) { + continue; + } + $this->columnWidths[$i] = $cellWidth + $lengthColumnBorder; + } } if (!str_contains($cell ?? '', "\n")) { continue; diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php index 3a6b2b724ebc..bb1b96346b60 100644 --- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php @@ -1576,17 +1576,17 @@ public function testWithColspanAndMaxWith() $expected = <<