package and depencies
This commit is contained in:
233
vendor/symfony/console/Helper/Table.php
vendored
233
vendor/symfony/console/Helper/Table.php
vendored
@@ -35,70 +35,31 @@ class Table
|
||||
private const SEPARATOR_BOTTOM = 3;
|
||||
private const BORDER_OUTSIDE = 0;
|
||||
private const BORDER_INSIDE = 1;
|
||||
private const DISPLAY_ORIENTATION_DEFAULT = 'default';
|
||||
private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal';
|
||||
private const DISPLAY_ORIENTATION_VERTICAL = 'vertical';
|
||||
|
||||
private $headerTitle;
|
||||
private $footerTitle;
|
||||
private ?string $headerTitle = null;
|
||||
private ?string $footerTitle = null;
|
||||
private array $headers = [];
|
||||
private array $rows = [];
|
||||
private array $effectiveColumnWidths = [];
|
||||
private int $numberOfColumns;
|
||||
private OutputInterface $output;
|
||||
private TableStyle $style;
|
||||
private array $columnStyles = [];
|
||||
private array $columnWidths = [];
|
||||
private array $columnMaxWidths = [];
|
||||
private bool $rendered = false;
|
||||
private string $displayOrientation = self::DISPLAY_ORIENTATION_DEFAULT;
|
||||
|
||||
/**
|
||||
* Table headers.
|
||||
*/
|
||||
private $headers = [];
|
||||
|
||||
/**
|
||||
* Table rows.
|
||||
*/
|
||||
private $rows = [];
|
||||
private $horizontal = false;
|
||||
|
||||
/**
|
||||
* Column widths cache.
|
||||
*/
|
||||
private $effectiveColumnWidths = [];
|
||||
|
||||
/**
|
||||
* Number of columns cache.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $numberOfColumns;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
|
||||
/**
|
||||
* @var TableStyle
|
||||
*/
|
||||
private $style;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $columnStyles = [];
|
||||
|
||||
/**
|
||||
* User set column widths.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $columnWidths = [];
|
||||
private $columnMaxWidths = [];
|
||||
|
||||
/**
|
||||
* @var array<string, TableStyle>|null
|
||||
*/
|
||||
private static $styles;
|
||||
|
||||
private $rendered = false;
|
||||
private static array $styles;
|
||||
|
||||
public function __construct(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
self::$styles ??= self::initStyles();
|
||||
|
||||
$this->setStyle('default');
|
||||
}
|
||||
@@ -108,39 +69,27 @@ class Table
|
||||
*/
|
||||
public static function setStyleDefinition(string $name, TableStyle $style)
|
||||
{
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
self::$styles ??= self::initStyles();
|
||||
|
||||
self::$styles[$name] = $style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a style definition by name.
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public static function getStyleDefinition(string $name)
|
||||
public static function getStyleDefinition(string $name): TableStyle
|
||||
{
|
||||
if (!self::$styles) {
|
||||
self::$styles = self::initStyles();
|
||||
}
|
||||
self::$styles ??= self::initStyles();
|
||||
|
||||
if (isset(self::$styles[$name])) {
|
||||
return self::$styles[$name];
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
return self::$styles[$name] ?? throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets table style.
|
||||
*
|
||||
* @param TableStyle|string $name The style name or a TableStyle instance
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStyle($name)
|
||||
public function setStyle(TableStyle|string $name): static
|
||||
{
|
||||
$this->style = $this->resolveStyle($name);
|
||||
|
||||
@@ -149,10 +98,8 @@ class Table
|
||||
|
||||
/**
|
||||
* Gets the current table style.
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function getStyle()
|
||||
public function getStyle(): TableStyle
|
||||
{
|
||||
return $this->style;
|
||||
}
|
||||
@@ -164,7 +111,7 @@ class Table
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnStyle(int $columnIndex, $name)
|
||||
public function setColumnStyle(int $columnIndex, TableStyle|string $name): static
|
||||
{
|
||||
$this->columnStyles[$columnIndex] = $this->resolveStyle($name);
|
||||
|
||||
@@ -175,10 +122,8 @@ class Table
|
||||
* Gets the current style for a column.
|
||||
*
|
||||
* If style was not set, it returns the global table style.
|
||||
*
|
||||
* @return TableStyle
|
||||
*/
|
||||
public function getColumnStyle(int $columnIndex)
|
||||
public function getColumnStyle(int $columnIndex): TableStyle
|
||||
{
|
||||
return $this->columnStyles[$columnIndex] ?? $this->getStyle();
|
||||
}
|
||||
@@ -188,7 +133,7 @@ class Table
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnWidth(int $columnIndex, int $width)
|
||||
public function setColumnWidth(int $columnIndex, int $width): static
|
||||
{
|
||||
$this->columnWidths[$columnIndex] = $width;
|
||||
|
||||
@@ -200,7 +145,7 @@ class Table
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnWidths(array $widths)
|
||||
public function setColumnWidths(array $widths): static
|
||||
{
|
||||
$this->columnWidths = [];
|
||||
foreach ($widths as $index => $width) {
|
||||
@@ -218,7 +163,7 @@ class Table
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setColumnMaxWidth(int $columnIndex, int $width): self
|
||||
public function setColumnMaxWidth(int $columnIndex, int $width): static
|
||||
{
|
||||
if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
|
||||
throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, get_debug_type($this->output->getFormatter())));
|
||||
@@ -232,10 +177,10 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaders(array $headers)
|
||||
public function setHeaders(array $headers): static
|
||||
{
|
||||
$headers = array_values($headers);
|
||||
if (!empty($headers) && !\is_array($headers[0])) {
|
||||
if ($headers && !\is_array($headers[0])) {
|
||||
$headers = [$headers];
|
||||
}
|
||||
|
||||
@@ -244,6 +189,9 @@ class Table
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setRows(array $rows)
|
||||
{
|
||||
$this->rows = [];
|
||||
@@ -254,7 +202,7 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addRows(array $rows)
|
||||
public function addRows(array $rows): static
|
||||
{
|
||||
foreach ($rows as $row) {
|
||||
$this->addRow($row);
|
||||
@@ -266,7 +214,7 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addRow($row)
|
||||
public function addRow(TableSeparator|array $row): static
|
||||
{
|
||||
if ($row instanceof TableSeparator) {
|
||||
$this->rows[] = $row;
|
||||
@@ -274,10 +222,6 @@ class Table
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!\is_array($row)) {
|
||||
throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
|
||||
}
|
||||
|
||||
$this->rows[] = array_values($row);
|
||||
|
||||
return $this;
|
||||
@@ -288,7 +232,7 @@ class Table
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function appendRow($row): self
|
||||
public function appendRow(TableSeparator|array $row): static
|
||||
{
|
||||
if (!$this->output instanceof ConsoleSectionOutput) {
|
||||
throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
|
||||
@@ -307,7 +251,7 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setRow($column, array $row)
|
||||
public function setRow(int|string $column, array $row): static
|
||||
{
|
||||
$this->rows[$column] = $row;
|
||||
|
||||
@@ -317,7 +261,7 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaderTitle(?string $title): self
|
||||
public function setHeaderTitle(?string $title): static
|
||||
{
|
||||
$this->headerTitle = $title;
|
||||
|
||||
@@ -327,7 +271,7 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setFooterTitle(?string $title): self
|
||||
public function setFooterTitle(?string $title): static
|
||||
{
|
||||
$this->footerTitle = $title;
|
||||
|
||||
@@ -337,9 +281,19 @@ class Table
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setHorizontal(bool $horizontal = true): self
|
||||
public function setHorizontal(bool $horizontal = true): static
|
||||
{
|
||||
$this->horizontal = $horizontal;
|
||||
$this->displayOrientation = $horizontal ? self::DISPLAY_ORIENTATION_HORIZONTAL : self::DISPLAY_ORIENTATION_DEFAULT;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setVertical(bool $vertical = true): static
|
||||
{
|
||||
$this->displayOrientation = $vertical ? self::DISPLAY_ORIENTATION_VERTICAL : self::DISPLAY_ORIENTATION_DEFAULT;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -360,8 +314,13 @@ class Table
|
||||
public function render()
|
||||
{
|
||||
$divider = new TableSeparator();
|
||||
if ($this->horizontal) {
|
||||
$rows = [];
|
||||
$isCellWithColspan = static fn ($cell) => $cell instanceof TableCell && $cell->getColspan() >= 2;
|
||||
|
||||
$horizontal = self::DISPLAY_ORIENTATION_HORIZONTAL === $this->displayOrientation;
|
||||
$vertical = self::DISPLAY_ORIENTATION_VERTICAL === $this->displayOrientation;
|
||||
|
||||
$rows = [];
|
||||
if ($horizontal) {
|
||||
foreach ($this->headers[0] ?? [] as $i => $header) {
|
||||
$rows[$i] = [$header];
|
||||
foreach ($this->rows as $row) {
|
||||
@@ -370,13 +329,48 @@ class Table
|
||||
}
|
||||
if (isset($row[$i])) {
|
||||
$rows[$i][] = $row[$i];
|
||||
} elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
|
||||
} elseif ($isCellWithColspan($rows[$i][0])) {
|
||||
// Noop, there is a "title"
|
||||
} else {
|
||||
$rows[$i][] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($vertical) {
|
||||
$formatter = $this->output->getFormatter();
|
||||
$maxHeaderLength = array_reduce($this->headers[0] ?? [], static fn ($max, $header) => max($max, Helper::width(Helper::removeDecoration($formatter, $header))), 0);
|
||||
|
||||
foreach ($this->rows as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($rows) {
|
||||
$rows[] = [$divider];
|
||||
}
|
||||
|
||||
$containsColspan = false;
|
||||
foreach ($row as $cell) {
|
||||
if ($containsColspan = $isCellWithColspan($cell)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->headers[0] ?? [];
|
||||
$maxRows = max(\count($headers), \count($row));
|
||||
for ($i = 0; $i < $maxRows; ++$i) {
|
||||
$cell = (string) ($row[$i] ?? '');
|
||||
if ($headers && !$containsColspan) {
|
||||
$rows[] = [sprintf(
|
||||
'<comment>%s</>: %s',
|
||||
str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT),
|
||||
$cell
|
||||
)];
|
||||
} elseif ('' !== $cell) {
|
||||
$rows[] = [$cell];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$rows = array_merge($this->headers, [$divider], $this->rows);
|
||||
}
|
||||
@@ -386,8 +380,8 @@ class Table
|
||||
$rowGroups = $this->buildTableRows($rows);
|
||||
$this->calculateColumnsWidth($rowGroups);
|
||||
|
||||
$isHeader = !$this->horizontal;
|
||||
$isFirstRow = $this->horizontal;
|
||||
$isHeader = !$horizontal;
|
||||
$isFirstRow = $horizontal;
|
||||
$hasTitle = (bool) $this->headerTitle;
|
||||
|
||||
foreach ($rowGroups as $rowGroup) {
|
||||
@@ -431,7 +425,12 @@ class Table
|
||||
$hasTitle = false;
|
||||
}
|
||||
|
||||
if ($this->horizontal) {
|
||||
if ($vertical) {
|
||||
$isHeader = false;
|
||||
$isFirstRow = false;
|
||||
}
|
||||
|
||||
if ($horizontal) {
|
||||
$this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
|
||||
} else {
|
||||
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
|
||||
@@ -453,7 +452,7 @@ class Table
|
||||
*/
|
||||
private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
|
||||
{
|
||||
if (0 === $count = $this->numberOfColumns) {
|
||||
if (!$count = $this->numberOfColumns) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -570,11 +569,11 @@ class Table
|
||||
$cellFormat = '<'.$tag.'>%s</>';
|
||||
}
|
||||
|
||||
if (strstr($content, '</>')) {
|
||||
if (str_contains($content, '</>')) {
|
||||
$content = str_replace('</>', '', $content);
|
||||
$width -= 3;
|
||||
}
|
||||
if (strstr($content, '<fg=default;bg=default>')) {
|
||||
if (str_contains($content, '<fg=default;bg=default>')) {
|
||||
$content = str_replace('<fg=default;bg=default>', '', $content);
|
||||
$width -= \strlen('<fg=default;bg=default>');
|
||||
}
|
||||
@@ -618,10 +617,10 @@ class Table
|
||||
if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
|
||||
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
|
||||
}
|
||||
if (!strstr($cell ?? '', "\n")) {
|
||||
if (!str_contains($cell ?? '', "\n")) {
|
||||
continue;
|
||||
}
|
||||
$escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell)));
|
||||
$escaped = implode("\n", array_map(OutputFormatter::escapeTrailingBackslash(...), explode("\n", $cell)));
|
||||
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
|
||||
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default></>\n", $cell));
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
@@ -662,7 +661,7 @@ class Table
|
||||
++$numberOfRows; // Add row for header separator
|
||||
}
|
||||
|
||||
if (\count($this->rows) > 0) {
|
||||
if ($this->rows) {
|
||||
++$numberOfRows; // Add row for footer separator
|
||||
}
|
||||
|
||||
@@ -678,13 +677,13 @@ class Table
|
||||
{
|
||||
$unmergedRows = [];
|
||||
foreach ($rows[$line] as $column => $cell) {
|
||||
if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
|
||||
if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !$cell instanceof \Stringable) {
|
||||
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell)));
|
||||
}
|
||||
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
|
||||
$nbLines = $cell->getRowspan() - 1;
|
||||
$lines = [$cell];
|
||||
if (strstr($cell, "\n")) {
|
||||
if (str_contains($cell, "\n")) {
|
||||
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
|
||||
$nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
|
||||
|
||||
@@ -847,7 +846,7 @@ class Table
|
||||
private function cleanup()
|
||||
{
|
||||
$this->effectiveColumnWidths = [];
|
||||
$this->numberOfColumns = null;
|
||||
unset($this->numberOfColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -900,16 +899,12 @@ class Table
|
||||
];
|
||||
}
|
||||
|
||||
private function resolveStyle($name): TableStyle
|
||||
private function resolveStyle(TableStyle|string $name): TableStyle
|
||||
{
|
||||
if ($name instanceof TableStyle) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if (isset(self::$styles[$name])) {
|
||||
return self::$styles[$name];
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
return self::$styles[$name] ?? throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user