mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-11 07:41:17 +02:00
merge banners into covers: remove banner field, migrate files, add covers to search/home/repertoire cards
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
* - Parse and validate GET parameters (`page`, `year`)
|
||||
* - Determine the display mode (default random-latest / year-filtered / paginated all)
|
||||
* - Run the appropriate Database queries
|
||||
* - Batch-load cover images for theses without a banner_path
|
||||
* - Batch-load cover images for displayed theses
|
||||
* - Assemble OG / meta tag array
|
||||
* - Return a flat array of view variables ready for template extraction
|
||||
*
|
||||
@@ -91,18 +91,11 @@ class HomeController
|
||||
$totalItems = $this->db->countPublishedTheses();
|
||||
}
|
||||
|
||||
// Batch-load cover images for theses that have no banner_path
|
||||
// Batch-load cover images for all displayed theses
|
||||
if (!empty($itemsToLoad)) {
|
||||
$needCover = array_column(
|
||||
array_filter(
|
||||
$itemsToLoad,
|
||||
static fn ($t) => empty($t['banner_path']),
|
||||
),
|
||||
'id',
|
||||
$coverMap = $this->db->getCoverPathsForTheses(
|
||||
array_column($itemsToLoad, 'id')
|
||||
);
|
||||
if (!empty($needCover)) {
|
||||
$coverMap = $this->db->getCoverPathsForTheses($needCover);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log('HomeController: ' . $e->getMessage());
|
||||
|
||||
@@ -118,6 +118,7 @@ class SearchController
|
||||
'results' => $results,
|
||||
'validationError' => $validationError,
|
||||
'baseParams' => $baseParams,
|
||||
'coverMap' => $coverMap,
|
||||
|
||||
// Filter dropdowns
|
||||
'years' => $years,
|
||||
@@ -225,6 +226,8 @@ class SearchController
|
||||
exit();
|
||||
}
|
||||
|
||||
$coverMap = $this->db->getCoverPathsForTheses(array_column($theses, 'id'));
|
||||
|
||||
header('Cache-Control: public, max-age=300');
|
||||
include APP_ROOT . '/templates/partials/student-preview.php';
|
||||
exit();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Responsibilities:
|
||||
* - Validate the `id` GET parameter and load the thesis record
|
||||
* - Enforce publication visibility (redirect to index on 404)
|
||||
* - Resolve the OG image (banner → first image file)
|
||||
* - Resolve the OG image (cover file → first image file)
|
||||
* - Build the complete OG / Twitter Card tag array
|
||||
* - Assemble the meta description from the synopsis
|
||||
* - Collect WebVTT caption file paths for video pairing
|
||||
@@ -155,16 +155,20 @@ class TfeController
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the OG image URL: banner_path → first image file → empty string.
|
||||
* Resolve the OG image URL: cover file → first image file → empty string.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $files
|
||||
*/
|
||||
private function resolveOgImage(array $files, ?string $bannerPath): string
|
||||
private function resolveOgImage(array $files): string
|
||||
{
|
||||
if (!empty($bannerPath)) {
|
||||
return self::BASE_URL . '/media.php?path=' . rawurlencode($bannerPath);
|
||||
// Prefer the dedicated cover
|
||||
foreach ($files as $file) {
|
||||
if (($file['file_type'] ?? '') === 'cover') {
|
||||
return self::BASE_URL . '/media.php?path=' . rawurlencode($file['file_path']);
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to first image file
|
||||
foreach ($files as $file) {
|
||||
$ext = strtolower(pathinfo($file['file_path'] ?? '', PATHINFO_EXTENSION));
|
||||
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'], true)) {
|
||||
@@ -183,7 +187,7 @@ class TfeController
|
||||
*/
|
||||
private function buildOgTags(array $data, int $thesisId, string $metaDescription): array
|
||||
{
|
||||
$ogImage = $this->resolveOgImage($data['files'] ?? [], $data['banner_path'] ?? null);
|
||||
$ogImage = $this->resolveOgImage($data['files'] ?? []);
|
||||
$title = $data['title'] . (!empty($data['authors']) ? ' – ' . $data['authors'] : '');
|
||||
$imageAlt = $data['title'] . (!empty($data['authors']) ? ' par ' . $data['authors'] : '');
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ class ThesisCreateController
|
||||
* 3. INSERT thesis row + link author (inside transaction)
|
||||
* 4. Link jury, languages, formats, tags (inside transaction)
|
||||
* 5. COMMIT
|
||||
* 6. Handle file uploads: cover, banner, thesis files (outside transaction)
|
||||
* 6. Handle file uploads: cover, thesis files (outside transaction)
|
||||
*
|
||||
* @param array $post Sanitised $_POST array.
|
||||
* @param array $files $_FILES array.
|
||||
@@ -213,7 +213,6 @@ class ThesisCreateController
|
||||
|
||||
// ── 5. File uploads (outside transaction — filesystem ops) ────────────
|
||||
$this->handleCoverUpload($thesisId, $files['couverture'] ?? null);
|
||||
$this->db->handleBannerUpload($thesisId, $files['banner'] ?? null);
|
||||
$this->handleThesisFiles($thesisId, $data['annee'], $identifier, $files['files'] ?? null, $authorSlug, $post);
|
||||
|
||||
// ── 6. Website URL — stored as thesis_files row ──────────────────────
|
||||
|
||||
@@ -320,20 +320,6 @@ class ThesisEditController
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// ── Banner (outside transaction — filesystem op) ──────────────────────
|
||||
if (isset($post['remove_banner'])) {
|
||||
$currentBannerPath = $this->db->getThesisBannerPath($thesisId);
|
||||
if ($currentBannerPath && defined('STORAGE_ROOT')) {
|
||||
$absPath = STORAGE_ROOT . '/' . $currentBannerPath;
|
||||
if (file_exists($absPath)) {
|
||||
unlink($absPath);
|
||||
}
|
||||
}
|
||||
$this->db->setBannerPath($thesisId, null);
|
||||
} else {
|
||||
$this->db->handleBannerUpload($thesisId, $files['banner'] ?? null);
|
||||
}
|
||||
|
||||
// ── Cover image (outside transaction — filesystem op) ─────────────────
|
||||
if (isset($post['remove_cover'])) {
|
||||
$allFiles = $this->db->getThesisFiles($thesisId);
|
||||
|
||||
Reference in New Issue
Block a user