70
common/Notifications/ContactPageMessage.php
Executable file
70
common/Notifications/ContactPageMessage.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use Common\Settings\Settings;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class ContactPageMessage extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public function __construct(public $message)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
$siteName = app(Settings::class)->get('branding.site_name');
|
||||
$userEmail = $this->message['email'];
|
||||
|
||||
return (new MailMessage())
|
||||
->subject(
|
||||
__('New message via :siteName contact page.', [
|
||||
'siteName' => $siteName,
|
||||
]),
|
||||
)
|
||||
->greeting(
|
||||
__("New message via :siteName contact page from ':userEmail'", [
|
||||
'siteName' => $siteName,
|
||||
'userEmail' => $userEmail,
|
||||
]),
|
||||
)
|
||||
->salutation(' ')
|
||||
->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->replyTo($userEmail, $this->message['name'])
|
||||
->line($this->message['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
48
common/Notifications/ErrorNotification.php
Executable file
48
common/Notifications/ErrorNotification.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class ErrorNotification extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['database'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
$config = $this->config;
|
||||
if ( ! Arr::get($config, 'image')) {
|
||||
$config['image'] = 'error-outline';
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
44
common/Notifications/GetsUserPreferredChannels.php
Executable file
44
common/Notifications/GetsUserPreferredChannels.php
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use NotificationChannels\Fcm\FcmChannel;
|
||||
|
||||
trait GetsUserPreferredChannels
|
||||
{
|
||||
/**
|
||||
* @param User $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable): array
|
||||
{
|
||||
if (!config('common.site.notif_subs_integrated')) {
|
||||
return ['database', 'mail'];
|
||||
}
|
||||
|
||||
$channels = [];
|
||||
if (
|
||||
$sub = $notifiable->notificationSubscriptions
|
||||
->where('notif_id', static::NOTIF_ID)
|
||||
->first()
|
||||
) {
|
||||
foreach (array_filter($sub->channels) as $channel => $isSelected) {
|
||||
if ($channel === 'browser') {
|
||||
$channels = array_merge($channels, [
|
||||
'database',
|
||||
'broadcast',
|
||||
]);
|
||||
} elseif ($channel === 'email') {
|
||||
$channels[] = 'mail';
|
||||
} elseif ($channel === 'mobile') {
|
||||
$channels[] = FcmChannel::class;
|
||||
} else {
|
||||
$channels[] = $channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
}
|
||||
59
common/Notifications/NotificationController.php
Executable file
59
common/Notifications/NotificationController.php
Executable file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use Auth;
|
||||
use Common\Core\BaseController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Notifications\DatabaseNotification;
|
||||
|
||||
class NotificationController extends BaseController
|
||||
{
|
||||
public function __construct(
|
||||
protected DatabaseNotification $notification,
|
||||
protected Request $request,
|
||||
) {
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$pagination = Auth::user()
|
||||
->notifications()
|
||||
->simplePaginate(request('perPage', 10));
|
||||
|
||||
return $this->success(['pagination' => $pagination]);
|
||||
}
|
||||
|
||||
public function markAsRead()
|
||||
{
|
||||
$data = $this->validate($this->request, [
|
||||
'ids' => 'array|required_without:markAllAsUnread',
|
||||
'markAllAsUnread' => 'boolean|required_without:ids',
|
||||
]);
|
||||
|
||||
Auth::user()
|
||||
->unreadNotifications()
|
||||
->when(
|
||||
isset($data['ids']),
|
||||
fn($q) => $q->whereIn('id', $data['ids']),
|
||||
)
|
||||
->update(['read_at' => now()]);
|
||||
|
||||
$unreadCount = Auth::user()
|
||||
->unreadNotifications()
|
||||
->count();
|
||||
|
||||
return $this->success(['unreadCount' => $unreadCount, 'date' => now()]);
|
||||
}
|
||||
|
||||
public function destroy($ids)
|
||||
{
|
||||
$ids = explode(',', $ids);
|
||||
Auth::user()
|
||||
->notifications()
|
||||
->whereIn('id', $ids)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
28
common/Notifications/NotificationSubscription.php
Executable file
28
common/Notifications/NotificationSubscription.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class NotificationSubscription extends Model
|
||||
{
|
||||
protected $guarded = ['id'];
|
||||
protected $keyType = 'string';
|
||||
public $timestamps = false;
|
||||
public $incrementing = false;
|
||||
|
||||
protected $casts = [
|
||||
'user_id' => 'integer',
|
||||
'channels' => 'array',
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function (Model $model) {
|
||||
$model->setAttribute($model->getKeyName(), Uuid::uuid4());
|
||||
});
|
||||
}
|
||||
}
|
||||
100
common/Notifications/NotificationSubscriptionsController.php
Executable file
100
common/Notifications/NotificationSubscriptionsController.php
Executable file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use Common\Core\BaseController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class NotificationSubscriptionsController extends BaseController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(['auth']);
|
||||
}
|
||||
|
||||
public function index(User $user): JsonResponse
|
||||
{
|
||||
$response = $this->getConfig();
|
||||
|
||||
// filter out notifications user does not have permission for
|
||||
$response['subscriptions'] = collect($response['subscriptions'])
|
||||
->map(function ($group) use ($user) {
|
||||
$group['subscriptions'] = collect($group['subscriptions'])
|
||||
->filter(function ($subscription) use ($user) {
|
||||
if (!isset($subscription['permissions'])) {
|
||||
return true;
|
||||
}
|
||||
return collect($subscription['permissions'])->every(
|
||||
fn($permission) => $user->hasPermission(
|
||||
$permission,
|
||||
),
|
||||
);
|
||||
})
|
||||
->values()
|
||||
->toArray();
|
||||
return $group;
|
||||
})
|
||||
->filter(fn($group) => count($group['subscriptions']))
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
$subs = $user->notificationSubscriptions;
|
||||
$response['user_selections'] = $subs;
|
||||
|
||||
return $this->success($response);
|
||||
}
|
||||
|
||||
public function update(User $user): JsonResponse
|
||||
{
|
||||
$data = $this->validate(request(), [
|
||||
'selections' => 'present|array',
|
||||
'selections.*.notif_id' => 'required|string',
|
||||
'selections.*.channels' => 'required|array',
|
||||
]);
|
||||
|
||||
$allConfig = collect($this->getConfig()['subscriptions'])->flatMap(
|
||||
fn($group) => $group['subscriptions'],
|
||||
);
|
||||
|
||||
foreach ($data['selections'] as $selection) {
|
||||
// check if user has permissions to subscribe to this notification
|
||||
$config = $allConfig->firstWhere(
|
||||
'notif_id',
|
||||
$selection['notif_id'],
|
||||
);
|
||||
if (isset($config['permissions'])) {
|
||||
$hasAllPermissions = collect($config['permissions'])->every(
|
||||
fn($permission) => $user->hasPermission($permission),
|
||||
);
|
||||
if (!$hasAllPermissions) {
|
||||
return $this->error(
|
||||
'You do not have permission to subscribe to one of these notifications.',
|
||||
[],
|
||||
403,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$subscription = $user
|
||||
->notificationSubscriptions()
|
||||
->firstOrNew(['notif_id' => $selection['notif_id']]);
|
||||
$newChannels = $subscription['channels'];
|
||||
// can update state of all channels at once or only a single channel
|
||||
foreach ($selection['channels'] as $newChannel => $isSubscribed) {
|
||||
$newChannels[$newChannel] = $isSubscribed;
|
||||
}
|
||||
$subscription->fill(['channels' => $newChannels])->save();
|
||||
}
|
||||
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
private function getConfig()
|
||||
{
|
||||
return File::getRequire(
|
||||
resource_path('defaults/notification-settings.php'),
|
||||
);
|
||||
}
|
||||
}
|
||||
41
common/Notifications/SubscribeUserToNotifications.php
Executable file
41
common/Notifications/SubscribeUserToNotifications.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Notifications;
|
||||
|
||||
use App\Models\User;
|
||||
use File;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class SubscribeUserToNotifications
|
||||
{
|
||||
public function execute(User $user, ?array $notificationIds)
|
||||
{
|
||||
$config = File::getRequire(
|
||||
resource_path('defaults/notification-settings.php'),
|
||||
);
|
||||
if (is_null($notificationIds)) {
|
||||
$notificationIds = collect($config['subscriptions'])
|
||||
->map(function ($group) {
|
||||
return collect($group['subscriptions'])->pluck('notif_id');
|
||||
})
|
||||
->flatten(1)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
$rows = array_map(function ($notifId) use ($config, $user) {
|
||||
return [
|
||||
'id' => Uuid::uuid4(),
|
||||
'notif_id' => $notifId,
|
||||
'channels' => json_encode(
|
||||
collect($config['available_channels'])->mapWithKeys(
|
||||
fn($channel) => [$channel => true],
|
||||
),
|
||||
),
|
||||
'user_id' => $user->id,
|
||||
];
|
||||
}, $notificationIds);
|
||||
|
||||
$user->notificationSubscriptions()->delete();
|
||||
$user->notificationSubscriptions()->insert($rows);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user