package and depencies

This commit is contained in:
RafficMohammed
2023-01-08 02:57:24 +05:30
parent d5332eb421
commit 1d54b8bc7f
4309 changed files with 193331 additions and 172289 deletions

View File

@@ -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));
}
}