197 lines
6.3 KiB
PHP
197 lines
6.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Communication;
|
|
|
|
use App\Http\Controllers\Api\Core\BaseApiController;
|
|
use App\Services\Communication\CommunicationFamilyService;
|
|
use App\Services\Communication\CommunicationPreviewService;
|
|
use App\Services\Communication\CommunicationSendService;
|
|
use App\Services\Communication\CommunicationStudentService;
|
|
use App\Services\Communication\CommunicationTemplateService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class CommunicationController extends BaseApiController
|
|
{
|
|
private CommunicationStudentService $students;
|
|
private CommunicationTemplateService $templates;
|
|
private CommunicationFamilyService $families;
|
|
private CommunicationPreviewService $previewService;
|
|
private CommunicationSendService $sendService;
|
|
|
|
public function __construct(
|
|
CommunicationStudentService $students,
|
|
CommunicationTemplateService $templates,
|
|
CommunicationFamilyService $families,
|
|
CommunicationPreviewService $previewService,
|
|
CommunicationSendService $sendService
|
|
) {
|
|
parent::__construct();
|
|
$this->students = $students;
|
|
$this->templates = $templates;
|
|
$this->families = $families;
|
|
$this->previewService = $previewService;
|
|
$this->sendService = $sendService;
|
|
}
|
|
|
|
public function options(): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'ok' => true,
|
|
'students' => $this->students->listStudents(),
|
|
'templates' => $this->templates->listActiveTemplates(),
|
|
]);
|
|
}
|
|
|
|
public function families(int $studentId): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'ok' => true,
|
|
'data' => $this->families->familiesForStudent($studentId),
|
|
]);
|
|
}
|
|
|
|
public function guardians(int $familyId): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'ok' => true,
|
|
'data' => $this->families->guardiansForFamily($familyId),
|
|
]);
|
|
}
|
|
|
|
public function preview(Request $request): JsonResponse
|
|
{
|
|
$templateKey = (string) $request->input('template_key', '');
|
|
$studentId = (int) $request->input('student_id', 0);
|
|
$familyId = (int) $request->input('family_id', 0);
|
|
$vars = $this->normalizeArray($request->input('vars', []));
|
|
|
|
if ($templateKey === '' || $studentId <= 0 || $familyId <= 0) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => 'template_key, student_id, and family_id are required.',
|
|
], 422);
|
|
}
|
|
|
|
$teacherName = $this->resolveTeacherName();
|
|
$result = $this->previewService->buildPreview($templateKey, $studentId, $familyId, $vars, $teacherName);
|
|
|
|
if (!$result['ok']) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => $result['message'] ?? 'Preview failed.',
|
|
], $result['status'] ?? 400);
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'subject' => $result['subject'],
|
|
'html' => $result['html'],
|
|
]);
|
|
}
|
|
|
|
public function send(Request $request): JsonResponse
|
|
{
|
|
$studentId = (int) $request->input('student_id', 0);
|
|
$familyId = (int) $request->input('family_id', 0);
|
|
$templateKey = (string) $request->input('template_key', '');
|
|
$subject = (string) $request->input('subject', '');
|
|
$body = (string) $request->input('body', '');
|
|
$recipients = $this->normalizeArray($request->input('recipients', []));
|
|
$cc = $this->normalizeArray($request->input('cc', []));
|
|
$bcc = $this->normalizeArray($request->input('bcc', []));
|
|
|
|
if ($studentId <= 0 || $familyId <= 0 || $templateKey === '' || $subject === '' || $body === '') {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => 'student_id, family_id, template_key, subject, and body are required.',
|
|
], 422);
|
|
}
|
|
|
|
if (empty($recipients)) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => 'At least one recipient is required.',
|
|
], 422);
|
|
}
|
|
|
|
$student = $this->students->getStudentBasic($studentId);
|
|
if (!$student) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => 'Student not found.',
|
|
], 404);
|
|
}
|
|
|
|
$senderId = $this->authenticatedUserIdOrUnauthorized();
|
|
if ($senderId instanceof JsonResponse) {
|
|
return $senderId;
|
|
}
|
|
|
|
$result = $this->sendService->send([
|
|
'student_id' => $studentId,
|
|
'family_id' => $familyId,
|
|
'template_key' => $templateKey,
|
|
'subject' => $subject,
|
|
'body' => $body,
|
|
'recipients' => $recipients,
|
|
'cc' => $cc,
|
|
'bcc' => $bcc,
|
|
'student_name' => trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? '')),
|
|
'sent_by' => $senderId,
|
|
]);
|
|
|
|
if (!$result['ok']) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'message' => 'Failed to send email.',
|
|
'error' => $result['error'],
|
|
], 500);
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'message' => 'Email sent successfully.',
|
|
]);
|
|
}
|
|
|
|
private function normalizeArray($value): array
|
|
{
|
|
if (is_array($value)) {
|
|
return $value;
|
|
}
|
|
|
|
if (is_string($value) && $value !== '') {
|
|
$decoded = json_decode($value, true);
|
|
if (is_array($decoded)) {
|
|
return $decoded;
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
private function resolveTeacherName(): string
|
|
{
|
|
$user = auth()->user();
|
|
if ($user) {
|
|
$name = trim(($user->firstname ?? '') . ' ' . ($user->lastname ?? ''));
|
|
return $name !== '' ? $name : 'Teacher';
|
|
}
|
|
return 'Teacher';
|
|
}
|
|
|
|
/**
|
|
* @return int|JsonResponse
|
|
*/
|
|
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
|
|
}
|
|
|
|
return $userId;
|
|
}
|
|
}
|