Files
xamxam/app/src/StudentEmail.php
Pontoporeia 406752bc6f 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
2026-05-19 00:08:06 +02:00

122 lines
5.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* StudentEmail — builds and sends confirmation e-mails to students
* after a successful TFE submission via a share-link form.
*
* The e-mail is addressed to the confirmation e-mail field provided
* by the student and contains a recap of every field submitted.
*/
class StudentEmail
{
/**
* Build the HTML body for the confirmation e-mail.
*
* @param array $thesis Thesis row (from getThesis / v_theses_full)
* @return string HTML body
*/
private static function buildHtml(array $thesis): string
{
$rows = '';
$fields = [
'Identifiant' => $thesis['identifier'] ?? '',
'Titre' => $thesis['title'] ?? '',
'Sous-titre' => $thesis['subtitle'] ?? '',
'Auteur·ice(s)' => $thesis['authors'] ?? '',
'Année' => $thesis['year'] ?? '',
'Orientation' => $thesis['orientation'] ?? '',
'Atelier pluridisciplinaire' => $thesis['ap_program'] ?? '',
'Finalité' => $thesis['finality_type'] ?? '',
'Synopsis' => $thesis['synopsis'] ?? '',
'Note contextuelle' => $thesis['context_note'] ?? '',
'Langue(s)' => $thesis['languages'] ?? '',
'Format(s)' => $thesis['formats'] ?? '',
'Mots-clés' => $thesis['keywords'] ?? '',
'Promoteur·ice(s) interne' => $thesis['jury_promoteurs'] ?? '',
'Promoteur·ice(s) ULB' => $thesis['jury_promoteurs_ulb'] ?? '',
'Président·e du jury' => $thesis['jury_president'] ?? '',
'Lecteurs·rices (interne)' => $thesis['jury_lecteurs_internes'] ?? '',
'Lecteurs·rices (externe)' => $thesis['jury_lecteurs_externes'] ?? '',
'Lien' => $thesis['baiu_link'] ?? '',
'Type d\'accès' => $thesis['access_type'] ?? '',
'Licence' => trim(($thesis['license_type'] ?? '') . (!empty($thesis['license_custom']) ? ' — ' . $thesis['license_custom'] : '')),
];
foreach ($fields as $label => $value) {
$v = $value === '' ? '' : htmlspecialchars((string)$value);
$rows .= "<tr><th style='text-align:left;padding:6px 10px;border-bottom:1px solid #eee'>"
. htmlspecialchars($label) . '</th>'
. "<td style='padding:6px 10px;border-bottom:1px solid #eee'>{$v}</td></tr>\n";
}
return <<<HTML
<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>
<p style="color:#555;font-size:0.95rem">
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>
<table style="width:100%;border-collapse:collapse;margin-top:1.5rem">
{$rows}
</table>
<p style="margin-top:2rem;font-size:0.85rem;color:#999">
xamxam · erg
</p>
</div>
HTML;
}
/**
* Send a confirmation e-mail for a given thesis.
*
* @param Database $db
* @param int $thesisId
* @param array $postData Raw $_POST (must contain 'confirmation_email')
* @return bool True when sent, false otherwise
*/
public static function sendConfirmation(
Database $db,
int $thesisId,
array $postData
): bool {
// ── 1. Read e-mail from confirmation field ─────────────────────────
$to = trim($postData['confirmation_email'] ?? '');
if ($to === '' || filter_var($to, FILTER_VALIDATE_EMAIL) === false) {
error_log('[StudentEmail] No valid confirmation e-mail — skipping thesis #' . $thesisId);
return false;
}
// ── 2. Check SMTP config ────────────────────────────────────────────
if (!SmtpRelay::isConfigured($db)) {
error_log('[StudentEmail] SMTP not configured — skipping thesis #' . $thesisId);
return false;
}
// ── 3. Fetch thesis data ────────────────────────────────────────────
$thesis = $db->getThesis($thesisId);
if (!$thesis) {
error_log('[StudentEmail] Thesis #' . $thesisId . ' not found after creation');
return false;
}
// ── 4. Send ─────────────────────────────────────────────────────────
$subject = 'Merci — ton TFE a bien été enregistré';
$htmlBody = self::buildHtml($thesis);
try {
$result = SmtpRelay::send($db, $to, $subject, $htmlBody);
} catch (SmtpSendException $e) {
error_log("[StudentEmail] SMTP error sending to {$to} for thesis #{$thesisId}: " . $e->getMessage());
throw $e; // re-throw so callers can react (e.g. redirect to retry page)
}
if ($result) {
error_log("[StudentEmail] Confirmation sent to {$to} for thesis #{$thesisId}");
} else {
error_log("[StudentEmail] Failed to send to {$to} for thesis #{$thesisId}");
}
return $result;
}
}