format('d/m/Y');
}
// ─── Email template loader ────────────────────────────────────────────────────
// {{placeholder}} HTML bodies under templates/emails/. Built locally, delivered
// by id.andmore.pt via the enqueue_email()/flush_message() façade.
function load_email_template(string $template, array $vars): string {
$path = __DIR__ . '/../templates/emails/' . $template . '.html';
if (!is_file($path)) {
throw new RuntimeException("Email template not found: {$template}");
}
$html = file_get_contents($path);
$brand = htmlspecialchars(APP_NAME, ENT_QUOTES, 'UTF-8');
$logo = (string) setting('logo_light_filename', '');
$logoTag = $logo !== ''
? ''
: '
' . $brand . '
'; $html = str_replace('{{logo_html}}', $logoTag, $html); foreach ($vars as $key => $value) { $html = str_replace('{{' . $key . '}}', htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'), $html); } return $html; } // ─── User-agent prettifier (last-login display) ────────────────────────────── // Mirrors fotografia's helper so views/user/index.php can show a short label. function parse_user_agent(string $ua): string { if ($ua === '') return '—'; $browser = 'Navegador'; foreach (['Edg' => 'Edge', 'OPR' => 'Opera', 'Chrome' => 'Chrome', 'Firefox' => 'Firefox', 'Safari' => 'Safari'] as $needle => $label) { if (stripos($ua, $needle) !== false) { $browser = $label; break; } } $os = 'SO'; foreach (['Windows' => 'Windows', 'Android' => 'Android', 'iPhone' => 'iOS', 'iPad' => 'iOS', 'Mac OS' => 'macOS', 'Linux' => 'Linux'] as $needle => $label) { if (stripos($ua, $needle) !== false) { $os = $label; break; } } return "$browser / $os"; }