Files
2026-06-11 11:46:12 -04:00

90 lines
4.4 KiB
PHP

<?php
namespace App\Support;
/**
* HTML for outbound email/PDF without Blade (SPA handles all user-facing UI).
*/
final class MailHtml
{
public static function document(string $title, string $bodyInnerHtml): string
{
$t = htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
return '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">'
.'<meta name="viewport" content="width=device-width, initial-scale=1">'
.'<title>'.$t.'</title></head>'
.'<body style="margin:0;padding:16px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#212529;background:#f8f9fa;">'
.'<div style="max-width:640px;margin:0 auto;background:#fff;padding:20px;border-radius:8px;border:1px solid #e9ecef;">'
.$bodyInnerHtml
.'</div></body></html>';
}
/** Late slip PDF body (Dompdf). */
public static function slipPdfHtml(array $entry, array $lines, array $page): string
{
$name = htmlspecialchars((string) ($entry['student_name'] ?? ''), ENT_QUOTES, 'UTF-8');
$blocks = [];
foreach ($lines as $line) {
$blocks[] = '<div style="font-family:Courier,monospace;font-size:11pt;line-height:1.25;margin:0 0 1.5mm 0;">'
.htmlspecialchars((string) $line, ENT_QUOTES, 'UTF-8').'</div>';
}
return '<!DOCTYPE html><html><head><meta charset="UTF-8">'
.'<style>body{margin:3mm;font-family:Courier,monospace;font-size:11pt;}</style></head><body>'
.'<div style="font-weight:bold;font-size:12pt;margin-bottom:2mm;">'.$name.'</div>'
.implode('', $blocks)
.'</body></html>';
}
/** Below-60 / performance alert email body (wrapped in {@see document()} by caller). */
public static function belowSixtyInnerHtml(array $d): string
{
$scores = $d['scores'] ?? [];
$rows = '';
if (is_array($scores)) {
foreach ($scores as $row) {
if (! is_array($row)) {
continue;
}
$label = htmlspecialchars((string) ($row['label'] ?? $row['name'] ?? ''), ENT_QUOTES, 'UTF-8');
$val = htmlspecialchars((string) ($row['value'] ?? $row['score'] ?? ''), ENT_QUOTES, 'UTF-8');
$rows .= '<tr><td style="padding:4px 8px;border:1px solid #dee2e6;">'.$label.'</td>'
.'<td style="padding:4px 8px;border:1px solid #dee2e6;">'.$val.'</td></tr>';
}
}
$comment = htmlspecialchars((string) ($d['comment'] ?? ''), ENT_QUOTES, 'UTF-8');
$title = htmlspecialchars((string) ($d['title'] ?? 'Performance alert'), ENT_QUOTES, 'UTF-8');
return '<h2 style="margin-top:0;">'.$title.'</h2>'
.'<p>Dear '.htmlspecialchars((string) ($d['parent_name'] ?? 'Parent/Guardian'), ENT_QUOTES, 'UTF-8').',</p>'
.'<p>Student: <strong>'.htmlspecialchars((string) ($d['student_name'] ?? ''), ENT_QUOTES, 'UTF-8').'</strong></p>'
.'<p>Class: '.htmlspecialchars((string) ($d['class_section_name'] ?? ''), ENT_QUOTES, 'UTF-8').'</p>'
.(($d['semester'] ?? '') !== '' || ($d['school_year'] ?? '') !== ''
? '<p>'.htmlspecialchars(trim((string) ($d['semester'] ?? '').' '.(string) ($d['school_year'] ?? '')), ENT_QUOTES, 'UTF-8').'</p>'
: '')
.($rows !== '' ? '<table style="border-collapse:collapse;width:100%;">'.$rows.'</table>' : '')
.($comment !== '' ? '<p><strong>Comment:</strong> '.$comment.'</p>' : '');
}
/** Broadcast email outer shell (replaces emails.broadcast_wrapper). */
public static function broadcastCompose(
string $subject,
string $contentHtml,
string $preheader,
string $ctaText,
string $ctaUrl
): string {
$pre = $preheader !== ''
? '<p style="color:#6c757d;font-size:12px;margin:0 0 12px;">'.htmlspecialchars($preheader, ENT_QUOTES, 'UTF-8').'</p>'
: '';
$cta = ($ctaText !== '' && $ctaUrl !== '')
? '<p style="margin-top:16px;"><a href="'.htmlspecialchars($ctaUrl, ENT_QUOTES, 'UTF-8')
.'" style="display:inline-block;padding:10px 16px;background:#0d6efd;color:#fff;text-decoration:none;border-radius:4px;">'
.htmlspecialchars($ctaText, ENT_QUOTES, 'UTF-8').'</a></p>'
: '';
return self::document($subject, $pre.'<div>'.$contentHtml.'</div>'.$cta);
}
}