Files
xamxam/public/index.php
Pontoporeia 769d56fabc wcag: fix 2.4.4 duplicate link text on home page cards
Add <span class="sr-only">, YEAR</span> to each thesis card <p> in
public/index.php. Screen readers now read "Author – Title, 2024" instead
of bare "Author – Title", so two theses sharing the same title produce
distinct accessible names (WCAG 2.4.4 Link Purpose — In Context).

Also audit and close WCAG 2.4.3: the tfe.php back link (<a class="tfe-back-link">
← Retour</a>) is already the first child of <header class="tfe-left">
in DOM order, preceding <h1 class="tfe-title">. No code change needed;
TODO item marked done.
2026-04-06 15:33:08 +02:00

136 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// Load configuration
require_once __DIR__ . '/../config/bootstrap.php';
require_once APP_ROOT . '/src/Database.php';
$page = isset($_GET["page"]) ? max(1, intval($_GET["page"])) : 1;
$year = isset($_GET["year"]) ? intval($_GET["year"]) : null;
$itemsPerPage = 24;
// Default home view: random theses from latest year (no year filter, no explicit page)
$isDefaultView = (!$year && $page === 1);
try {
$db = Database::getInstance();
$offset = ($page - 1) * $itemsPerPage;
$availableYears = $db->getAvailableYears();
if ($year) {
$itemsToLoad = $db->searchTheses(['year' => $year], $itemsPerPage, $offset);
$totalItems = $db->countSearchResults(['year' => $year]);
} elseif ($isDefaultView) {
$latestYear = $db->getLatestPublishedYear();
$itemsToLoad = $db->getLatestYearTheses($itemsPerPage);
$totalItems = count($itemsToLoad); // no pagination on default view
} else {
$itemsToLoad = $db->getPublishedTheses($itemsPerPage, $offset);
$totalItems = $db->countPublishedTheses();
}
$totalPages = $isDefaultView ? 1 : (int)ceil($totalItems / $itemsPerPage);
// Batch-load cover images for theses that have no banner_path
$coverMap = [];
if (!empty($itemsToLoad)) {
$needCover = array_column(
array_filter($itemsToLoad, fn($t) => empty($t['banner_path'])),
'id'
);
$coverMap = $db->getCoverPathsForTheses($needCover);
}
} catch (Exception $e) {
error_log("Error loading theses: " . $e->getMessage());
$itemsToLoad = [];
$totalPages = 0;
$availableYears = [];
$totalItems = 0;
$latestYear = null;
$isDefaultView = false;
$coverMap = [];
}
$currentNav = '';
$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' => $pageTitle,
'description' => $metaDescription,
'url' => 'https://posterg.erg.be/',
'site_name' => 'Posterg ERG',
];
$extraCss = ['/assets/css/main.css'];
$bodyClass = 'home-body';
?>
<?php include APP_ROOT . '/templates/head.php'; ?>
<?php include APP_ROOT . '/templates/header.php'; ?>
<?php if ($year): ?>
<p class="filter-info" role="status">
Année : <?= htmlspecialchars($year) ?>
<a href="index.php" class="clear-filter"><span aria-hidden="true">✕</span> Réinitialiser</a>
</p>
<?php elseif ($isDefaultView && !empty($latestYear)): ?>
<p class="filter-info home-latest-label" role="status">
Découvrez les TFE de <?= (int)$latestYear ?> — sélection aléatoire
</p>
<?php endif; ?>
<main class="home-main" id="main-content">
<h1 class="sr-only">Mémoires de l'ERG</h1>
<ul class="cards-container">
<?php foreach ($itemsToLoad as $item): ?>
<li class="card">
<a href="tfe.php?id=<?= (int)$item["id"] ?>">
<?php
// Resolve thumbnail: banner_path → cover file → gradient placeholder
$thumb = null;
// 1. Banner path (dedicated home thumbnail)
if (!empty($item['banner_path'])) {
$thumb = $item['banner_path'];
}
// 2. Cover image from thesis_files (batch-loaded above)
if (!$thumb && isset($coverMap[$item['id']])) {
$thumb = $coverMap[$item['id']];
}
// 3. Fall through to gradient
?>
<?php if ($thumb): ?>
<figure>
<img src="/media.php?path=<?= urlencode($thumb) ?>"
alt="Couverture — <?= htmlspecialchars($item['title']) ?> par <?= htmlspecialchars($item['authors'] ?? '') ?>"
loading="lazy">
</figure>
<?php else: ?>
<?php
$hue = ($item['id'] * 47 + 160) % 360;
$hue2 = ($hue + 40) % 360;
?>
<div class="card__media--gradient"
style="background:linear-gradient(135deg,hsl(<?= $hue ?>,55%,40%),hsl(<?= $hue2 ?>,50%,28%));"
aria-hidden="true">
<span class="card__gradient-author"><?= htmlspecialchars($item['authors'] ?? '') ?></span>
<span class="card__gradient-title"><?= htmlspecialchars($item['title']) ?></span>
</div>
<?php endif; ?>
<p><?= htmlspecialchars($item["authors"] ?? '') ?><?php if (!empty($item['authors']) && !empty($item['title'])): ?> <?php endif; ?><?= htmlspecialchars($item["title"]) ?><?php if (!empty($item['year'])): ?><span class="sr-only">, <?= (int)$item['year'] ?></span><?php endif; ?></p>
</a>
</li>
<?php endforeach; ?>
<?php if (empty($itemsToLoad)): ?>
<li class="cards-empty">Aucun mémoire trouvé.</li>
<?php endif; ?>
</ul>
<?php
$baseParams = array_filter(['year' => $year]);
include APP_ROOT . '/templates/partials/pagination.php';
?>
</main>
<?php include APP_ROOT . '/templates/footer.php'; ?>