false, 'message' => 'No event listener registered for WhatsappInvitesSend.', 'triggered' => 0, ]; } $normalize = static function (array $list): array { $out = []; foreach ($list as $e) { $e = strtolower(trim((string) $e)); if ($e !== '' && filter_var($e, FILTER_VALIDATE_EMAIL)) { $out[$e] = true; } } return array_keys($out); }; $triggered = 0; foreach ($bundles as $bundle) { try { $primaryEmails = $normalize((array) ($bundle['emails'] ?? [])); $secondaryEmails = $this->extractSecondaryEmails($bundle, $normalize); if (empty($secondaryEmails)) { Log::info('No secondary emails for WhatsApp invite.', [ 'parent_id' => $bundle['parent']['id'] ?? null, ]); } $to = $primaryEmails; $cc = []; if (! empty($primaryEmails) && ! empty($secondaryEmails)) { $cc = array_values(array_diff($secondaryEmails, $primaryEmails)); } elseif (empty($primaryEmails) && ! empty($secondaryEmails)) { $to = $secondaryEmails; } if (empty($to)) { Log::warning('Skipping WhatsApp invite: no recipient email(s).', [ 'parent_id' => $bundle['parent']['id'] ?? null, ]); continue; } event(new WhatsappInvitesSend([ 'parent' => $bundle['parent'] ?? null, 'sections' => $bundle['sections'] ?? [], 'schoolYear' => $schoolYear, 'semester' => $semester, 'links' => $bundle['links'] ?? [], 'teachers' => $bundle['teachers'] ?? [], 'to_emails' => $to, 'cc_emails' => $cc, ])); $triggered++; } catch (\Throwable $e) { Log::error('WhatsappInvitesSend dispatch failed: '.$e->getMessage()); } } return [ 'ok' => true, 'triggered' => $triggered, ]; } private function extractSecondaryEmails(array $bundle, callable $normalize): array { $collected = []; if (! empty($bundle['emails_secondary'])) { $collected = array_merge($collected, (array) $bundle['emails_secondary']); } if (! empty($bundle['secondary_parents'])) { foreach ((array) $bundle['secondary_parents'] as $sp) { if (! empty($sp['email'])) { $collected[] = $sp['email']; } } } $parent = $bundle['parent'] ?? []; foreach (['secondary_email', 'secondparent_email', 'sec_email', 'email_secondary'] as $key) { if (! empty($parent[$key])) { $collected[] = $parent[$key]; } } if (! empty($parent['secondparent']['email'])) { $collected[] = $parent['secondparent']['email']; } try { $primaryId = (int) ($parent['id'] ?? 0); if ($primaryId > 0) { $row = ParentModel::query() ->select('secondparent_email') ->where('firstparent_id', $primaryId) ->orderByDesc('updated_at') ->first(); if (! empty($row?->secondparent_email)) { $collected[] = $row->secondparent_email; } } } catch (\Throwable $e) { Log::warning('Secondary email DB lookup failed: '.$e->getMessage()); } return $normalize($collected); } }