8000 Console Table vertical rendering · symfony/symfony@90f54fe · GitHub
[go: up one dir, main page]

Skip to content

Commit 90f54fe

Browse files
committed
Console Table vertical rendering
Using an enum instead of 2 separated booleans Rephrase changelog for better consistency
1 parent cfd44fb commit 90f54fe

File tree

3 files changed

+428
-7
lines changed

3 files changed

+428
-7
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
6.1
55
---
66

7+
* Add support to display table vertically when calling setVertical()
78
* Add method `__toString()` to `InputInterface`
89
* Deprecate `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead
910
* Add suggested values for arguments and options in input definition, for input completion

src/Symfony/Component/Console/Helper/Table.php

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class Table
3535
private const SEPARATOR_BOTTOM = 3;
3636
private const BORDER_OUTSIDE = 0;
3737
private const BORDER_INSIDE = 1;
38+
private const DISPLAY_ORIENTATION_DEFAULT = 'default';
39+
private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal';
40+
private const DISPLAY_ORIENTATION_VERTICAL = 'vertical';
3841

3942
private ?string $headerTitle = null;
4043
private ?string $footerTitle = null;
@@ -49,6 +52,7 @@ class Table
4952
private array $columnWidths = [];
5053
private array $columnMaxWidths = [];
5154
private bool $rendered = false;
55+
private string $displayOrientation = self::DISPLAY_ORIENTATION_DEFAULT;
5256

5357
private static array $styles;
5458

@@ -277,7 +281,14 @@ public function setFooterTitle(?string $title): static
277281
*/
278282
public function setHorizontal(bool $horizontal = true): static
279283
{
280-
$this->horizontal = $horizontal;
284+
$this->displayOrientation = $horizontal ? self::DISPLAY_ORIENTATION_HORIZONTAL : self::DISPLAY_ORIENTATION_DEFAULT;
285+
286+
return $this;
287+
}
288+
289+
public function setVertical(bool $vertical = true): self
290+
{
291+
$this->displayOrientation = $vertical ? self::DISPLAY_ORIENTATION_VERTICAL : self::DISPLAY_ORIENTATION_DEFAULT;
281292

282293
return $this;
283294
}
@@ -298,8 +309,13 @@ public function setHorizontal(bool $horizontal = true): static
298309
public function render()
299310
{
300311
$divider = new TableSeparator();
301-
if ($this->horizontal) {
302-
$rows = [];
312+
$isCellWithColspan = static fn ($cell): bool => $cell instanceof TableCell && $cell->getColspan() >= 2;
313+
314+
$horizontal = self::DISPLAY_ORIENTATION_HORIZONTAL === $this->displayOrientation;
315+
$vertical = self::DISPLAY_ORIENTATION_VERTICAL === $this->displayOrientation;
316+
317+
$rows = [];
318+
if ($horizontal) {
303319
foreach ($this->headers[0] ?? [] as $i => $header) {
304320
$rows[$i] = [$header];
305321
foreach ($this->rows as $row) {
@@ -308,13 +324,42 @@ public function render()
308324
}
309325
if (isset($row[$i])) {
310326
$rows[$i][] = $row[$i];
311-
} elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
327+
} elseif ($isCellWithColspan($rows[$i][0])) {
312328
// Noop, there is a "title"
313329
} else {
314330
$rows[$i][] = null;
315331
}
316332
}
317333
}
334+
} elseif ($vertical) {
335+
$maxHeaderLength = array_reduce($this->headers[0] ?? [], static fn (int $max, string $header) => max($max, mb_strlen($header)), 0);
336+
337+
foreach ($this->rows as $row) {
338+
if ($row instanceof TableSeparator) {
339+
continue;
340+
}
341+
342+
if (0 < \count($rows)) {
343+
$rows[] = [$divider];
344+
}
345+
346+
$containsColspan = 0 < \count(array_filter($row, $isCellWithColspan));
347+
348+
$headers = $this->headers[0] ?? [];
349+
$maxRows = max(\count($headers), \count($row));
350+
for ($i = 0; $i < $maxRows; ++$i) {
351+
$cell = (string) ($row[$i] ?? '');
352+
if ([] !== $headers && !$containsColspan) {
353+
$rows[] = [sprintf(
354+
'<comment>%s</>: %s',
355+
str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT),
356+
$cell
357+
)];
358+
} elseif (!empty($cell)) {
359+
$rows[] = [$cell];
360+
}
361+
}
362+
}
318363
} else {
319364
$rows = array_merge($this->headers, [$divider], $this->rows);
320365
}
@@ -324,8 +369,8 @@ public function render()
324369
$rows = $this->buildTableRows($rows);
325370
$this->calculateColumnsWidth($rows);
326371

327-
$isHeader = !$this->horizontal;
328-
$isFirstRow = $this->horizontal;
372+
$isHeader = !$horizontal;
373+
$isFirstRow = $horizontal;
329374
$hasTitle = (bool) $this->headerTitle;
330375
foreach ($rows as $row) {
331376
if ($divider === $row) {
@@ -352,7 +397,12 @@ public function render()
352397
$isFirstRow = false;
353398
$hasTitle = false;
354399
}
355-
if ($this->horizontal) {
400+
if ($vertical) {
401+
$isHeader = false;
402+
$isFirstRow = false;
403+
}
404+
405+
if ($horizontal) {
356406
$this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
357407
} else {
358408
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());

0 commit comments

Comments
 (0)
0