templates = $templates; $this->students = $students; $this->families = $families; } public function buildPreview( string $templateKey, int $studentId, int $familyId, array $vars, string $teacherName ): array { $template = $this->templates->findTemplateByKey($templateKey); if (! $template) { return [ 'ok' => false, 'status' => 404, 'message' => 'Template not found', ]; } $student = $this->students->getStudentBasic($studentId); if (! $student) { return [ 'ok' => false, 'status' => 404, 'message' => 'Student not found', ]; } $salutation = $this->families->guardianSalutation($familyId); $autoVars = [ 'student_fullname' => trim(($student['firstname'] ?? '').' '.($student['lastname'] ?? '')), 'student_grade' => $student['grade'] ?? '', 'parent_salutation' => $salutation, 'date' => $this->formatLocalDate('Y-m-d'), 'school_name' => 'Al Rahma Sunday School', 'teacher_name' => $teacherName !== '' ? $teacherName : 'Teacher', ]; $allVars = array_merge($autoVars, $vars); $subject = $this->renderTwig($template['subject'], $allVars); $body = $this->renderTwig($template['body'], $allVars); return [ 'ok' => true, 'subject' => $subject, 'html' => nl2br($body), ]; } private function renderTwig(string $template, array $vars): string { return (string) preg_replace_callback('/\\{\\{\\s*([a-zA-Z0-9_\\.]+)\\s*\\}\\}/', function ($m) use ($vars) { $key = $m[1]; return htmlspecialchars((string) ($vars[$key] ?? ''), ENT_QUOTES, 'UTF-8'); }, $template); } private function formatLocalDate(string $format): string { if (function_exists('local_date') && function_exists('utc_now')) { return (string) local_date(utc_now(), $format); } return now()->format($format); } }