mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
Improve recap page + fix CSV import for jury roles
recapitulatif.php (partage): - Center .thanks-success and add bottom margin/padding - Display ALL fields: identifier, synopsis, languages, formats, jury (all roles), baiu link, license, access type - Add validation notice asking user to verify info, with xamxam@erg.be contact link (email obfuscated) StudentEmail: - Add 'Note contextuelle' and license_custom to email recap - Rename 'Promoteur·ice(s)' to 'Promoteur·ice(s) interne' - Change email message to ask student to verify info + contact for errors CSV export/import: - Add 3 new CSV columns: Lecteur·ice(s) interne, Lecteur·ice(s) externe, Promoteur·ice(s) ULB - Export splits supervisors by role/is_external/is_ulb into separate columns - Import inserts supervisors with correct role, is_external, and is_ulb flags (was: all treated as generic supervisors) - Add header matching for short distinguishers (ulb, externe) via str_contains fallback
This commit is contained in:
5
TODO.md
5
TODO.md
@@ -1,5 +1,10 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
- [x] Improve recapitulatif.php (partage): bottom margin/padding, center .thanks-success
|
||||||
|
- [x] Display ALL submitted info in recapitulatif page + email recap
|
||||||
|
- [x] Add "validate your info / contact xamxam@erg.be" note on recap page
|
||||||
|
- [x] Fix CSV import: lecteur interne/externe + promoteurice ULB not imported with correct role/is_external/is_ulb flags
|
||||||
|
|
||||||
- [x] Replace HTMX+PHP file upload queues with client-side JS
|
- [x] Replace HTMX+PHP file upload queues with client-side JS
|
||||||
- [x] Fix submit button on all forms — add JS/PHP debug logging
|
- [x] Fix submit button on all forms — add JS/PHP debug logging
|
||||||
- [x] Fix file-upload-queue.js: redirect detection broken due to opaque redirect (switched from fetch to XHR for reliable responseURL)
|
- [x] Fix file-upload-queue.js: redirect detection broken due to opaque redirect (switched from fetch to XHR for reliable responseURL)
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
$headerRowNum = 0;
|
$headerRowNum = 0;
|
||||||
$knownHeaders = [
|
$knownHeaders = [
|
||||||
'identifiant', 'titre', 'sous-titre', 'auteur', 'contact',
|
'identifiant', 'titre', 'sous-titre', 'auteur', 'contact',
|
||||||
'promoteur', 'format', 'année', 'ap', 'orientation', 'finalité',
|
'promoteur', 'lecteur', 'ulb', 'externe', 'format', 'année', 'ap', 'orientation', 'finalité',
|
||||||
'mots-clés', 'synopsis', 'contexte', 'remarques', 'langue',
|
'mots-clés', 'synopsis', 'contexte', 'remarques', 'langue',
|
||||||
'autorisation', 'licence', 'license', 'points', 'lien baiu',
|
'autorisation', 'licence', 'license', 'points', 'lien baiu',
|
||||||
];
|
];
|
||||||
@@ -68,10 +68,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
// Avoid short prefixes matching unrelated words
|
// Avoid short prefixes matching unrelated words
|
||||||
if ($hlen >= 5 || $cell === $h) { $hits++; $map[$h] = $pos; $used[$pos] = true; break; }
|
if ($hlen >= 5 || $cell === $h) { $hits++; $map[$h] = $pos; $used[$pos] = true; break; }
|
||||||
}
|
}
|
||||||
|
// Substring match for short distinguishers (ulb, externe)
|
||||||
|
if ($hlen >= 3 && $hlen <= 7 && str_contains($cell, $h)) {
|
||||||
|
$hits++; $map[$h] = $pos; $used[$pos] = true; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Require at least 8 known headers to trust the row.
|
// Require at least 11 known headers to trust the row.
|
||||||
if ($hits >= 8) { $colIdx = $map; break; }
|
if ($hits >= 11) { $colIdx = $map; break; }
|
||||||
}
|
}
|
||||||
// If no header row found, rewind and fall back to positional (skip 4 rows).
|
// If no header row found, rewind and fall back to positional (skip 4 rows).
|
||||||
if ($colIdx === null) {
|
if ($colIdx === null) {
|
||||||
@@ -238,27 +242,30 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
if ($contact !== '' && in_array(strtoupper(trim($contact)), ['NON', 'OUI'], true)) {
|
if ($contact !== '' && in_array(strtoupper(trim($contact)), ['NON', 'OUI'], true)) {
|
||||||
$contact = '';
|
$contact = '';
|
||||||
}
|
}
|
||||||
$supervisorsRaw = $cell($row, 'promoteur', 5);
|
$supervisorsRaw = $cell($row, 'promoteur', 5);
|
||||||
$formatsRaw = $cell($row, 'format', 6);
|
$lecteursInternesRaw = $cell($row, 'lecteur', 6); // first "lecteur" col = interne
|
||||||
$yearRaw = $cell($row, 'année', 7);
|
$lecteursExternesRaw = $cell($row, 'externe', 7); // contains "externe"
|
||||||
|
$promoteursUlbRaw = $cell($row, 'ulb', 8); // contains "ulb"
|
||||||
|
$formatsRaw = $cell($row, 'format', 9);
|
||||||
|
$yearRaw = $cell($row, 'année', 10);
|
||||||
$year = $yearRaw !== '' ? intval($yearRaw) : 0;
|
$year = $yearRaw !== '' ? intval($yearRaw) : 0;
|
||||||
// Fallback: derive year from identifier (e.g. "2024-003" → 2024)
|
// Fallback: derive year from identifier (e.g. "2024-003" → 2024)
|
||||||
if ($year === 0 && $identifier !== '' && preg_match('/^(\d{4})-/', $identifier, $m)) {
|
if ($year === 0 && $identifier !== '' && preg_match('/^(\d{4})-/', $identifier, $m)) {
|
||||||
$year = (int)$m[1];
|
$year = (int)$m[1];
|
||||||
}
|
}
|
||||||
$apCode = $cell($row, 'ap', 8);
|
$apCode = $cell($row, 'ap', 11);
|
||||||
$orientationCode = $cell($row, 'orientation', 9);
|
$orientationCode = $cell($row, 'orientation', 12);
|
||||||
$finalityName = $cell($row, 'finalité', 10);
|
$finalityName = $cell($row, 'finalité', 13);
|
||||||
$keywordsRaw = $cell($row, 'mots-clés', 11);
|
$keywordsRaw = $cell($row, 'mots-clés', 14);
|
||||||
$synopsis = $cell($row, 'synopsis', 12);
|
$synopsis = $cell($row, 'synopsis', 15);
|
||||||
$context = $cell($row, 'contexte', 13);
|
$context = $cell($row, 'contexte', 16);
|
||||||
$remarks = $cell($row, 'remarques', 14);
|
$remarks = $cell($row, 'remarques', 17);
|
||||||
$languageRaw = $cell($row, 'langue', 15);
|
$languageRaw = $cell($row, 'langue', 18);
|
||||||
$access = $cell($row, 'autorisation', 16);
|
$access = $cell($row, 'autorisation', 19);
|
||||||
$license = $cell($row, 'license', 17);
|
$license = $cell($row, 'license', 20);
|
||||||
$juryPointsRaw = $cell($row, 'points', 18);
|
$juryPointsRaw = $cell($row, 'points', 21);
|
||||||
$juryPoints = $juryPointsRaw !== '' ? floatval($juryPointsRaw) : null;
|
$juryPoints = $juryPointsRaw !== '' ? floatval($juryPointsRaw) : null;
|
||||||
$baiuLink = $cell($row, 'lien baiu', 19);
|
$baiuLink = $cell($row, 'lien baiu', 22);
|
||||||
|
|
||||||
if ($title === '' || $year === 0) {
|
if ($title === '' || $year === 0) {
|
||||||
$missing = [];
|
$missing = [];
|
||||||
@@ -328,12 +335,49 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Insert supervisors with proper role/is_external/is_ulb flags
|
||||||
|
$juryOrder = 0;
|
||||||
|
// Promoteurs internes
|
||||||
if (!empty($supervisorsRaw)) {
|
if (!empty($supervisorsRaw)) {
|
||||||
foreach (array_map('trim', explode(',', $supervisorsRaw)) as $idx => $name) {
|
foreach (array_map('trim', explode(',', $supervisorsRaw)) as $name) {
|
||||||
if ($name) {
|
if ($name) {
|
||||||
|
$juryOrder++;
|
||||||
$sId = $importDb->findOrCreateSupervisor($name);
|
$sId = $importDb->findOrCreateSupervisor($name);
|
||||||
$s = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, supervisor_order) VALUES (?,?,?)");
|
$stmt = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, role, is_external, is_ulb, supervisor_order) VALUES (?,?,?,?,?,?)");
|
||||||
$s->execute([$thesisId, $sId, $idx + 1]);
|
$stmt->execute([$thesisId, $sId, 'promoteur', 0, 0, $juryOrder]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Lecteurs internes
|
||||||
|
if (!empty($lecteursInternesRaw)) {
|
||||||
|
foreach (array_map('trim', explode(',', $lecteursInternesRaw)) as $name) {
|
||||||
|
if ($name) {
|
||||||
|
$juryOrder++;
|
||||||
|
$sId = $importDb->findOrCreateSupervisor($name);
|
||||||
|
$stmt = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, role, is_external, is_ulb, supervisor_order) VALUES (?,?,?,?,?,?)");
|
||||||
|
$stmt->execute([$thesisId, $sId, 'lecteur', 0, 0, $juryOrder]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Lecteurs externes
|
||||||
|
if (!empty($lecteursExternesRaw)) {
|
||||||
|
foreach (array_map('trim', explode(',', $lecteursExternesRaw)) as $name) {
|
||||||
|
if ($name) {
|
||||||
|
$juryOrder++;
|
||||||
|
$sId = $importDb->findOrCreateSupervisor($name);
|
||||||
|
$stmt = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, role, is_external, is_ulb, supervisor_order) VALUES (?,?,?,?,?,?)");
|
||||||
|
$stmt->execute([$thesisId, $sId, 'lecteur', 1, 0, $juryOrder]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Promoteurs ULB
|
||||||
|
if (!empty($promoteursUlbRaw)) {
|
||||||
|
foreach (array_map('trim', explode(',', $promoteursUlbRaw)) as $name) {
|
||||||
|
if ($name) {
|
||||||
|
$juryOrder++;
|
||||||
|
$sId = $importDb->findOrCreateSupervisor($name);
|
||||||
|
$stmt = $importPdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, role, is_external, is_ulb, supervisor_order) VALUES (?,?,?,?,?,?)");
|
||||||
|
$stmt->execute([$thesisId, $sId, 'promoteur', 1, 1, $juryOrder]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -797,12 +797,41 @@ a.recap-file-name:hover {
|
|||||||
.partage-recap {
|
.partage-recap {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
gap: var(--space-l);
|
gap: var(--space-l);
|
||||||
|
padding-bottom: var(--space-3xl);
|
||||||
|
margin-bottom: var(--space-2xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.partage-recap .thanks-success {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recap-validate-notice {
|
||||||
|
text-align: center;
|
||||||
|
font-size: var(--step--1);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--accent-primary) 20%, transparent);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: var(--space-s) var(--space-m);
|
||||||
|
max-width: 560px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recap-validate-notice p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recap-validate-notice a {
|
||||||
|
color: var(--accent-primary);
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recap-section {
|
.recap-section {
|
||||||
border-top: 1px solid var(--border-primary);
|
border-top: 1px solid var(--border-primary);
|
||||||
padding-top: var(--space-m);
|
padding-top: var(--space-m);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 620px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recap-section h2 {
|
.recap-section h2 {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ if (!defined('APP_ROOT')) {
|
|||||||
App::boot();
|
App::boot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once APP_ROOT . '/src/EmailObfuscator.php';
|
||||||
|
|
||||||
$thesisId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
$thesisId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
|
||||||
if ($thesisId <= 0) {
|
if ($thesisId <= 0) {
|
||||||
@@ -69,9 +71,18 @@ $pageTitle = 'Merci — TFE enregistré';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="recap-validate-notice">
|
||||||
|
<p>Veuillez vérifier les informations ci-dessous. Si vous constatez une erreur, contactez-nous à <a href="<?= EmailObfuscator::mailto('xamxam@erg.be') ?>"><?= EmailObfuscator::email('xamxam@erg.be') ?></a>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section class="recap-section">
|
<section class="recap-section">
|
||||||
<h2>Récapitulatif de votre soumission</h2>
|
<h2>Récapitulatif de votre soumission</h2>
|
||||||
<dl class="recap-dl">
|
<dl class="recap-dl">
|
||||||
|
<?php if (!empty($thesis['identifier'])): ?>
|
||||||
|
<dt>Identifiant</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['identifier']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<dt>Titre</dt>
|
<dt>Titre</dt>
|
||||||
<dd><?= htmlspecialchars($thesis['title']) ?></dd>
|
<dd><?= htmlspecialchars($thesis['title']) ?></dd>
|
||||||
|
|
||||||
@@ -105,10 +116,60 @@ $pageTitle = 'Merci — TFE enregistré';
|
|||||||
<dd><?= htmlspecialchars($thesis['finality_type']) ?></dd>
|
<dd><?= htmlspecialchars($thesis['finality_type']) ?></dd>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['synopsis'])): ?>
|
||||||
|
<dt>Synopsis</dt>
|
||||||
|
<dd><?= nl2br(htmlspecialchars($thesis['synopsis'])) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['languages'])): ?>
|
||||||
|
<dt>Langue(s)</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['languages']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['formats'])): ?>
|
||||||
|
<dt>Format(s)</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['formats']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (!empty($thesis['keywords'])): ?>
|
<?php if (!empty($thesis['keywords'])): ?>
|
||||||
<dt>Mots-clés</dt>
|
<dt>Mots-clés</dt>
|
||||||
<dd><?= htmlspecialchars($thesis['keywords']) ?></dd>
|
<dd><?= htmlspecialchars($thesis['keywords']) ?></dd>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['jury_promoteurs'])): ?>
|
||||||
|
<dt>Promoteur·ice(s) interne</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['jury_promoteurs']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['jury_promoteurs_ulb'])): ?>
|
||||||
|
<dt>Promoteur·ice(s) ULB</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['jury_promoteurs_ulb']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['jury_lecteurs_internes'])): ?>
|
||||||
|
<dt>Lecteur·ice(s) interne</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['jury_lecteurs_internes']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['jury_lecteurs_externes'])): ?>
|
||||||
|
<dt>Lecteur·ice(s) externe</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['jury_lecteurs_externes']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['baiu_link'])): ?>
|
||||||
|
<dt>Lien</dt>
|
||||||
|
<dd><a href="<?= htmlspecialchars($thesis['baiu_link']) ?>" target="_blank" rel="noopener"><?= htmlspecialchars($thesis['baiu_link']) ?></a></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['license_type'])): ?>
|
||||||
|
<dt>Licence</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['license_type']) ?><?= !empty($thesis['license_custom']) ? ' — ' . htmlspecialchars($thesis['license_custom']) : '' ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($thesis['access_type'])): ?>
|
||||||
|
<dt>Type d'accès</dt>
|
||||||
|
<dd><?= htmlspecialchars($thesis['access_type']) ?></dd>
|
||||||
|
<?php endif; ?>
|
||||||
</dl>
|
</dl>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,10 @@ class ExportController
|
|||||||
'Sous-titre',
|
'Sous-titre',
|
||||||
'Auteur·ice(s)',
|
'Auteur·ice(s)',
|
||||||
'Contact',
|
'Contact',
|
||||||
'Promoteur·ice(s)',
|
'Promoteur·ice(s) interne',
|
||||||
|
'Lecteur·ice(s) interne',
|
||||||
|
'Lecteur·ice(s) externe',
|
||||||
|
'Promoteur·ice(s) ULB',
|
||||||
'Format(s)',
|
'Format(s)',
|
||||||
'Année',
|
'Année',
|
||||||
'AP',
|
'AP',
|
||||||
@@ -252,10 +255,28 @@ class ExportController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supervisors
|
// Supervisors — split by role
|
||||||
$supList = [];
|
$promoteursInternes = [];
|
||||||
|
$lecteursInternes = [];
|
||||||
|
$lecteursExternes = [];
|
||||||
|
$promoteursUlb = [];
|
||||||
foreach (($supervisors[$tid] ?? []) as $s) {
|
foreach (($supervisors[$tid] ?? []) as $s) {
|
||||||
$supList[] = $s['name'];
|
$role = $s['role'] ?? '';
|
||||||
|
$isExternal = (int)($s['is_external'] ?? 0);
|
||||||
|
$isUlb = (int)($s['is_ulb'] ?? 0);
|
||||||
|
$name = $s['name'];
|
||||||
|
if ($role === 'promoteur' && $isUlb) {
|
||||||
|
$promoteursUlb[] = $name;
|
||||||
|
} elseif ($role === 'promoteur') {
|
||||||
|
$promoteursInternes[] = $name;
|
||||||
|
} elseif ($role === 'lecteur' && $isExternal) {
|
||||||
|
$lecteursExternes[] = $name;
|
||||||
|
} elseif ($role === 'lecteur') {
|
||||||
|
$lecteursInternes[] = $name;
|
||||||
|
} else {
|
||||||
|
// Legacy rows with no role: treat as promoteur interne
|
||||||
|
$promoteursInternes[] = $name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
@@ -282,7 +303,10 @@ class ExportController
|
|||||||
$t['subtitle'] ?? '',
|
$t['subtitle'] ?? '',
|
||||||
implode(', ', $authorList),
|
implode(', ', $authorList),
|
||||||
$contact,
|
$contact,
|
||||||
implode(', ', $supList),
|
implode(', ', $promoteursInternes),
|
||||||
|
implode(', ', $lecteursInternes),
|
||||||
|
implode(', ', $lecteursExternes),
|
||||||
|
implode(', ', $promoteursUlb),
|
||||||
implode(', ', $fmtList),
|
implode(', ', $fmtList),
|
||||||
$t['year'] ?? '',
|
$t['year'] ?? '',
|
||||||
$t['ap_program'] ?? '',
|
$t['ap_program'] ?? '',
|
||||||
|
|||||||
@@ -2340,7 +2340,7 @@ class Database
|
|||||||
public function getAllThesisSupervisorsForExport(): array
|
public function getAllThesisSupervisorsForExport(): array
|
||||||
{
|
{
|
||||||
return $this->pdo->query('
|
return $this->pdo->query('
|
||||||
SELECT ts.thesis_id, s.name
|
SELECT ts.thesis_id, s.name, ts.role, ts.is_external, ts.is_ulb
|
||||||
FROM thesis_supervisors ts
|
FROM thesis_supervisors ts
|
||||||
JOIN supervisors s ON s.id = ts.supervisor_id
|
JOIN supervisors s ON s.id = ts.supervisor_id
|
||||||
ORDER BY ts.thesis_id, ts.supervisor_order
|
ORDER BY ts.thesis_id, ts.supervisor_order
|
||||||
|
|||||||
@@ -28,17 +28,18 @@ class StudentEmail
|
|||||||
'Atelier pluridisciplinaire' => $thesis['ap_program'] ?? '',
|
'Atelier pluridisciplinaire' => $thesis['ap_program'] ?? '',
|
||||||
'Finalité' => $thesis['finality_type'] ?? '',
|
'Finalité' => $thesis['finality_type'] ?? '',
|
||||||
'Synopsis' => $thesis['synopsis'] ?? '',
|
'Synopsis' => $thesis['synopsis'] ?? '',
|
||||||
|
'Note contextuelle' => $thesis['context_note'] ?? '',
|
||||||
'Langue(s)' => $thesis['languages'] ?? '',
|
'Langue(s)' => $thesis['languages'] ?? '',
|
||||||
'Format(s)' => $thesis['formats'] ?? '',
|
'Format(s)' => $thesis['formats'] ?? '',
|
||||||
'Mots-clés' => $thesis['keywords'] ?? '',
|
'Mots-clés' => $thesis['keywords'] ?? '',
|
||||||
'Promoteur·ice(s)' => $thesis['jury_promoteurs'] ?? '',
|
'Promoteur·ice(s) interne' => $thesis['jury_promoteurs'] ?? '',
|
||||||
'Promoteur·ice(s) ULB' => $thesis['jury_promoteurs_ulb'] ?? '',
|
'Promoteur·ice(s) ULB' => $thesis['jury_promoteurs_ulb'] ?? '',
|
||||||
'Président·e du jury' => $thesis['jury_president'] ?? '',
|
'Président·e du jury' => $thesis['jury_president'] ?? '',
|
||||||
'Lecteurs·rices (interne)' => $thesis['jury_lecteurs_internes'] ?? '',
|
'Lecteurs·rices (interne)' => $thesis['jury_lecteurs_internes'] ?? '',
|
||||||
'Lecteurs·rices (externe)' => $thesis['jury_lecteurs_externes'] ?? '',
|
'Lecteurs·rices (externe)' => $thesis['jury_lecteurs_externes'] ?? '',
|
||||||
'Lien' => $thesis['baiu_link'] ?? '',
|
'Lien' => $thesis['baiu_link'] ?? '',
|
||||||
'Type d\'accès' => $thesis['access_type'] ?? '',
|
'Type d\'accès' => $thesis['access_type'] ?? '',
|
||||||
'Licence' => $thesis['license_type'] ?? '',
|
'Licence' => trim(($thesis['license_type'] ?? '') . (!empty($thesis['license_custom']) ? ' — ' . $thesis['license_custom'] : '')),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($fields as $label => $value) {
|
foreach ($fields as $label => $value) {
|
||||||
@@ -52,7 +53,8 @@ class StudentEmail
|
|||||||
<div style="font-family:system-ui,sans-serif;max-width:600px;margin:0 auto;color:#333">
|
<div style="font-family:system-ui,sans-serif;max-width:600px;margin:0 auto;color:#333">
|
||||||
<h1 style="font-size:1.4rem;color:#222">Merci, ton TFE a bien été enregistré.</h1>
|
<h1 style="font-size:1.4rem;color:#222">Merci, ton TFE a bien été enregistré.</h1>
|
||||||
<p style="color:#555;font-size:0.95rem">
|
<p style="color:#555;font-size:0.95rem">
|
||||||
Voici un récapitulatif de ta soumission. Tu n'as pas besoin de répondre à cet e-mail.
|
Voici un récapitulatif de ta soumission. Vérifie bien toutes les informations ci-dessous.
|
||||||
|
Si tu constates une erreur, écris à <a href="mailto:xamxam@erg.be">xamxam@erg.be</a>.
|
||||||
</p>
|
</p>
|
||||||
<table style="width:100%;border-collapse:collapse;margin-top:1.5rem">
|
<table style="width:100%;border-collapse:collapse;margin-top:1.5rem">
|
||||||
{$rows}
|
{$rows}
|
||||||
|
|||||||
@@ -480,6 +480,19 @@
|
|||||||
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
+\\\\\\\ to: vqxpnkox f51d447c "fix migration 028, promoteurice repopulation, DB bootstrap" (rebased revision)
|
+\\\\\\\ to: vqxpnkox f51d447c "fix migration 028, promoteurice repopulation, DB bootstrap" (rebased revision)
|
||||||
++ $linkName = $link['name'] ?? '';
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: vqxpnkox f51d447c "fix migration 028, promoteurice repopulation, DB bootstrap" (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: zxryvzkv 9d3f6b53 "Improve recap page + fix CSV import for jury roles" (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: zxryvzkv 27814cea "Improve recap page + fix CSV import for jury roles" (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
?>
|
?>
|
||||||
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
||||||
|
|||||||
Reference in New Issue
Block a user