!in_array($item, ['.', '..']) && is_dir("$dir/$item") ); } function extractTitle(string $filePath): ?string { $files = findAllContentFiles($filePath); if (empty($files)) return null; // Check the first content file for a title $file = $files[0]; $ext = pathinfo($file, PATHINFO_EXTENSION); $content = file_get_contents($file); if ($ext === 'md' && preg_match('/^#\s+(.+)$/m', $content, $matches)) { return trim($matches[1]); } if (in_array($ext, ['html', 'php']) && preg_match('/]*>(.*?)<\/h1>/i', $content, $matches)) { return strip_tags($matches[1]); } return null; } function extractDateFromFolder(string $folderName): ?string { if (preg_match('/^(\d{4})-(\d{2})-(\d{2})-/', $folderName, $matches)) { $dateString = $matches[1] . '-' . $matches[2] . '-' . $matches[3]; // Let plugins format the date return Hooks::apply(Hook::PROCESS_CONTENT, $dateString, 'date_format'); } return null; } function findCoverImage(string $dirPath): ?string { $found = array_find( COVER_IMAGE_EXTENSIONS, fn($ext) => file_exists("$dirPath/cover.$ext") ); return $found ? "cover.$found" : null; } function findPdfFile(string $dirPath): ?string { $pdfs = glob("$dirPath/*.pdf") ?: []; return $pdfs ? basename($pdfs[0]) : null; } function findPageCss(string $dirPath, string $contentDir): ?array { $cssFile = "$dirPath/styles.css"; if (!file_exists($cssFile) || !is_file($cssFile)) { return null; } $relativePath = str_replace($contentDir, '', $dirPath); $relativePath = trim($relativePath, '/'); $cssUrl = '/' . ($relativePath ? $relativePath . '/' : '') . 'styles.css'; return [ 'url' => $cssUrl, 'hash' => hash_file('md5', $cssFile) ]; } function extractMetaDescription(string $dirPath, ?array $metadata): ?string { // 1. Check for search_description in metadata if ($metadata && isset($metadata['search_description'])) { return $metadata['search_description']; } // 2. Fall back to summary in metadata if ($metadata && isset($metadata['summary'])) { return $metadata['summary']; } // 3. Fall back to first paragraph in content files $files = findAllContentFiles($dirPath); if (empty($files)) return null; foreach ($files as $file) { $ext = pathinfo($file, PATHINFO_EXTENSION); $content = file_get_contents($file); if ($ext === 'md') { $lines = explode("\n", $content); foreach ($lines as $line) { $line = trim($line); if (empty($line) || str_starts_with($line, '#')) continue; if (strlen($line) > 20) { return strip_tags($line); } } } elseif (in_array($ext, ['html', 'php'])) { if (preg_match('/]*>(.*?)<\/p>/is', $content, $matches)) { return strip_tags($matches[1]); } } } return null; }