mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
Split search into search.php; repertoire.php is index-only
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
/**
|
||||
* SearchController
|
||||
*
|
||||
* Handles all data-fetching logic for the public search / répertoire page.
|
||||
* The entry point (public/repertoire.php) delegates to this class and receives
|
||||
* a plain array of view variables ready for template inclusion.
|
||||
* Handles all data-fetching logic for the public search and répertoire pages.
|
||||
*
|
||||
* Entry points:
|
||||
* - public/search.php calls handleSearch() — text-query results
|
||||
* - public/repertoire.php calls handleRepertoire() — filter index + HTMX swaps
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Rate-limit enforcement (returns early HTTP 429 response when needed)
|
||||
@@ -13,8 +15,8 @@
|
||||
* - OG / meta tag assembly
|
||||
* - HTMX partial response for repertoire filter swaps
|
||||
*
|
||||
* The class has NO output side-effects; all template rendering stays in
|
||||
* public/repertoire.php so the view layer remains easy to inspect and modify.
|
||||
* The class has NO output side-effects; all template rendering stays in the
|
||||
* respective public/*.php files so the view layer remains easy to inspect.
|
||||
* Exception: renderRepertoirePartial() exits early for HTMX requests.
|
||||
*/
|
||||
class SearchController
|
||||
@@ -59,47 +61,93 @@ class SearchController
|
||||
return new self(Database::getInstance(), $rateLimit);
|
||||
}
|
||||
|
||||
// ── Main entry point ─────────────────────────────────────────────────────
|
||||
// ── Entry points ──────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Process the current request and return all variables needed by the view.
|
||||
* Handle the search results page (public/search.php).
|
||||
* Requires a ?query= parameter; always returns search-result view variables.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function handle(): array
|
||||
public function handleSearch(): array
|
||||
{
|
||||
$isHtmx = !empty($_SERVER['HTTP_HX_REQUEST']);
|
||||
$searchParams = $this->collectSearchParams();
|
||||
$hasSearch = !empty($searchParams);
|
||||
|
||||
$activeFilters = $this->collectFilterParams();
|
||||
|
||||
$searchParams = $this->collectSearchParams();
|
||||
$page = isset($_GET['page']) ? max(1, (int) $_GET['page']) : 1;
|
||||
$offset = ($page - 1) * self::ITEMS_PER_PAGE;
|
||||
$validationError = null;
|
||||
|
||||
$results = [];
|
||||
$totalItems = 0;
|
||||
$totalPages = 0;
|
||||
$repData = null;
|
||||
|
||||
// For search filter dropdowns (text search mode only)
|
||||
$results = [];
|
||||
$totalItems = 0;
|
||||
$totalPages = 0;
|
||||
$years = [];
|
||||
$orientations = [];
|
||||
$apPrograms = [];
|
||||
|
||||
try {
|
||||
if ($hasSearch) {
|
||||
$results = $this->db->searchTheses($searchParams, self::ITEMS_PER_PAGE, $offset);
|
||||
$totalItems = $this->db->countSearchResults($searchParams);
|
||||
$totalPages = (int) ceil($totalItems / self::ITEMS_PER_PAGE);
|
||||
$years = $this->db->getAvailableYears();
|
||||
$orientations = $this->db->getAllOrientations();
|
||||
$apPrograms = $this->db->getAllAPPrograms();
|
||||
} else {
|
||||
// Repertoire index: compute filter data (all columns + matched flags)
|
||||
$repData = $this->db->getRepertoireFilterData($activeFilters);
|
||||
}
|
||||
$results = $this->db->searchTheses($searchParams, self::ITEMS_PER_PAGE, $offset);
|
||||
$totalItems = $this->db->countSearchResults($searchParams);
|
||||
$totalPages = (int) ceil($totalItems / self::ITEMS_PER_PAGE);
|
||||
$years = $this->db->getAvailableYears();
|
||||
$orientations = $this->db->getAllOrientations();
|
||||
$apPrograms = $this->db->getAllAPPrograms();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$validationError = $e->getMessage();
|
||||
} catch (Exception $e) {
|
||||
error_log('SearchController: ' . $e->getMessage());
|
||||
$validationError = 'Une erreur est survenue.';
|
||||
}
|
||||
|
||||
// Preserve all active params, strip 'page' (pagination partial adds it)
|
||||
$baseParams = array_diff_key($_GET, ['page' => '']);
|
||||
|
||||
$query = $_GET['query'] ?? '';
|
||||
|
||||
return [
|
||||
'searchParams' => $searchParams,
|
||||
'page' => $page,
|
||||
'totalItems' => $totalItems,
|
||||
'totalPages' => $totalPages,
|
||||
'results' => $results,
|
||||
'validationError' => $validationError,
|
||||
'baseParams' => $baseParams,
|
||||
|
||||
// Filter dropdowns
|
||||
'years' => $years,
|
||||
'orientations' => $orientations,
|
||||
'apPrograms' => $apPrograms,
|
||||
|
||||
// Page meta
|
||||
'searchBarValue' => $query,
|
||||
'pageTitle' => $query !== '' ? 'Recherche : ' . $query . ' – Posterg' : 'Recherche – Posterg',
|
||||
'metaDescription' => "Résultats de recherche dans le répertoire des TFE de l'erg.",
|
||||
'ogTags' => [
|
||||
'type' => 'website',
|
||||
'title' => 'Recherche – Posterg',
|
||||
'description' => "Résultats de recherche dans le répertoire des TFE de l'erg.",
|
||||
'url' => 'https://posterg.erg.be/search.php',
|
||||
'site_name' => 'Posterg – ERG',
|
||||
],
|
||||
'currentNav' => 'repertoire',
|
||||
'extraCss' => ['/assets/css/search.css'],
|
||||
'bodyClass' => 'search-body',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the répertoire index page (public/repertoire.php).
|
||||
* Serves the filter-column index; HTMX partial swaps are handled here too.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function handleRepertoire(): array
|
||||
{
|
||||
$isHtmx = !empty($_SERVER['HTTP_HX_REQUEST']);
|
||||
$activeFilters = $this->collectFilterParams();
|
||||
$repData = null;
|
||||
$validationError = null;
|
||||
|
||||
try {
|
||||
$repData = $this->db->getRepertoireFilterData($activeFilters);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$validationError = $e->getMessage();
|
||||
} catch (Exception $e) {
|
||||
@@ -108,36 +156,18 @@ class SearchController
|
||||
}
|
||||
|
||||
// HTMX partial: render just the index div and exit
|
||||
if ($isHtmx && !$hasSearch && $repData !== null) {
|
||||
if ($isHtmx && $repData !== null) {
|
||||
$this->renderRepertoirePartial($repData, $activeFilters);
|
||||
}
|
||||
|
||||
// Preserve all active search/filter params, strip 'page' (pagination partial adds it)
|
||||
$baseParams = array_diff_key($_GET, ['page' => '']);
|
||||
|
||||
return [
|
||||
// Search state
|
||||
'searchParams' => $searchParams,
|
||||
'hasSearch' => $hasSearch,
|
||||
'page' => $page,
|
||||
'totalItems' => $totalItems,
|
||||
'totalPages' => $totalPages,
|
||||
'results' => $results,
|
||||
'validationError' => $validationError,
|
||||
'baseParams' => $baseParams,
|
||||
|
||||
// Repertoire filter state
|
||||
'repData' => $repData,
|
||||
'activeFilters' => $activeFilters,
|
||||
'isHtmx' => $isHtmx,
|
||||
|
||||
// Search filter dropdowns (text search mode only)
|
||||
'years' => $years,
|
||||
'orientations' => $orientations,
|
||||
'apPrograms' => $apPrograms,
|
||||
'validationError' => $validationError,
|
||||
|
||||
// Page meta
|
||||
'searchBarValue' => $_GET['query'] ?? '',
|
||||
'searchBarValue' => '',
|
||||
'pageTitle' => 'Répertoire – Posterg',
|
||||
'metaDescription' => "Parcourez le répertoire des mémoires de fin d'études (TFE) de l'erg – École de Recherches Graphiques de Bruxelles.",
|
||||
'ogTags' => [
|
||||
|
||||
Reference in New Issue
Block a user