Files
michaelschiemer/src/Framework/Console/Layout/LayoutRenderer.php
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

185 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Console\Layout;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleFormat;
use App\Framework\Console\ConsoleStyle;
use App\Framework\Display\Themes\ConsoleTheme;
/**
* Rendering engine for all layout types
*/
final readonly class LayoutRenderer
{
public function __construct(
private ConsoleTheme $theme
) {
}
/**
* Render a box with borders
*/
public function renderBox(string $content, int $width, bool $showBorders = true, string $title = ''): string
{
$lines = explode("\n", $content);
$output = [];
if ($showBorders) {
// Top border
if ($title !== '') {
$titleWidth = mb_strlen($title);
$availableSpace = $width - $titleWidth - 4; // Space for '[ ' and ' ]'
$leftPadding = max(0, (int)floor($availableSpace / 2));
$rightPadding = max(0, $availableSpace - $leftPadding);
$topBorder = '┌' . str_repeat('─', $leftPadding) . '[ ' . $title . ' ]' . str_repeat('─', $rightPadding) . '┐';
$output[] = $topBorder;
} else {
$output[] = '┌' . str_repeat('─', $width - 2) . '┐';
}
// Content lines
foreach ($lines as $line) {
$paddedLine = str_pad($line, $width - 4);
$output[] = '│ ' . $paddedLine . ' │';
}
// Bottom border
$output[] = '└' . str_repeat('─', $width - 2) . '┘';
} else {
$output = $lines;
}
return implode("\n", $output);
}
/**
* Render a horizontal divider
*/
public function renderDivider(int $width, ?string $label = null, bool $double = false): string
{
$char = $double ? '═' : '─';
if ($label !== null) {
$labelLength = mb_strlen($label);
$availableSpace = $width - $labelLength - 4; // Space for ' ' on both sides
$leftWidth = max(0, (int)floor($availableSpace / 2));
$rightWidth = max(0, $availableSpace - $leftWidth);
return str_repeat($char, $leftWidth) . ' ' . $label . ' ' . str_repeat($char, $rightWidth);
}
return str_repeat($char, $width);
}
/**
* Render a header
*/
public function renderHeader(string $title, ?string $subtitle = null, int $width = 80): string
{
$output = [];
$titleStyle = ConsoleStyle::create(color: $this->theme->classNameColor, format: ConsoleFormat::BOLD);
// Top border
$output[] = '╔' . str_repeat('═', $width - 2) . '╗';
// Title
$titlePadded = str_pad($title, $width - 4);
$output[] = '║ ' . $titleStyle->apply($titlePadded) . ' ║';
// Subtitle (if provided)
if ($subtitle !== null) {
$subtitleStyle = ConsoleStyle::create(color: $this->theme->metadataColor);
$subtitlePadded = str_pad($subtitle, $width - 4);
$output[] = '║ ' . $subtitleStyle->apply($subtitlePadded) . ' ║';
}
// Bottom border
$output[] = '╚' . str_repeat('═', $width - 2) . '╝';
return implode("\n", $output);
}
/**
* Render a footer
*/
public function renderFooter(string $content, int $width = 80): string
{
$output = [];
$footerStyle = ConsoleStyle::create(color: $this->theme->metadataColor);
// Top border
$output[] = '╔' . str_repeat('═', $width - 2) . '╗';
// Content
$contentPadded = str_pad($content, $width - 4);
$output[] = '║ ' . $footerStyle->apply($contentPadded) . ' ║';
// Bottom border
$output[] = '╚' . str_repeat('═', $width - 2) . '╝';
return implode("\n", $output);
}
/**
* Apply ANSI formatting to text
*/
public function applyStyle(string $text, ConsoleColor $color, ?ConsoleFormat $format = null): string
{
$style = ConsoleStyle::create(color: $color, format: $format);
return $style->apply($text);
}
/**
* Wrap text to fit width
*/
public function wrapText(string $text, int $width): array
{
$lines = explode("\n", $text);
$wrapped = [];
foreach ($lines as $line) {
if (mb_strlen($line) <= $width) {
$wrapped[] = $line;
} else {
$wrapped = array_merge($wrapped, $this->splitLine($line, $width));
}
}
return $wrapped;
}
private function splitLine(string $line, int $width): array
{
$words = explode(' ', $line);
$currentLine = '';
$result = [];
foreach ($words as $word) {
$testLine = empty($currentLine) ? $word : $currentLine . ' ' . $word;
if (mb_strlen($testLine) <= $width) {
$currentLine = $testLine;
} else {
if (!empty($currentLine)) {
$result[] = $currentLine;
$currentLine = $word;
} else {
$result[] = mb_substr($word, 0, $width);
$currentLine = mb_substr($word, $width);
}
}
}
if (!empty($currentLine)) {
$result[] = $currentLine;
}
return $result ?: [''];
}
}