139 lines
4.7 KiB
PHP
139 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories;
|
|
|
|
use App\Models\Notification;
|
|
|
|
class NotificationRepository extends BaseRepository
|
|
{
|
|
public function __construct(Notification $model)
|
|
{
|
|
parent::__construct($model);
|
|
}
|
|
|
|
/**
|
|
* Get the list of recipient categories a user is authorized to see.
|
|
* Hierarchy: Developer > Administrator > User > all
|
|
*/
|
|
public function getAuthorizedRecipients($user)
|
|
{
|
|
$recipients = ['all'];
|
|
|
|
if ($user->hasRole('Developer')) {
|
|
return ['Developer', 'Administrator', 'User', 'all'];
|
|
}
|
|
|
|
if ($user->hasRole('Administrator')) {
|
|
return ['Administrator', 'User', 'all'];
|
|
}
|
|
|
|
// Default: only see notifications for 'User' and 'all'
|
|
return ['User', 'all'];
|
|
}
|
|
|
|
/**
|
|
* Get ALL notifications for a user based on their roles,
|
|
* BUT exclude those they have personally deleted/hidden.
|
|
*/
|
|
public function getActiveNotificationsForUser($user, $offset = 0, $limit = 10)
|
|
{
|
|
$query = $this->model->query();
|
|
|
|
// 1. Filter by roles (Broadcast targeting) hierarchical
|
|
$authorizedRecipients = $this->getAuthorizedRecipients($user);
|
|
$query->whereIn('recipient', $authorizedRecipients);
|
|
|
|
// 2. Left Join personal interactions
|
|
$query->leftJoin('system_notification_user', function ($join) use ($user) {
|
|
$join->on('system_notifications.id', '=', 'system_notification_user.notification_id')
|
|
->where('system_notification_user.user_id', '=', $user->id);
|
|
});
|
|
|
|
// 3. Exclude personally deleted ones
|
|
$query->whereNull('system_notification_user.deleted_at');
|
|
|
|
// 4. Select needed columns (avoiding ID collision with Join)
|
|
return $query->select('system_notifications.*', 'system_notification_user.read_at as personal_read_at')
|
|
->latest('system_notifications.created_at')
|
|
->skip($offset)
|
|
->take($limit)
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* Get personal unread count.
|
|
*/
|
|
public function getUnreadCount($user)
|
|
{
|
|
$query = $this->model->query();
|
|
|
|
// Target filtering hierarchical
|
|
$authorizedRecipients = $this->getAuthorizedRecipients($user);
|
|
$query->whereIn('recipient', $authorizedRecipients);
|
|
|
|
// Join to check read/deleted status
|
|
$query->leftJoin('system_notification_user', function ($join) use ($user) {
|
|
$join->on('system_notifications.id', '=', 'system_notification_user.notification_id')
|
|
->where('system_notification_user.user_id', '=', $user->id);
|
|
});
|
|
|
|
// Unread = (Global read_at is null AND Personal read_at is null) AND not deleted
|
|
$query->whereNull('system_notification_user.read_at')
|
|
->whereNull('system_notification_user.deleted_at');
|
|
|
|
return $query->count();
|
|
}
|
|
|
|
/**
|
|
* Personal Mark As Read
|
|
*/
|
|
public function markAsRead($notificationId, $userId)
|
|
{
|
|
\DB::table('system_notification_user')->updateOrInsert(
|
|
['notification_id' => $notificationId, 'user_id' => $userId],
|
|
['read_at' => now(), 'updated_at' => now()]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Personal Delete (Hide)
|
|
*/
|
|
public function personalDelete($notificationId, $userId)
|
|
{
|
|
\DB::table('system_notification_user')->updateOrInsert(
|
|
['notification_id' => $notificationId, 'user_id' => $userId],
|
|
['deleted_at' => now(), 'updated_at' => now()]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Mark ALL visible notifications as read for this user.
|
|
*/
|
|
public function markAllAsReadForUser($user)
|
|
{
|
|
$authorizedRecipients = $this->getAuthorizedRecipients($user);
|
|
|
|
// 1. Get IDs of notifications that are visible to user but either:
|
|
// - Have no entry in pivot (meaning unread)
|
|
// - Have an entry with read_at IS NULL and deleted_at IS NULL
|
|
$unreadIds = $this->model->query()
|
|
->whereIn('recipient', $authorizedRecipients)
|
|
->leftJoin('system_notification_user', function ($join) use ($user) {
|
|
$join->on('system_notifications.id', '=', 'system_notification_user.notification_id')
|
|
->where('system_notification_user.user_id', '=', $user->id);
|
|
})
|
|
->whereNull('system_notification_user.read_at')
|
|
->whereNull('system_notification_user.deleted_at')
|
|
->pluck('system_notifications.id');
|
|
|
|
if ($unreadIds->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
// 2. Perform batch updateOrInsert for each (or just loop if small, but let's stick to markAsRead helper)
|
|
foreach ($unreadIds as $id) {
|
|
$this->markAsRead($id, $user->id);
|
|
}
|
|
}
|
|
}
|