['/assets/dist/form.min.css'], 'extraCssAdmin' => [], '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/dist/form.min.js', ], ]; } // ── Helpers ─────────────────────────────────────────────────────────────── /** * Build an `old()` callable for admin forms (add/edit). * * Returns `htmlspecialchars`-escaped string values, or the raw array for * array-typed keys. Uses the $formData array from the caller's scope * (which may be $_SESSION['form_data'] with an edit-data overlay). */ public static function adminOld(array &$formData): callable { return function (string $key, string $default = '') use (&$formData): string|array { if (!isset($formData[$key])) { return $default; } if (is_array($formData[$key])) { return $formData[$key]; } return htmlspecialchars((string)$formData[$key]); }; } /** * Build an `old()` callable for share/partage forms. * * Returns raw values (no escaping) — callers must apply htmlspecialchars() * when rendering. Supports colon-delimited keys (e.g. "key:0"). */ public static function shareOld(array &$formData): callable { return function (string $key, string $default = '') use (&$formData) { $parts = explode(':', $key); $value = $formData; foreach ($parts as $part) { if (is_array($value) && array_key_exists($part, $value)) { $value = $value[$part]; } else { return $default; } } return $value; }; } // ── Common form variables ───────────────────────────────────────────────── /** * Return the standard variable set needed by form partials for an admin * add/edit page. Returns an array suitable for extract(). * * @param string $mode 'add' | 'edit' * @param string $formAction URL string * @param string $hiddenFields Raw HTML for hidden inputs * @param array $formData Merged form data for repopulation * @param array $siteSettings from getAllSettings() * @param array $helpBlocks from getAllFormHelpBlocks() * @param array $options Overrides for individual keys (juryPromoteur, etc.) */ public static function adminFormVariables( string $mode, string $formAction, string $hiddenFields, array &$formData, array $siteSettings, array $helpBlocks, array $options = [] ): array { $helpFn = function (string $key) use ($helpBlocks): string { return empty($helpBlocks[$key]['enabled']) ? '' : ($helpBlocks[$key]['content'] ?? ''); }; $autofocusField = App::consumeAutofocus(); // Controls $showContact = false; $showBackoffice = ($mode === 'add' || $mode === 'edit'); // Licence / access toggles: admin always enables all three $libreEnabled = true; $interneEnabled = true; $interditEnabled = true; $generalitiesHtml = $helpFn('fieldset_generalites'); $defaultAccessTypeId = $options['defaultAccessTypeId'] ?? 2; // ── Autosave draft wiring (add / edit only) ─────────────────────┐ $autosaveUrl = '/admin/actions/draft.php'; $formExtraAttrs = ''; $showAutosaveStatus = false; $extraHidden = ''; if ($mode === 'add') { // Reuse draft token from session so drafts survive page reloads if (empty($_SESSION['admin_draft_add_token'])) { $_SESSION['admin_draft_add_token'] = bin2hex(random_bytes(8)); } $draftToken = $_SESSION['admin_draft_add_token']; $draftKey = 'admin_draft_' . $draftToken; $extraHidden = ''; // Hydrate from any previous session (survives accidental navigations) $draft = $_SESSION[$draftKey] ?? []; $formData = array_merge($draft, $formData); $showAutosaveStatus = true; } elseif ($mode === 'edit') { $thesisId = (int)($options['thesisId'] ?? 0); if ($thesisId > 0) { $draftKey = 'admin_draft_edit_' . $thesisId; $extraHidden = ''; $draft = $_SESSION[$draftKey] ?? []; $formData = array_merge($draft, $formData); $showAutosaveStatus = true; } } // NOTE: Do NOT set hx-post on the