initializeStrategies(); } public function render(TemplateContext $context, callable $renderer): string { // 1. Template analysieren für optimale Strategy $analysis = $this->analyzer->analyze($context->template); $this->lastAnalysis = $analysis; // 2. Passende Strategy auswählen $strategy = $this->selectStrategy($analysis); if (! $strategy->shouldCache($context)) { $content = $renderer(); if (! is_string($content)) { throw new \RuntimeException('Renderer must return a string, got: ' . get_debug_type($content)); } return $content; } // 3. Cache-Key generieren $cacheKey = $strategy->generateKey($context); // 4. Cache-Lookup $result = $this->cache->get($cacheKey); $cached = $result->getItem($cacheKey); if ($cached->isHit && is_string($cached->value)) { return $cached->value; } // 5. Rendern und cachen $content = $renderer(); if (! is_string($content)) { throw new \RuntimeException('Renderer must return a string, got: ' . get_debug_type($content)); } $ttl = $strategy->getTtl($context); $this->cache->set(CacheItem::forSet($cacheKey, $content, \App\Framework\Core\ValueObjects\Duration::fromSeconds($ttl))); return $content; } public function invalidateTemplate(string $template): int { $invalidated = 0; // Invalidiere alle Strategies für dieses Template foreach ($this->strategies as $strategy) { if ($strategy->canInvalidate($template)) { // Pattern-basierte Invalidierung je nach Strategy $pattern = $this->buildInvalidationPattern($strategy, $template); $invalidated += $this->invalidateByPattern($pattern); } } return $invalidated; } private function selectStrategy(TemplateAnalysis $analysis): ViewCacheStrategy { return match($analysis->recommendedStrategy) { CacheStrategy::FULL_PAGE => $this->strategies['full_page'], CacheStrategy::COMPONENT => $this->strategies['component'], CacheStrategy::FRAGMENT => $this->strategies['fragment'], CacheStrategy::USER_AWARE => $this->strategies['user_aware'], default => $this->strategies['no_cache'] }; } private function initializeStrategies(): void { $this->strategies = [ 'full_page' => new FullPageCacheStrategy($this->cache), 'component' => new ComponentCacheStrategy($this->cache), 'fragment' => new FragmentCacheStrategy($this->cache), 'no_cache' => new NoCacheStrategy(), ]; } private function buildInvalidationPattern(mixed $strategy, string $template): string { return match(get_class($strategy)) { FullPageCacheStrategy::class => "page:{$template}:*", ComponentCacheStrategy::class => "component:*{$template}*", FragmentCacheStrategy::class => "fragment:{$template}:*", default => "*{$template}*" }; } private function invalidateByPattern(string $pattern): int { // Vereinfachte Implementation - in Realität müsste das der Cache-Driver unterstützen // Für jetzt: Cache komplett leeren bei Pattern-Match $invalidated = 0; if (str_contains($pattern, '*')) { $this->cache->clear(); $invalidated = 1; } return $invalidated; } }