Installation:
composer require ibexa/notifications
(Note: Requires Ibexa DXP as a dependency—install via Ibexa DXP docs)
Configuration:
Add to config/services.yaml (or equivalent Ibexa config):
ibexa:
notifier:
channels:
email:
transport: 'symfony://mailer.default'
# Add other channels (e.g., 'push', 'sms')
First Use Case: Trigger a notification via a service:
use Ibexa\Notifications\Notification\Notification;
use Ibexa\Notifications\Notification\NotificationFactory;
$notificationFactory = app(NotificationFactory::class);
$notification = $notificationFactory->create(
'user.registered',
['user' => $userData]
);
$notification->send();
NotificationFactory: Create typed notifications (e.g., user.registered, content.published).NotificationSender: Dispatch notifications to configured channels.NotificationTemplateResolver: Override default templates per notification type.Define Notification Types:
Extend Notification or use built-in types (e.g., SystemNotification, UserNotification).
class CustomNotification extends Notification
{
public function __construct(
public string $type,
public array $context = []
) {}
}
Channel Integration:
Register custom channels (e.g., Slack, Webhook) by implementing ChannelInterface:
use Ibexa\Notifications\Channel\ChannelInterface;
class SlackChannel implements ChannelInterface
{
public function send(Notification $notification): void
{
// Logic to send to Slack
}
}
Bind in DI container:
services:
Ibexa\Notifications\Channel\SlackChannel: ~
ibexa.notifier.channels.slack: '@SlackChannel'
Dynamic Templates:
Override templates via NotificationTemplateResolver:
use Ibexa\Notifications\Template\NotificationTemplateResolver;
class CustomTemplateResolver implements NotificationTemplateResolver
{
public function resolve(Notification $notification): string
{
return match ($notification->getType()) {
'user.registered' => 'emails/user_registered.twig',
default => 'emails/default.twig',
};
}
}
Event-Driven Triggers:
Listen for Ibexa events (e.g., ContentPublishEvent) to dispatch notifications:
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NotificationSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'Ibexa\Content\Event\ContentPublishEvent' => 'onContentPublish',
];
}
public function onContentPublish(ContentPublishEvent $event): void
{
$notification = app(NotificationFactory::class)->create(
'content.published',
['content' => $event->getContent()]
);
$notification->send();
}
}
NotificationType::USER_REGISTERED).NotificationSender in a queue job:
use Ibexa\Notifications\Notification\NotificationSender;
class SendNotificationJob implements ShouldQueue
{
public function handle(NotificationSender $sender, Notification $notification)
{
$sender->send($notification);
}
}
NotificationSender in unit tests:
$sender = $this->createMock(NotificationSender::class);
$sender->expects($this->once())->method('send');
Channel Configuration:
ibexa.notifier.channels.services.yaml includes all active channels (e.g., email, push).ibexa.notifier.channel_manager for registered channels.Template Resolution:
NotificationTemplateResolver and bind it as a service:
services:
Ibexa\Notifications\Template\CustomTemplateResolver: ~
ibexa.notifier.template_resolver: '@CustomTemplateResolver'
BC Breaks:
Async Delays:
$job->onQueue('notifications')->retryUntil(3600); // Retry for 1 hour
Log Notifications:
Decorate NotificationSender to log sent notifications:
class LoggingNotificationSender implements NotificationSender
{
public function __construct(private NotificationSender $decorated) {}
public function send(Notification $notification): void
{
\Log::info('Sent notification', ['type' => $notification->getType()]);
$this->decorated->send($notification);
}
}
Validate Payloads:
Use Notification::assertValid() to catch malformed data early:
$notification = $factory->create('invalid.type');
$notification->assertValid(); // Throws \InvalidArgumentException
Custom Channels:
Extend AbstractChannel for reusable logic (e.g., rate limiting, retry logic).
Notification Metadata:
Add metadata via Notification::setMetadata(['key' => 'value']) for tracking.
Template Inheritance:
Use Twig’s {% extends %} in custom templates to inherit from Ibexa’s base templates.
Testing:
Stub NotificationSender in PHPUnit:
$sender = $this->createMock(NotificationSender::class);
$sender->method('send')->willReturnCallback(fn($n) => $this->assertEquals('user.registered', $n->getType()));
How can I help you explore Laravel packages today?