Skip to content

Commit 8861fc9

Browse files
committed
[Console] Added support for definition list
1 parent 545d38a commit 8861fc9

File tree

8 files changed

+201
-7
lines changed

8 files changed

+201
-7
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* added method `preventRedrawFasterThan()` and `forceRedrawSlowerThan()` on `ProgressBar`
99
* `Application` implements `ResetInterface`
1010
* marked all dispatched event classes as `@final`
11+
* added support form displaying table horizontally
1112

1213
4.3.0
1314
-----

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

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class Table
4949
*/
5050
private $rows = [];
5151

52+
private $horizontal = false;
53+
5254
/**
5355
* Column widths cache.
5456
*/
@@ -322,6 +324,13 @@ public function setFooterTitle(?string $title): self
322324
return $this;
323325
}
324326

327+
public function setHorizontal(bool $horizontal = true): self
328+
{
329+
$this->horizontal = $horizontal;
330+
331+
return $this;
332+
}
333+
325334
/**
326335
* Renders table to output.
327336
*
@@ -337,14 +346,35 @@ public function setFooterTitle(?string $title): self
337346
*/
338347
public function render()
339348
{
340-
$rows = array_merge($this->headers, [$divider = new TableSeparator()], $this->rows);
349+
$divider = new TableSeparator();
350+
if ($this->horizontal) {
351+
$rows = [];
352+
foreach ($this->headers[0] ?? [] as $i => $header) {
353+
$rows[$i] = [$header];
354+
foreach ($this->rows as $row) {
355+
if ($row instanceof TableSeparator) {
356+
continue;
357+
}
358+
if (isset($row[$i])) {
359+
$rows[$i][] = $row[$i];
360+
} elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
361+
// Noop, the there is "title"
362+
} else {
363+
$rows[$i][] = null;
364+
}
365+
}
366+
}
367+
} else {
368+
$rows = array_merge($this->headers, [$divider], $this->rows);
369+
}
370+
341371
$this->calculateNumberOfColumns($rows);
342372

343373
$rows = $this->buildTableRows($rows);
344374
$this->calculateColumnsWidth($rows);
345375

346-
$isHeader = true;
347-
$isFirstRow = false;
376+
$isHeader = !$this->horizontal;
377+
$isFirstRow = $this->horizontal;
348378
foreach ($rows as $row) {
349379
if ($divider === $row) {
350380
$isHeader = false;
@@ -369,8 +399,11 @@ public function render()
369399
$this->renderRowSeparator(self::SEPARATOR_TOP, $this->headerTitle, $this->style->getHeaderTitleFormat());
370400
}
371401
}
372-
373-
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
402+
if ($this->horizontal) {
403+
$this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
404+
} else {
405+
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
406+
}
374407
}
375408
$this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
376409

@@ -450,13 +483,17 @@ private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE)
450483
*
451484
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
452485
*/
453-
private function renderRow(array $row, string $cellFormat)
486+
private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null)
454487
{
455488
$rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
456489
$columns = $this->getRowColumns($row);
457490
$last = \count($columns) - 1;
458491
foreach ($columns as $i => $column) {
459-
$rowContent .= $this->renderCell($row, $column, $cellFormat);
492+
if ($firstCellFormat && 0 === $i) {
493+
$rowContent .= $this->renderCell($row, $column, $firstCellFormat);
494+
} else {
495+
$rowContent .= $this->renderCell($row, $column, $cellFormat);
496+
}
460497
$rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE);
461498
}
462499
$this->output->writeln($rowContent);

src/Symfony/Component/Console/Style/SymfonyStyle.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111

1212
namespace Symfony\Component\Console\Style;
1313

14+
use Symfony\Component\Console\Exception\InvalidArgumentException;
1415
use Symfony\Component\Console\Exception\RuntimeException;
1516
use Symfony\Component\Console\Formatter\OutputFormatter;
1617
use Symfony\Component\Console\Helper\Helper;
1718
use Symfony\Component\Console\Helper\ProgressBar;
1819
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
1920
use Symfony\Component\Console\Helper\Table;
21+
use Symfony\Component\Console\Helper\TableCell;
22+
use Symfony\Component\Console\Helper\TableSeparator;
2023
use Symfony\Component\Console\Input\InputInterface;
2124
use Symfony\Component\Console\Output\BufferedOutput;
2225
use Symfony\Component\Console\Output\OutputInterface;
@@ -190,6 +193,59 @@ public function table(array $headers, array $rows)
190193
$this->newLine();
191194
}
192195

