Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -1,24 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Framework\View\Processors;
use App\Framework\DI\Container;
use App\Framework\Template\Processing\StringProcessor;
use App\Framework\View\Functions\ImageSlotFunction;
use App\Framework\View\Functions\UrlFunction;
use App\Framework\View\RawHtml;
use App\Framework\View\RenderContext;
use App\Framework\View\StringProcessor;
use App\Framework\View\TemplateFunctions;
use DateTime;
use DateTimeZone;
final class PlaceholderReplacer implements StringProcessor
{
public function __construct(
private Container $container,
)
{
private readonly Container $container,
) {
}
// Erlaubte Template-Funktionen für zusätzliche Sicherheit
/**
* @var string[]
*/
private array $allowedTemplateFunctions = [
'date', 'format_date', 'format_currency', 'format_filesize',
'strtoupper', 'strtolower', 'ucfirst', 'trim', 'count', /*'imageslot'*/
@@ -32,7 +39,7 @@ final class PlaceholderReplacer implements StringProcessor
// Standard Variablen und Methoden: {{ item.getRelativeFile() }}
return preg_replace_callback(
'/{{\\s*([\\w.]+)(?:\\(\\s*([^)]*)\\s*\\))?\\s*}}/',
function($matches) use ($context) {
function ($matches) use ($context) {
$expression = $matches[1];
$params = isset($matches[2]) ? trim($matches[2]) : null;
@@ -50,22 +57,22 @@ final class PlaceholderReplacer implements StringProcessor
{
return preg_replace_callback(
'/{{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\(([^)]*)\\)\\s*}}/',
function($matches) use ($context) {
function ($matches) use ($context) {
$functionName = $matches[1];
$params = trim($matches[2]);
$functions = new TemplateFunctions($this->container, ImageSlotFunction::class, UrlFunction::class);
if($functions->has($functionName)) {
if ($functions->has($functionName)) {
$function = $functions->get($functionName);
$args = $this->parseParams($params, $context->data);
if(is_callable($function)) {
if (is_callable($function)) {
return $function(...$args);
}
#return $function(...$args);
}
// Nur erlaubte Funktionen
if (!in_array($functionName, $this->allowedTemplateFunctions)) {
if (! in_array($functionName, $this->allowedTemplateFunctions)) {
return $matches[0];
}
@@ -75,6 +82,7 @@ final class PlaceholderReplacer implements StringProcessor
// Custom Template-Funktionen
if (method_exists($this, 'function_' . $functionName)) {
$result = $this->{'function_' . $functionName}(...$args);
return $result;
#return htmlspecialchars((string)$result, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
@@ -82,6 +90,7 @@ final class PlaceholderReplacer implements StringProcessor
// Standard PHP-Funktionen (begrenzt)
if (function_exists($functionName)) {
$result = $functionName(...$args);
return htmlspecialchars((string)$result, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
@@ -98,15 +107,17 @@ final class PlaceholderReplacer implements StringProcessor
private function function_imageslot(string $slotName): string
{
$function = $this->container->get(ImageSlotFunction::class);
return ($function('slot1'));
}
// Custom Template-Funktionen
private function function_format_date(string|\DateTime $date, string $format = 'Y-m-d H:i:s'): string
private function function_format_date(string|DateTime $date, string $format = 'Y-m-d H:i:s'): string
{
if (is_string($date)) {
$date = new \DateTimeImmutable($date, new DateTimeZone('Europe/Berlin'));
}
return $date->format($format);
}
@@ -119,6 +130,7 @@ final class PlaceholderReplacer implements StringProcessor
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$factor = floor((strlen((string)$bytes) - 1) / 3);
return sprintf("%.1f %s", $bytes / pow(1024, $factor), $units[$factor]);
}
@@ -131,11 +143,11 @@ final class PlaceholderReplacer implements StringProcessor
// Objekt auflösen
$object = $this->resolveValue($data, $objectPath);
if (!is_object($object)) {
if (! is_object($object)) {
return '{{ ' . $expression . '() }}'; // Platzhalter beibehalten
}
if (!method_exists($object, $methodName)) {
if (! method_exists($object, $methodName)) {
return '{{ ' . $expression . '() }}'; // Platzhalter beibehalten
}
@@ -160,6 +172,12 @@ final class PlaceholderReplacer implements StringProcessor
// Bleibt als Platzhalter stehen
return '{{ ' . $expr . ' }}';
}
// RawHtml-Objekte nicht escapen
if ($value instanceof RawHtml) {
return $value->content;
}
return htmlspecialchars((string)$value, $flags, 'UTF-8');
}
@@ -199,28 +217,33 @@ final class PlaceholderReplacer implements StringProcessor
// String-Literale: 'text' oder "text"
if (preg_match('/^[\'\"](.*)[\'\"]/s', $part, $matches)) {
$params[] = $matches[1];
continue;
}
// Zahlen
if (is_numeric($part)) {
$params[] = str_contains($part, '.') ? (float)$part : (int)$part;
continue;
}
// Boolean
if ($part === 'true') {
$params[] = true;
continue;
}
if ($part === 'false') {
$params[] = false;
continue;
}
// Null
if ($part === 'null') {
$params[] = null;
continue;
}
@@ -229,12 +252,22 @@ final class PlaceholderReplacer implements StringProcessor
$varName = substr($part, 1);
if (array_key_exists($varName, $data)) {
$params[] = $data[$varName];
continue;
}
} elseif (str_contains($part, '.')) {
$value = $this->resolveValue($data, $part);
if ($value !== null) {
$params[] = $value;
continue;
}
} else {
// Einfache Variablennamen (ohne $ oder .) aus Template-Daten auflösen
$value = $this->resolveValue($data, $part);
if ($value !== null) {
$params[] = $value;
continue;
}
}
@@ -260,7 +293,7 @@ final class PlaceholderReplacer implements StringProcessor
for ($i = 0; $i < $length; $i++) {
$char = $paramsString[$i];
if (!$inQuotes && ($char === '"' || $char === "'")) {
if (! $inQuotes && ($char === '"' || $char === "'")) {
$inQuotes = true;
$quoteChar = $char;
$current .= $char;
@@ -268,7 +301,7 @@ final class PlaceholderReplacer implements StringProcessor
$inQuotes = false;
$quoteChar = null;
$current .= $char;
} elseif (!$inQuotes && $char === ',') {
} elseif (! $inQuotes && $char === ',') {
$params[] = trim($current);
$current = '';
} else {