diff --git a/TODO.md b/TODO.md index e010811..1322383 100644 --- a/TODO.md +++ b/TODO.md @@ -322,7 +322,7 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis - [x] Add flake.nix for Nix-based PHP dev environment - [x] Add favicon (`` → admin_favicon.svg) to all pages; nginx 204 for /favicon.ico - [x] Remove 100-item cap from répertoire student index: `getAllPublishedTheses()` fetches all published theses; search results remain paginated at 30/page -- [ ] Thumbnail generation / cover image support for home grid cards +- [x] Cover image fallback for home grid cards: batch-load `thesis_files` covers for theses without `banner_path`; resolution order: banner → cover → gradient ## Admin / Server diff --git a/public/index.php b/public/index.php index 9000c61..ae3e5fd 100644 --- a/public/index.php +++ b/public/index.php @@ -28,6 +28,26 @@ try { } $totalPages = $isDefaultView ? 1 : (int)ceil($totalItems / $itemsPerPage); + + // Batch-load cover images for theses that have no banner_path + $coverMap = []; + if (!empty($itemsToLoad)) { + $needCover = array_column( + array_filter($itemsToLoad, fn($t) => empty($t['banner_path'])), + 'id' + ); + if (!empty($needCover)) { + $ph = implode(',', array_fill(0, count($needCover), '?')); + $cStmt = $db->getConnection()->prepare(" + SELECT thesis_id, file_path FROM thesis_files + WHERE file_type = 'cover' AND thesis_id IN ($ph) + "); + $cStmt->execute($needCover); + foreach ($cStmt->fetchAll() as $row) { + $coverMap[$row['thesis_id']] = $row['file_path']; + } + } + } } catch (Exception $e) { error_log("Error loading theses: " . $e->getMessage()); $itemsToLoad = []; @@ -36,6 +56,7 @@ try { $totalItems = 0; $latestYear = null; $isDefaultView = false; + $coverMap = []; } $currentNav = ''; @@ -91,7 +112,11 @@ $currentNav = ''; $thumb = $item['banner_path']; } - // 2. Cover image from thesis_files (not returned by view — skip for now) + // 2. Cover image from thesis_files (batch-loaded above) + if (!$thumb && isset($coverMap[$item['id']])) { + $thumb = $coverMap[$item['id']]; + } + // 3. Fall through to gradient ?>