notificationModel = new NotificationModel(); $this->userNotificationModel = new UserNotificationModel(); $this->userModel = new UserModel(); } public function index() { $userId = session()->get('user_id'); $notifications = $this->userNotificationModel ->select('notifications.*, user_notifications.is_read') ->join('notifications', 'notifications.id = user_notifications.notification_id') ->where('user_notifications.user_id', $userId) ->orderBy('notifications.created_at', 'DESC') ->findAll(); return view('notifications/index', ['notifications' => $notifications]); } public function create() { return view('notifications/create'); } public function send() { $title = $this->request->getPost('title'); $message = $this->request->getPost('message'); $group = $this->request->getPost('target_group'); $channels = $this->request->getPost('channels'); // ['in_app', 'email', 'sms'] $notifId = $this->notificationModel->insert([ 'title' => $title, 'message' => $message, 'target_group' => $group, 'delivery_channels' => implode(',', $channels), 'created_at' => utc_now() ]); $users = $this->userModel->where('role', $group)->findAll(); foreach ($users as $user) { $this->userNotificationModel->insert([ 'notification_id' => $notifId, 'user_id' => $user['id'], 'is_read' => false ]); if (in_array('email', $channels)) { $this->sendEmail($user['email'], $title, $message); } if (in_array('sms', $channels) && !empty($user['phone'])) { $this->sendSMS($user['phone'], $message); } } return redirect()->back()->with('success', 'Notification sent successfully.'); } public function markAsRead($id) { $userId = session()->get('user_id'); $this->userNotificationModel->where('notification_id', $id) ->where('user_id', $userId) ->set(['is_read' => 1]) ->update(); return redirect()->back(); } public function listActive() { helper('url'); $targetGroup = $this->request->getGet('target_group'); return view('notifications/list_active', [ 'notificationsEndpoint' => site_url('api/notifications/active'), 'defaultTargetGroup' => $targetGroup, ]); } public function listDeleted() { helper(['url', 'form']); return view('notifications/list_deleted', [ 'deletedNotificationsEndpoint' => site_url('api/notifications/deleted'), 'restoreEndpoint' => site_url('notifications/restore'), 'csrfTokenName' => csrf_token(), 'csrfTokenValue' => csrf_hash(), ]); } public function activeNotificationsData() { $targetGroup = $this->request->getGet('target_group'); return $this->response->setJSON($this->buildActiveNotificationsPayload($targetGroup)); } public function deletedNotificationsData() { return $this->response->setJSON($this->buildDeletedNotificationsPayload()); } public function restore($id) { if ($this->notificationModel->restoreNotification($id)) { return redirect()->to(base_url('notifications/deleted'))->with('success', 'Notification restored successfully.'); } return redirect()->to(base_url('notifications/deleted'))->with('error', 'Failed to restore notification.'); } protected function sendEmail($to, $subject, $message) { $mailer = new EmailController(); $mailer->sendEmail($to, $subject, $message); } protected function sendSMS($phone, $message) { log_message('info', "SMS to {$phone}: {$message}"); } private function buildActiveNotificationsPayload(?string $targetGroup): array { $targetGroup = $targetGroup !== null ? trim($targetGroup) : null; if ($targetGroup === '') { $targetGroup = null; } $rows = $this->notificationModel->getActiveNotifications($targetGroup); if (!is_array($rows)) { $rows = []; } $now = time(); $notifications = array_map(static function ($row) use ($now) { if (!is_array($row)) { return []; } $expiresAt = $row['expires_at'] ?? null; $expiryTs = $expiresAt ? strtotime((string) $expiresAt) : false; $isExpired = $expiryTs !== false && $expiryTs <= $now; return [ 'id' => $row['id'] ?? null, 'title' => $row['title'] ?? null, 'message' => $row['message'] ?? null, 'priority' => $row['priority'] ?? null, 'scheduled_at' => $row['scheduled_at'] ?? null, 'expires_at' => $expiresAt, 'created_at' => $row['created_at'] ?? null, 'target_group' => $row['target_group'] ?? null, 'isExpired' => $isExpired, ]; }, $rows); return [ 'notifications' => $notifications, ]; } private function buildDeletedNotificationsPayload(): array { $rows = $this->notificationModel->getDeletedNotifications(); if (!is_array($rows)) { $rows = []; } $notifications = array_map(static function ($row) { if (!is_array($row)) { return []; } return [ 'id' => $row['id'] ?? null, 'title' => $row['title'] ?? null, 'message' => $row['message'] ?? null, 'priority' => $row['priority'] ?? null, 'scheduled_at' => $row['scheduled_at'] ?? null, 'expires_at' => $row['expires_at'] ?? null, 'deleted_at' => $row['deleted_at'] ?? null, ]; }, $rows); return [ 'notifications' => $notifications, ]; } }