input('notify'); if (!is_array($notify)) { return [ 'success' => false, 'message' => 'Select at least one teacher to notify.', 'status' => 422, ]; } $missingItemsPayload = $request->input('missing_items', []); $targets = $this->extractTargets($notify); if (empty($targets)) { return [ 'success' => false, 'message' => 'Select at least one teacher to notify.', 'status' => 422, ]; } $teacherIds = array_values(array_unique(array_column($targets, 'teacher_id'))); $classSectionIds = array_values(array_unique(array_column($targets, 'class_section_id'))); $classSections = ClassSection::query() ->select('class_section_id', 'class_section_name') ->whereIn('class_section_id', $classSectionIds) ->get() ->keyBy('class_section_id'); $teachers = User::query() ->select('id', 'firstname', 'lastname', 'email') ->whereIn('id', $teacherIds) ->get() ->keyBy('id'); $adminUser = User::find($adminId); $adminName = trim(($adminUser->firstname ?? '') . ' ' . ($adminUser->lastname ?? '')) ?: 'Administrator'; $scoreUrl = url('/'); $sentCount = 0; $failCount = 0; foreach ($targets as $target) { $classSectionId = (int) $target['class_section_id']; $teacherId = (int) $target['teacher_id']; $teacher = $teachers->get($teacherId); $sectionName = $classSections->get($classSectionId)?->class_section_name ?? "Section {$classSectionId}"; $teacherName = trim(($teacher->firstname ?? '') . ' ' . ($teacher->lastname ?? '')) ?: 'Teacher'; $missingPayload = $missingItemsPayload[$classSectionId][$teacherId] ?? ''; $missingItems = $this->support->parseMissingItemsPayload((string) $missingPayload); $missingNote = !empty($missingItems) ? '

Outstanding items: ' . e($this->support->formatMissingItemsText($missingItems)) . '.

' : '

Our records show no outstanding submissions for this section, but please verify if anything still needs attention.

'; $subject = "Reminder: Complete submissions for {$sectionName}"; $body = "

Dear {$teacherName},

" . "

Administration is gently reminding you to wrap up any remaining score submissions and/or comments for {$sectionName}.

" . $missingNote . "

Visit Teacher Score Submission to address any remaining items.

" . "

Thank you,
{$adminName}

"; $email = $teacher->email ?? ''; $status = 'failed'; if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) { try { Mail::html($body, function ($message) use ($email, $subject) { $message->to($email)->subject($subject); }); $status = 'sent'; } catch (\Throwable $e) { Log::error('Teacher submission notification failed: ' . $e->getMessage()); } } if ($status === 'sent') { $sentCount++; } else { $failCount++; } TeacherSubmissionNotificationHistory::create([ 'teacher_id' => $teacherId, 'class_section_id' => $classSectionId, 'admin_id' => $adminId, 'notification_category' => 'teacher_submissions', 'message' => $this->support->truncateNotificationMessage($body), 'status' => $status, 'school_year' => $this->shared->getSchoolYear(), 'semester' => $this->shared->getSemester(), 'sent_at' => now(), ]); } $parts = []; if ($sentCount > 0) { $parts[] = $sentCount . ' reminder' . ($sentCount === 1 ? '' : 's') . ' sent'; } if ($failCount > 0) { $parts[] = $failCount . ' reminder' . ($failCount === 1 ? '' : 's') . ' failed'; } return [ 'success' => $failCount === 0, 'message' => !empty($parts) ? implode(' and ', $parts) : 'No notifications were sent.', 'sent' => $sentCount, 'failed' => $failCount, 'status' => $failCount === 0 ? 200 : 207, ]; } protected function extractTargets(array $notify): array { $targets = []; foreach ($notify as $sectionIdRaw => $teachers) { $sectionId = (int) $sectionIdRaw; if ($sectionId <= 0 || !is_array($teachers)) { continue; } foreach ($teachers as $teacherIdRaw => $value) { $teacherId = (int) $teacherIdRaw; if ($teacherId <= 0 || $value === null || $value === '') { continue; } $targets["{$sectionId}_{$teacherId}"] = [ 'class_section_id' => $sectionId, 'teacher_id' => $teacherId, ]; } } return array_values($targets); } }