mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
1. note_intention: Delete old file only when a genuinely new upload arrives
(32-char hex file_id), not when the FilePond pool preserves an existing
file by sending its DB integer ID. Previously the DB integer ID
triggered $hasNewNote=true, which deleted the existing note_intention
from disk+DB, then handleFilePondSingleFile couldn't re-process it
because the regex requires a hex pattern. Same fix applied to cover.
2. All file deletions now use deleteThesisFileToTrash() which renames
files to tmp/_trash/ instead of unlinking. The trash preserves
original filenames prefixed with DB id for traceability. Skips
website URLs and PeerTube refs (no disk file).
3. Storage prefix changed from theses/ to documents/ to reflect that
the folder holds all document types (determined by file_type in DB).
MediaController visibility gate supports both prefixes for backward
compat with existing files.
4. File browser + relink feature for orphaned files:
- /admin/fragments/file-browser.php — HTMX tree browser for
storage/documents/ and storage/theses/
- /admin/actions/filepond/relink.php — POST endpoint that inserts
a thesis_files row pointing to existing on-disk file
- Per-pool "📂 Relier" buttons (edit mode only)
- JS: XamxamOpenFileBrowser / XamxamRelinkFile with FilePond integration
- CSS: .relink-modal dialog + .file-browser tree styles
48 lines
2.0 KiB
PHP
48 lines
2.0 KiB
PHP
<?php
|
|
require_once __DIR__ . "/../../bootstrap.php";
|
|
require_once __DIR__ . '/../../src/AdminAuth.php';
|
|
AdminAuth::requireLogin();
|
|
|
|
if (empty($_SESSION['csrf_token'])) {
|
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|
}
|
|
|
|
require_once APP_ROOT . '/src/Controllers/ThesisEditController.php';
|
|
|
|
$thesisId = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
|
|
|
if ($thesisId <= 0) {
|
|
die("ID invalide");
|
|
}
|
|
|
|
$autofocusField = App::consumeAutofocus();
|
|
|
|
// Form help blocks for editable généralités
|
|
$helpBlocks = Database::getInstance()->getAllFormHelpBlocks();
|
|
$helpFn = fn(string $key) => empty($helpBlocks[$key]['enabled']) ? '' : ($helpBlocks[$key]['content'] ?? '');
|
|
|
|
function old($key, $default = "") {
|
|
global $formData;
|
|
if (!isset($formData[$key])) return $default;
|
|
if (is_array($formData[$key])) return $formData[$key]; // Return raw array for callers that handle it
|
|
if ($formData[$key] === null) return $default;
|
|
return htmlspecialchars((string)$formData[$key]);
|
|
}
|
|
|
|
try {
|
|
$ctrl = ThesisEditController::create();
|
|
$view = $ctrl->load($thesisId);
|
|
extract($view);
|
|
} catch (Exception $e) {
|
|
error_log("Error loading edit page: " . $e->getMessage());
|
|
die("Erreur lors du chargement: " . $e->getMessage());
|
|
}
|
|
|
|
$isAdmin = true; $bodyClass = 'admin-body';
|
|
$extraCss = ['/assets/css/form.css', '/assets/css/filepond.min.css', '/assets/css/filepond-plugin-image-preview.min.css'];
|
|
$extraJs = ['/assets/js/vendor/filepond.min.js', '/assets/js/vendor/filepond-plugin-file-validate-type.min.js', '/assets/js/vendor/filepond-plugin-file-validate-size.min.js', '/assets/js/vendor/filepond-plugin-image-preview.min.js', '/assets/js/vendor/filepond-plugin-image-exif-orientation.min.js', '/assets/js/app/file-upload-filepond.js', '/assets/js/app/beforeunload-guard.js', '/assets/js/app/pill-search.js', '/assets/js/app/jury-autocomplete.js'];
|
|
require_once APP_ROOT . '/templates/head.php';
|
|
include APP_ROOT . '/templates/header.php';
|
|
include APP_ROOT . '/templates/admin/edit.php';
|
|
require_once APP_ROOT . '/templates/admin/footer.php';
|