error("Directory not found: {$directory}"); return []; } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $file) { if ($file->isFile() && $this->isHtmlFile($file)) { $html = file_get_contents($file->getPathname()); [$content, $breadcrumb] = app(ExtractHtmlContentTask::class)->run($html); if ($content !== false) { $breadcrumb = app(GetBreadcrumbFromHtmlTask::class)->run($breadcrumb); $text = $this->normalizeText(strip_tags($content)); $index[$file->getPathname()] = [ 'title' => $this->getFirstH1Content($content), 'content' => $text, 'category' => $breadcrumb ?? null, ]; } } } return $index; } catch (\Exception $e) { Log::channel('app')->error('Index creation error: ' . $e->getMessage()); return []; } }); } protected function isHtmlFile(\SplFileInfo $file): bool { $extension = strtolower($file->getExtension()); return in_array($extension, ['html', 'htm']); } protected function normalizeText(string $text): string { $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $text = preg_replace('/\s+/u', ' ', $text); $text = trim($text); return Str::lower($text); } public function getFirstH1Content(string $content): ?string { try { if (preg_match('/]*>(.*?)<\/h1>/is', $content, $matches)) { return $this->normalizeText($matches[1]); } return null; } catch (\Exception $e) { Log::channel('app')->error('Failed to get H1: ' . $e->getMessage()); return null; } } }