Skip to content

Commit

Permalink
fix auto size table output
Browse files Browse the repository at this point in the history
  • Loading branch information
phpdevcommunity committed Dec 23, 2024
1 parent 430a201 commit 7569666
Showing 1 changed file with 90 additions and 45 deletions.
135 changes: 90 additions & 45 deletions src/Output/ConsoleOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace PhpDevCommunity\Console\Output;


use InvalidArgumentException;
use PhpDevCommunity\Console\OutputInterface;
use RuntimeException;

final class ConsoleOutput implements OutputInterface
{
Expand Down Expand Up @@ -80,20 +82,20 @@ public function title(string $message): void
$titleLength = mb_strlen($message);
$underline = str_repeat('=', min($consoleWidth, $titleLength));

$this->writeColor(PHP_EOL);
$this->writeColor($message);
$this->writeColor(PHP_EOL);
$this->writeColor($underline);
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
$this->write($message);
$this->write(PHP_EOL);
$this->write($underline);
$this->write(PHP_EOL);
}

public function list(array $items): void
{
foreach ($items as $item) {
$this->writeColor('- ' . $item);
$this->writeColor(PHP_EOL);
$this->write('- ' . $item);
$this->write(PHP_EOL);
}
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}

public function listKeyValues(array $items, bool $inlined = false): void
Expand All @@ -111,17 +113,17 @@ public function listKeyValues(array $items, bool $inlined = false): void
foreach ($items as $key => $value) {
$key = str_pad($key, $maxKeyLength, ' ', STR_PAD_RIGHT);
$this->writeColor($key, 'green');
$this->writeColor(' : ');
$this->write(' : ');
$this->writeColor($value, 'white');
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}

public function indentedList(array $items, int $indentLevel = 1): void
{
if ($indentLevel == 1) {
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}

foreach ($items as $item) {
Expand All @@ -134,12 +136,12 @@ public function indentedList(array $items, int $indentLevel = 1): void
}
$this->writeColor($indentation . '- ', 'red');
$this->writeColor($item, 'white');
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
}

if ($indentLevel == 1) {
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
}

Expand All @@ -148,36 +150,57 @@ public function numberedList(array $items)
foreach ($items as $index => $item) {
$this->writeColor(($index + 1) . '. ', 'white');
$this->writeColor($item, 'green');
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}

