Files
michaelschiemer/src/Framework/Console/Layout/LayoutContainer.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

212 lines
6.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Console\Layout;
use App\Framework\Console\Layout\ValueObjects\LayoutOptions;
use App\Framework\Display\Themes\ConsoleTheme;
use App\Framework\Display\Themes\DefaultThemes;
/**
* Base container for all console layouts
*/
abstract class LayoutContainer implements LayoutInterface
{
protected TerminalSize $terminalSize;
protected LayoutOptions $options;
protected ConsoleTheme $theme;
public function __construct(
protected ?TerminalSize $customTerminalSize = null,
?LayoutOptions $options = null
) {
$this->terminalSize = $this->customTerminalSize ?? TerminalSize::detect();
$this->options = $options ?? LayoutOptions::default();
$this->theme = $this->options->theme ?? DefaultThemes::getConsoleTheme('default');
}
public function getTerminalSize(): TerminalSize
{
return $this->terminalSize;
}
public function getOptions(): LayoutOptions
{
return $this->options;
}
public function getTheme(): ConsoleTheme
{
return $this->theme;
}
/**
* Get effective width for layout (considering padding and margins)
*/
protected function getEffectiveWidth(): int
{
$width = $this->options->width > 0
? $this->options->width
: $this->terminalSize->getUsableWidth();
// Subtract margins and padding
$totalMargin = ($this->options->margin * 2);
$totalPadding = ($this->options->padding * 2);
return max(40, $width - $totalMargin - $totalPadding);
}
/**
* Get effective height for layout
*/
protected function getEffectiveHeight(): int
{
return $this->terminalSize->getUsableHeight();
}
/**
* Check if layout should be responsive
*/
protected function isResponsive(): bool
{
return $this->options->responsive;
}
/**
* Get border characters based on border style
*/
protected function getBorderChars(): array
{
return match ($this->options->borderStyle) {
'double' => [
'top-left' => '╔',
'top-right' => '╗',
'bottom-left' => '╚',
'bottom-right' => '╝',
'horizontal' => '═',
'vertical' => '║',
'cross' => '╬',
'top-cross' => '╦',
'bottom-cross' => '╩',
'left-cross' => '╠',
'right-cross' => '╣',
],
'rounded' => [
'top-left' => '╭',
'top-right' => '╮',
'bottom-left' => '╰',
'bottom-right' => '╯',
'horizontal' => '─',
'vertical' => '│',
'cross' => '┼',
'top-cross' => '┬',
'bottom-cross' => '┴',
'left-cross' => '├',
'right-cross' => '┤',
],
'none' => [
'top-left' => '',
'top-right' => '',
'bottom-left' => '',
'bottom-right' => '',
'horizontal' => '',
'vertical' => '',
'cross' => '',
'top-cross' => '',
'bottom-cross' => '',
'left-cross' => '',
'right-cross' => '',
],
default => [ // 'single'
'top-left' => '┌',
'top-right' => '┐',
'bottom-left' => '└',
'bottom-right' => '┘',
'horizontal' => '─',
'vertical' => '│',
'cross' => '┼',
'top-cross' => '┬',
'bottom-cross' => '┴',
'left-cross' => '├',
'right-cross' => '┤',
],
};
}
/**
* Render a horizontal border line
*/
protected function renderHorizontalBorder(string $left = '', string $right = '', ?string $middle = null): string
{
if (!$this->options->showBorders) {
return '';
}
$chars = $this->getBorderChars();
$width = $this->getEffectiveWidth();
$horizontal = str_repeat($chars['horizontal'], $width);
$leftChar = $left !== '' ? $left : $chars['horizontal'];
$rightChar = $right !== '' ? $right : $chars['horizontal'];
if ($middle !== null) {
$horizontal = $leftChar . $middle . $rightChar;
} else {
$horizontal = $leftChar . $horizontal . $rightChar;
}
return $horizontal;
}
/**
* Wrap content with padding
*/
protected function wrapWithPadding(string $content): string
{
if ($this->options->padding === 0) {
return $content;
}
$padding = str_repeat(' ', $this->options->padding);
$lines = explode("\n", $content);
$wrapped = [];
foreach ($lines as $line) {
$wrapped[] = $padding . $line;
}
return implode("\n", $wrapped);
}
/**
* Wrap content with borders
*/
protected function wrapWithBorders(string $content): string
{
if (!$this->options->showBorders) {
return $content;
}
$chars = $this->getBorderChars();
$width = $this->getEffectiveWidth();
$lines = explode("\n", $content);
$bordered = [];
// Top border
$bordered[] = $chars['top-left'] . str_repeat($chars['horizontal'], $width) . $chars['top-right'];
// Content lines with vertical borders
foreach ($lines as $line) {
$paddedLine = str_pad($line, $width);
$bordered[] = $chars['vertical'] . $paddedLine . $chars['vertical'];
}
// Bottom border
$bordered[] = $chars['bottom-left'] . str_repeat($chars['horizontal'], $width) . $chars['bottom-right'];
return implode("\n", $bordered);
}
}