Weave 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

Notification Bundle Laravel Package

modera/notification-bundle

Modera Notification Bundle adds a flexible notification system to Modera CMS applications, letting you compose, queue, and deliver messages through channels like email and SMS, with reusable templates, recipient handling, and simple integration into Laravel-based projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no auto-discovery, and no config/notifications.php to publish. It ships Doctrine ORM entities and Symfony DI service definitions from the Symfony 2.8/3.x era (last release 2017-12-12). Before you invest time, ask whether you actually need it — Laravel already ships a database notification channel (Notifiable trait + notifications table + DatabaseNotification model) that covers ~90% of what this bundle does, with no bridge code.

If you are evaluating it for a Symfony app (or porting it into Laravel):

  1. composer require modera/notification-bundle — then immediately read composer.json for the php, symfony/*, and doctrine/orm constraints. If the app runs PHP 8.1+/Symfony 6, expect conflicts; you'll be running it with --ignore-platform-reqs at your own risk.
  2. Register the bundle in AppKernel::registerBundles() (Symfony ≤4). It depends on modera/foundation-bundle, so that gets registered too.
  3. Update the schema — the bundle ships its own entity mapping, so doctrine:schema:update --dump-sql and convert the resulting notification table DDL into a migration (Laravel) or Doctrine migration. Do not rely on schema:update in production.
  4. Where to look first:
    • Entity/ — the notification model and its fields (recipient, type/level, message, timestamps, read flag).
    • Service/ — the manager. Modera bundles use their own "serviceable" pattern (AbstractService::getDef() returning a ServiceDefinition), not plain Symfony service YAML, so don't hunt for the class name in services.yml.
    • DependencyInjection/Configuration.php — the handful of knobs (user class/interface, table prefix, allowed types).
    • Resources/views/ — if there's a default rendering partial, copy it rather than override it.
  5. First use case — the one this bundle was built for: an in-app "bell" inbox. Persist a notification when a background job finishes ("Your export is ready"), then list the current user's notifications newest-first and decrement an unread badge.

Implementation Patterns

Inject a thin wrapper, not the manager directly. Modera's AbstractService retrieval API is awkward ($container->get('modera_notification.notification_manager')->get($container) in older versions). Wrap it in your own NotificationService with notify(User $u, string $type, array $payload) so the rest of the app never touches Modera types. This also makes the eventual port/removal a one-file change.

Fan-out is the main design decision. For a single recipient, create one row per event. For "notify all 5,000 users," do not loop-save synchronously — chunk the inserts (->persist() in batches of 500, then flush()/clear()) or push the fan-out onto a queue job with an idempotency key. The 2017-era entity almost certainly has no bulk-insert helper.

Write notifications inside the business transaction, or after commit. Persisting a notification in the same unit of work as the thing it describes is simplest, but if the outer transaction rolls back your users get phantom notifications in other code paths. Pick one rule and apply it consistently — the safer default is "create after the business transaction commits."

Read/unread needs an explicit query, not a flag check. Use a repository method like findForRecipient($user, $onlyUnread, $limit, $offset) ordered by createdAt DESC, and expose two counters: unread badge count and paginated list. Never load all notifications and filter in PHP — the badge count renders on every page.

Type is a string, labels are yours. Store a stable machine value (export.ready, invoice.paid) plus a small JSON payload column if available; map type → label/icon/URL in a PHP enum-like class and render in a Blade/Twig partial. Store data, never rendered HTML — otherwise translations, escaping, and route changes all break retroactively.

Add a retention job. A nightly command that deletes read notifications older than N days (and unread older than, say, 90). This table grows faster than anything else in the app and nobody remembers to clean it.

If you're bridging into Laravel: don't. Copy the schema idea (recipient id, type, payload, read_at, created_at; index on (recipient_id, read_at, created_at)), implement it as a Laravel Notifiable database notification or a plain Eloquent model with a Notification::markRead() scope. You get queues, broadcasting, and mail channels for free.

Gotchas and Tips

  • Abandoned since December 2017. No PHP 7.4+/8.x support, no Symfony 4.4+ support, no security patches. Two stars and zero dependents means you are the only person on this code path — treat every line as unmaintained.
  • "Serviceable" DI is not standard Symfony DI. Modera services are objects returned by ServiceDefinition, and the container id differs from the class name. If $container->has('modera_notification.notification_manager') returns false, check Resources/config/services.xml and the bundle's compiler pass rather than assuming the bundle didn't register.
  • The manager may not flush. Several Modera managers persist but leave flushing to the caller. The classic symptom is "notification created but never appears" — add an explicit flush() and confirm with the Doctrine SQL logger (doctrine.dbal.logging) that an INSERT actually ran.
  • The user reference is configurable and is the #1 integration break. The entity references the recipient by configured class/interface; if your User model doesn't match, Doctrine throws a mapping/association error at metadata-load time, not at runtime. Resolve this before writing any feature code.
  • Missing indexes. Schema auto-generated in 2017 typically indexes nothing useful. Add a composite index on recipient + read flag + created timestamp, or the unread-badge query becomes a table scan.
  • It is storage only. No email, no push, no websockets, no delivery guarantees, no per-channel preferences. Anything "real-time" is on you (polling endpoint or broadcast).
  • Extension points, in order of safety: decorate your own wrapper → override the view templates via bundle inheritance (app/Resources/ModeraNotificationBundle/views/) → override the entity class (doctrine.orm.resolve_target_entities / bundle override) as a last resort, since entity overrides break on every schema diff.
  • Migrating off it later is cheap if you kept the wrapper: your NotificationService interface survives, and you map old rows into the new table with a single SQL INSERT ... SELECT (type → type, read flag → read_at, message/payload → JSON column).
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core