add projet
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Notification;
|
||||
use App\Models\UserNotification;
|
||||
use App\Models\User;
|
||||
use App\Services\EmailService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class NotificationManagementController extends BaseApiController
|
||||
{
|
||||
protected Notification $notification;
|
||||
protected UserNotification $userNotification;
|
||||
protected User $user;
|
||||
protected EmailService $emailService;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->notification = model(Notification::class);
|
||||
$this->userNotification = model(UserNotification::class);
|
||||
$this->user = model(User::class);
|
||||
$this->emailService = app(EmailService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/notifications/active
|
||||
* Get active (non-deleted, non-expired) notifications
|
||||
*/
|
||||
public function activeNotificationsData()
|
||||
{
|
||||
try {
|
||||
$targetGroup = $this->request->getGet('target_group');
|
||||
$payload = $this->buildActiveNotificationsPayload($targetGroup);
|
||||
return $this->success($payload, 'Active notifications retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Active notifications data error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to retrieve active notifications', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/notifications/deleted
|
||||
* Get soft-deleted notifications
|
||||
*/
|
||||
public function deletedNotificationsData()
|
||||
{
|
||||
try {
|
||||
$payload = $this->buildDeletedNotificationsPayload();
|
||||
return $this->success($payload, 'Deleted notifications retrieved successfully');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Deleted notifications data error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to retrieve deleted notifications', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/notifications/send
|
||||
* Create and send notifications to a target group
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
if (!$user) {
|
||||
return $this->respondError('Authentication required', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$payload = $this->payloadData();
|
||||
|
||||
$title = trim((string) ($payload['title'] ?? ''));
|
||||
$message = trim((string) ($payload['message'] ?? ''));
|
||||
$group = trim((string) ($payload['target_group'] ?? ''));
|
||||
$channels = (array) ($payload['channels'] ?? []);
|
||||
|
||||
if (empty($title) || empty($message) || empty($group) || empty($channels)) {
|
||||
return $this->respondError('Title, message, target_group, and channels are required', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
// Create notification
|
||||
$notifId = $this->notification->insert([
|
||||
'title' => $title,
|
||||
'message' => $message,
|
||||
'target_group' => $group,
|
||||
'delivery_channels' => implode(',', $channels),
|
||||
'created_at' => utc_now(),
|
||||
], true);
|
||||
|
||||
if (!$notifId) {
|
||||
return $this->respondError('Failed to create notification', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// Get users by role (target_group)
|
||||
$users = $this->user->getUsersByRole($group);
|
||||
|
||||
$sentCount = 0;
|
||||
$emailCount = 0;
|
||||
$smsCount = 0;
|
||||
|
||||
foreach ($users as $user) {
|
||||
// Create user notification record
|
||||
$this->userNotification->insert([
|
||||
'notification_id' => $notifId,
|
||||
'user_id' => (int) $user['id'],
|
||||
'is_read' => 0,
|
||||
]);
|
||||
|
||||
// Send via email if requested
|
||||
if (in_array('email', $channels) && !empty($user['email'])) {
|
||||
try {
|
||||
$this->sendEmail($user['email'], $title, $message);
|
||||
$emailCount++;
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Failed to send email to ' . $user['email'] . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Send via SMS if requested
|
||||
if (in_array('sms', $channels) && !empty($user['cellphone'])) {
|
||||
try {
|
||||
$this->sendSMS($user['cellphone'], $message);
|
||||
$smsCount++;
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Failed to send SMS to ' . $user['cellphone'] . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$sentCount++;
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'notification_id' => $notifId,
|
||||
'users_notified' => $sentCount,
|
||||
'emails_sent' => $emailCount,
|
||||
'sms_sent' => $smsCount,
|
||||
], 'Notification sent successfully');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Notification send error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to send notification: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/v1/notifications/{id}/restore
|
||||
* Restore a soft-deleted notification
|
||||
*/
|
||||
public function restore($id)
|
||||
{
|
||||
try {
|
||||
$id = (int) $id;
|
||||
|
||||
// Check if notification exists and is deleted
|
||||
$notification = $this->notification->withDeleted()->find($id);
|
||||
if (!$notification) {
|
||||
return $this->respondError('Notification not found', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$restored = $this->notification->restoreNotification($id);
|
||||
|
||||
// Check if update was successful (update returns affected rows or false)
|
||||
if ($restored !== false) {
|
||||
return $this->success([
|
||||
'id' => $id,
|
||||
], 'Notification restored successfully');
|
||||
}
|
||||
|
||||
return $this->respondError('Failed to restore notification', Response::HTTP_BAD_REQUEST);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Notification restore error: ' . $e->getMessage());
|
||||
return $this->respondError('Failed to restore notification: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build active notifications payload
|
||||
*/
|
||||
private function buildActiveNotificationsPayload(?string $targetGroup): array
|
||||
{
|
||||
$targetGroup = $targetGroup !== null ? trim($targetGroup) : null;
|
||||
if ($targetGroup === '') {
|
||||
$targetGroup = null;
|
||||
}
|
||||
|
||||
$rows = $this->notification->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,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build deleted notifications payload
|
||||
*/
|
||||
private function buildDeletedNotificationsPayload(): array
|
||||
{
|
||||
$rows = $this->notification->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,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email notification
|
||||
*/
|
||||
protected function sendEmail(string $to, string $subject, string $message): void
|
||||
{
|
||||
try {
|
||||
$this->emailService->setTo($to);
|
||||
$this->emailService->setSubject($subject);
|
||||
$this->emailService->setMessage($message);
|
||||
$this->emailService->send();
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Email send error: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send SMS notification (placeholder - logs for now)
|
||||
*/
|
||||
protected function sendSMS(string $phone, string $message): void
|
||||
{
|
||||
log_message('info', "SMS to {$phone}: {$message}");
|
||||
// TODO: Implement actual SMS sending via SendSMSController or SMS service
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user