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
- 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
212 lines
6.0 KiB
PHP
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);
|
|
}
|
|
}
|
|
|