mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
The closure returned arrays when formData values were arrays (e.g. jury_promoteur), but the PHP return type annotation was :string. PHP 8.x enforces this strictly, causing a fatal TypeError in jury-fieldset.php on add mode.
221 lines
9.2 KiB
PHP
221 lines
9.2 KiB
PHP
<?php
|
|
|
|
/**
|
|
* FormBootstrap — shared bootstrap logic for TFE form pages.
|
|
*
|
|
* Provides factory methods and helper closures used by add, edit, and partage
|
|
* form scripts, eliminating copy-pasted preamble across the three entry points.
|
|
*
|
|
* Each public static method returns an associative array of variables to be
|
|
* extracted in the caller's scope.
|
|
*/
|
|
class FormBootstrap
|
|
{
|
|
// ── Asset arrays (identical for all admin form pages) ────────────────────
|
|
|
|
public static function adminAssetArrays(): array
|
|
{
|
|
return [
|
|
'extraCss' => ['/assets/css/form-base.css'],
|
|
'extraCssAdmin' => [
|
|
'/assets/css/form-admin.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',
|
|
'/assets/js/app/autosave-handler.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];
|
|
if ($formData[$key] === null) return $default;
|
|
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 = '<input type="hidden" name="draft_token" value="' . $draftToken . '">';
|
|
// 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 = '<input type="hidden" name="thesis_id" value="' . $thesisId . '">';
|
|
$draft = $_SESSION[$draftKey] ?? [];
|
|
$formData = array_merge($draft, $formData);
|
|
$showAutosaveStatus = true;
|
|
}
|
|
}
|
|
if ($showAutosaveStatus) {
|
|
$formExtraAttrs = 'hx-post="' . htmlspecialchars($autosaveUrl) . '"';
|
|
}
|
|
|
|
return array_merge([
|
|
// Base
|
|
'mode' => $mode,
|
|
'formAction' => $formAction,
|
|
'hiddenFields' => $hiddenFields . $extraHidden,
|
|
'errorFieldName' => $autofocusField,
|
|
'synopsisExtra' => $options['synopsisExtra'] ?? '',
|
|
'formExtraAttrs' => $formExtraAttrs,
|
|
'showAutosaveStatus' => $showAutosaveStatus,
|
|
'autosaveUrl' => $autosaveUrl,
|
|
|
|
// Helpers
|
|
'helpFn' => $helpFn,
|
|
'helpBlocks' => $helpBlocks,
|
|
'oldFn' => self::adminOld($formData),
|
|
'withAutofocusFn' => function (string $field, array $attrs = []) use ($autofocusField): array {
|
|
if ($autofocusField === $field) $attrs['autofocus'] = true;
|
|
return $attrs;
|
|
},
|
|
|
|
// Jury
|
|
'juryPromoteur' => null,
|
|
'juryPromoteurs' => [],
|
|
'juryPromoteurUlb' => null,
|
|
'juryPromoteursUlb' => [],
|
|
'lecteursInternes' => [],
|
|
'lecteursExternes' => [],
|
|
'showPromoteurUlb' => true,
|
|
'promoteurUlbConditional' => false,
|
|
|
|
// Licence / access
|
|
'libreEnabled' => $libreEnabled,
|
|
'interneEnabled' => $interneEnabled,
|
|
'interditEnabled' => $interditEnabled,
|
|
'generalitiesHtml' => $generalitiesHtml,
|
|
'defaultAccessTypeId' => $defaultAccessTypeId,
|
|
|
|
// Optional sections
|
|
'showContact' => $showContact,
|
|
'showBackoffice' => $showBackoffice,
|
|
'showCoverPreview' => false,
|
|
'showExistingFiles' => false,
|
|
'showEmailConfirmation' => false,
|
|
'showFlash' => false,
|
|
'showIntroHelp' => false,
|
|
|
|
// Files
|
|
'filesMode' => $options['filesMode'] ?? 'add',
|
|
|
|
// Website
|
|
'existingWebsiteUrl' => $options['existingWebsiteUrl'] ?? '',
|
|
'existingWebsiteLabel' => $options['existingWebsiteLabel'] ?? '',
|
|
'checkedFormatsForSiteWeb' => $options['checkedFormats'] ?? [],
|
|
|
|
// Backoffice (empty for add, populated for edit by caller)
|
|
'currentRaw' => [],
|
|
'contactInterne' => null,
|
|
'contactPublic' => false,
|
|
'currentContextNote' => null,
|
|
'currentContactVisible' => null,
|
|
'currentDurationValue' => null,
|
|
'currentDurationUnit' => 'pages',
|
|
|
|
// Files (edit mode)
|
|
'currentCover' => null,
|
|
'currentFiles' => [],
|
|
], $options);
|
|
}
|
|
}
|