headerStyle ??= ConsoleStyle::create(color: ConsoleColor::BRIGHT_WHITE, format: ConsoleFormat::BOLD); $this->rowStyle ??= ConsoleStyle::create(); $this->borderStyle ??= ConsoleStyle::create(color: ConsoleColor::GRAY); } /** * Setzt die Spaltenüberschriften der Tabelle. */ public function setHeaders(array $headers): self { $this->headers = $headers; $this->calculateColumnWidths(); return $this; } /** * Fügt eine Zeile zur Tabelle hinzu. */ public function addRow(array $row): self { $this->rows[] = $row; $this->calculateColumnWidths(); return $this; } /** * Setzt alle Zeilen der Tabelle. */ public function setRows(array $rows): self { $this->rows = $rows; $this->calculateColumnWidths(); return $this; } /** * Setzt den Innenabstand der Zellen. */ public function setPadding(int $padding): self { $this->padding = max(0, $padding); return $this; } /** * Rendert die Tabelle und gibt den Text zurück. */ public function render(): string { if (empty($this->headers) && empty($this->rows)) { return ''; } $output = ''; if ($this->showBorders) { $output .= $this->renderBorder('top') . "\n"; } // Header if (! empty($this->headers)) { $output .= $this->renderRow($this->headers, $this->headerStyle) . "\n"; if ($this->showBorders) { $output .= $this->renderBorder('middle') . "\n"; } } // Zeilen foreach ($this->rows as $index => $row) { $output .= $this->renderRow($row, $this->rowStyle) . "\n"; } if ($this->showBorders) { $output .= $this->renderBorder('bottom') . "\n"; } return $output; } /** * Rendert eine Zeile der Tabelle. */ private function renderRow(array $cells, ConsoleStyle $style): string { $output = ''; if ($this->showBorders) { $output .= $this->borderStyle->apply('│'); } foreach ($cells as $index => $cell) { $width = $this->columnWidths[$index] ?? 10; $cellText = (string)$cell; // Linksbündige Ausrichtung mit exakter Breite $paddedCell = str_pad($cellText, $width, ' ', STR_PAD_RIGHT); // Padding hinzufügen $padding = str_repeat(' ', $this->padding); $finalCell = $padding . $paddedCell . $padding; $output .= $style->apply($finalCell); if ($this->showBorders) { $output .= $this->borderStyle->apply('│'); } } return $output; } /** * Rendert eine Trennlinie der Tabelle. */ private function renderBorder(string $type): string { $left = match($type) { 'top' => '┌', 'middle' => '├', 'row' => '├', 'bottom' => '└', default => '│' }; $right = match($type) { 'top' => '┐', 'middle' => '┤', 'row' => '┤', 'bottom' => '┘', default => '│' }; $horizontal = '─'; $junction = match($type) { 'top' => '┬', 'middle' => '┼', 'row' => '┼', 'bottom' => '┴', default => '│' }; $border = $left; foreach ($this->columnWidths as $index => $width) { $cellWidth = $width + ($this->padding * 2); $border .= str_repeat($horizontal, $cellWidth); if ($index < count($this->columnWidths) - 1) { $border .= $junction; } } $border .= $right; return $this->borderStyle->apply($border); } /** * Berechnet die Breite jeder Spalte basierend auf dem Inhalt. */ private function calculateColumnWidths(): void { $this->columnWidths = []; // Header-Breiten foreach ($this->headers as $index => $header) { $this->columnWidths[$index] = mb_strlen((string)$header); } // Zeilen-Breiten foreach ($this->rows as $row) { foreach ($row as $index => $cell) { $length = mb_strlen((string)$cell); $this->columnWidths[$index] = max($this->columnWidths[$index] ?? 0, $length); } } } public function getOutputFormat(): OutputFormat { return OutputFormat::CONSOLE; } /** * Build table from Display ArrayStructure */ public function fromArrayStructure(ArrayStructure $structure): self { $headers = $structure->isAssociative ? ['Key', 'Value'] : ['Index', 'Value']; $this->setHeaders($headers); $rows = []; foreach ($structure->items as $key => $value) { $valueStr = is_scalar($value) ? (string) $value : get_debug_type($value); $rows[] = [(string) $key, $valueStr]; } $this->setRows($rows); return $this; } }