sonata-project/notification-bundle
Installation
composer require sonata-project/notification-bundle
Register the bundle in config/bundles.php:
return [
// ...
Sonata\NotificationBundle\SonataNotificationBundle::class => ['all' => true],
];
Database Setup
Run migrations (check vendor/sonata-project/notification-bundle/src/Resources/doc/index.md for schema):
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First Notification
Create a notification class (e.g., src/Notification/ExampleNotification.php):
namespace App\Notification;
use Sonata\NotificationBundle\Model\NotificationInterface;
class ExampleNotification implements NotificationInterface
{
public function getSubject(): string
{
return 'Hello!';
}
public function getMessage(): string
{
return 'This is your first notification.';
}
}
Send a Notification
Inject Sonata\NotificationBundle\Model\NotificationManagerInterface and use:
$notification = new ExampleNotification();
$notificationManager->send($notification, $recipientUser);
config/packages/sonata_notification.yaml (auto-generated).vendor/sonata-project/notification-bundle/src/Resources/doc/index.md for schema.vendor/sonata-project/notification-bundle/src/Notification/ for built-in templates.vendor/sonata-project/notification-bundle/Resources/views/ for email/notification layouts.AbstractNotification (recommended):
use Sonata\NotificationBundle\Notification\AbstractNotification;
class WelcomeNotification extends AbstractNotification
{
protected $subject = 'Welcome!';
protected $message = 'Thanks for joining!';
public function getRecipient(): ?UserInterface
{
return $this->getParameter('recipient'); // Set via send() method
}
}
$notification = new WelcomeNotification();
$notification->setParameter('recipient', $user);
$notificationManager->send($notification);
AbstractNotification for reusable templates:
class OrderConfirmationNotification extends AbstractNotification
{
protected $subject = 'Your order #%order_id% is confirmed';
protected $message = 'Thank you for your purchase!';
public function getRecipient(): ?UserInterface
{
return $this->getParameter('customer');
}
public function getParameters(): array
{
return [
'order_id' => $this->getParameter('order_id'),
];
}
}
getSubject()/getMessage() for dynamic content.getRecipient() to define who receives the notification.getParameters() to pass data to Twig templates.$notification = new CustomNotification();
$notification->setParameter('key', 'value');
$notificationManager->send($notification, $recipientUser);
$users = $userRepository->findByRole('admin');
foreach ($users as $user) {
$notificationManager->send($notification, $user);
}
$notificationManager->sendAsync($notification, $recipientUser);
templates/sonata_notification/ (e.g., email.html.twig).{% extends '@SonataNotification/email.html.twig' %}
{% block subject %}
{{ parent() }} - Custom Subject
{% endblock %}
sonata.notification.send event to modify notifications:
$eventDispatcher->addListener('sonata.notification.send', function (NotificationEvent $event) {
$event->getNotification()->setSubject('[URGENT] ' . $event->getNotification()->getSubject());
});
CronTrigger or SingleMessage for delayed sends:
$message = new SendNotificationMessage($notification, $recipient);
$bus->dispatch($message);
Service Container Integration
Bind the notification manager in config/services.php:
'SonataNotificationBundle' => [
'notification_manager' => \Sonata\NotificationBundle\Model\NotificationManager::class,
],
Resolve it in Laravel:
$notificationManager = app('SonataNotificationBundle.notification_manager');
Laravel Events Convert Symfony events to Laravel:
Event::listen('sonata.notification.send', function ($event) {
// Laravel logic here
});
Laravel Mail Integration
Override the transporter to use Laravel’s Mailer:
$notification->setTransporter(new LaravelMailTransporter(app('mailer')));
Laravel Queues Use Laravel queues for async sends:
$notificationManager->sendAsync($notification, $user)
->setQueue('notifications');
Notification entity is mapped.sonata.notification.admin to manage notifications via UI.# config/api_platform/resources.yaml
Sonata\NotificationBundle\Entity\Notification:
collectionOperations:
get: ~
itemOperations:
get: ~
Database Schema Mismatch
vendor/sonata-project/notification-bundle/src/Resources/doc/index.md before migrating.php artisan make:migration create_notifications_table --table=notification
Circular Dependencies in Notifications
A triggers B, which triggers A again) can cause infinite loops.sent_at check or use a NotificationSent event to track sent notifications.Transporter Configuration
$notification->setTransporter($container->get('sonata.notification.transporter.mail'));
Recipient Validation
if (!$recipientUser || !$recipientUser->isEnabled()) {
throw new \RuntimeException('Invalid recipient');
}
Async Send Quirks
$notificationManager->sendAsync($notification, $user)
->setRetryDelay(300); // 5 minutes
Enable Debug Mode
Set sonata_notification.debug: true in config to log sent notifications:
sonata_notification:
debug: true
Check the Notification Log
Query the notification table for sent/not-sent records:
SELECT * FROM notification WHERE recipient_id = ? AND sent_at IS NULL;
Twig Debugging Dump template variables:
{% dump notification.parameters %}
Event Listener Debugging Log events to understand the flow:
$eventDispatcher->addListener('sonata.notification.send', function (NotificationEvent $event) {
\Log::debug('Notification sent', ['subject' => $event->getNotification()->getSubject()]);
});
sonata_notification:
transporter:
mail:
service: sonata.notification.transporter.mail
from_email: 'no-reply@example.com'
How can I help you explore Laravel packages today?