196+
/**
197+
* {@inheritdoc}
198+
*/
199+
public function horizontalTable(array $headers, array $rows)
200+
{
201+
$style = clone Table::getStyleDefinition('symfony-style-guide');
202+
$style->setCellHeaderFormat('<info>%s</info>');
203+
204+
$table = new Table($this);
205+
$table->setHeaders($headers);
206+
$table->setRows($rows);
207+
$table->setStyle($style);
208+
$table->setHorizontal(true);
209+
210+
$table->render();
211+
$this->newLine();
212+
}
213+
214+
public function definitionList(...$list)
215+
{
216+
$style = clone Table::getStyleDefinition('symfony-style-guide');
217+
$style->setCellHeaderFormat('<info>%s</info>');
218+
219+
$table = new Table($this);
220+
$headers = [];
221+
$row = [];
222+
foreach ($list as $value) {
223+
if ($value instanceof TableSeparator) {
224+
$headers[] = $value;
225+
$row[] = $value;
226+
continue;
227+
}
228+
if (\is_string($value)) {
229+
$headers[] = new TableCell($value, ['colspan' => 2]);
230+
$row[] = null;
231+
continue;
232+
}
233+
if (!\is_array($value)) {
234+
throw new InvalidArgumentException('Value should be an array, string, or an instance of TableSeparator.');
235+
}
236+
$headers[] = key($value);
237+
$row[] = current($value);
238+
}
239+
240+
$table->setHeaders($headers);
241+
$table->setRows([$row]);
242+
$table->setHorizontal();
243+
$table->setStyle($style);
244+
245+
$table->render();
246+
$this->newLine();
247+
}
248+
193249
/**
194250
* {@inheritdoc}
195251
*/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Helper\TableSeparator;
4+
use Symfony\Component\Console\Input\InputInterface;
5+
use Symfony\Component\Console\Output\OutputInterface;
6+
use Symfony\Component\Console\Style\SymfonyStyle;
7+
8+
return function (InputInterface $input, OutputInterface $output) {
9+
$output = new SymfonyStyle($input, $output);
10+
11+
$output->definitionList(
12+
['foo' => 'bar'],
13+
new TableSeparator(),
14+
'this is a title',
15+
new TableSeparator(),
16+
['foo2' => 'bar2']
17+
);
18+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
use Symfony\Component\Console\Helper\TableCell;
4+
use Symfony\Component\Console\Input\InputInterface;
5+
use Symfony\Component\Console\Output\OutputInterface;
6+
use Symfony\Component\Console\Style\SymfonyStyle;
7+
8+
//Ensure formatting tables when using multiple headers with TableCell
9+
return function (InputInterface $input, OutputInterface $output) {
10+
$output = new SymfonyStyle($input, $output);
11+
$output->horizontalTable(['a', 'b', 'c', 'd'], [[1, 2, 3], [4, 5], [7, 8, 9]]);
12+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---------- ---------
2+
foo bar
3+
---------- ---------
4+
this is a title
5+
---------- ---------
6+
foo2 bar2
7+
---------- ---------
8+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--- --- --- ---
2+
a 1 4 7
3+
b 2 5 8
4+
c 3 9
5+
d
6+
--- --- --- ---
7+

src/Symfony/Component/Console/Tests/Helper/TableTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,61 @@ public function testBoxedStyleWithColspan()
11251125
$this->assertSame($expected, $this->getOutputContent($output));
11261126
}
11271127

1128+
public function provideRenderHorizontalTests()
1129+
{
1130+
$headers = ['foo', 'bar', 'baz'];
1131+
$rows = [['one', 'two', 'tree'], ['1', '2', '3']];
1132+
$expected = <<<EOTXT
1133+
+-----+------+---+
1134+
| foo | one | 1 |
1135+
| bar | two | 2 |
1136+
| baz | tree | 3 |
1137+
+-----+------+---+
1138+
1139+
EOTXT;
1140+
yield [$headers, $rows, $expected];
1141+
1142+
$headers = ['foo', 'bar', 'baz'];
1143+
$rows = [['one', 'two'], ['1']];
1144+
$expected = <<<EOTXT
1145+
+-----+-----+---+
1146+
| foo | one | 1 |
1147+
| bar | two | |
1148+
| baz | | |
1149+
+-----+-----+---+
1150+
1151+
EOTXT;
1152+
yield [$headers, $rows, $expected];
1153+
1154+
$headers = ['foo', 'bar', 'baz'];
1155+
$rows = [['one', 'two', 'tree'], new TableSeparator(), ['1', '2', '3']];
1156+
$expected = <<<EOTXT
1157+
+-----+------+---+
1158+
| foo | one | 1 |
1159+
| bar | two | 2 |
1160+
| baz | tree | 3 |
1161+
+-----+------+---+
1162+
1163+
EOTXT;
1164+
yield [$headers, $rows, $expected];
1165+
}
1166+
1167+
/**
1168+
* @dataProvider provideRenderHorizontalTests
1169+
*/
1170+
public function testRenderHorizontal(array $headers, array $rows, string $expected)
1171+
{
1172+
$table = new Table($output = $this->getOutputStream());
1173+
$table
1174+
->setHeaders($headers)
1175+
->setRows($rows)
1176+
->setHorizontal()
1177+
;
1178+
$table->render();
1179+
1180+
$this->assertEquals($expected, $this->getOutputContent($output));
1181+
}
1182+
11281183
protected function getOutputStream($decorated = false)
11291184
{
11301185
return new StreamOutput($this->stream, StreamOutput::VERBOSITY_NORMAL, $decorated);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy