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

johnkrovitch/notification-bundle

johnkrovitch/notification-bundle is a Symfony bundle for adding notification handling to PHP applications. It provides a structured, integration-friendly way to manage and deliver notifications within Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the mismatch: this is a Symfony bundle (johnkrovitch/notification-bundle), not a Laravel package. There is no service provider, no config/notification.php, and Composer will not auto-discover it. If you are maintaining a Laravel app, you cannot install this — you read its source for domain modelling and port the ideas to Laravel's Notifiable trait + notifications table + database channel. The rest of this section assumes you actually have a Symfony 4.4/5.x app to drop it into, or you are evaluating it for a port.

What v1.0 changes: it is the first stable release, and it is the release that adds Symfony 5 support. That makes 1.0 the version to install and the version to read — everything below assumes it. It does not change the fundamentals: still a 2020-vintage bundle, still zero dependents, still no Laravel story, and Symfony 5 is the ceiling. There is no Symfony 6/7 support and no claim of PHP 8 compatibility.

Minimal Symfony steps:

  1. composer require johnkrovitch/notification-bundle:^1.0 and confirm the PHP/Symfony constraints resolve. v1.0 lifts the ceiling to Symfony 5, but expect symfony/*: ^4.4|^5.0-style pins that will still fight a Symfony 6/7 app. Run composer why-not johnkrovitch/notification-bundle ^1.0 before writing code — it tells you in one line whether you are wasting an afternoon.
  2. Enable it in config/bundles.php (JohnKrovitch\NotificationBundle\...Bundle::class => ['all' => true] — verify the exact FQCN from composer.json's autoload.psr-4 after install).
  3. Dump the merged config: bin/console config:dump-reference <bundle_alias>. The alias will not be obvious; bin/console debug:container --parameter and grep the generated var/cache/dev/App_KernelDevDebugContainer.xml for the bundle namespace to find the registered service IDs.
  4. Look for Doctrine entities in src/Entity/ and any migrations in the package. v1.0 is a stability/ compatibility release, not a schema release — if a Notification entity exists, you must run bin/console make:migration yourself. doctrine:schema:update --dump-sql is your fastest way to see what's missing.

Where to look first, in this order: DependencyInjection/Configuration.php (the authoritative config schema — it is the only reliable documentation), DependencyInjection/*Extension.php (service aliases you can autowire), Resources/config/services.yaml, then the entity/model classes. READMEs on 3-star bundles are frequently stale relative to the code; the Configuration tree is not. The v1.0 release notes are two bullet points — they tell you the API is frozen and Symfony 5 works, not how anything behaves.

First use case to validate: persist a notification for a recipient, render an unread count in Twig, and mark it read. If you can do that end-to-end in an afternoon, the bundle is usable. If wiring a single notification requires reading three service definitions, budget for a rewrite instead. Do this validation on Symfony 5 specifically — that compatibility is the entire content of the v1.0 release, so it is the one thing you should not take on trust.

Implementation Patterns

Persist-then-fanout. The durable pattern for any notification system, and the one to verify this bundle supports: write the notification row synchronously in the same transaction as the domain event, then dispatch delivery (email, push) asynchronously. If the bundle couples persistence and transport in one call, wrap the call in your own service and push it onto Symfony Messenger (SyncMessenger in test/dev, Doctrine transport in prod) so a mail outage never rolls back your business write.

Pin the API and treat 1.0 as final. The upside of a first stable release is that the public API is now a promise: you can code against its interfaces and services without expecting a breaking change in a patch release. The downside is that there is no 1.1 coming, so "stable" here means frozen, not maintained. Commit composer.lock, pin ^1.0 (not *), and prefer a path repository or a fork so you can patch without waiting for a release that will not arrive.

Notification as a small value object, not a string. Whatever the bundle's API, do not let controllers construct notifications inline. Define one class per event (InvoiceOverdue, CommentMentioned) with a toDatabase(), toMail(), toArray() shape, and a single factory service that maps a domain event to the right class. This gives you a place to change copy without touching controllers and makes the whole thing testable. When you port to Laravel this maps 1:1 onto Notification classes with via().

Recipient resolution belongs in your code, not the bundle's. Bundles of this vintage typically take a UserInterface or an ID. Put a RecipientResolver in front of it that handles roles, teams, and "notify the assignee or the manager if unassigned." This is the part that always rots, and it will be the part you keep when you throw the bundle away.

Channel abstraction via tagged services. If the bundle exposes a channel/transport interface, register your custom channels with a service tag rather than editing the bundle. Check services.yaml in the package for _instanceof blocks and tags. If there is no tag, use a compiler pass in your app to add your services to the bundle's collection service — this is the cleanest way to extend a bundle you cannot fork.

Read state as a separate concern. Keep read_at timestamps and unread counters in your application layer with a small query service, even if the bundle stores the notification. You will want unread_count indexed by (recipient_id, read_at) and cached in Redis for the header bell — the bundle almost certainly does not do this for you.

Event listener bridge. Emit a Symfony event from your domain (InvoiceWasOverdue) and have one listener that calls the bundle. This keeps the bundle at the edge of your architecture and makes the removal cost one file.

Testing. Build an in-memory fake behind the same interface the bundle provides, assert against the fake in unit tests, and keep exactly one integration test that hits the real bundle service plus a real (SQLite) database. Do not mock Doctrine for notification tests — half the bugs are persistence and serialization. Run that integration test on both Symfony 4.4 and 5.x if you support both; v1.0 is the first release where the 5.x path exists at all, so it is the least exercised.

Gotchas and Tips

  • v1.0 is a semver label, not a maintenance signal. First stable release, Symfony 5 support, still zero dependents and no releases since. There is no ecosystem to lean on, no security response, and issue fixes are yours. Treat it as vendored source: consider composer require then forking into src/ or a path repository so you can patch it without a fork-blessing ceremony.
  • Upgrading from 0.x is not guaranteed safe. A "first stable release" is precisely the moment a maintainer is free to break things, and pre-1.0 code carries no BC promise. If you are already on a 0.x tag, diff DependencyInjection/Configuration.php and the public service signatures between the two versions before bumping — the release notes do not enumerate changes.
  • Symfony 5 support is new; Symfony 6/7 support does not exist. Expect missing return types, ContainerAwareCommand, deprecated getDoctrine(), and SwiftMailer if email is involved — none of that was cleaned up in this release. Run a static analysis pass (phpstan level 5, or rector with the Symfony sets) before adopting, and do not assume "supports Symfony 5" means "supports Symfony 5.4 LTS with PHP 8" — verify on your exact version.
  • The README is not the spec. Diff the README against DependencyInjection/Configuration.php and read Resources/config/services.yaml line by line. You will find config keys that are documented but unused, and services that are defined but never aliased for autowiring. A stability release is the least likely moment for docs to be refreshed.
  • No migrations. You own schema management. Generate the migration, review it by hand, add the indexes the bundle forgot (recipient, created_at, read_at) — unindexed notification tables are a classic slow-query source at even modest volume.
  • Autowiring aliases. If the bundle defines an interface without a #[Autowire]-style alias or services.yaml alias, inject by concrete service ID (@bundle.notification_manager) or declare the alias yourself in config/services.yaml.
  • Debugging: bin/console debug:container <namespace> to see what registered, bin/console debug:event-dispatcher to confirm listeners, bin/console doctrine:query:sql to inspect rows. var/log/dev.log at DEBUG will show the full service graph if a service fails to instantiate.
  • Extension points worth using: template overrides via Resources/views in your app if the bundle renders Twig; a compiler pass for tagged channels; a decorator over the bundle's manager service (decorates: in services.yaml) to add logging, retries, or multi-tenancy without touching the vendor code. Decorating is the single highest-leverage move with an abandoned bundle — and with 1.0 frozen, it is the only move.
  • Evaluate the replacement before committing. Symfony Notifier (symfony/notifier) does channels and transports properly and is maintained; Laravel Notifications does the same on the other side. If your need is "persist + render + email," the framework-native answer is probably 100 lines of your own code, and this bundle is a detour. Adopt it only if its entity and channel model saves you real work in the next two sprints — and note that v1.0's headline feature, Symfony 5 support, is something the framework-native alternative has had all along.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console