From 8f4f9d00b45786098906771a058479e0fed1113c Mon Sep 17 00:00:00 2001 From: Pontoporeia Date: Fri, 8 May 2026 17:03:42 +0200 Subject: [PATCH] Refactor: Form improvements and cleanup: note contextuel, annexes, fichiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. fix: form improvements — multiple promoteurices, asterisks, contact dedup, bentopdf - Multiple promoteurice (interne + ULB): both fieldsets now support dynamic add/remove rows (same pattern as lecteurs). field names changed to arrays (jury_promoteur[], jury_promoteur_ulb_name[]). Controllers accept both scalar and array forms for backwards compat. - ULB promoteurice: when finality=Approfondi, asterisk appears on legend and first ULB input is marked required (JS toggle). Non-Approfondi hides the fieldset and clears values. - Contact visibility duplication: removed redundant contact_public checkbox from admin add/edit forms (showContact=false). The 'mail' field in fieldset-tfe-info already serves this purpose. - Asterisk fixes: website URL field now has asterisk+required when Site web format selected. Video/audio already had correct required handling. - bentopdf link: clearer full URL 'https://bentopdf.com/' in both fichiers-fragment.php and form.php (edit mode) 2. refactor: merge Note contextuelle into Backoffice, add Lien BAIU, reorder fields Backoffice fieldset now contains in order: 1. Note contextuelle (was standalone fieldset) 2. Points du jury 3. Remarques 4. Lien BAIU (moved from Métadonnées complémentaires) 5. Exemplaire physique BAIU 6. Exemplaire physique ERG 7. Contact interne Métadonnées complémentaires now only has: pages, minutes, annexes checkbox. Removed dead showContextNote variable from form.php, add.php, edit.php. Controller baiu_link still mapped to input name "lien" (no migration needed). 3. refactor: move annexes checkbox from Métadonnées into Fichiers fieldset - Removed 'Ce TFE comporte des annexes' checkbox from fieldset-metadata.php. - Added annexes checkbox + conditional file input to fichiers-fragment.php. When checked, an HTMX swap reveals the 'annexes' file input (multiple, PDF or ZIP/TAR, max 500 MB). - form.php seeds ['has_annexes'] for initial fragment render. - Métadonnées complémentaires now only contains pages + minutes. --- TODO.md | 14 ++ app/public/partage/fichiers-fragment.php | 40 ++++- app/public/partage/index.php | 2 + .../Controllers/ThesisCreateController.php | 42 +++-- app/src/Controllers/ThesisEditController.php | 40 +++-- app/templates/admin/add.php | 5 +- app/templates/admin/edit.php | 16 +- .../partials/form/fieldset-files.php | 2 +- .../partials/form/fieldset-metadata.php | 20 +-- app/templates/partials/form/form.php | 157 ++++++------------ app/templates/partials/form/jury-fieldset.php | 119 ++++++++++--- 11 files changed, 270 insertions(+), 187 deletions(-) diff --git a/TODO.md b/TODO.md index 7d5abb9..d308f94 100644 --- a/TODO.md +++ b/TODO.md @@ -15,6 +15,20 @@ - [x] `AdminLogger` — `logPeerTubeUpdate()` audit method - [x] Direct file upload fallback: when `peertube_upload_enabled = 0`, standard `` + local storage works unchanged +- [x] Backoffice fieldset reorder — Note contextuelle merged in, Lien BAIU added, removed from Métadonnées + - [x] Backoffice order: Note contextuelle → Points du jury → Remarques → Lien BAIU → Exemplaire BAIU → Exemplaire ERG → Contact interne + - [x] Removed standalone "Note contextuelle" fieldset (now inside Backoffice) + - [x] Lien BAIU moved from Métadonnées complémentaires into Backoffice + - [x] Métadonnées fieldset now: pages, minutes, annexes only + +- [x] Form fixes batch + - [x] bentopdf link clearer: "PDFs trop lourds ? https://bentopdf.com/" (full URL visible) + - [x] Multiple promoteurices: interne and ULB fields now dynamic (add/remove rows, same as lecteurs) + - [x] Contact visibility duplication removed from admin forms (`showContact = false`; `mail` field in fieldset-tfe-info covers it) + - [x] Asterisk corrections in files section: note_intention, website URL, video, audio all show red asterisk + `required` when non-admin + - [x] ULB promoteurice asterisk + required when finality=Approfondi (JS toggles `*` + `required` on first ULB input) + - [x] Controllers handle `jury_promoteur` and `jury_promoteur_ulb_name` as both scalar and array (backwards compat) + - [x] Fix `just serve` — justfile shebang recipes (`deploy-env`, `reencrypt-password`) used space indentation instead of tabs, causing "extra leading whitespace" parse error - [x] PDF 100 MB limit + bentopdf mention diff --git a/app/public/partage/fichiers-fragment.php b/app/public/partage/fichiers-fragment.php index 0685166..023ae20 100644 --- a/app/public/partage/fichiers-fragment.php +++ b/app/public/partage/fichiers-fragment.php @@ -132,11 +132,11 @@ $hxPost = $adminMode ? '/admin/fichiers-fragment.php' : '/partage/fichiers-fragm
- PDF (max 100 MB) · Images (JPG/PNG/GIF/WEBP) · Archives ZIP/TAR (max 500 MB). - PDFs trop lourds ? bentopdf.com + PDF (max 100 MB) · Images (JPG/PNG/GIF/WEBP). + PDFs trop lourds ? https://bentopdf.com/ @@ -144,6 +144,35 @@ $hxPost = $adminMode ? '/admin/fichiers-fragment.php' : '/partage/fichiers-fragm
+ + + +
+ +
+ + + + @@ -151,11 +180,12 @@ $hxPost = $adminMode ? '/admin/fichiers-fragment.php' : '/partage/fichiers-fragm
Site web
- +
+ placeholder="https://mon-tfe.erg.be" + > Le TFE sera affiché comme un site embarqué sur sa page publique.
diff --git a/app/public/partage/index.php b/app/public/partage/index.php index 1580bfa..20cfba2 100644 --- a/app/public/partage/index.php +++ b/app/public/partage/index.php @@ -285,7 +285,9 @@ function renderShareLinkForm(string $slug, array $link): void // Jury data from repopulation $juryPromoteur = old($formData, 'jury_promoteur'); + $juryPromoteurs = []; $juryPromoteurUlb = old($formData, 'jury_promoteur_ulb_name'); + $juryPromoteursUlb = []; $lecteursInternes = []; $lecteursExternes = []; for ($i = 0; $i < 10; $i++) { diff --git a/app/src/Controllers/ThesisCreateController.php b/app/src/Controllers/ThesisCreateController.php index 0836b53..ec4698a 100644 --- a/app/src/Controllers/ThesisCreateController.php +++ b/app/src/Controllers/ThesisCreateController.php @@ -364,24 +364,36 @@ class ThesisCreateController // Jury members — new structure: separate interne/externe lecteurs $juryMembers = []; $hasPromoteur = false; + $hasPromoteurUlb = false; $hasLecteurInt = false; $hasLecteurExt = false; - if (!empty(trim($post['jury_promoteur'] ?? ''))) { - $juryMembers[] = [ - 'name' => trim($post['jury_promoteur']), - 'role' => 'promoteur', - 'is_external' => 0, - 'is_ulb' => 0, - ]; - $hasPromoteur = true; + // Promoteurs internes (accept both scalar and array) + $promoteurs = $post['jury_promoteur'] ?? null; + if ($promoteurs !== null && !is_array($promoteurs)) { + $promoteurs = [$promoteurs]; } - if (!empty(trim($post['jury_promoteur_ulb_name'] ?? ''))) { - $juryMembers[] = [ - 'name' => trim($post['jury_promoteur_ulb_name']), - 'role' => 'promoteur', - 'is_external' => 1, - 'is_ulb' => 1, - ]; + if (is_array($promoteurs)) { + foreach ($promoteurs as $name) { + $name = trim($name ?? ''); + if ($name !== '') { + $juryMembers[] = ['name' => $name, 'role' => 'promoteur', 'is_external' => 0, 'is_ulb' => 0]; + $hasPromoteur = true; + } + } + } + // Promoteurs ULB (accept both scalar and array) + $promoteursUlb = $post['jury_promoteur_ulb_name'] ?? null; + if ($promoteursUlb !== null && !is_array($promoteursUlb)) { + $promoteursUlb = [$promoteursUlb]; + } + if (is_array($promoteursUlb)) { + foreach ($promoteursUlb as $name) { + $name = trim($name ?? ''); + if ($name !== '') { + $juryMembers[] = ['name' => $name, 'role' => 'promoteur', 'is_external' => 1, 'is_ulb' => 1]; + $hasPromoteurUlb = true; + } + } } foreach ($post['jury_lecteur_interne'] ?? [] as $name) { $name = trim($name); diff --git a/app/src/Controllers/ThesisEditController.php b/app/src/Controllers/ThesisEditController.php index 6b8f449..0577661 100644 --- a/app/src/Controllers/ThesisEditController.php +++ b/app/src/Controllers/ThesisEditController.php @@ -606,24 +606,32 @@ class ThesisEditController { $members = []; - // Promoteur interne - if (!empty(trim($post['jury_promoteur'] ?? ''))) { - $members[] = [ - 'name' => trim($post['jury_promoteur']), - 'role' => 'promoteur', - 'is_external' => 0, - 'is_ulb' => 0, - ]; + // Promoteurs internes (accept both scalar and array) + $promoteurs = $post['jury_promoteur'] ?? null; + if ($promoteurs !== null && !is_array($promoteurs)) { + $promoteurs = [$promoteurs]; + } + if (is_array($promoteurs)) { + foreach ($promoteurs as $name) { + $name = trim($name ?? ''); + if ($name !== '') { + $members[] = ['name' => $name, 'role' => 'promoteur', 'is_external' => 0, 'is_ulb' => 0]; + } + } } - // Promoteur ULB - if (!empty(trim($post['jury_promoteur_ulb_name'] ?? ''))) { - $members[] = [ - 'name' => trim($post['jury_promoteur_ulb_name']), - 'role' => 'promoteur', - 'is_external' => 1, - 'is_ulb' => 1, - ]; + // Promoteurs ULB (accept both scalar and array) + $promoteursUlb = $post['jury_promoteur_ulb_name'] ?? null; + if ($promoteursUlb !== null && !is_array($promoteursUlb)) { + $promoteursUlb = [$promoteursUlb]; + } + if (is_array($promoteursUlb)) { + foreach ($promoteursUlb as $name) { + $name = trim($name ?? ''); + if ($name !== '') { + $members[] = ['name' => $name, 'role' => 'promoteur', 'is_external' => 1, 'is_ulb' => 1]; + } + } } // Lecteurs internes diff --git a/app/templates/admin/add.php b/app/templates/admin/add.php index 27ff117..63d611b 100644 --- a/app/templates/admin/add.php +++ b/app/templates/admin/add.php @@ -11,7 +11,9 @@ // Jury: fresh add (all empty) $juryPromoteur = null; + $juryPromoteurs = []; $juryPromoteurUlb = null; + $juryPromoteursUlb = []; $lecteursInternes = []; $lecteursExternes = []; $juryPresident = null; @@ -27,8 +29,7 @@ $defaultAccessTypeId = 2; // Optional sections - $showContact = true; - $showContextNote = true; + $showContact = false; // Admin: contact visibility controlled by filling 'mail' field in fieldset-tfe-info $showBackoffice = true; // Files: add mode diff --git a/app/templates/admin/edit.php b/app/templates/admin/edit.php index 4df2a58..f217640 100644 --- a/app/templates/admin/edit.php +++ b/app/templates/admin/edit.php @@ -39,7 +39,9 @@ // Jury data $juryPromoteur = null; + $juryPromoteurs = []; $juryPromoteurUlb = null; + $juryPromoteursUlb = []; $lecteursInternes = []; $lecteursExternes = []; $juryPresident = null; @@ -48,9 +50,9 @@ $juryPresident = $jm['name']; } elseif ($jm['role'] === 'promoteur') { if (($jm['is_ulb'] ?? 0) == 1) { - $juryPromoteurUlb = $jm['name']; + $juryPromoteursUlb[] = $jm; } else { - $juryPromoteur = $jm['name']; + $juryPromoteurs[] = $jm; } } elseif ($jm['role'] === 'lecteur') { if (($jm['is_external'] ?? 0) == 1) { @@ -60,6 +62,13 @@ } } } + // Backwards compat: if only one, also set the scalar for simple templates + if (!empty($juryPromoteurs) && $juryPromoteur === null) { + $juryPromoteur = $juryPromoteurs[0]['name']; + } + if (!empty($juryPromoteursUlb) && $juryPromoteurUlb === null) { + $juryPromoteurUlb = $juryPromoteursUlb[0]['name']; + } $showPresident = true; $showPromoteurUlb = true; $promoteurUlbConditional = false; @@ -76,8 +85,7 @@ $formData['cc2r'] = $currentRaw['cc4r'] ?? false; // Optional sections - $showContact = true; - $showContextNote = true; + $showContact = false; // Admin: contact visibility controlled by filling 'mail' field in fieldset-tfe-info $showBackoffice = true; $showPublish = true; diff --git a/app/templates/partials/form/fieldset-files.php b/app/templates/partials/form/fieldset-files.php index 8933859..10e54f7 100644 --- a/app/templates/partials/form/fieldset-files.php +++ b/app/templates/partials/form/fieldset-files.php @@ -39,7 +39,7 @@ $adminMode = $adminMode ?? false;
Types acceptés : PDF · JPG/PNG/GIF/WEBP · MP4/WebM/MOV (vidéo) · MP3/OGG/WAV/FLAC (audio) · ZIP/TAR (archives). Max 500 MB par fichier. diff --git a/app/templates/partials/form/fieldset-metadata.php b/app/templates/partials/form/fieldset-metadata.php index 17ac689..548b086 100644 --- a/app/templates/partials/form/fieldset-metadata.php +++ b/app/templates/partials/form/fieldset-metadata.php @@ -2,8 +2,9 @@ /** * Shared partial — "Métadonnées complémentaires" fieldset. * - * Now split: licence/access moved to licence-explanation fieldset. - * This fieldset keeps: duration (pages + minutes), lien (external link). + * Fields: duration (pages + minutes). + * Annexes checkbox + file input moved to Fichiers fieldset (fichiers-fragment.php). + * Lien BAIU moved to Backoffice fieldset. * * Variables consumed: * callable|null $oldFn — callable($key, $default='') for old/current values. @@ -29,20 +30,5 @@ $formData = $formData ?? []; $type = 'number'; $placeholder = ''; $hint = 'Ex : 32 (pour œuvres audio/vidéo)'; include APP_ROOT . '/templates/partials/form/text-field.php'; ?> - -
- -
- -
- -
- Format(s) - -
- - -
- Fichiers + + + +
@@ -397,64 +394,7 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
- - -
- -
- - - PDF (max 100 MB) · Images (JPG/PNG/GIF/WEBP) · ZIP/TAR (max 500 MB) · autres fichiers. - PDFs trop lourds ? bentopdf.com - -
    -

    Aucun nouveau fichier sélectionné.

    -
    -
    -
    - - - - getConnection() - ->prepare("SELECT id FROM format_types WHERE name = ? LIMIT 1"); - $_stmt->execute(["Site web"]); - $_siteWebId = $_stmt->fetchColumn(); - if ( - $_siteWebId && - in_array( - (string) $_siteWebId, - array_map("strval", $checkedFormatsForSiteWeb), - true, - ) - ) { - echo ''; - } - ?> + @@ -471,11 +411,13 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? []; "/templates/partials/form/fieldset-licence-explanation.php"; ?> - - + +
    - Note contextuelle -
    + Backoffice + + +