Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Clarc Notification Bundle Laravel Package

artox-lab/clarc-notification-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require artox-lab/clarc-notification-bundle
    

    Enable the bundle in config/bundles.php:

    ArtoxLab\Bundle\ClarcNotificationBundle\ArtoxLabClarcNotificationBundle::class => ['all' => true],
    
  2. First Use Case: Create a custom notification entity (e.g., App\Entities\Notification\WelcomeNotification) extending the bundle’s base structure. Implement a presenter (e.g., App\Interfaces\Notification\WelcomeNotificationPresenter) to format the notification content.

    // ExampleNotification.php
    namespace App\Entities\Notification;
    use ArtoxLab\Bundle\ClarcNotificationBundle\Notification\Entities\Notification;
    
    class WelcomeNotification extends Notification {
        public function __construct(string $userName) {
            $this->setData(['user_name' => $userName]);
        }
    }
    

    Register the notification in your service container (e.g., via config/services.yaml):

    services:
        App\Interfaces\Notification\WelcomeNotificationPresenter:
            tags: ['clarc_notification.presenter']
    
  3. Send a Notification: Inject the NotifierInterface into a service and dispatch:

    use ArtoxLab\Bundle\ClarcNotificationBundle\Notification\Entities\Notifier\NotifierInterface;
    use ArtoxLab\Bundle\ClarcNotificationBundle\Notification\Entities\Recipient\EmailRecipient;
    
    class WelcomeService {
        public function __construct(private NotifierInterface $notifier) {}
    
        public function sendWelcomeEmail(string $email, string $userName) {
            $notification = new WelcomeNotification($userName);
            $recipient = new EmailRecipient($email);
            $this->notifier->notify($notification, $recipient);
        }
    }
    

Implementation Patterns

Core Workflow

  1. Notification Lifecycle:

    • Creation: Extend Notification or implement NotificationInterface with your data.
    • Presentation: Use presenters (tagged services) to format notifications for specific channels (e.g., email, SMS).
    • Dispatch: Inject NotifierInterface and call notify() with the notification and recipient(s).
  2. Recipient Handling:

    • Use built-in recipients (EmailRecipient, SmsRecipient) or create custom ones (e.g., SlackRecipient).
    • Recipients can be passed as arrays for batch notifications:
      $this->notifier->notify($notification, [$recipient1, $recipient2]);
      
  3. Transport Integration:

    • Implement TransportInterface for custom channels (e.g., Webhook, Push):
      class WebhookTransport implements TransportInterface {
          public function send(Notification $notification, RecipientInterface $recipient): void {
              // Logic to send via HTTP
          }
      }
      
    • Register transports in config/packages/clarc_notification.yaml:
      clarc_notification:
          transports:
              webhook: App\Transport\WebhookTransport
      
  4. Dependency Injection:

    • Use Symfony’s autowiring for presenters/transports. Tag services with:
      tags: ['clarc_notification.presenter', 'clarc_notification.transport']
      

Common Patterns

  • Event-Driven Notifications: Listen to domain events (e.g., UserRegisteredEvent) and dispatch notifications in event handlers:

    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class UserRegisteredSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [UserRegisteredEvent::class => 'onUserRegistered'];
        }
    
        public function onUserRegistered(UserRegisteredEvent $event) {
            $this->notifier->notify(new WelcomeNotification($event->getUserName()), new EmailRecipient($event->getEmail()));
        }
    }
    
  • Dynamic Recipients: Fetch recipients from a database or API and loop through them:

    foreach ($user->getSubscribedEmails() as $email) {
        $this->notifier->notify($notification, new EmailRecipient($email));
    }
    
  • Fallback Transports: Configure fallback transports in clarc_notification.yaml to retry failed deliveries:

    clarc_notification:
        transports:
            email:
                class: App\Transport\EmailTransport
                fallback: sms
    

Gotchas and Tips

Pitfalls

  1. Presenter Priority:

    • Presenters are resolved in the order they are tagged. Ensure the correct presenter is first for a given notification type.
    • Fix: Use explicit priority in tags:
      tags: ['clarc_notification.presenter', { priority: 10 }]
      
  2. Transport Configuration:

    • Transports must be properly registered in clarc_notification.yaml; otherwise, notifications will fail silently.
    • Debug: Check Symfony’s profiler for unresolved transports or use debug:container to verify service registration.
  3. Recipient Validation:

    • The bundle does not validate recipient formats (e.g., email/SMS syntax). Add validation in your transport or presenter:
      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
          throw new \InvalidArgumentException('Invalid email');
      }
      
  4. Circular Dependencies:

    • Avoid injecting NotifierInterface into presenters/transports to prevent circular dependencies. Use method injection or pass dependencies explicitly.
  5. Symfony 6+ Compatibility:

    • The bundle supports Symfony 6, but some older patterns (e.g., AppKernel) may cause issues. Use config/bundles.php as shown in the README.

Debugging Tips

  • Log Notifications: Enable debug logging in config/packages/dev/clarc_notification.yaml:

    clarc_notification:
        debug: true
    

    Logs will appear in var/log/dev.log.

  • Test Transports: Use a mock transport for testing:

    class MockTransport implements TransportInterface {
        public function send(Notification $notification, RecipientInterface $recipient): void {
            // Log or assert notification data
        }
    }
    

    Register it in config/packages/test/clarc_notification.yaml:

    clarc_notification:
        transports:
            mock: App\Transport\MockTransport
    
  • Profiler Integration: Install symfony/profiler-pack to inspect notification dispatches in the Symfony profiler.

Extension Points

  1. Custom Notification Types: Extend the base Notification class or implement NotificationInterface for domain-specific needs:

    interface NotificationInterface {
        public function getData(): array;
        public function getType(): string;
    }
    
  2. Channel-Specific Logic: Use presenters to add channel-specific logic (e.g., SMS character limits, email templates):

    class EmailPresenter implements PresenterInterface {
        public function present(Notification $notification): string {
            return $this->twig->render('emails/welcome.html.twig', $notification->getData());
        }
    }
    
  3. Async Processing: Integrate with Symfony Messenger or a queue system (e.g., RabbitMQ) to process notifications asynchronously:

    use Symfony\Component\Messenger\MessageBusInterface;
    
    class AsyncNotifier {
        public function __construct(private MessageBusInterface $bus) {}
    
        public function notify(Notification $notification, RecipientInterface $recipient) {
            $this->bus->dispatch(new NotificationMessage($notification, $recipient));
        }
    }
    
  4. Rate Limiting: Implement a decorator around NotifierInterface to enforce rate limits:

    class RateLimitedNotifier implements NotifierInterface {
        public function notify(Notification $notification, RecipientInterface $recipient): void {
            if ($this->isRateLimited($recipient)) {
                throw new \RuntimeException('Rate limit exceeded');
            }
            $this->decoratedNotifier->notify($notification, $recipient);
        }
    }
    
  5. Localization: Use Symfony’s translation system in presenters to support multiple languages:

    class EmailPresenter {
        public function __construct(private TranslatorInterface $translator) {}
    
        public function present(Notification $notification): string {
            return $this->translator->trans(
                'welcome.email.subject',
                ['%name%' => $notification->getData()['user_name']]
            );
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor