first commit
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Lucent Notifications
|
||||
|
||||
This package is responsible for creating and pushing notifications. Notifications can be either sent via mail, broadcasted using SSE and they are stored inside the database.
|
||||
|
||||
## Creating Notifications
|
||||
Every notification is an instance of `LucentNotifications\Models\Notification` model. There is a static function caled ::create which facilitates the creation of the notification.
|
||||
|
||||
### Mail notifications
|
||||
The static::create function accepts a Mailable class as its mail parameter. Lucent Notifications will instanciate the new Mailable class with the following parameters:
|
||||
- Notification $notification,
|
||||
- array $userFrom and
|
||||
- array $userTo
|
||||
so keep that in mind when defining your own Mailable class
|
||||
|
||||
|
||||
## Dispatching Notifications
|
||||
Notifications are Dispatched using the `LucentNotifications\Events\NotificationsDispatcher` event in order to be dispatched. The dispatcher accepts an array of Notification objects and dispatches them to the default queue.
|
||||
|
||||
|
||||
## Listening for broadcasted notifications
|
||||
Notifications are broadcasteded on the `broadcast/notifications` route. Yoy can easily listen for messages using an EventSource in js.
|
||||
|
||||
## Retrieving notifications
|
||||
Notifications can be retrieved using the HookManager's get-notifications function. The function accepts an array of filters.
|
||||
When the string 'unread' is passed, it will fetch al unread notifications. Otherwise you can filter based on key => values for the following fields: userIdFrom, type
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "radical/lucent-notifications",
|
||||
"description": "A notifications package for Lucent",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arvanitakis Konstantinos",
|
||||
"email": "arvanitakis@radical-elements.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.3",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/prompts": "^0.1.18",
|
||||
"hashids/hashids": "^5.0.2"
|
||||
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"laravel/framework": "^10.10"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LucentNotifications\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LucentNotifications\\LucentNotificationsServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Collections;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use LucentNotifications\Models\QuietHourSection;
|
||||
|
||||
class QuietHoursCollecton extends Collection
|
||||
{
|
||||
function __construct($items = [])
|
||||
{
|
||||
return collect($items)->map(fn($item) => new QuietHourSection($item));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'defaults' => [
|
||||
'quietHours' => ['18:00-10:00'],
|
||||
'commented' => 'both',
|
||||
'assigned' => 'none',
|
||||
'mentioned' => 'none',
|
||||
'dailyBriefing' => false
|
||||
]
|
||||
];
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Enums;
|
||||
|
||||
enum SettingValues: string
|
||||
{
|
||||
case NONE = "none";
|
||||
case BOTH = "both";
|
||||
case EMAIL = "email";
|
||||
case BROADCAST = "broadcast";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Events;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use LucentNotifications\Models\Notification;
|
||||
|
||||
class NotificationsDispatcher
|
||||
{
|
||||
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
function __construct(public array $notifications)
|
||||
{
|
||||
collect($notifications)->map(function ($notification) {
|
||||
if (!$notification instanceof Notification) {
|
||||
throw new Exception("NotificationsDispatcsher only accepts an array of \LucentNotifications\Models\Notification on its constructor");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Events;
|
||||
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ReadNotification{
|
||||
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
function __construct(public string $notificationId)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Http\Controller;
|
||||
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use LucentNotifications\NotificationsRepo;
|
||||
|
||||
class NotificationsController{
|
||||
|
||||
function __construct()
|
||||
{
|
||||
ini_set('default_socket_timeout', -1);
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
|
||||
return response()->stream(function () {
|
||||
while (true) {
|
||||
Redis::subscribe(['user-channel-' . Session::get('user.id')], function (string $message) {
|
||||
|
||||
// Flush the output buffer
|
||||
$data = json_encode(['message' => $message]);
|
||||
|
||||
echo "data: $data\n\n";
|
||||
ob_flush();
|
||||
|
||||
flush();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}, 200, [
|
||||
'Cache-Control' => 'no-cache',
|
||||
'X-Accel-Buffering' => 'no',
|
||||
'Content-Type' => 'text/event-stream',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use LucentNotifications\Http\Controller\NotificationsController;
|
||||
|
||||
Route::group([
|
||||
'middleware' => ['web'],
|
||||
], function () {
|
||||
|
||||
Route::get('/broadcasting/notifications', [NotificationsController::class, 'index']);
|
||||
Route::get('/broadcasting/notifications/forUser', [NotificationsController::class, 'forUser']);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
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;
|
||||
|
||||
class PushNotifications implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
function __construct(private NotificationsRepo $repo, private UserRepo $userRepo, private SettingsService $settingsService) {}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Listeners;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use LucentNotifications\Events\ReadNotification;
|
||||
use LucentNotifications\NotificationsRepo;
|
||||
|
||||
class UpdateNotificationReadAt implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
function __construct(private NotificationsRepo $repo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function handle(ReadNotification $event)
|
||||
{
|
||||
$this->repo->updateReadAt($event->notificationId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications;
|
||||
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Hive\Hook\HookManager;
|
||||
use LucentNotifications\Events\NotificationsDispatcher;
|
||||
use LucentNotifications\Listeners\PushNotifications;
|
||||
use LucentNotifications\Services\NotificationService;
|
||||
|
||||
class LucentNotificationsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any package services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$hookManager = $this->app->make(HookManager::class);
|
||||
$hookManager->push("get-notifications", function (array $filters) {
|
||||
$notificationsService = new NotificationService;
|
||||
return $notificationsService->getForUser($filters);
|
||||
});
|
||||
|
||||
Event::listen(NotificationsDispatcher::class, PushNotifications::class);
|
||||
|
||||
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/Migrations/' => database_path('migrations'),
|
||||
]);
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/Config/notifications.php' => config_path('notifications.php'),
|
||||
],"notifications");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('notificationsSettings', function (Blueprint $table) {
|
||||
$table->uuid('userId')->primary();
|
||||
$table->text('data');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('notificationsSettings');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('notifications', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->string('type');
|
||||
$table->string('userIdFrom');
|
||||
$table->string('userIdTo');
|
||||
$table->text('data');
|
||||
$table->timestamp('readAt')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('notifications');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Support\Str;
|
||||
use stdClass;
|
||||
|
||||
class Notification
|
||||
{
|
||||
|
||||
public ?string $mailClass = null;
|
||||
|
||||
public bool $broadcast = true;
|
||||
|
||||
|
||||
function __construct(
|
||||
public string $id,
|
||||
public array $data,
|
||||
public string $userIdFrom,
|
||||
public string $userIdTo,
|
||||
public ?string $type,
|
||||
public Carbon $created_at,
|
||||
public Carbon $updated_at,
|
||||
public ?Carbon $read_at,
|
||||
) {}
|
||||
|
||||
public function toDB()
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'data' => json_encode($this->data),
|
||||
'userIdFrom' => $this->userIdFrom,
|
||||
'userIdTo' => $this->userIdTo,
|
||||
'type' => $this->type,
|
||||
"created_at" => $this->created_at,
|
||||
"updated_at" => $this->updated_at,
|
||||
"read_at" => $this->read_at
|
||||
];
|
||||
}
|
||||
|
||||
static function fromDB(stdClass $data)
|
||||
{
|
||||
return new Notification(
|
||||
id: $data->id,
|
||||
data: json_decode($data->data, true),
|
||||
userIdFrom: $data->userIdFrom,
|
||||
userIdTo: $data->userIdTo,
|
||||
type: $data->type,
|
||||
created_at: Carbon::parse($data->created_at),
|
||||
updated_at: Carbon::parse($data->updated_at),
|
||||
read_at: Carbon::parse($data->read_at)
|
||||
);
|
||||
}
|
||||
|
||||
static function create(array $data, string $userIdFrom, string $userIdTo, string $type, ?string $mailClass = null, ?bool $broadcast = true)
|
||||
{
|
||||
$notification = new Notification(
|
||||
id: (string) Str::uuid(),
|
||||
data: $data,
|
||||
userIdFrom: $userIdFrom,
|
||||
userIdTo: $userIdTo,
|
||||
type: $type,
|
||||
created_at: Carbon::now(),
|
||||
updated_at: Carbon::now(),
|
||||
read_at: null
|
||||
);
|
||||
if ($mailClass) {
|
||||
if (!class_exists($mailClass)){
|
||||
throw new Exception("\$mailClass accepts only mailable class-strings");
|
||||
}
|
||||
$notification->mailClass = $mailClass;
|
||||
}
|
||||
if (!$broadcast) {
|
||||
$notification->broadcast = false;
|
||||
}
|
||||
return $notification;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Models;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use LucentNotifications\Enums\SettingValues;
|
||||
|
||||
class NotificationsSettings
|
||||
{
|
||||
|
||||
function __construct(
|
||||
public ?SettingValues $mentioned,
|
||||
public ?SettingValues $commented,
|
||||
public ?SettingValues $assigned,
|
||||
) {}
|
||||
|
||||
function toDB()
|
||||
{
|
||||
return json_encode([
|
||||
'mentioned' => $this->mentioned,
|
||||
'commented' => $this->commented,
|
||||
'assigned' => $this->assigned,
|
||||
]);
|
||||
}
|
||||
|
||||
static function fromDB($data)
|
||||
{
|
||||
$decoded = json_decode($data, true);
|
||||
return new NotificationsSettings(
|
||||
mentioned: SettingValues::from($decoded['mentioned'] ?? 'none'),
|
||||
commented: SettingValues::from($decoded['commented'] ?? 'none'),
|
||||
assigned: SettingValues::from($decoded['assigned'] ?? 'none')
|
||||
);
|
||||
}
|
||||
|
||||
static function fromArray($data)
|
||||
{
|
||||
return new NotificationsSettings(
|
||||
mentioned: SettingValues::from($data['mentioned'] ?? "none") ,
|
||||
commented: SettingValues::from($data['commented'] ?? "none"),
|
||||
assigned: SettingValues::from($data['assigned'] ?? "none")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Models;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class QuietHourSection{
|
||||
public Carbon $from;
|
||||
public Carbon $to;
|
||||
function __construct(
|
||||
string $item
|
||||
)
|
||||
{
|
||||
[$from, $to] = explode("-",$item);
|
||||
$this->from = Carbon::parse($from);
|
||||
$this->to = Carbon::parse($to);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace LucentNotifications\Models;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use LucentNotifications\Enums\SettingValues;
|
||||
|
||||
class UserPreferences
|
||||
{
|
||||
|
||||
function __construct(
|
||||
public ?bool $dailyBriefing,
|
||||
public ?Collection $quietHours
|
||||
) {}
|
||||
|
||||
function toDB()
|
||||
{
|
||||
return json_encode([
|
||||
'dailyBriefing' => $this->dailyBriefing,
|
||||
'quietHours' => $this->quietHours
|
||||
]);
|
||||
}
|
||||
|
||||
static function fromDB($data)
|
||||
{
|
||||
$decoded = json_decode($data, true);
|
||||
return new UserPreferences(
|
||||
dailyBriefing: $decoded['dailyBriefing'],
|
||||
quietHours: new Collection($decoded['quietHours'])
|
||||
);
|
||||
}
|
||||
|
||||
static function fromArray($data)
|
||||
{
|
||||
return new UserPreferences(
|
||||
dailyBriefing: $data['dailyBriefing'] ?? null,
|
||||
quietHours: new Collection($data['quietHours'] ?? null)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace LucentNotifications\Models;
|
||||
|
||||
class UserSettings
|
||||
{
|
||||
|
||||
function __construct(
|
||||
public string $userId,
|
||||
public NotificationsSettings $notificationsSettings,
|
||||
public UserPreferences $userPreferences
|
||||
) {}
|
||||
|
||||
function toDB()
|
||||
{
|
||||
return [
|
||||
'userId' => $this->userId,
|
||||
'notificationsSettings' => $this->notificationsSettings->toDB(),
|
||||
'userPreferences' => $this->userPreferences->toDB()
|
||||
];
|
||||
}
|
||||
|
||||
static function fromDB($data)
|
||||
{
|
||||
if (!$data){
|
||||
return null;
|
||||
}
|
||||
return new UserSettings(
|
||||
userId: $data->userId,
|
||||
notificationsSettings: NotificationsSettings::fromDB($data->notificationsSettings),
|
||||
userPreferences: UserPreferences::fromDB($data->userPreferences)
|
||||
);
|
||||
}
|
||||
|
||||
static function fromArray($userId, $data)
|
||||
{
|
||||
return new UserSettings(
|
||||
userId: $userId,
|
||||
notificationsSettings: NotificationsSettings::fromArray($data['notificationsSettings']),
|
||||
userPreferences: UserPreferences::fromArray($data['userPreferences'])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Repos;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Lucent\Database\Database;
|
||||
|
||||
class NotificationsRepo {
|
||||
|
||||
|
||||
private function database(){
|
||||
return Database::make()->table('notifications');
|
||||
}
|
||||
|
||||
public function getById($id){
|
||||
return $this->database()->where('id', $id)->get();
|
||||
}
|
||||
|
||||
public function getForUser($userId, $filters){
|
||||
$query = $this->database()->where('userIdTo', $userId)->orderBy('created_at', 'desc')->get();
|
||||
$query = $this->parseFilters($query, $filters);
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
public function getUnreadForUser($userId, $filters){
|
||||
$query = $this->database()->where('userIdTo', $userId)->orderBy('created_at', 'desc')->where('read_at', null);
|
||||
$query = $this->parseFilters($query, $filters);
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
public function create(array $data)
|
||||
{
|
||||
$this->database()->insert($data);
|
||||
}
|
||||
|
||||
public function updateReadAt(string $notificationId)
|
||||
{
|
||||
$this->database()->where('id', $notificationId)->update(['read_at' => Carbon::now()]);
|
||||
}
|
||||
|
||||
private function parseFilters($query, $filters)
|
||||
{
|
||||
foreach ($filters as $key => $value) {
|
||||
$query = $query->where($key, $value);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Repos;
|
||||
|
||||
use Lucent\Database\Database;
|
||||
|
||||
class SettingsRepo
|
||||
{
|
||||
|
||||
private function database()
|
||||
{
|
||||
return Database::make()->table('userSettings');
|
||||
}
|
||||
|
||||
public function getForUser($userId)
|
||||
{
|
||||
return $this->database()->where('userId', $userId)->get()->first();
|
||||
}
|
||||
|
||||
public function upsert(string $userId, array $data)
|
||||
{
|
||||
$this->database()->upsert(
|
||||
[
|
||||
'userId' => $userId,
|
||||
'notificationsSettings' => json_encode($data['notificationsSettings']),
|
||||
'userPreferences' => json_encode($data['userPreferences'])
|
||||
],
|
||||
['userId'],
|
||||
['notificationsSettings', 'userPreferences']
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace LucentNotifications\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use LucentNotifications\Repos\SettingsRepo;
|
||||
use LucentNotifications\Models\UserSettings;
|
||||
|
||||
class SettingsService
|
||||
{
|
||||
function __construct(private SettingsRepo $repo) {}
|
||||
|
||||
function getForUser(string $userId)
|
||||
{
|
||||
$userSettings = UserSettings::fromArray($userId, json_decode(Redis::get("users.$userId.settings"), true));
|
||||
$userSettings = null;
|
||||
if (!$userSettings) {
|
||||
$userSettings = UserSettings::fromDB($this->repo->getForUser($userId)) ?? null;
|
||||
if (!$userSettings) {
|
||||
$userSettings = UserSettings::fromArray($userId, config('notifications'));
|
||||
}
|
||||
Redis::set("users.$userId.settings", json_encode($userSettings));
|
||||
}
|
||||
return $userSettings;
|
||||
}
|
||||
|
||||
function updateForUser(string $userId, array $settings)
|
||||
{
|
||||
$this->repo->upsert($userId, $settings);
|
||||
Redis::set("users.$userId.settings", json_encode($settings));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user