public function table(array $headers, array $rows): void
{
$maxWidth = $this->geTerminalWidth();
$maxWidthPerColumn = $maxWidth / count($headers);
$columnWidths = array_map(function ($header) {
return mb_strlen($header);
}, $headers);

$processedRows = [];
foreach ($rows as $row) {
$row = array_values($row);
$processedRow = [];
foreach ($row as $index => $column) {
$columnWidths[$index] = max($columnWidths[$index], mb_strlen($column));
$column = $this->variableToString($column);
$lines = explode(PHP_EOL, trim($column));
foreach ($lines as $i => $line) {
$maxWidth = max($columnWidths[$index], mb_strlen($line));
if ($maxWidth > $maxWidthPerColumn) {
$maxWidth = $maxWidthPerColumn;
}
$columnWidths[$index] = $maxWidth;
if (mb_strlen($line) > $maxWidth) {
$lines[$i] = mb_substr($line, 0, $maxWidth) . '...';
}
}
$processedRow[$index] = $lines;
}
$processedRows[] = $processedRow;
}

foreach ($headers as $index => $header) {
$this->writeColor(str_pad($header, $columnWidths[$index] + 2));
$this->write(str_pad($header, $columnWidths[$index] + 2));
}
$this->writeColor(PHP_EOL);

$this->writeColor(str_repeat('-', array_sum($columnWidths) + count($columnWidths) * 2));
$this->writeColor(PHP_EOL);

foreach ($rows as $row) {
foreach ($row as $index => $column) {
$this->writeColor(str_pad($column, $columnWidths[$index] + 2));
$this->write(PHP_EOL);
$this->write(str_repeat('-', array_sum($columnWidths) + count($columnWidths) * 2));
$this->write(PHP_EOL);

foreach ($processedRows as $row) {
$maxLines = max(array_map('count', $row));
for ($lineIndex = 0; $lineIndex < $maxLines; $lineIndex++) {
foreach ($row as $index => $lines) {
$line = $lines[$lineIndex] ?? ''; // Récupère la ligne actuelle ou une chaîne vide
$this->write(str_pad($line, $columnWidths[$index] + 2));
}
$this->write(PHP_EOL);
}
$this->writeColor(PHP_EOL);
}
}

Expand All @@ -186,9 +209,9 @@ public function progressBar(int $total, int $current): void
$barWidth = 50;
$progress = ($current / $total) * $barWidth;
$bar = str_repeat('#', (int)$progress) . str_repeat(' ', $barWidth - (int)$progress);
$this->writeColor(sprintf("\r[%s] %d%%", $bar, ($current / $total) * 100));
$this->write(sprintf("\r[%s] %d%%", $bar, ($current / $total) * 100));
if ($current === $total) {
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
}

Expand All @@ -209,12 +232,12 @@ public function ask(string $question, bool $hidden = false, bool $required = fal

if ($hidden) {
if (strncasecmp(PHP_OS, 'WIN', 3) == 0) {
throw new \RuntimeException('Windows platform is not supported for hidden input');
throw new RuntimeException('Windows platform is not supported for hidden input');
} else {
system('stty -echo');
$input = trim(fgets(STDIN));
system('stty echo');
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
}
} else {
$handle = fopen('php://stdin', 'r');
Expand All @@ -223,7 +246,7 @@ public function ask(string $question, bool $hidden = false, bool $required = fal
}

if ($required && empty($input)) {
throw new \InvalidArgumentException('Response cannot be empty');
throw new InvalidArgumentException('Response cannot be empty');
}

return $input;
Expand All @@ -235,11 +258,11 @@ public function spinner(int $duration = 3): void
$time = microtime(true);
while ((microtime(true) - $time) < $duration) {
foreach ($spinnerChars as $char) {
$this->writeColor("\r$char");
$this->write("\r$char");
usleep(100000);
}
}
$this->writeColor("\r");
$this->write("\r");
}

public function json(array $data): void
Expand All @@ -250,12 +273,12 @@ public function json(array $data): void
$this->writeColor("Error encoding JSON: " . json_last_error_msg() . PHP_EOL, 'red');
return;
}
$this->writeColor($jsonOutput . PHP_EOL);
$this->write($jsonOutput . PHP_EOL);
}

public function boxed(string $message, string $borderChar = '*', int $padding = 1): void
{
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
$lineLength = mb_strlen($message);
$boxWidth = $this->geTerminalWidth();
if ($lineLength > $boxWidth) {
Expand All @@ -264,13 +287,13 @@ public function boxed(string $message, string $borderChar = '*', int $padding =
$lines = explode('|', wordwrap($message, $lineLength, '|', true));
$border = str_repeat($borderChar, $lineLength + ($padding * 2) + 2);

$this->writeColor($border . PHP_EOL);
$this->write($border . PHP_EOL);
foreach ($lines as $line) {
$strPad = str_repeat(' ', $padding);
$this->writeColor($borderChar . $strPad . str_pad($line, $lineLength) . $strPad . $borderChar . PHP_EOL);
$this->write($borderChar . $strPad . str_pad($line, $lineLength) . $strPad . $borderChar . PHP_EOL);
}
$this->writeColor($border . PHP_EOL);
$this->writeColor(PHP_EOL);
$this->write($border . PHP_EOL);
$this->write(PHP_EOL);
}

public function writeColor(string $message, ?string $color = null, ?string $background = null): void
Expand Down Expand Up @@ -302,9 +325,9 @@ public function writeln(string $message): void

private function outputMessage($formattedMessage, int $lineLength, string $color): void
{
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
$this->writeColor(str_repeat(' ', $lineLength), 'white', $color);
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);

if (is_string($formattedMessage)) {
$formattedMessage = [$formattedMessage];
Expand All @@ -314,10 +337,10 @@ private function outputMessage($formattedMessage, int $lineLength, string $color
$this->writeColor($line, 'white', $color);
}

$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
$this->writeColor(str_repeat(' ', $lineLength), 'white', $color);
$this->writeColor(PHP_EOL);
$this->writeColor(PHP_EOL);
$this->write(PHP_EOL);
$this->write(PHP_EOL);
}

private function formatMessage(string $prefix, string $message, string $color): array
Expand All @@ -335,8 +358,30 @@ private function formatMessage(string $prefix, string $message, string $color):
}
return [$formattedMessage, $lineLength, $color];
}

private function geTerminalWidth(): int
{
return ((int)exec('tput cols') ?? 85 - 5);
}

private function variableToString($variable): string
{
if (is_object($variable)) {
return 'Object: ' . get_class($variable);
} elseif (is_array($variable)) {
$variables = [];
foreach ($variable as $item) {
$variables[] = $this->variableToString($item);
}
return var_export($variables, true);
} elseif (is_resource($variable)) {
return (string)$variable;
} elseif (is_null($variable)) {
return 'NULL';
} elseif (is_string($variable)) {
return $variable;
}

return var_export($variable, true);
}
}

0 comments on commit 7569666

Please sign in to comment.