Files
michaelschiemer/src/Framework/Discovery/Results/TemplateRegistry.php
Michael Schiemer e30753ba0e fix: resolve RedisCache array offset error and improve discovery diagnostics
- Fix RedisCache driver to handle MGET failures gracefully with fallback
- Add comprehensive discovery context comparison debug tools
- Identify root cause: WEB context discovery missing 166 items vs CLI
- WEB context missing RequestFactory class entirely (52 vs 69 commands)
- Improved exception handling with detailed binding diagnostics
2025-09-12 20:05:18 +02:00

168 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Discovery\Results;
use App\Framework\Discovery\ValueObjects\TemplateMapping;
use Countable;
/**
* Memory-optimized registry for template discoveries using Value Objects
* Pure Value Object implementation without legacy array support
*/
final class TemplateRegistry implements Countable
{
/** @var TemplateMapping[] */
private array $templates = [];
/** @var array<string, TemplateMapping> */
private array $templatesByName = [];
private bool $isOptimized = false;
public function __construct()
{
}
/**
* Convert to array for cache serialization
* @return array<string, mixed>
*/
public function toArray(): array
{
$serializedTemplates = [];
foreach ($this->templates as $template) {
$serializedTemplates[] = $template->toArray();
}
return [
'templates' => $serializedTemplates,
];
}
/**
* Create TemplateRegistry from array data (for cache deserialization)
* Always loads as non-optimized to ensure data integrity
*/
public static function fromArray(array $data): self
{
$registry = new self();
$templates = [];
foreach (($data['templates'] ?? []) as $templateArray) {
try {
$templates[] = TemplateMapping::fromArray($templateArray);
} catch (\InvalidArgumentException $e) {
// Skip invalid template mappings from corrupted cache data
continue;
}
}
$registry->templates = $templates;
$registry->templatesByName = []; // Don't restore cache, will be rebuilt
$registry->isOptimized = false; // Always force re-optimization for cache data integrity
return $registry;
}
/**
* Get all templates as Value Objects
* @return TemplateMapping[]
*/
public function getAll(): array
{
return $this->templates;
}
public function get(string $name): ?TemplateMapping
{
if (! isset($this->templatesByName[$name])) {
foreach ($this->templates as $template) {
if ($template->name === $name) {
$this->templatesByName[$name] = $template;
break;
}
}
}
return $this->templatesByName[$name] ?? null;
}
public function has(string $name): bool
{
return $this->get($name) !== null;
}
public function add(TemplateMapping $template): void
{
$this->templates[] = $template;
$this->templatesByName = [];
$this->isOptimized = false;
}
/**
* Count total templates (Countable interface)
*/
public function count(): int
{
return count($this->templates);
}
public function optimize(): void
{
if ($this->isOptimized) {
return;
}
// Deduplicate templates using Value Object unique IDs
$seen = [];
$deduplicated = [];
foreach ($this->templates as $template) {
$uniqueId = $template->getUniqueId();
if (! isset($seen[$uniqueId])) {
$seen[$uniqueId] = true;
$deduplicated[] = $template;
}
}
$this->templates = $deduplicated;
$this->templatesByName = [];
$this->isOptimized = true;
}
public function clearCache(): void
{
$this->templatesByName = [];
}
public function getMemoryStats(): array
{
return [
'templates' => count($this->templates),
'estimated_bytes' => count($this->templates) * 150,
'is_optimized' => $this->isOptimized,
];
}
public function merge(self $other): self
{
$merged = new self();
foreach ($this->templates as $template) {
$merged->add($template);
}
foreach ($other->templates as $template) {
$merged->add($template);
}
$merged->optimize();
return $merged;
}
}