PHP code example of andydefer / laravel-notification
1. Go to this page and download the library: Download andydefer/laravel-notification library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
andydefer / laravel-notification example snippets
namespace App\Models;
use AndyDefer\LaravelNotification\Contracts\NotifiableInterface;
use AndyDefer\LaravelNotification\Collections\NotificationRouteCollection;
use AndyDefer\LaravelNotification\ValueObjects\NotificationRouteVO;
use AndyDefer\LaravelNotification\Channels\MailChannel;
use AndyDefer\LaravelNotification\Channels\DatabaseChannel;
use AndyDefer\LaravelNotification\Channels\PusherChannel;
use AndyDefer\LaravelNotification\Channels\WebPushChannel;
use AndyDefer\LaravelNotification\Channels\FirebaseCloudMessagingChannel;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements NotifiableInterface
{
public function getNotificationChannels(): NotificationRouteCollection
{
$collection = new NotificationRouteCollection;
// ✅ Email principal
if ($this->email_primary) {
$collection->add(new NotificationRouteVO(
channelClass: MailChannel::class,
destination: $this->email_primary,
metadata: new StrictDataObject(['type' => 'primary'])
));
}
// ✅ Email secondaire
if ($this->email_secondary) {
$collection->add(new NotificationRouteVO(
channelClass: MailChannel::class,
destination: $this->email_secondary,
metadata: new StrictDataObject(['type' => 'secondary'])
));
}
// ✅ Pusher (temps réel)
$collection->add(new NotificationRouteVO(
channelClass: PusherChannel::class,
destination: "private-user.{$this->id}",
metadata: new StrictDataObject(['event' => 'notification.received'])
));
// ✅ Web Push (navigateur)
foreach ($this->webPushSubscriptions as $subscription) {
$collection->add(new NotificationRouteVO(
channelClass: WebPushChannel::class,
destination: $subscription->endpoint,
metadata: new StrictDataObject([
'endpoint' => $subscription->endpoint,
'p256dh' => $subscription->p256dh,
'auth' => $subscription->auth,
])
));
}
// ✅ FCM (mobile)
foreach ($this->fcmDevices as $device) {
$collection->add(new NotificationRouteVO(
channelClass: FirebaseCloudMessagingChannel::class,
destination: $device->token,
metadata: new StrictDataObject([
'type' => 'fcm',
'device_id' => $device->device_id,
])
));
}
// ✅ Base de données (traçabilité)
$collection->add(new NotificationRouteVO(
channelClass: DatabaseChannel::class,
destination: 'database'
));
return $collection;
}
public function getMorphClass(): string
{
return 'user';
}
public function getKey(): int
{
return $this->id;
}
}
new NotificationRouteVO(
channelClass: MailChannel::class,
destination: '[email protected]',
metadata: new StrictDataObject(['type' => 'primary'])
);
use AndyDefer\LaravelNotification\Services\NotificationService;
use AndyDefer\LaravelNotification\Records\SendNowRecord;
use AndyDefer\LaravelNotification\ValueObjects\NotificationMessageVO;
use AndyDefer\LaravelNotification\ValueObjects\MessageBodyVO;
use AndyDefer\LaravelNotification\ValueObjects\MessageSubjectVO;
use AndyDefer\LaravelNotification\Channels\MailChannel;
use AndyDefer\LaravelNotification\Channels\PusherChannel;
use AndyDefer\DomainStructures\Utils\StrictDataObject;
class UserController extends Controller
{
public function __construct(
private readonly NotificationService $service
) {}
public function welcome(User $user)
{
$message = new NotificationMessageVO(
body: new MessageBodyVO('<h1>Bonjour !</h1><p>Bienvenue sur notre plateforme.</p>'),
subject: new MessageSubjectVO('Bienvenue !'),
type: 'welcome',
data: new StrictDataObject(['user_id' => $user->id])
);
$record = SendNowRecord::from([
'channels' => [MailChannel::class, PusherChannel::class],
'limit_per_channel' => 1,
]);
$results = $this->service->sendNow($user, $message, $record);
return response()->json([
'success' => $results->allSuccess(),
'sent' => $results->getSuccessCount(),
'failed' => $results->getFailureCount(),
]);
}
}
class TaskManager
{
public function __construct(
private readonly NotificationService $service
) {}
public function pause(string $alias): bool
{
return $this->service->pause($alias);
}
public function resume(string $alias): bool
{
return $this->service->resume($alias);
}
public function changeInterval(string $alias, int $newIntervalSeconds): bool
{
return $this->service->changeInterval($alias, $newIntervalSeconds);
}
public function cancel(string $alias): bool
{
return $this->service->cancel($alias);
}
}
interface PingPongInterface
{
public function ping(Model $notifiable): PingStatus;
public function isAlive(Model $notifiable): bool;
public function pingOrPrune(Model $notifiable): PingStatus;
}
enum PingStatus: string
{
case PONG = 'pong';
case INVALID = 'invalid';
public function isPong(): bool;
public function isInvalid(): bool;
}
final class FcmDevice extends Model implements NotifiableInterface, PingableInterface
{
use HasPingPong;
// ...
}
final class WebPushSubscription extends Model implements NotifiableInterface, PingableInterface
{
use HasPingPong;
// ...
}
final class PingPongAdapter
{
private const HELPERS = [
FcmDevice::class => FcmPingPong::class,
WebPushSubscription::class => WebPushPingPong::class,
];
public function for(Model $model): PingPongInterface;
}
// Vérifier une cible
if ($subscription->isAlive()) {
// Toujours joignable
}
// Vérifier et supprimer si invalide
$status = $subscription->pingOrPrune();
if ($status->isInvalid()) {
logger()->info('Subscription pruned', ['id' => $subscription->id]);
}
class DiscordDriver extends AbstractDriver
{
public function __construct(private readonly array $config) {}
public function getChannel(): string
{
return 'discord';
}
public function validateConfiguration(): bool
{
return !empty($this->config['webhook_url']);
}
protected function execute(
NotificationMessageVO $message,
NotificationRouteVO $route
): bool {
$webhookUrl = $route->getMetadata()?->get('webhook_url')
?? $this->config['webhook_url'];
$response = Http::post($webhookUrl, [
'content' => $message->getBodyValue(),
]);
if (!$response->successful()) {
throw new RuntimeException('Discord API error: ' . $response->body());
}
return true;
}
}
class DiscordChannel extends AbstractChannel
{
public function getName(): string { return 'discord'; }
public function getLabel(): string { return 'Discord'; }
public function getIcon(): string { return '🎮'; }
public function isEnabled(): bool
{
return $this->configRepository->get('notification.channels.discord.enabled', false);
}
public function getConfig(): AbstractRecord
{
return DiscordConfigRecord::from(
$this->configRepository->get('notification.channels.discord', [])
);
}
public function createDriver(): AbstractDriver
{
return new DiscordDriver($this->getConfig()->toArray());
}
public static function validateDestination(string $destination): bool
{
return filter_var($destination, FILTER_VALIDATE_URL) !== false
&& str_contains($destination, 'discord.com/api/webhooks');
}
}
final class DiscordConfigRecord extends AbstractRecord
{
public function __construct(
public readonly bool $enabled = false,
public readonly ?string $webhook_url = null,
) {}
}
class Doctor extends Model implements NotifiableInterface
{
public function getNotificationChannels(): NotificationRouteCollection
{
$collection = new NotificationRouteCollection;
if ($this->email_professional) {
$collection->add(new NotificationRouteVO(
MailChannel::class,
$this->email_professional,
new StrictDataObject(['priority' => 'high'])
));
}
if ($this->email_personal) {
$collection->add(new NotificationRouteVO(
MailChannel::class,
$this->email_personal,
new StrictDataObject(['priority' => 'low'])
));
}
$collection->add(new NotificationRouteVO(
DatabaseChannel::class,
'database'
));
return $collection;
}
}
class Order extends Model implements NotifiableInterface
{
public function getNotificationChannels(): NotificationRouteCollection
{
$collection = new NotificationRouteCollection;
$collection->add(new NotificationRouteVO(MailChannel::class, $this->customer_email));
$collection->add(new NotificationRouteVO(PusherChannel::class, "private-order.{$this->id}"));
foreach ($this->customer->webPushSubscriptions as $subscription) {
$collection->add(new NotificationRouteVO(
WebPushChannel::class,
$subscription->endpoint,
new StrictDataObject([
'endpoint' => $subscription->endpoint,
'p256dh' => $subscription->p256dh,
'auth' => $subscription->auth,
])
));
}
foreach ($this->customer->fcmDevices as $device) {
$collection->add(new NotificationRouteVO(
FirebaseCloudMessagingChannel::class,
$device->token,
new StrictDataObject([
'device_id' => $device->device_id,
])
));
}
return $collection;
}
}
$message = new NotificationMessageVO(
body: new MessageBodyVO('Votre commande a été expédiée.'),
subject: new MessageSubjectVO('Commande expédiée'),
type: 'order_shipped',
data: new StrictDataObject(['order_id' => 42, 'url' => '/orders/42']),
);
$record = SendNowRecord::from([
'channels' => [
PusherChannel::class,
WebPushChannel::class,
FirebaseCloudMessagingChannel::class,
DatabaseChannel::class,
],
'limit_per_channel' => 1,
]);
$results = $service->sendNow($order->customer, $message, $record);
class UserController extends Controller
{
public function __construct(
private readonly NotificationService $service
) {}
}
if ($this->email) {
$collection->add(new NotificationRouteVO(MailChannel::class, $this->email));
}