100 lines
2.6 KiB
PHP
100 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Notifications;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Notifications\Notification;
|
|
|
|
abstract class MobileNotification extends Notification implements ShouldQueue
|
|
{
|
|
use Queueable;
|
|
|
|
public const array TYPES = [
|
|
'certification_approved',
|
|
'certification_rejected',
|
|
'engagement_reminder',
|
|
'meal_commented',
|
|
'new_follower',
|
|
'payment_failed',
|
|
];
|
|
|
|
protected const string CATEGORY_ACCOUNT = 'account';
|
|
|
|
protected const string CATEGORY_ENGAGEMENT = 'engagement';
|
|
|
|
protected const string CATEGORY_SOCIAL = 'social';
|
|
|
|
public function __construct()
|
|
{
|
|
$this->afterCommit();
|
|
}
|
|
|
|
/** @return list<string> */
|
|
public function via(object $notifiable): array
|
|
{
|
|
if ($this->category() === self::CATEGORY_ENGAGEMENT
|
|
&& $notifiable instanceof User
|
|
&& ! $notifiable->engagement_reminders_enabled) {
|
|
return [];
|
|
}
|
|
|
|
$channels = ['database'];
|
|
|
|
if ($this->shouldSendPush($notifiable)) {
|
|
$channels[] = 'expo';
|
|
}
|
|
|
|
return $channels;
|
|
}
|
|
|
|
/** @return array<string, mixed> */
|
|
public function toDatabase(object $notifiable): array
|
|
{
|
|
return [
|
|
...$this->payload($notifiable),
|
|
'category' => $this->category(),
|
|
];
|
|
}
|
|
|
|
public function databaseType(object $notifiable): string
|
|
{
|
|
return $this->payload($notifiable)['type'];
|
|
}
|
|
|
|
/** @return array<string, mixed> */
|
|
public function toExpoPush(object $notifiable): array
|
|
{
|
|
$payload = $this->payload($notifiable);
|
|
|
|
return [
|
|
'title' => $payload['title'],
|
|
'body' => $payload['body'],
|
|
'sound' => 'default',
|
|
'channelId' => 'default',
|
|
'data' => [
|
|
'type' => $payload['type'],
|
|
'url' => $payload['url'],
|
|
...($this->id ? ['notificationId' => $this->id] : []),
|
|
...($payload['data'] ?? []),
|
|
],
|
|
];
|
|
}
|
|
|
|
abstract protected function category(): string;
|
|
|
|
/** @return array{type: string, title: string, body: string, url: string, data?: array<string, mixed>} */
|
|
abstract protected function payload(object $notifiable): array;
|
|
|
|
private function shouldSendPush(object $notifiable): bool
|
|
{
|
|
if (! $notifiable instanceof User) {
|
|
return false;
|
|
}
|
|
|
|
return $this->category() !== self::CATEGORY_SOCIAL
|
|
|| $notifiable->social_notifications_enabled;
|
|
}
|
|
}
|