Extract ThesisEditController from admin/edit.php and actions/edit.php

src/ThesisEditController.php (285 lines) centralises all data-fetching and
mutation logic for the thesis-edit workflow:

  load(int $thesisId): array
    Fetches the thesis row, current language/format/jury selections, and all
    lookup tables (orientations, AP programmes, finality types, languages,
    formats, licences, access types) in one call.  Returns a flat view-variable
    array that the dispatcher extracts directly.

  save(int $thesisId, array $post, array $files): void
    Runs the full edit inside a transaction: thesis metadata, authors, jury,
    languages, formats, tags.  Banner upload/removal is handled outside the
    transaction (filesystem op).  Rolls back and re-throws on any failure.

  static autofocusFieldForError(string $msg): ?string
    Centralises the WCAG 3.3.1 exception-message → field-name mapping that
    was previously duplicated inline in actions/edit.php.

Dispatcher changes:
  admin/edit.php      191 → 162 lines  (pure view + ThesisEditController::create() + load())
  actions/edit.php    153 →  53 lines  (CSRF guard + ThesisEditController::save() call)

Follows the same pattern as SearchController and SystemController.
This commit is contained in:
Pontoporeia
2026-04-05 19:17:27 +02:00
parent 40cb119448
commit 41629398d3
5 changed files with 301 additions and 143 deletions

View File

@@ -11,7 +11,7 @@ if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
require_once __DIR__ . '/../../src/Database.php';
require_once APP_ROOT . '/src/ThesisEditController.php';
$thesisId = isset($_GET['id']) ? intval($_GET['id']) : 0;
@@ -19,43 +19,14 @@ if ($thesisId <= 0) {
die("ID invalide");
}
// Flash messages are consumed by the flash-messages partial below.
// WCAG 3.3.1 — consume the autofocus hint stored by the edit action on
// validation failure.
$autofocusField = App::consumeAutofocus();
try {
$db = new Database();
// Load thesis data
$thesis = $db->getThesis($thesisId);
if (!$thesis) {
die("TFE non trouvé");
}
// Load current relationships via dedicated DB methods (no raw PDO)
$currentLanguages = $db->getThesisLanguageIds($thesisId);
$currentFormats = $db->getThesisFormatIds($thesisId);
$jury = $db->getThesisJury($thesisId);
// Reference / lookup data
$orientations = $db->getAllOrientations();
$apPrograms = $db->getAllAPPrograms();
$finalityTypes = $db->getAllFinalityTypes();
$languages = $db->getAllLanguages();
$formatTypes = $db->getAllFormatTypes();
$licenseTypes = $db->getAllLicenseTypes();
$accessTypes = $db->getAccessTypes();
// Fetch raw FK IDs (view only exposes name strings)
$rawRow = $db->getThesisRawFields($thesisId);
$currentLicenseId = $rawRow['license_id'] ?? null;
$currentAccessTypeId = $rawRow['access_type_id'] ?? null;
$currentContextNote = $rawRow['context_note'] ?? '';
// Set page title for header
$pageTitle = "Éditer TFE - " . htmlspecialchars($thesis['title']);
// WCAG 3.3.1 — consume the autofocus hint stored by the edit action on validation failure.
$autofocusField = App::consumeAutofocus();
$ctrl = ThesisEditController::create();
$view = $ctrl->load($thesisId);
extract($view); // thesis, currentLanguages, currentFormats, jury, lookup tables, pageTitle …
} catch (Exception $e) {
error_log("Error loading edit page: " . $e->getMessage());
die("Erreur lors du chargement: " . $e->getMessage());