109 lines
3.2 KiB
PHP
109 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Archive\Archived;
|
|
|
|
use App\Framework\View\RenderContext;
|
|
|
|
final class TemplatePreprocessor
|
|
{
|
|
private array $normalizedTemplates = [];
|
|
|
|
public function normalizeTemplate(string $template, RenderContext $context): string
|
|
{
|
|
$cacheKey = md5($template . serialize($context->data));
|
|
|
|
if (isset($this->normalizedTemplates[$cacheKey])) {
|
|
return $this->normalizedTemplates[$cacheKey];
|
|
}
|
|
|
|
$normalized = $template;
|
|
|
|
// Entferne Kommentare für konsistentere Cache-Keys
|
|
$normalized = preg_replace('/<!--.*?-->/s', '', $normalized);
|
|
|
|
// Normalisiere Whitespace
|
|
$normalized = preg_replace('/\s+/', ' ', $normalized);
|
|
$normalized = trim($normalized);
|
|
|
|
// Cache das normalisierte Template
|
|
$this->normalizedTemplates[$cacheKey] = $normalized;
|
|
|
|
return $normalized;
|
|
}
|
|
|
|
public function extractCacheableBlocks(string $template): array
|
|
{
|
|
$blocks = [];
|
|
|
|
// Finde data-cache Attribute für explizite Cache-Bereiche
|
|
if (preg_match_all('/<[^>]+data-cache="([^"]+)"[^>]*>(.*?)<\/[^>]+>/s', $template, $matches, PREG_SET_ORDER)) {
|
|
foreach ($matches as $match) {
|
|
$blocks[] = [
|
|
'id' => $match[1],
|
|
'content' => $match[2],
|
|
'type' => 'explicit'
|
|
];
|
|
}
|
|
}
|
|
|
|
// Finde wiederholende Strukturen (Listen, Cards etc.)
|
|
if (preg_match_all('/<(ul|ol|div class="[^"]*list[^"]*")[^>]*>(.*?)<\/\1>/s', $template, $matches, PREG_SET_ORDER)) {
|
|
foreach ($matches as $i => $match) {
|
|
$blocks[] = [
|
|
'id' => 'list_block_' . $i,
|
|
'content' => $match[2],
|
|
'type' => 'list'
|
|
];
|
|
}
|
|
}
|
|
|
|
return $blocks;
|
|
}
|
|
|
|
public function generateOptimizedCacheKey(RenderContext $context, array $dependencies = []): string
|
|
{
|
|
$keyParts = [
|
|
$context->template,
|
|
$context->controllerClass ?? 'default',
|
|
];
|
|
|
|
// Füge nur relevante Daten hinzu (nicht alles aus $context->data)
|
|
$relevantData = $this->extractRelevantData($context->data, $dependencies);
|
|
if (!empty($relevantData)) {
|
|
$keyParts[] = md5(serialize($relevantData));
|
|
}
|
|
|
|
// Füge Template-Änderungszeit hinzu für Auto-Invalidation
|
|
$templatePath = $this->resolveTemplatePath($context->template);
|
|
if (file_exists($templatePath)) {
|
|
$keyParts[] = filemtime($templatePath);
|
|
}
|
|
|
|
return implode(':', $keyParts);
|
|
}
|
|
|
|
private function extractRelevantData(array $data, array $dependencies): array
|
|
{
|
|
if (empty($dependencies)) {
|
|
return $data;
|
|
}
|
|
|
|
$relevant = [];
|
|
foreach ($dependencies as $key) {
|
|
if (isset($data[$key])) {
|
|
$relevant[$key] = $data[$key];
|
|
}
|
|
}
|
|
|
|
return $relevant;
|
|
}
|
|
|
|
private function resolveTemplatePath(string $template): string
|
|
{
|
|
// Vereinfachte Template-Pfad-Auflösung
|
|
return "views/{$template}.php";
|
|
}
|
|
}
|