toString(), '.php'); $type = str_contains($path->toString(), '/views/') ? 'view' : 'template'; return new self( name: $name, path: $path, type: $type ); } /** * Get unique identifier for deduplication */ public function getUniqueId(): string { return $this->name . '::' . $this->type; } /** * Check if this mapping is the same as another */ public function isSameAs(self $other): bool { return $this->name === $other->name && $this->type === $other->type; } /** * Check if template matches name pattern */ public function matchesName(string $pattern): bool { return fnmatch($pattern, $this->name); } /** * Get template extension */ public function getExtension(): string { return pathinfo($this->path->toString(), PATHINFO_EXTENSION); } /** * Check if template is of specific type */ public function isType(string $type): bool { return $this->type === $type; } /** * Convert to array for serialization */ public function toArray(): array { return [ 'name' => $this->name, 'path' => $this->path->toString(), 'type' => $this->type, ]; } /** * Create from array data */ public static function fromArray(array $data): self { // Handle both string paths and FilePath objects/arrays from old cache data $path = $data['path']; if (is_array($path)) { // Old cache format: FilePath object was serialized as array $path = $path['path'] ?? (string) reset($path); } elseif (! is_string($path)) { // Fallback: convert to string $path = (string) $path; } // Skip invalid/empty paths from corrupted cache data if (empty(trim($path))) { throw new \InvalidArgumentException("Cannot create TemplateMapping with empty path"); } return new self( name: $data['name'], path: FilePath::create($path), type: $data['type'] ?? 'view' ); } /** * Get memory footprint estimate */ public function getMemoryFootprint(): Byte { $bytes = strlen($this->name) + strlen($this->path->toString()) + strlen($this->type); return Byte::fromBytes($bytes); } }