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/public.css"], "bodyClass" => "home-body", ]; } }