214 lines
6.7 KiB
PHP
Executable File
214 lines
6.7 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Controllers\View;
|
|
use App\Controllers\BaseController;
|
|
use App\Controllers\View\EmailController;
|
|
use App\Models\NotificationModel;
|
|
use App\Models\UserNotificationModel;
|
|
use App\Models\UserModel;
|
|
|
|
class NotificationsController extends BaseController
|
|
{
|
|
protected $notificationModel;
|
|
protected $userNotificationModel;
|
|
protected $userModel;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->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,
|
|
];
|
|
}
|
|
}
|