fix: Gitea Traefik routing and connection pool optimization
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
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
This commit is contained in:
253
src/Framework/Display/Formatters/AutoFormatter.php
Normal file
253
src/Framework/Display/Formatters/AutoFormatter.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Display\Formatters;
|
||||
|
||||
use App\Framework\Display\Formatters\CsvFormatter;
|
||||
use App\Framework\Display\Formatters\JsonFormatter;
|
||||
use App\Framework\Display\Formatters\XmlFormatter;
|
||||
use App\Framework\Display\Formatters\YamlFormatter;
|
||||
use App\Framework\Display\ValueObjects\DisplayOptions;
|
||||
use App\Framework\Display\ValueObjects\OutputFormat;
|
||||
use App\Framework\Filesystem\ValueObjects\FilePath;
|
||||
|
||||
/**
|
||||
* Auto-detecting formatter that automatically selects the appropriate formatter
|
||||
* based on the input data type.
|
||||
*
|
||||
* This is the main entry point for the Display module. It automatically detects
|
||||
* the type of input data and routes it to the appropriate formatter:
|
||||
* - Arrays → ArrayFormatter
|
||||
* - Objects → ObjectFormatter
|
||||
* - JSON strings → JsonFormatter
|
||||
* - YAML strings → YamlFormatter
|
||||
* - XML strings → XmlFormatter
|
||||
* - CSV strings → CsvFormatter
|
||||
* - Class names → ClassFormatter
|
||||
* - Directory paths → FilesystemFormatter
|
||||
* - Scalars → Scalar formatting
|
||||
*
|
||||
* @example
|
||||
* $formatter = new AutoFormatter();
|
||||
* echo $formatter->formatForConsole($data);
|
||||
*/
|
||||
final readonly class AutoFormatter
|
||||
{
|
||||
public function __construct(
|
||||
private ArrayFormatter $arrayFormatter = new ArrayFormatter(),
|
||||
private ObjectFormatter $objectFormatter = new ObjectFormatter(),
|
||||
private ClassFormatter $classFormatter = new ClassFormatter(),
|
||||
private FilesystemFormatter $filesystemFormatter = new FilesystemFormatter(),
|
||||
private JsonFormatter $jsonFormatter = new JsonFormatter(),
|
||||
private YamlFormatter $yamlFormatter = new YamlFormatter(),
|
||||
private XmlFormatter $xmlFormatter = new XmlFormatter(),
|
||||
private CsvFormatter $csvFormatter = new CsvFormatter(),
|
||||
private CodeFormatter $codeFormatter = new CodeFormatter(),
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Format data with specified options and output format.
|
||||
*
|
||||
* @param mixed $value The data to format (array, object, string, etc.)
|
||||
* @param DisplayOptions $options Display configuration options
|
||||
* @param OutputFormat $format Output format (CONSOLE or HTML)
|
||||
* @return string Formatted output string
|
||||
*/
|
||||
public function format(mixed $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return match (true) {
|
||||
is_array($value) => $this->formatArray($value, $options, $format),
|
||||
is_object($value) => $this->formatObject($value, $options, $format),
|
||||
is_string($value) && $this->isJsonString($value) => $this->formatJsonString($value, $options, $format),
|
||||
is_string($value) && $this->isYamlString($value) => $this->formatYamlString($value, $options, $format),
|
||||
is_string($value) && $this->isXmlString($value) => $this->formatXmlString($value, $options, $format),
|
||||
is_string($value) && $this->isCsvString($value) => $this->formatCsvString($value, $options, $format),
|
||||
is_string($value) && CodeFormatter::isPhpCode($value) => $this->formatCode($value, $options, $format),
|
||||
is_string($value) && class_exists($value) => $this->formatClass($value, $options, $format),
|
||||
is_string($value) && (is_dir($value) || ($value instanceof FilePath && is_dir($value->toString()))) => $this->formatDirectory($value, $options, $format),
|
||||
$value instanceof FilePath => $this->formatDirectory($value, $options, $format),
|
||||
default => $this->formatScalar($value, $options, $format),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Format data for console output with default options.
|
||||
*
|
||||
* @param mixed $value The data to format
|
||||
* @param DisplayOptions|null $options Optional display options (defaults to DisplayOptions::default())
|
||||
* @return string Formatted console output with ANSI colors
|
||||
*/
|
||||
public function formatForConsole(mixed $value, ?DisplayOptions $options = null): string
|
||||
{
|
||||
$options ??= DisplayOptions::default();
|
||||
|
||||
return $this->format($value, $options, OutputFormat::CONSOLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format data for HTML output with default options.
|
||||
*
|
||||
* @param mixed $value The data to format
|
||||
* @param DisplayOptions|null $options Optional display options (defaults to DisplayOptions::default())
|
||||
* @return string Formatted HTML output with semantic HTML/CSS classes
|
||||
*/
|
||||
public function formatForHtml(mixed $value, ?DisplayOptions $options = null): string
|
||||
{
|
||||
$options ??= DisplayOptions::default();
|
||||
|
||||
return $this->format($value, $options, OutputFormat::HTML);
|
||||
}
|
||||
|
||||
private function formatArray(array $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
// Check if array contains objects - could use ObjectFormatter for items
|
||||
$hasObjects = false;
|
||||
foreach ($value as $item) {
|
||||
if (is_object($item)) {
|
||||
$hasObjects = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->arrayFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatObject(object $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->objectFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatJsonString(string $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->jsonFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatYamlString(string $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->yamlFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatXmlString(string $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->xmlFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatCsvString(string $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->csvFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatCode(string $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->codeFormatter->format($value, $options, $format);
|
||||
}
|
||||
|
||||
private function formatClass(string $className, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->classFormatter->format($className, $options, $format);
|
||||
}
|
||||
|
||||
private function formatDirectory(string|FilePath $path, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
return $this->filesystemFormatter->format($path, $options, $format);
|
||||
}
|
||||
|
||||
private function formatScalar(mixed $value, DisplayOptions $options, OutputFormat $format): string
|
||||
{
|
||||
$formatted = match (true) {
|
||||
is_string($value) => $format === OutputFormat::HTML
|
||||
? '<span class="display-string">' . htmlspecialchars($value) . '</span>'
|
||||
: "\033[32m\"{$value}\"\033[0m",
|
||||
is_int($value) => $format === OutputFormat::HTML
|
||||
? '<span class="display-number">' . $value . '</span>'
|
||||
: "\033[94m{$value}\033[0m",
|
||||
is_float($value) => $format === OutputFormat::HTML
|
||||
? '<span class="display-number">' . $value . '</span>'
|
||||
: "\033[94m{$value}\033[0m",
|
||||
is_bool($value) => $format === OutputFormat::HTML
|
||||
? '<span class="display-boolean">' . ($value ? 'true' : 'false') . '</span>'
|
||||
: "\033[95m" . ($value ? 'true' : 'false') . "\033[0m",
|
||||
is_null($value) => $format === OutputFormat::HTML
|
||||
? '<span class="display-null">null</span>'
|
||||
: "\033[90mnull\033[0m",
|
||||
default => $format === OutputFormat::HTML
|
||||
? '<span class="display-type">' . htmlspecialchars(get_debug_type($value)) . '</span>'
|
||||
: get_debug_type($value),
|
||||
};
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
private function isJsonString(string $value): bool
|
||||
{
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$trimmed = trim($value);
|
||||
if (! ($trimmed[0] === '{' || $trimmed[0] === '[')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return json_validate($value);
|
||||
}
|
||||
|
||||
private function isYamlString(string $value): bool
|
||||
{
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$trimmed = trim($value);
|
||||
|
||||
// Basic YAML detection: starts with key: or has --- or ...
|
||||
// More sophisticated detection would require a YAML parser
|
||||
return preg_match('/^(\s*[a-zA-Z_][a-zA-Z0-9_]*\s*:|\s*---|\s*\.\.\.)/', $trimmed) === 1;
|
||||
}
|
||||
|
||||
private function isXmlString(string $value): bool
|
||||
{
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$trimmed = trim($value);
|
||||
|
||||
// Basic XML detection: starts with < or <?xml
|
||||
return str_starts_with($trimmed, '<') || str_starts_with($trimmed, '<?xml');
|
||||
}
|
||||
|
||||
private function isCsvString(string $value): bool
|
||||
{
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lines = explode("\n", $value);
|
||||
if (count($lines) < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the first line contains common CSV separators
|
||||
$firstLine = $lines[0];
|
||||
$separators = [',', ';', "\t"];
|
||||
|
||||
foreach ($separators as $separator) {
|
||||
$parts = explode($separator, $firstLine);
|
||||
if (count($parts) >= 2) {
|
||||
// Check if second line has same number of parts
|
||||
if (isset($lines[1])) {
|
||||
$secondParts = explode($separator, $lines[1]);
|
||||
if (count($secondParts) >= 2 && abs(count($parts) - count($secondParts)) <= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user