129 lines
4.7 KiB
PHP
129 lines
4.7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\View\Loading;
|
|
|
|
use App\Framework\Cache\Cache;
|
|
use App\Framework\Core\PathProvider;
|
|
use App\Framework\Discovery\Results\DiscoveryResults;
|
|
use App\Framework\Filesystem\FileStorage;
|
|
use App\Framework\View\Loading\Resolvers\ControllerResolver;
|
|
use App\Framework\View\Loading\Resolvers\DefaultPathResolver;
|
|
use App\Framework\View\Loading\Resolvers\DiscoveryResolver;
|
|
use App\Framework\View\Loading\Resolvers\TemplateMapResolver;
|
|
use App\Framework\View\Loading\Resolvers\LayoutResolver;
|
|
use App\Framework\View\Loading\Resolvers\ComponentResolver;
|
|
use App\Framework\View\RenderContext;
|
|
use App\Framework\View\TemplateDiscoveryVisitor;
|
|
|
|
final class TemplateLoader
|
|
{
|
|
private readonly TemplatePathResolver $pathResolver;
|
|
private readonly TemplateContentLoader $contentLoader;
|
|
#private readonly TemplateCache $cache;
|
|
|
|
public function __construct(
|
|
private readonly PathProvider $pathProvider,
|
|
private readonly Cache $cache,
|
|
private readonly ?DiscoveryResults $discoveryResults = null,
|
|
private readonly array $templates = [],
|
|
private readonly string $templatePath = '/src/Framework/View/templates',
|
|
private readonly FileStorage $storage = new FileStorage,
|
|
#private readonly ?TemplateDiscoveryVisitor $templateVisitor = null,
|
|
) {
|
|
$this->pathResolver = $this->createPathResolver();
|
|
$this->contentLoader = new TemplateContentLoader();
|
|
#$this->cache = new TemplateCache();
|
|
}
|
|
|
|
private function createPathResolver(): TemplatePathResolver
|
|
{
|
|
$resolvers = [
|
|
// 1. Explizite Template-Map (höchste Priorität)
|
|
new TemplateMapResolver($this->templates),
|
|
|
|
// 2. Discovery-basierte Templates (falls verfügbar)
|
|
new DiscoveryResolver($this->discoveryResults),
|
|
|
|
// 3. Layout-spezifische Suche (für "main" etc.)
|
|
new LayoutResolver($this->pathProvider, $this->templatePath),
|
|
|
|
// 4. Component-spezifische Suche
|
|
new ComponentResolver($this->pathProvider, $this->templatePath),
|
|
|
|
// 5. Controller-basierte Templates
|
|
new ControllerResolver(),
|
|
|
|
// 6. Standard-Pfad (Fallback)
|
|
new DefaultPathResolver($this->pathProvider, $this->templatePath),
|
|
];
|
|
|
|
return new TemplatePathResolver($resolvers);
|
|
}
|
|
|
|
public function load(string $template, ?string $controllerClass = null, ?RenderContext $context = null): string
|
|
{
|
|
$cacheKey = 'template_content|' . $template . '|' . ($controllerClass ?? 'default');
|
|
|
|
return $this->cache->remember($cacheKey, function() use ($template, $controllerClass, $context) {
|
|
$path = $this->pathResolver->resolve($template, $controllerClass);
|
|
$content = $this->contentLoader->load($path);
|
|
return $content;
|
|
})->value;
|
|
|
|
if ($cached = $this->cache->get($cacheKey)) {
|
|
return $cached;
|
|
}
|
|
|
|
$path = $this->pathResolver->resolve($template, $controllerClass);
|
|
$content = $this->contentLoader->load($path);
|
|
|
|
$this->cache->set($cacheKey, $content);
|
|
return $content;
|
|
}
|
|
|
|
public function getTemplatePath(string $template, ?string $controllerClass = null): string
|
|
{
|
|
return $this->pathResolver->resolve($template, $controllerClass);
|
|
}
|
|
|
|
public function clearCache(): void
|
|
{
|
|
$this->cache->clear();
|
|
}
|
|
|
|
public function getComponentPath(string $name): string
|
|
{
|
|
return __DIR__ . "/../templates/components/{$name}.html";
|
|
}
|
|
|
|
public function debugTemplatePath(string $template, ?string $controllerClass = null): array
|
|
{
|
|
$debug = ['template' => $template, 'attempts' => []];
|
|
|
|
$resolvers = [
|
|
'TemplateMap' => new TemplateMapResolver($this->templates),
|
|
'Discovery' => new DiscoveryResolver($this->discoveryResults),
|
|
'Layout' => new LayoutResolver($this->pathProvider, $this->templatePath),
|
|
'Component' => new ComponentResolver($this->pathProvider, $this->templatePath),
|
|
'Controller' => new ControllerResolver(),
|
|
'Default' => new DefaultPathResolver($this->pathProvider, $this->templatePath),
|
|
];
|
|
|
|
foreach ($resolvers as $name => $resolver) {
|
|
try {
|
|
$path = $resolver->resolve($template, $controllerClass);
|
|
$debug['attempts'][$name] = [
|
|
'path' => $path,
|
|
'exists' => $path ? file_exists($path) : false,
|
|
'success' => $path && file_exists($path)
|
|
];
|
|
} catch (\Exception $e) {
|
|
$debug['attempts'][$name] = ['error' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
return $debug;
|
|
}
|
|
}
|