fix: search filter labels, 429 page styling, __wakeup PHP 8.x deprecation

- Replace three <span class='search-filter-label'> with proper <label for='...'> elements in
  search.php filter bar; add id attributes to the corresponding <select> elements so the
  label/control association is programmatic (WCAG 1.3.1, 3.3.2).

- Rewrite the rate-limit 429 early-exit in search.php from a bare one-liner echo to a full
  HTML document with lang='fr', viewport meta, and inline dark styles matching maintenance.php;
  inject the retry countdown into the user-facing message (Template audit F).

- Fix PHP 8.x __wakeup() deprecation in Database.php singleton guard: replace the throw
  statement with trigger_error(..., E_USER_ERROR) and add an explicit void return type
  (Refactor audit C).
This commit is contained in:
Pontoporeia
2026-03-29 15:47:30 +02:00
parent 3a8ffa6afe
commit 7a4a471838
3 changed files with 61 additions and 22 deletions

View File

@@ -8,7 +8,46 @@ $rateLimit = new RateLimit(30, 60);
if (!$rateLimit->check()) {
http_response_code(429);
header('Retry-After: ' . $rateLimit->getResetTime());
echo '<!DOCTYPE html><html lang="fr"><body><h1>Trop de requêtes</h1><p>Réessayez dans ' . $rateLimit->getResetTime() . ' secondes.</p></body></html>';
$retrySeconds = (int)$rateLimit->getResetTime();
echo <<<HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trop de requêtes Posterg</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: #0d0d0d;
color: #e0e0e0;
font-family: 'Helvetica Neue', Arial, sans-serif;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
.box { max-width: 520px; text-align: center; }
.box__logo {
font-size: 1.1rem; font-weight: 700;
letter-spacing: .12em; text-transform: uppercase;
color: #fff; margin-bottom: 2.5rem;
}
.box__title { font-size: 1.6rem; font-weight: 300; margin-bottom: 1rem; }
.box__text { font-size: .95rem; color: #999; line-height: 1.7; }
</style>
</head>
<body>
<div class="box">
<div class="box__logo">POSTERG</div>
<h1 class="box__title">Trop de requêtes</h1>
<p class="box__text">Vous avez effectué trop de recherches en peu de temps.<br>
Réessayez dans {$retrySeconds} secondes.</p>
</div>
</body>
</html>
HTML;
exit;
}
$rateLimit->sendHeaders();
@@ -91,8 +130,8 @@ $extraCss = ['assets/search.css'];
<input type="hidden" name="query" value="<?= htmlspecialchars($_GET['query'] ?? '') ?>">
<div class="search-filter-group">
<span class="search-filter-label">Année</span>
<select class="search-filter-select" name="year">
<label class="search-filter-label" for="filter-year">Année</label>
<select class="search-filter-select" name="year" id="filter-year">
<option value="">Toutes</option>
<?php foreach ($years as $y): ?>
<option value="<?= (int)$y ?>" <?= (isset($_GET['year']) && $_GET['year'] == $y) ? 'selected' : '' ?>>
@@ -103,8 +142,8 @@ $extraCss = ['assets/search.css'];
</div>
<div class="search-filter-group">
<span class="search-filter-label">Orientation</span>
<select class="search-filter-select" name="orientation">
<label class="search-filter-label" for="filter-orientation">Orientation</label>
<select class="search-filter-select" name="orientation" id="filter-orientation">
<option value="">Toutes</option>
<?php foreach ($orientations as $o): ?>
<option value="<?= htmlspecialchars($o['name']) ?>"
@@ -116,8 +155,8 @@ $extraCss = ['assets/search.css'];
</div>
<div class="search-filter-group">
<span class="search-filter-label">AP</span>
<select class="search-filter-select" name="ap_program">
<label class="search-filter-label" for="filter-ap">AP</label>
<select class="search-filter-select" name="ap_program" id="filter-ap">
<option value="">Tous</option>
<?php foreach ($apPrograms as $ap): ?>
<option value="<?= htmlspecialchars($ap['name']) ?>"