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:
@@ -183,27 +183,13 @@ try {
|
|||||||
$db->setThesisJury($thesisId, $juryMembers);
|
$db->setThesisJury($thesisId, $juryMembers);
|
||||||
|
|
||||||
// ===== LINK LANGUAGES TO THESIS =====
|
// ===== LINK LANGUAGES TO THESIS =====
|
||||||
foreach ($languageIds as $languageId) {
|
$db->setThesisLanguages($thesisId, $languageIds);
|
||||||
$stmt = $pdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$thesisId, $languageId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== LINK FORMATS TO THESIS =====
|
// ===== LINK FORMATS TO THESIS =====
|
||||||
foreach ($formatIds as $formatId) {
|
$db->setThesisFormats($thesisId, $formatIds);
|
||||||
$stmt = $pdo->prepare("INSERT INTO thesis_formats (thesis_id, format_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$thesisId, $formatId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== LINK TAGS TO THESIS =====
|
// ===== LINK TAGS TO THESIS =====
|
||||||
foreach ($keywords as $keyword) {
|
$db->setThesisTags($thesisId, $keywords);
|
||||||
if (!empty($keyword)) {
|
|
||||||
$tagId = $db->findOrCreateTag($keyword);
|
|
||||||
if ($tagId) {
|
|
||||||
$stmt = $pdo->prepare("INSERT OR IGNORE INTO thesis_tags (tag_id, thesis_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$tagId, $thesisId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== HANDLE FILE UPLOADS =====
|
// ===== HANDLE FILE UPLOADS =====
|
||||||
|
|
||||||
@@ -266,28 +252,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process banner image
|
// Process banner image
|
||||||
if ($bannerFile && isset($bannerFile["error"]) && $bannerFile["error"] === UPLOAD_ERR_OK) {
|
$db->handleBannerUpload($thesisId, $bannerFile ?: null);
|
||||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
|
||||||
$mimeType = $finfo->file($bannerFile["tmp_name"]);
|
|
||||||
$fileExtension = strtolower(pathinfo($bannerFile["name"], PATHINFO_EXTENSION));
|
|
||||||
$allowedBannerMimes = ['image/jpeg', 'image/png', 'image/webp'];
|
|
||||||
$allowedBannerExts = ['jpg', 'jpeg', 'png', 'webp'];
|
|
||||||
$maxBannerSize = 5 * 1024 * 1024; // 5 MB
|
|
||||||
|
|
||||||
if (in_array($mimeType, $allowedBannerMimes) && in_array($fileExtension, $allowedBannerExts)
|
|
||||||
&& $bannerFile["size"] <= $maxBannerSize) {
|
|
||||||
$randomName = bin2hex(random_bytes(16));
|
|
||||||
$safeFileName = $randomName . "." . $fileExtension;
|
|
||||||
$targetFile = $bannerDir . $safeFileName;
|
|
||||||
if (move_uploaded_file($bannerFile["tmp_name"], $targetFile)) {
|
|
||||||
chmod($targetFile, 0644);
|
|
||||||
$db->setBannerPath($thesisId, "banners/" . $safeFileName);
|
|
||||||
error_log("Banner image uploaded: " . $safeFileName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error_log("Invalid or oversized banner image: " . $bannerFile["name"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process thesis files
|
// Process thesis files
|
||||||
if ($files && is_array($files["name"])) {
|
if ($files && is_array($files["name"])) {
|
||||||
|
|||||||
@@ -109,71 +109,28 @@ try {
|
|||||||
$db->setThesisJury($thesisId, $editJuryMembers);
|
$db->setThesisJury($thesisId, $editJuryMembers);
|
||||||
|
|
||||||
// Update languages
|
// Update languages
|
||||||
$pdo->prepare("DELETE FROM thesis_languages WHERE thesis_id = ?")->execute([$thesisId]);
|
$db->setThesisLanguages($thesisId, isset($_POST['languages']) && is_array($_POST['languages']) ? $_POST['languages'] : []);
|
||||||
if (isset($_POST['languages']) && is_array($_POST['languages'])) {
|
|
||||||
foreach ($_POST['languages'] as $languageId) {
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$thesisId, intval($languageId)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update formats
|
// Update formats
|
||||||
$pdo->prepare("DELETE FROM thesis_formats WHERE thesis_id = ?")->execute([$thesisId]);
|
$db->setThesisFormats($thesisId, isset($_POST['formats']) && is_array($_POST['formats']) ? $_POST['formats'] : []);
|
||||||
if (isset($_POST['formats']) && is_array($_POST['formats'])) {
|
|
||||||
foreach ($_POST['formats'] as $formatId) {
|
|
||||||
$stmt = $pdo->prepare("INSERT INTO thesis_formats (thesis_id, format_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$thesisId, intval($formatId)]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update tags
|
// Update tags
|
||||||
$pdo->prepare("DELETE FROM thesis_tags WHERE thesis_id = ?")->execute([$thesisId]);
|
|
||||||
$keywordsRaw = trim($_POST['tag'] ?? '');
|
$keywordsRaw = trim($_POST['tag'] ?? '');
|
||||||
if (!empty($keywordsRaw)) {
|
$editKeywords = !empty($keywordsRaw) ? array_map('trim', explode(',', $keywordsRaw)) : [];
|
||||||
$keywords = array_map('trim', explode(',', $keywordsRaw));
|
$db->setThesisTags($thesisId, $editKeywords);
|
||||||
$keywords = array_slice($keywords, 0, 10); // Max 10
|
|
||||||
foreach ($keywords as $keyword) {
|
|
||||||
if (!empty($keyword)) {
|
|
||||||
$tagId = $db->findOrCreateTag($keyword);
|
|
||||||
if ($tagId) {
|
|
||||||
$stmt = $pdo->prepare("INSERT OR IGNORE INTO thesis_tags (tag_id, thesis_id) VALUES (?, ?)");
|
|
||||||
$stmt->execute([$tagId, $thesisId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$db->commit();
|
$db->commit();
|
||||||
|
|
||||||
// Handle banner upload/removal (after commit, outside transaction)
|
// Handle banner upload/removal (after commit, outside transaction)
|
||||||
$bannerDir = defined('STORAGE_ROOT') ? STORAGE_ROOT . "/banners/" : null;
|
|
||||||
if ($bannerDir && !file_exists($bannerDir)) {
|
|
||||||
mkdir($bannerDir, 0755, true);
|
|
||||||
}
|
|
||||||
if (isset($_POST['remove_banner'])) {
|
if (isset($_POST['remove_banner'])) {
|
||||||
// Unlink existing banner file if present
|
|
||||||
$currentBannerPath = $db->getThesisBannerPath($thesisId);
|
$currentBannerPath = $db->getThesisBannerPath($thesisId);
|
||||||
if ($currentBannerPath && $bannerDir) {
|
if ($currentBannerPath && defined('STORAGE_ROOT')) {
|
||||||
$absPath = STORAGE_ROOT . '/' . $currentBannerPath;
|
$absPath = STORAGE_ROOT . '/' . $currentBannerPath;
|
||||||
if (file_exists($absPath)) unlink($absPath);
|
if (file_exists($absPath)) unlink($absPath);
|
||||||
}
|
}
|
||||||
$db->setBannerPath($thesisId, null);
|
$db->setBannerPath($thesisId, null);
|
||||||
} elseif (isset($_FILES['banner']) && $_FILES['banner']['error'] === UPLOAD_ERR_OK && $bannerDir) {
|
} else {
|
||||||
$bannerFile = $_FILES['banner'];
|
$db->handleBannerUpload($thesisId, $_FILES['banner'] ?? null);
|
||||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
|
||||||
$mimeType = $finfo->file($bannerFile["tmp_name"]);
|
|
||||||
$fileExtension = strtolower(pathinfo($bannerFile["name"], PATHINFO_EXTENSION));
|
|
||||||
$allowedBannerMimes = ['image/jpeg', 'image/png', 'image/webp'];
|
|
||||||
$allowedBannerExts = ['jpg', 'jpeg', 'png', 'webp'];
|
|
||||||
if (in_array($mimeType, $allowedBannerMimes) && in_array($fileExtension, $allowedBannerExts)
|
|
||||||
&& $bannerFile["size"] <= 5 * 1024 * 1024) {
|
|
||||||
$randomName = bin2hex(random_bytes(16));
|
|
||||||
$safeFileName = $randomName . '.' . $fileExtension;
|
|
||||||
if (move_uploaded_file($bannerFile["tmp_name"], $bannerDir . $safeFileName)) {
|
|
||||||
chmod($bannerDir . $safeFileName, 0644);
|
|
||||||
$db->setBannerPath($thesisId, "banners/" . $safeFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = "TFE mis à jour avec succès!";
|
$success = "TFE mis à jour avec succès!";
|
||||||
|
|||||||
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
|
// BANNER METHODS
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
@@ -883,6 +948,64 @@ class Database {
|
|||||||
$stmt->execute([$path, $thesisId]);
|
$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
|
// ENCAPSULATED QUERY HELPERS
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[1774701765]
|
[1774702033]
|
||||||
BIN
storage/test.db
BIN
storage/test.db
Binary file not shown.
Reference in New Issue
Block a user