mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
refactor: use encapsulated Database methods in formulaire.php and edit.php
This commit is contained in:
123
src/Database.php
123
src/Database.php
@@ -869,6 +869,71 @@ class Database {
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// JUNCTION-TABLE HELPERS (delete-then-reinsert pattern)
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* Replace all language associations for a thesis.
|
||||
* @param int $thesisId
|
||||
* @param int[] $languageIds IDs from the languages table
|
||||
*/
|
||||
public function setThesisLanguages(int $thesisId, array $languageIds): void {
|
||||
$this->pdo->prepare("DELETE FROM thesis_languages WHERE thesis_id = ?")->execute([$thesisId]);
|
||||
$stmt = $this->pdo->prepare(
|
||||
"INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?, ?)"
|
||||
);
|
||||
foreach ($languageIds as $langId) {
|
||||
$id = (int)$langId;
|
||||
if ($id > 0) {
|
||||
$stmt->execute([$thesisId, $id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all format associations for a thesis.
|
||||
* @param int $thesisId
|
||||
* @param int[] $formatIds IDs from the format_types table
|
||||
*/
|
||||
public function setThesisFormats(int $thesisId, array $formatIds): void {
|
||||
$this->pdo->prepare("DELETE FROM thesis_formats WHERE thesis_id = ?")->execute([$thesisId]);
|
||||
$stmt = $this->pdo->prepare(
|
||||
"INSERT INTO thesis_formats (thesis_id, format_id) VALUES (?, ?)"
|
||||
);
|
||||
foreach ($formatIds as $fmtId) {
|
||||
$id = (int)$fmtId;
|
||||
if ($id > 0) {
|
||||
$stmt->execute([$thesisId, $id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all tag associations for a thesis.
|
||||
* Tags are identified by name (findOrCreateTag is called for each).
|
||||
* Empty / whitespace-only names are silently skipped.
|
||||
* Maximum 10 tags are accepted; extras are ignored.
|
||||
*
|
||||
* @param int $thesisId
|
||||
* @param string[] $tagNames
|
||||
*/
|
||||
public function setThesisTags(int $thesisId, array $tagNames): void {
|
||||
$this->pdo->prepare("DELETE FROM thesis_tags WHERE thesis_id = ?")->execute([$thesisId]);
|
||||
$stmt = $this->pdo->prepare(
|
||||
"INSERT OR IGNORE INTO thesis_tags (tag_id, thesis_id) VALUES (?, ?)"
|
||||
);
|
||||
$count = 0;
|
||||
foreach ($tagNames as $name) {
|
||||
if ($count >= 10) break;
|
||||
$tagId = $this->findOrCreateTag($name); // trims, returns null for empty
|
||||
if ($tagId !== null) {
|
||||
$stmt->execute([$tagId, $thesisId]);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// BANNER METHODS
|
||||
// ========================================================================
|
||||
@@ -883,6 +948,64 @@ class Database {
|
||||
$stmt->execute([$path, $thesisId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a banner image upload for a thesis.
|
||||
*
|
||||
* Validates MIME type, extension, and file size, then saves the file to the
|
||||
* banners/ directory under STORAGE_ROOT and calls setBannerPath().
|
||||
*
|
||||
* Returns the relative path (e.g. "banners/abc123.jpg") on success,
|
||||
* or null if the file array is absent, has an error, fails validation,
|
||||
* or cannot be moved.
|
||||
*
|
||||
* @param int $thesisId Target thesis ID
|
||||
* @param array|null $uploadedFile Entry from $_FILES (e.g. $_FILES['banner'])
|
||||
* @return string|null Relative path stored in the DB, or null
|
||||
*/
|
||||
public function handleBannerUpload(int $thesisId, ?array $uploadedFile): ?string {
|
||||
if (!$uploadedFile || ($uploadedFile['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$allowedMimes = ['image/jpeg', 'image/png', 'image/webp'];
|
||||
$allowedExts = ['jpg', 'jpeg', 'png', 'webp'];
|
||||
$maxBytes = 5 * 1024 * 1024; // 5 MB
|
||||
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mimeType = $finfo->file($uploadedFile['tmp_name']);
|
||||
$ext = strtolower(pathinfo($uploadedFile['name'], PATHINFO_EXTENSION));
|
||||
|
||||
if (!in_array($mimeType, $allowedMimes, true) ||
|
||||
!in_array($ext, $allowedExts, true) ||
|
||||
$uploadedFile['size'] > $maxBytes) {
|
||||
error_log("handleBannerUpload: rejected " . $uploadedFile['name'] . " ($mimeType, {$uploadedFile['size']} bytes)");
|
||||
return null;
|
||||
}
|
||||
|
||||
$bannerDir = defined('STORAGE_ROOT') ? STORAGE_ROOT . '/banners/' : null;
|
||||
if (!$bannerDir) {
|
||||
error_log("handleBannerUpload: STORAGE_ROOT not defined");
|
||||
return null;
|
||||
}
|
||||
if (!file_exists($bannerDir)) {
|
||||
mkdir($bannerDir, 0755, true);
|
||||
}
|
||||
|
||||
$safeName = bin2hex(random_bytes(16)) . '.' . $ext;
|
||||
$targetPath = $bannerDir . $safeName;
|
||||
|
||||
if (!move_uploaded_file($uploadedFile['tmp_name'], $targetPath)) {
|
||||
error_log("handleBannerUpload: move_uploaded_file failed for " . $uploadedFile['name']);
|
||||
return null;
|
||||
}
|
||||
|
||||
chmod($targetPath, 0644);
|
||||
$relativePath = 'banners/' . $safeName;
|
||||
$this->setBannerPath($thesisId, $relativePath);
|
||||
error_log("handleBannerUpload: saved $relativePath");
|
||||
return $relativePath;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// ENCAPSULATED QUERY HELPERS
|
||||
// ========================================================================
|
||||
|
||||
@@ -1 +1 @@
|
||||
[1774701765]
|
||||
[1774702033]
|
||||
Reference in New Issue
Block a user