for review

This commit is contained in:
2025-01-07 13:31:56 +02:00
parent 75d62872c3
commit 431fd1ac3a
10 changed files with 141 additions and 109 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ namespace LucentNotifications\Collections;
use Illuminate\Support\Collection;
use LucentNotifications\Models\QuietHourSection;
class QuietHoursCollecton extends Collection
class QuietHoursCollection extends Collection
{
function __construct($items = [])
{
@@ -15,7 +15,6 @@ class NotificationsController{
function index()
{
return response()->stream(function () {
while (true) {
Redis::subscribe(['user-channel-' . Session::get('user.id')], function (string $message) {
-2
View File
@@ -8,6 +8,4 @@ Route::group([
], function () {
Route::get('/broadcasting/notifications', [NotificationsController::class, 'index']);
Route::get('/broadcasting/notifications/forUser', [NotificationsController::class, 'forUser']);
});
+3 -44
View File
@@ -5,57 +5,16 @@ namespace LucentNotifications\Listeners;
use LucentNotifications\Events\NotificationsDispatcher;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redis;
use Lucent\Account\UserRepo;
use LucentNotifications\Models\Notification;
use LucentNotifications\Repos\NotificationsRepo;
use LucentNotifications\Services\SettingsService;
use LucentNotifications\Models\UserSettings;
use LucentNotifications\Enums\SettingValues;
use LucentNotifications\Services\NotificationsService;
class PushNotifications implements ShouldQueue
{
use Queueable;
function __construct(private NotificationsRepo $repo, private UserRepo $userRepo, private SettingsService $settingsService) {}
function __construct(private NotificationsService $notificationsService) {}
function handle(NotificationsDispatcher $event)
{
collect($event->notifications)->map(function (Notification $notification) {
$this->repo->create($notification->toDB());
$userSettings = $this->settingsService->getForUser($notification->userIdTo);
$actions = $this->calculateActions($userSettings, $notification);
foreach ($actions as $action){
$action();
}
});
}
function calculateActions(UserSettings $userSettings, Notification $notification)
{
$actions = [];
$type = $notification->type;
if ($notification->broadcast && $this->shouldBroadcast($type, $userSettings->notificationsSettings)) {
$actions[] = (fn() => Redis::publish('user-channel-' . $notification->userIdTo, json_encode($notification)));
}
if ($notification->mailClass && $this->shouldSendEmail($type, $userSettings->notificationsSettings)) {
$actions[] = (function () use ($notification) {
$userFrom = $this->userRepo->findById($notification->userIdFrom)->get()->safe();
$userTo = $this->userRepo->findById($notification->userIdTo)->get()->safe();
Mail::to($userTo['email'])->send(new $notification->mailClass($notification, $userFrom, $userTo));
});
}
return $actions;
}
function shouldBroadcast($type, $userSettings)
{
return $userSettings->$type == SettingValues::BROADCAST || $userSettings->$type == SettingValues::BOTH;
}
function shouldSendEmail($type, $userSettings)
{
return $userSettings->$type == SettingValues::EMAIL || $userSettings->$type == SettingValues::BOTH;
$this->notificationsService->pushForUser($event->notifications);
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ namespace LucentNotifications\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use LucentNotifications\Events\ReadNotification;
use LucentNotifications\NotificationsRepo;
use LucentNotifications\Repos\NotificationsRepo;
class UpdateNotificationReadAt implements ShouldQueue
{
+12 -2
View File
@@ -7,7 +7,7 @@ use Illuminate\Support\ServiceProvider;
use Hive\Hook\HookManager;
use LucentNotifications\Events\NotificationsDispatcher;
use LucentNotifications\Listeners\PushNotifications;
use LucentNotifications\Services\NotificationService;
use LucentNotifications\Services\NotificationsService;
class LucentNotificationsServiceProvider extends ServiceProvider
{
@@ -26,10 +26,20 @@ class LucentNotificationsServiceProvider extends ServiceProvider
{
$hookManager = $this->app->make(HookManager::class);
$hookManager->push("get-notifications", function (array $filters) {
$notificationsService = new NotificationService;
$notificationsService = new NotificationsService;
return $notificationsService->getForUser($filters);
});
$hookManager->push("push-notifications", function (array $notifications) {
$notificationsService = new NotificationsService;
return $notificationsService->createNotifications($notifications);
});
$hookManager->push("update-read-at", function (string $notificationId) {
$notificationsService = new NotificationsService;
return $notificationsService->updateReadAt($notificationId);
});
Event::listen(NotificationsDispatcher::class, PushNotifications::class);
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
+4 -5
View File
@@ -4,7 +4,6 @@ namespace LucentNotifications\Models;
use Carbon\Carbon;
use Exception;
use Illuminate\Mail\Mailable;
use Illuminate\Support\Str;
use stdClass;
@@ -24,7 +23,7 @@ class Notification
public ?string $type,
public Carbon $created_at,
public Carbon $updated_at,
public ?Carbon $read_at,
public ?Carbon $readAt,
) {}
public function toDB()
@@ -37,7 +36,7 @@ class Notification
'type' => $this->type,
"created_at" => $this->created_at,
"updated_at" => $this->updated_at,
"read_at" => $this->read_at
"readAt" => $this->readAt
];
}
@@ -51,7 +50,7 @@ class Notification
type: $data->type,
created_at: Carbon::parse($data->created_at),
updated_at: Carbon::parse($data->updated_at),
read_at: Carbon::parse($data->read_at)
readAt: Carbon::parse($data->readAt)
);
}
@@ -65,7 +64,7 @@ class Notification
type: $type,
created_at: Carbon::now(),
updated_at: Carbon::now(),
read_at: null
readAt: null
);
if ($mailClass) {
if (!class_exists($mailClass)){
+2 -2
View File
@@ -19,7 +19,7 @@ class NotificationsRepo {
public function getForUser($userId, $filters){
$query = $this->database()->where('userIdTo', $userId)->orderBy('created_at', 'desc')->get();
$query = $this->parseFilters($query, $filters);
return $query->get();
return $query;
}
public function getUnreadForUser($userId, $filters){
@@ -35,7 +35,7 @@ class NotificationsRepo {
public function updateReadAt(string $notificationId)
{
$this->database()->where('id', $notificationId)->update(['read_at' => Carbon::now()]);
$this->database()->where('id', $notificationId)->update(['readAt' => Carbon::now()]);
}
private function parseFilters($query, $filters)
-51
View File
@@ -1,51 +0,0 @@
<?php
namespace LucentNotifications\Services;
use Hive\Result\Fail;
use Hive\Result\Result;
use Hive\Result\Success;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
use LucentNotifications\Repos\NotificationsRepo;
use LucentNotifications\Models\Notification;
class NotificationService
{
private $repo;
function __construct()
{
$this->repo = App::make(NotificationsRepo::class);
}
public function getForUser($filters): Result
{
if (in_array("unread", $filters)) {
unset($filters['unread']);
$filters = $this->enforceFilters($filters);
$results = $this->repo->getUnreadForUser(Session::get('user.id'), $filters);
} else {
$filters = $this->enforceFilters($filters);
$results = $this->repo->getForUser(Session::get('user.id'));
}
if (!$results) {
return new Fail;
}
$results = collect($results)->map(fn($notification) => Notification::fromDB($notification));
return new Success($results);
}
private function enforceFilters($filters)
{
$acceptableFilters = ['type', 'userIdFrom'];
$returnedFilters = [];
foreach ($filters as $key => $value){
if (in_array($key, $acceptableFilters)){
$returnedFilters[$key] = $value ;
}
}
return $returnedFilters;
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php
namespace LucentNotifications\Services;
use Hive\Result\Fail;
use Hive\Result\Result;
use Hive\Result\Success;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Session;
use Lucent\Account\UserRepo;
use LucentNotifications\Enums\SettingValues;
use LucentNotifications\Events\NotificationsDispatcher;
use LucentNotifications\Repos\NotificationsRepo;
use LucentNotifications\Models\Notification;
use LucentNotifications\Models\UserSettings;
class NotificationsService
{
private $repo;
private $settingsService;
private $userRepo;
function __construct()
{
$this->repo = App::make(NotificationsRepo::class);
$this->settingsService = App::make(SettingsService::class);
$this->userRepo = App::make(UserRepo::class);
}
public function getForUser($filters): Result
{
if (in_array("unread", $filters)) {
unset($filters['unread']);
$filters = $this->enforceFilters($filters);
$results = $this->repo->getUnreadForUser(Session::get('user.id'), $filters);
} else {
$filters = $this->enforceFilters($filters);
$results = $this->repo->getForUser(Session::get('user.id'), $filters);
}
if (!$results) {
return new Fail;
}
$results = collect($results)->map(fn($notification) => Notification::fromDB($notification));
return new Success($results);
}
public function createNotifications(array $notifications){
if (config('notifications.shouldDispatch')) {
NotificationsDispatcher::dispatch($notifications);
} else {
$this->pushForUser($notifications);
}
}
public function pushForUser($notifications)
{
collect($notifications)->map(function (Notification $notification) {
$this->repo->create($notification->toDB());
$userSettings = $this->settingsService->getForUser($notification->userIdTo);
$actions = $this->calculateActions($userSettings, $notification);
foreach ($actions as $action){
$action();
}
});
}
function calculateActions(UserSettings $userSettings, Notification $notification)
{
$actions = [];
$type = $notification->type;
if ($notification->broadcast && $this->shouldBroadcast($type, $userSettings->notificationsSettings)) {
$actions[] = (fn() => Redis::publish('user-channel-' . $notification->userIdTo, json_encode($notification)));
}
if ($notification->mailClass && $this->shouldSendEmail($type, $userSettings->notificationsSettings)) {
$actions[] = (function () use ($notification) {
$userFrom = $this->userRepo->findById($notification->userIdFrom)->get()->safe();
$userTo = $this->userRepo->findById($notification->userIdTo)->get()->safe();
Mail::to($userTo['email'])->send(new $notification->mailClass($notification, $userFrom, $userTo));
});
}
return $actions;
}
function shouldBroadcast($type, $userSettings)
{
return $userSettings->$type == SettingValues::BROADCAST || $userSettings->$type == SettingValues::BOTH;
}
function shouldSendEmail($type, $userSettings)
{
return $userSettings->$type == SettingValues::EMAIL || $userSettings->$type == SettingValues::BOTH;
}
private function enforceFilters($filters)
{
$acceptableFilters = ['type', 'userIdFrom'];
$returnedFilters = [];
foreach ($filters as $key => $value){
if (in_array($key, $acceptableFilters)){
$returnedFilters[$key] = $value ;
}
}
return $returnedFilters;
}
public function updateReadAt($notificationId)
{
$this->repo->updateReadAt($notificationId);
return;
}
}