From 9a58b97cb87cfaf45ef3e2a60efe968d093b0e48 Mon Sep 17 00:00:00 2001 From: Pontoporeia Date: Sat, 4 Apr 2026 12:39:34 +0200 Subject: [PATCH] Extract SearchController from public/search.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all data-fetching and request logic out of the 285-line search page into src/SearchController.php: - SearchController::create() — static factory; builds RateLimit + Database dependencies, sends HTTP 429 (and exits) if rate limit is exceeded, runs probabilistic cleanup, returns ready instance - SearchController::handle() — sanitises GET params (query/year/orientation/ ap_program/keyword), runs all DB queries (searchTheses, countSearchResults, getAvailableYears, getAllOrientations, getAllAPPrograms, getUsedTags, getPublishedAuthors), builds alphabetical author→id map, assembles OG/meta tags, returns a flat array of view variables - Rate-limit 429 HTML response moved into private sendRateLimitResponse() public/search.php is now a 6-line dispatcher: require SearchController; extract(SearchController::create()->handle()); followed by the unchanged view template (162 lines total, was 285). The view template is byte-for-byte equivalent: same HTML, same variable names, same pagination partial include. --- TODO.md | 3 + public/search.php | 135 +------------------- src/SearchController.php | 257 ++++++++++++++++++++++++++++++++++++++ todo/02-php-components.md | 2 +- 4 files changed, 267 insertions(+), 130 deletions(-) create mode 100644 src/SearchController.php diff --git a/TODO.md b/TODO.md index 3c49f1a..95227d8 100644 --- a/TODO.md +++ b/TODO.md @@ -11,6 +11,9 @@ Pending tasks have been split into topic files under [`todo/`](todo/README.md): ## Recently completed (this session) +- [x] `src/SearchController.php` — extracted all data-fetching logic from `public/search.php` into a dedicated controller class; `SearchController::create()` handles rate-limit enforcement (429 response + exit) and returns a ready instance; `handle()` sanitises GET params, runs all DB queries (`searchTheses`, `countSearchResults`, `getAvailableYears`, `getAllOrientations`, `getAllAPPrograms`, `getUsedTags`, `getPublishedAuthors`), builds the alphabetical author map, assembles OG/meta tags, and returns a flat view-variable array; `public/search.php` reduced from 285 lines to 162 lines (pure dispatcher + view template) + + - [x] `admin/system.php` + `assets/js/system.js` + `assets/css/system.css` — extracted the large `$extraJsInline` heredoc (≈130 lines) into a static `public/assets/js/system.js` loaded via `$extraJs`; replaced 4 inline `style=` attributes with named CSS modifier classes (`srv-section-title--compact`, `srv-section-title--sub`, `php-grid--flush`, `log-toolbar label` rule); only the dynamic `--disk-pct`/`--disk-color` CSS custom properties remain inline because they carry PHP runtime values diff --git a/public/search.php b/public/search.php index 60e0bed..e1b3a88 100644 --- a/public/search.php +++ b/public/search.php @@ -1,116 +1,12 @@ check()) { - http_response_code(429); - header('Retry-After: ' . $rateLimit->getResetTime()); - $retrySeconds = (int)$rateLimit->getResetTime(); - echo << - - - - - Trop de requêtes – Posterg - - - -
- -

Trop de requêtes

-

Vous avez effectué trop de recherches en peu de temps.
- Réessayez dans {$retrySeconds} secondes.

-
- - -HTML; - exit; -} -$rateLimit->sendHeaders(); -if (rand(1, 100) === 1) $rateLimit->cleanup(); +// Build controller (performs rate-limit check; exits with HTTP 429 if exceeded) +$ctrl = SearchController::create(); -// Collect search/filter params -$searchParams = []; -if (!empty($_GET['query'])) $searchParams['query'] = trim($_GET['query']); -if (!empty($_GET['year'])) $searchParams['year'] = intval($_GET['year']); -if (!empty($_GET['orientation'])) $searchParams['orientation'] = $_GET['orientation']; -if (!empty($_GET['ap_program'])) $searchParams['ap_program'] = $_GET['ap_program']; -if (!empty($_GET['keyword'])) $searchParams['keyword'] = $_GET['keyword']; - -$hasSearch = !empty($searchParams); - -$page = isset($_GET['page']) ? intval($_GET['page']) : 1; -$itemsPerPage = 30; -$validationError = null; - -try { - $db = Database::getInstance(); - $offset = ($page - 1) * $itemsPerPage; - - if ($hasSearch) { - $results = $db->searchTheses($searchParams, $itemsPerPage, $offset); - $totalItems = $db->countSearchResults($searchParams); - $totalPages = ceil($totalItems / $itemsPerPage); - } else { - $results = []; - $totalItems = 0; - $totalPages = 0; - } - - $years = $db->getAvailableYears(); - $orientations = $db->getAllOrientations(); - $apPrograms = $db->getAllAPPrograms(); - $keywords = $db->getUsedTags(); - // Fetch id+authors only — lean query bypassing the fat v_theses_public view - $students = $db->getPublishedAuthors(); -} catch (InvalidArgumentException $e) { - $validationError = $e->getMessage(); - $results = []; $totalItems = 0; $totalPages = 0; - $years = []; $orientations = []; $apPrograms = []; $keywords = []; $students = []; -} catch (Exception $e) { - error_log("Search error: " . $e->getMessage()); - $validationError = "Une erreur est survenue."; - $results = []; $totalItems = 0; $totalPages = 0; - $years = []; $orientations = []; $apPrograms = []; $keywords = []; $students = []; -} - -$currentNav = 'repertoire'; -$searchBarValue = $_GET['query'] ?? ''; -$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. Recherche par année, orientation, atelier et mots-clés.'; -$ogTags = [ - 'type' => 'website', - 'title' => $pageTitle, - 'description' => $metaDescription, - 'url' => 'https://posterg.erg.be/search.php', - 'site_name' => 'Posterg – ERG', -]; -$extraCss = ['/assets/css/search.css']; -$bodyClass = 'search-body'; +// Collect all view variables +extract($ctrl->handle()); ?> @@ -179,11 +75,7 @@ $bodyClass = 'search-body'; - '']); - include APP_ROOT . '/templates/partials/pagination.php'; - ?> +

Aucun résultat pour cette recherche.

@@ -241,21 +133,6 @@ $bodyClass = 'search-body';

Étudiantes

-