mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
merge banners into covers: remove banner field, migrate files, add covers to search/home/repertoire cards
This commit is contained in:
130
app/migrations/applied/016_merge_banners_into_covers.php
Normal file
130
app/migrations/applied/016_merge_banners_into_covers.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* Migration 016 — merge banners into covers
|
||||
*
|
||||
* 1. For every thesis that has a banner_path:
|
||||
* a. Copy the file from storage/banners/<file> to storage/covers/<file>
|
||||
* b. Insert a thesis_files row with file_type='cover'
|
||||
* c. Clear theses.banner_path
|
||||
* 2. Remove the now-empty storage/banners/ directory (best-effort).
|
||||
*
|
||||
* Safe to re-run: if a cover record already exists for a thesis, the banner
|
||||
* migration for that thesis is skipped.
|
||||
*/
|
||||
|
||||
defined('APP_ROOT') || define('APP_ROOT', dirname(__DIR__, 2));
|
||||
defined('STORAGE_ROOT') || define('STORAGE_ROOT', APP_ROOT . '/storage');
|
||||
|
||||
$dbPath = APP_ROOT . '/storage/xamxam.db';
|
||||
if (!file_exists($dbPath)) {
|
||||
echo "ERROR: database not found at $dbPath\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$pdo = new PDO('sqlite:' . $dbPath);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
$pdo->exec('PRAGMA foreign_keys = ON');
|
||||
|
||||
$coverDir = STORAGE_ROOT . '/covers/';
|
||||
$bannerDir = STORAGE_ROOT . '/banners/';
|
||||
|
||||
if (!is_dir($coverDir)) {
|
||||
mkdir($coverDir, 0755, true);
|
||||
echo "Created covers/ directory.\n";
|
||||
}
|
||||
|
||||
// Fetch all theses with a non-null banner_path
|
||||
$stmt = $pdo->query("SELECT id, banner_path FROM theses WHERE banner_path IS NOT NULL");
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
if (empty($rows)) {
|
||||
echo "No banners to migrate.\n";
|
||||
} else {
|
||||
foreach ($rows as $row) {
|
||||
$thesisId = (int)$row['id'];
|
||||
$bannerPath = $row['banner_path']; // e.g. "banners/abc123.png"
|
||||
|
||||
// Skip if a cover record already exists for this thesis
|
||||
$check = $pdo->prepare("SELECT id FROM thesis_files WHERE thesis_id = ? AND file_type = 'cover' LIMIT 1");
|
||||
$check->execute([$thesisId]);
|
||||
if ($check->fetch()) {
|
||||
echo " Thesis $thesisId: cover record already exists — skipping banner migration.\n";
|
||||
// Still clear banner_path so UI stays clean
|
||||
$pdo->prepare("UPDATE theses SET banner_path = NULL WHERE id = ?")->execute([$thesisId]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$srcAbs = STORAGE_ROOT . '/' . $bannerPath;
|
||||
$filename = basename($bannerPath);
|
||||
$dstAbs = $coverDir . $filename;
|
||||
$dstRel = 'covers/' . $filename;
|
||||
|
||||
if (!file_exists($srcAbs)) {
|
||||
echo " Thesis $thesisId: source file missing ($srcAbs) — inserting DB record with new path anyway, skipping file copy.\n";
|
||||
} else {
|
||||
if (!copy($srcAbs, $dstAbs)) {
|
||||
echo " ERROR: could not copy $srcAbs → $dstAbs — skipping thesis $thesisId.\n";
|
||||
continue;
|
||||
}
|
||||
chmod($dstAbs, 0644);
|
||||
echo " Thesis $thesisId: copied $bannerPath → $dstRel\n";
|
||||
}
|
||||
|
||||
// Determine MIME from extension
|
||||
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
$mime = match($ext) {
|
||||
'jpg', 'jpeg' => 'image/jpeg',
|
||||
'png' => 'image/png',
|
||||
'webp' => 'image/webp',
|
||||
default => 'image/jpeg',
|
||||
};
|
||||
|
||||
// Get file size
|
||||
$size = file_exists($dstAbs) ? filesize($dstAbs) : 0;
|
||||
|
||||
// Insert cover record
|
||||
$ins = $pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, sort_order)
|
||||
VALUES (?, 'cover', ?, ?, ?, ?, 0)"
|
||||
);
|
||||
$ins->execute([$thesisId, $dstRel, $filename, $size, $mime]);
|
||||
echo " Thesis $thesisId: inserted cover record → $dstRel\n";
|
||||
|
||||
// Clear banner_path
|
||||
$pdo->prepare("UPDATE theses SET banner_path = NULL WHERE id = ?")->execute([$thesisId]);
|
||||
echo " Thesis $thesisId: cleared banner_path.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Remove old banner files that were successfully copied
|
||||
$remaining = glob($bannerDir . '*') ?: [];
|
||||
$allClear = true;
|
||||
foreach ($remaining as $f) {
|
||||
$basename = basename($f);
|
||||
if (file_exists($coverDir . $basename)) {
|
||||
@unlink($f);
|
||||
echo "Removed migrated banner file: banners/$basename\n";
|
||||
} else {
|
||||
echo "WARNING: banners/$basename has no corresponding cover — leaving in place.\n";
|
||||
$allClear = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the now-empty banners/ directory (best-effort, ignoring .gitkeep)
|
||||
if ($allClear && is_dir($bannerDir)) {
|
||||
$leftovers = array_diff(scandir($bannerDir), ['.', '..', '.gitkeep']);
|
||||
if (empty($leftovers)) {
|
||||
// Remove .gitkeep if present, then the dir
|
||||
$gitkeep = $bannerDir . '.gitkeep';
|
||||
if (file_exists($gitkeep)) {
|
||||
@unlink($gitkeep);
|
||||
}
|
||||
@rmdir($bannerDir);
|
||||
echo "Removed banners/ directory.\n";
|
||||
} else {
|
||||
echo "WARNING: banners/ directory still has files after migration — leaving in place.\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "\nMigration 016 complete.\n";
|
||||
Reference in New Issue
Block a user