mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-07 03:29:19 +02:00
admin edit.php: add cover image + thesis file management fields
- Database: add deleteThesisFile() and handleCoverUpload() methods - ThesisEditController::load(): expose currentFiles + currentCover to view - ThesisEditController::save(): handle couverture upload/removal, per-file deletion (delete_files[]), and new thesis file uploads - edit.php template: new Fichiers fieldset with cover preview+remove, existing files list with delete checkboxes, new file upload input (mirrors add.php / partage.php)
This commit is contained in:
@@ -1744,6 +1744,95 @@ class Database {
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single thesis file record by its ID and optionally remove the
|
||||
* file from disk. Returns the file_path that was deleted (or null if not
|
||||
* found), so the caller can clean up the filesystem.
|
||||
*
|
||||
* @param int $fileId Primary key of thesis_files row.
|
||||
* @param int $thesisId Owning thesis ID (used as a safety guard).
|
||||
* @return string|null The file_path that was stored, or null.
|
||||
*/
|
||||
public function deleteThesisFile(int $fileId, int $thesisId): ?string
|
||||
{
|
||||
$stmt = $this->pdo->prepare(
|
||||
"SELECT file_path FROM thesis_files WHERE id = ? AND thesis_id = ? LIMIT 1"
|
||||
);
|
||||
$stmt->execute([$fileId, $thesisId]);
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
$this->pdo->prepare("DELETE FROM thesis_files WHERE id = ?")->execute([$fileId]);
|
||||
return $row['file_path'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the cover image for a thesis: removes any existing cover record
|
||||
* (and its file from disk), then inserts the new one.
|
||||
*
|
||||
* @param int $thesisId
|
||||
* @param array|null $upload Single-file $_FILES entry.
|
||||
* @return string|null Relative path of the new cover, or null.
|
||||
*/
|
||||
public function handleCoverUpload(int $thesisId, ?array $upload): ?string
|
||||
{
|
||||
if (!$upload || ($upload['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$allowedMimes = ['image/jpeg', 'image/png'];
|
||||
$allowedExts = ['jpg', 'jpeg', 'png'];
|
||||
$maxBytes = 10 * 1024 * 1024; // 10 MB
|
||||
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mimeType = $finfo->file($upload['tmp_name']);
|
||||
$ext = strtolower(pathinfo($upload['name'], PATHINFO_EXTENSION));
|
||||
|
||||
if (!in_array($mimeType, $allowedMimes, true)
|
||||
|| !in_array($ext, $allowedExts, true)
|
||||
|| $upload['size'] > $maxBytes) {
|
||||
error_log("handleCoverUpload: rejected {$upload['name']} ($mimeType, {$upload['size']} bytes)");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove existing cover record + file
|
||||
$existing = $this->pdo->prepare(
|
||||
"SELECT id, file_path FROM thesis_files WHERE thesis_id = ? AND file_type = 'cover' LIMIT 1"
|
||||
);
|
||||
$existing->execute([$thesisId]);
|
||||
if ($old = $existing->fetch()) {
|
||||
$this->pdo->prepare("DELETE FROM thesis_files WHERE id = ?")->execute([$old['id']]);
|
||||
if (!empty($old['file_path']) && defined('STORAGE_ROOT')) {
|
||||
$abs = STORAGE_ROOT . '/' . $old['file_path'];
|
||||
if (file_exists($abs)) @unlink($abs);
|
||||
}
|
||||
}
|
||||
|
||||
$coverDir = defined('STORAGE_ROOT') ? STORAGE_ROOT . '/covers/' : null;
|
||||
if (!$coverDir) {
|
||||
error_log('handleCoverUpload: STORAGE_ROOT not defined');
|
||||
return null;
|
||||
}
|
||||
if (!is_dir($coverDir)) {
|
||||
mkdir($coverDir, 0755, true);
|
||||
}
|
||||
|
||||
$safeName = bin2hex(random_bytes(16)) . '.' . $ext;
|
||||
$targetPath = $coverDir . $safeName;
|
||||
|
||||
if (!move_uploaded_file($upload['tmp_name'], $targetPath)) {
|
||||
error_log("handleCoverUpload: move_uploaded_file failed for {$upload['name']}");
|
||||
return null;
|
||||
}
|
||||
|
||||
chmod($targetPath, 0644);
|
||||
$relPath = 'covers/' . $safeName;
|
||||
$this->insertThesisFile($thesisId, 'cover', $relPath, basename($upload['name']), $upload['size'], $mimeType);
|
||||
error_log("handleCoverUpload: saved $relPath");
|
||||
return $relPath;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// EXPORT HELPERS — used by ExportController
|
||||
// ========================================================================
|
||||
|
||||
Reference in New Issue
Block a user