db = $db; } // ── Factory ─────────────────────────────────────────────────────────────── /** * Convenience factory: loads the Database singleton and returns a ready * controller instance. */ public static function create(): self { require_once APP_ROOT . '/src/Database.php'; return new self(Database::getInstance()); } // ── Main entry point ───────────────────────────────────────────────────── /** * Process the current request and return all variables needed by the view. * * @return array */ public function handle(): array { $page = isset($_GET['page']) ? max(1, (int) $_GET['page']) : 1; $year = isset($_GET['year']) ? (int) $_GET['year'] : null; // Normalise zero (e.g. ?year=0) to null so it is treated as "no filter" if ($year === 0) { $year = null; } // Default home view: random theses from latest year (no year filter, no explicit page) $isDefaultView = ($year === null && $page === 1); $itemsToLoad = []; $totalItems = 0; $availableYears = []; $latestYear = null; $coverMap = []; try { $offset = ($page - 1) * self::ITEMS_PER_PAGE; $availableYears = $this->db->getAvailableYears(); if ($year !== null) { $itemsToLoad = $this->db->searchTheses(['year' => $year], self::ITEMS_PER_PAGE, $offset); $totalItems = $this->db->countSearchResults(['year' => $year]); } elseif ($isDefaultView) { $latestYear = $this->db->getLatestPublishedYear(); $itemsToLoad = $this->db->getLatestYearTheses(self::ITEMS_PER_PAGE); $totalItems = count($itemsToLoad); // no multi-page on default view } else { $itemsToLoad = $this->db->getPublishedTheses(self::ITEMS_PER_PAGE, $offset); $totalItems = $this->db->countPublishedTheses(); } // Batch-load cover images for theses that have no banner_path if (!empty($itemsToLoad)) { $needCover = array_column( array_filter($itemsToLoad, static fn($t) => empty($t['banner_path'])), 'id' ); if (!empty($needCover)) { $coverMap = $this->db->getCoverPathsForTheses($needCover); } } } catch (Exception $e) { error_log('HomeController: ' . $e->getMessage()); // Return safe empty state; view will show "Aucun mémoire trouvé" $isDefaultView = false; } $totalPages = $isDefaultView ? 1 : (int) ceil($totalItems / self::ITEMS_PER_PAGE); // Avoid division by zero on empty DB if ($totalPages < 1) { $totalPages = 0; } $baseParams = array_filter(['year' => $year]); return [ // Pagination / filter state 'page' => $page, 'year' => $year, 'isDefaultView' => $isDefaultView, 'totalItems' => $totalItems, 'totalPages' => $totalPages, 'baseParams' => $baseParams, // Thesis data 'itemsToLoad' => $itemsToLoad, 'latestYear' => $latestYear, 'availableYears' => $availableYears, 'coverMap' => $coverMap, // Page meta 'pageTitle' => 'Posterg – Mémoires de l\'ERG', 'metaDescription' => 'Posterg répertorie et valorise les mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles.', 'ogTags' => [ 'type' => 'website', 'title' => 'Posterg – Mémoires de l\'ERG', 'description' => 'Posterg répertorie et valorise les mémoires de fin d\'études (TFE) de l\'erg – École de Recherches Graphiques de Bruxelles.', 'url' => 'https://posterg.erg.be/', 'site_name' => 'Posterg – ERG', ], // Layout 'currentNav' => '', 'extraCss' => ['/assets/css/main.css'], 'bodyClass' => 'home-body', ]; } }