aboutcoders/notification-bundle
Symfony bundle extending SonataNotificationBundle with process control for starting/stopping notification/message processing, ideal for CI environments. Integrates with AbcProcessControlBundle to manage workers and execution flow during builds and tests.
Install Dependencies:
composer require aboutcoders/process-control-bundle sonata-project/notification-bundle aboutcoders/notification-bundle
Ensure AbcProcessControlBundle and SonataNotificationBundle are registered in config/bundles.php.
Extend Your Notification Bundle:
Replace your existing MySonataNotificationBundle (extending SonataNotificationBundle) with:
use Abc\Bundle\NotificationBundle\AbcNotificationBundle;
class MySonataNotificationBundle extends AbcNotificationBundle
{
// Override methods as needed
}
Configure Process Control:
Add to config/packages/abc_process_control.yaml:
abc_process_control:
processes:
notification_worker:
command: 'app:notification:worker'
enabled: true # Set to false in CI/CD
First Use Case: Trigger a notification via a command or event listener:
use Sonata\NotificationBundle\Model\NotificationInterface;
$notification = $this->get('sonata.notification.manager')->create();
$notification->setType('email');
$this->get('sonata.notification.manager')->send($notification);
CI/CD Integration:
Disable the notification worker in CI by setting enabled: false in abc_process_control.yaml. Re-enable in production:
# config/packages/prod/abc_process_control.yaml
abc_process_control:
processes:
notification_worker:
enabled: true
Event-Driven Notifications:
Listen to domain events (e.g., UserRegisteredEvent) and dispatch notifications:
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NotificationSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'user.registered' => 'onUserRegistered',
];
}
public function onUserRegistered(UserRegisteredEvent $event)
{
$notification = $this->get('sonata.notification.manager')->create();
$notification->setType('email')
->setFrom('noreply@example.com')
->setTo($event->getUser()->getEmail())
->setSubject('Welcome!');
$this->get('sonata.notification.manager')->send($notification);
}
}
Bulk Processing: Use the worker to process queued notifications asynchronously:
php bin/console app:notification:worker
Configure the worker in config/packages/abc_notification.yaml:
abc_notification:
worker:
batch_size: 50 # Process 50 notifications per batch
delay: 300 # Delay between batches (ms)
Custom Notification Types:
Extend SonataNotificationBundle's notification types (e.g., SMS, Push) and integrate with AbcNotificationBundle:
use Sonata\NotificationBundle\Model\NotificationTypeInterface;
class SmsNotificationType implements NotificationTypeInterface
{
public function send(NotificationInterface $notification)
{
// Custom SMS logic
}
}
Register in services.yaml:
services:
app.sms_notification.type:
class: App\Notification\SmsNotificationType
tags:
- { name: sonata.notification.type, type: 'sms' }
Bundle Inheritance:
AbcNotificationBundle instead of SonataNotificationBundle will break process control.AbcNotificationBundle and not SonataNotificationBundle directly.Worker Configuration:
abc_process_control.yaml (e.g., wrong command name) will prevent the worker from starting.app:notification:worker command in config/packages/abc_process_control.yaml.CI/CD Conflicts:
enabled: false for the notification_worker in CI environments.Notification Queuing:
Worker Logs: Enable debug mode for the worker to log processed notifications:
abc_notification:
worker:
debug: true
Check logs at var/log/notification_worker.log.
Process Control: Manually start/stop the worker for debugging:
# Start worker
php bin/console abc:process-control:start notification_worker
# Stop worker
php bin/console abc:process-control:stop notification_worker
Database Locks:
notification table can block the worker.DELETE FROM notification WHERE status = 'pending' AND locked_at < NOW() - INTERVAL '1 hour';
Custom Worker Logic: Override the worker command to add pre/post-processing:
use Abc\Bundle\NotificationBundle\Command\NotificationWorkerCommand;
class CustomNotificationWorkerCommand extends NotificationWorkerCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
// Custom logic before processing
parent::execute($input, $output);
// Custom logic after processing
}
}
Register the command in services.yaml:
services:
app.notification.worker.command:
class: App\Command\CustomNotificationWorkerCommand
tags: ['console.command']
Dynamic Process Control:
Use the AbcProcessControlBundle's API to enable/disable the worker dynamically:
$this->get('abc_process_control.process_manager')->setEnabled('notification_worker', true);
Notification Prioritization:
Extend the NotificationInterface to add priority fields and filter in the worker:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Notification implements NotificationInterface
{
/**
* @ORM\Column(type="integer")
*/
private $priority = 1; // 1=low, 5=high
}
Update the worker to process high-priority notifications first:
// In CustomNotificationWorkerCommand
$notifications = $this->getDoctrine()
->getRepository(Notification::class)
->findBy(['status' => 'pending'], ['priority' => 'DESC']);
How can I help you explore Laravel packages today?