mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
Mirrors the mots-clé tag-search system: dropdown suggestions from existing languages via HTMX, pill display with bin-icon remove buttons, 'Créer' option for new languages. Replaces the plain text input. - New partial: templates/partials/form/language-search.php - New fragment: public/partage/language-search-fragment.php - Admin wrapper: public/admin/language-search-fragment.php - Updated language-autre-fragment to return just the required asterisk indicator - Updated both controllers to handle language_autre as array (pill-based) with backward-compatible string path - Updated edit form to compute selectedOtherLanguages from DB - Registered new route in partage/index.php - Fix CSV importer: split comma-separated language column into individual entries - Add htmx active search to admin index, title line-clamp, predefined languages only in checkboxes - Admin index: filter form now uses htmx triggers (input delay:300ms on search, change on selects) to actively search without page reload - Sort links include hx-push-url for back-button support - Added loading indicator bar (.admin-search-indicator) - Title column: line-clamp at 2 lines with overflow hidden, native title attr tooltip for full text - Language checkboxes now show only 3 predefined languages (Français, Anglais, Néerlandais); all others go via the Autre langue search component - Added Database::getPredefinedLanguages() and excluded predefined from language-search-fragment suggestions - Included hidden sort/dir inputs in table-wrap so sort state preserved across filter changes - Fix language-search: block 'Créer' for predefined languages in dropdown The 'Créer' option in the language-search dropdown now also checks against the predefined set (français, anglais, néerlandais) to avoid offering creation of languages that already exist as checkboxes.
146 lines
6.2 KiB
PHP
146 lines
6.2 KiB
PHP
<main id="main-content">
|
|
<h1><a href="/admin/" class="admin-back-btn" title="Retour à la liste"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48-88a8,8,0,0,1-8,8H107.31l18.35,18.34a8,8,0,0,1-11.32,11.32l-32-32a8,8,0,0,1,0-11.32l32-32a8,8,0,0,1,11.32,11.32L107.31,120H168A8,8,0,0,1,176,128Z"></path></svg></a> Modifier un TFE</h1>
|
|
|
|
<?php
|
|
// ── Build a unified old() callable for the entire edit form ────────────────
|
|
$editFormData = array_merge($formData ?? [], [
|
|
'titre' => $thesis['title'],
|
|
'subtitle' => $thesis['subtitle'] ?? '',
|
|
'auteurice' => $thesis['authors'] ?? '',
|
|
'mail' => $contactInterne ?? '',
|
|
'synopsis' => $thesis['synopsis'] ?? '',
|
|
'tag' => $thesis['keywords'] ?? '',
|
|
'année' => $thesis['year'],
|
|
'orientation' => $thesis['orientation'],
|
|
'ap' => $thesis['ap_program'],
|
|
'finality' => $thesis['finality_type'],
|
|
'lien' => $thesis['baiu_link'] ?? '',
|
|
'contact_public' => $contactPublic ?? false,
|
|
'contact_interne' => $contactInterne ?? '',
|
|
]);
|
|
$oldFn = fn(string $key, string $default = '') =>
|
|
isset($editFormData[$key]) && !is_array($editFormData[$key])
|
|
? htmlspecialchars((string)$editFormData[$key]) : $default;
|
|
|
|
$withAutofocusFn = function (string $field, array $attrs = []) use ($autofocusField) {
|
|
if ($autofocusField === $field) $attrs['autofocus'] = true;
|
|
return $attrs;
|
|
};
|
|
|
|
// ── Shared form variables ──────────────────────────────────────────────────
|
|
$mode = 'edit';
|
|
$formAction = '/admin/actions/edit.php';
|
|
$hiddenFields = '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($_SESSION['csrf_token']) . '">'
|
|
. '<input type="hidden" name="thesis_id" value="' . $thesisId . '">';
|
|
|
|
$synopsisExtra = '';
|
|
$formData = $editFormData;
|
|
|
|
// Jury data
|
|
$juryPromoteur = null;
|
|
$juryPromoteurs = [];
|
|
$juryPromoteurUlb = null;
|
|
$juryPromoteursUlb = [];
|
|
$lecteursInternes = [];
|
|
$lecteursExternes = [];
|
|
foreach ($jury as $jm) {
|
|
if ($jm['role'] === 'president') {
|
|
continue;
|
|
}
|
|
if ($jm['role'] === 'promoteur') {
|
|
if (($jm['is_ulb'] ?? 0) == 1) {
|
|
$juryPromoteursUlb[] = $jm;
|
|
} else {
|
|
$juryPromoteurs[] = $jm;
|
|
}
|
|
} elseif ($jm['role'] === 'lecteur') {
|
|
if (($jm['is_external'] ?? 0) == 1) {
|
|
$lecteursExternes[] = $jm;
|
|
} else {
|
|
$lecteursInternes[] = $jm;
|
|
}
|
|
}
|
|
}
|
|
// 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'];
|
|
}
|
|
$showPromoteurUlb = true;
|
|
$promoteurUlbConditional = false;
|
|
|
|
// Licence / access — always all enabled for admin
|
|
$libreEnabled = true;
|
|
$interneEnabled = true;
|
|
$interditEnabled = true;
|
|
$generalitiesHtml = $helpFn('fieldset_generalites');
|
|
$defaultAccessTypeId = $currentAccessTypeId ?? 2;
|
|
$formData['access_type_id'] = $currentAccessTypeId;
|
|
$formData['license_id'] = $currentLicenseId;
|
|
$formData['license_custom'] = $currentRaw['license_custom'] ?? '';
|
|
$formData['cc2r'] = $currentRaw['cc2r'] ?? false;
|
|
|
|
// Optional sections
|
|
$showContact = false; // Admin: contact visibility controlled by filling 'mail' field in fieldset-tfe-info
|
|
$showBackoffice = true;
|
|
|
|
// Files: edit mode
|
|
$filesMode = 'edit';
|
|
$currentCover = $currentCover ?? null;
|
|
$currentFiles = $currentFiles ?? [];
|
|
$currentContextNote = $currentContextNote ?? null;
|
|
|
|
// Website URL from existing files
|
|
$existingWebsiteUrl = '';
|
|
$existingWebsiteLabel = '';
|
|
foreach ($currentFiles as $f) {
|
|
if ($f['file_type'] === 'website') {
|
|
$existingWebsiteUrl = $f['file_path'] ?? '';
|
|
$existingWebsiteLabel = $f['display_label'] ?? '';
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Languages — either from flash repopulation or current thesis data
|
|
$formData['languages'] = $formData['languages'] ?? $currentLanguages ?? [];
|
|
|
|
// Compute "other" languages (those not in the predefined checkbox list)
|
|
$predefinedLangIds = array_column($languages, 'id');
|
|
$otherLangIds = array_diff($currentLanguages ?? [], $predefinedLangIds);
|
|
$selectedOtherLanguages = [];
|
|
if (!empty($otherLangIds)) {
|
|
$allLangs = Database::getInstance()->getAllLanguages();
|
|
$allLangMap = [];
|
|
foreach ($allLangs as $al) {
|
|
$allLangMap[(int)$al['id']] = $al['name'];
|
|
}
|
|
foreach ($otherLangIds as $lid) {
|
|
$lid = (int)$lid;
|
|
if (isset($allLangMap[$lid])) {
|
|
$selectedOtherLanguages[] = $allLangMap[$lid];
|
|
}
|
|
}
|
|
// Sort alphabetically
|
|
sort($selectedOtherLanguages, SORT_NATURAL | SORT_FLAG_CASE);
|
|
}
|
|
|
|
// Tags — either from flash repopulation or current thesis data
|
|
$keywordsStr = $thesis['keywords'] ?? '';
|
|
$currentTags = $keywordsStr !== '' ? array_map('trim', explode(',', $keywordsStr)) : [];
|
|
// If formData has tag[], use that instead
|
|
if (!empty($formData['tag']) && is_array($formData['tag'])) {
|
|
$currentTags = $formData['tag'];
|
|
}
|
|
|
|
// Formats — either from flash repopulation or current thesis data
|
|
$checkedFormats = $formData['formats'] ?? $currentFormats ?? [];
|
|
// Populate formData.formats for checkbox-list partial
|
|
$formData['formats'] = $checkedFormats;
|
|
$checkedFormatsForSiteWeb = $checkedFormats;
|
|
|
|
include APP_ROOT . '/templates/partials/form/form.php';
|
|
?>
|
|
</main>
|