phil / notifications-bundle
Notifications for Symfony on Symfony Notifier: declared types delivered to each recipient's chosen channels — a notification centre with toasts, email and its daily or weekly digest, Web Push, Slack or Discord —, messages of identifiers only written out when shown, and notifications received signed
Package info
github.com/parler-haut-interagir-librement/notifications-bundle
Type:symfony-bundle
pkg:composer/phil/notifications-bundle
Requires
- php: >=8.5
- ext-mbstring: *
- ext-sodium: *
- doctrine/dbal: ^4.5
- phil/url: ^0.1@dev
- psr/clock: ^1.0
- psr/log: ^3.0
- symfony/config: ^8.2
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
- symfony/notifier: ^8.2
- symfony/security-csrf: ^8.2
- symfony/service-contracts: ^3.6
- symfony/translation-contracts: ^3.6
- symfony/uid: ^8.2
Requires (Dev)
- ext-openssl: *
- ext-pdo: *
- doctrine/doctrine-bundle: ^3.3
- doctrine/orm: ^3.7
- minishlink/web-push: ^11.0
- nyholm/psr7: ^1.8
- phil/standard-webhooks: ^0.1@dev
- phil/standard-webhooks-bundle: ^0.1@dev
- phpunit/phpunit: ^13.4
- psr/event-dispatcher: ^1.0
- symfony/asset: ^8.2
- symfony/asset-mapper: ^8.2
- symfony/browser-kit: ^8.2
- symfony/clock: ^8.2
- symfony/console: ^8.2
- symfony/css-selector: ^8.2
- symfony/discord-notifier: ^8.2
- symfony/event-dispatcher: ^8.2
- symfony/event-dispatcher-contracts: ^3.6
- symfony/framework-bundle: ^8.2
- symfony/http-client: ^8.2
- symfony/http-client-contracts: ^3.6
- symfony/http-kernel: ^8.2
- symfony/mailer: ^8.2
- symfony/mercure: ^0.10
- symfony/mercure-bundle: ^0.7
- symfony/messenger: ^8.2
- symfony/mime: ^8.2
- symfony/routing: ^8.2
- symfony/scheduler: ^8.2
- symfony/slack-notifier: ^8.2
- symfony/translation: ^8.2
- symfony/twig-bridge: ^8.2
- symfony/twig-bundle: ^8.2
- symfony/ux-turbo: ^3.7
- symfony/ux-twig-component: ^3.7
- twig/twig: ^3.21
Suggests
- ext-openssl: To make VAPID keys with phil:notifications:vapid-keys and encrypt Web Push messages
- doctrine/orm: To add the tables to the schema the ORM generates, for doctrine:migrations:diff
- minishlink/web-push: For the bundle's Web Push sender, with a PSR-7 implementation such as nyholm/psr7
- nyholm/psr7: The PSR-7 messages minishlink/web-push builds its requests with
- phil/standard-webhooks-bundle: To receive the notifications of the other sites of a network, signed
- symfony/asset: To give the Web Push button the URL of the bundle's service worker
- symfony/asset-mapper: To serve the controller and its stylesheet without a build step
- symfony/console: For the purge command
- symfony/discord-notifier: For the chat/discord channel
- symfony/http-client: To post Web Push messages to the browsers' push services
- symfony/mailer: For the email digest
- symfony/mercure-bundle: To push toasts and the unread count live
- symfony/messenger: To deliver notifications and digests in the background, one recipient at a time
- symfony/routing: For the endpoints of the notification centre
- symfony/scheduler: To send the digests and purge on schedule
- symfony/slack-notifier: For the chat/slack channel
- symfony/stimulus-bundle: For the notification centre controller
- symfony/twig-bridge: For the email digest's template
- symfony/ux-turbo: To keep the bell across Turbo page visits
- symfony/ux-twig-component: For the bell, list and toasts components
Provides
None
Conflicts
- symfony/mailer: <8.2
Replaces
None
This package is auto-updated.
Last update: 2026-11-15 03:41:02 UTC
README
Notifications for Symfony applications: a centre with toasts, email and its digest, Web Push and chat, as each recipient chose, made of identifiers only.
phil/notifications-bundle lets an application tell its members what happened: a reply to their comment, a seat freed at an event, a new member in their group. The application declares its notification types — their channels, whether similar ones collapse, their templates in English and French or any locale — and sends one with a type, the recipients' identifiers, what it is about and who caused it. The bundle delivers it on Symfony Notifier to each recipient's channels, as they chose: the site's own notification centre, with its bell, its list and its toasts; email, at once or in a daily or weekly digest; Web Push to the browsers they turned it on in; SMS or push through any Notifier transport; and a Slack or Discord channel, once for everyone. Quiet hours hold back what interrupts, and each channel can be turned off per type.
A notification carries references, never content: a type, a recipient, an actor, a subject (comment:981) and a few
more identifiers. What it says is written from its type's templates when it is shown or sent, the subject's label and
URL looked up by the application's resolvers at that moment. Its Messenger messages are as small, and a notification
sent to many becomes one message per recipient, retried alone.
In a network of sites, a site takes the notifications another one sends, signed as Standard Webhooks, into its own centre: one centre for the whole network. Sending through a central platform is not part of this bundle.
It is a Symfony bundle on Symfony Notifier and DBAL; MercureBundle pushes the toasts and the unread count live, the session keeps them for the next page without it. Web Push is sent with minishlink/web-push, behind a port an application may fill with its own sender. The centre's forms work without JavaScript, and a Stimulus controller sends them in the background and shows the toasts, without motion when the visitor asks for less.
Status
| Part | State |
|---|---|
Notification, SubjectReference, NotificationData: references only, collapsing, read and archived states |
Implemented and tested |
NotificationType, NotificationTypes, Channels: declared types, channels, broadcast channels, importance, templates |
Implemented and tested |
Notifications, SendNotification and its handler, NotificationDispatcher: the entry point, the split per recipient, the delivery on each channel |
Implemented and tested |
NotificationRenderer, SubjectResolver, RecipientDirectory: written out when shown, translated |
Implemented and tested |
NotificationPreferences: digest, quiet hours, channels turned off, locale; ConfiguredPreferences, DbalPreferences |
Implemented and tested |
NotificationRepository: DbalNotificationRepository, InMemoryNotificationRepository, the tables and the schema listener |
Implemented and tested on SQLite; the unread count and the delivery benchmarked |
Digests, MailerDigestSender and its tracking off without EmailTrackingConsent, NotificationSchedule, Retention, phil:notifications:purge |
Implemented and tested |
MercureToasts, FlashToasts, the centre's endpoints and its Twig components |
Implemented and tested |
The notifications Stimulus controller |
Implemented; its module tested under Node |
RemoteNotificationReceiver and its endpoint, on phil/standard-webhooks-bundle |
Implemented and tested |
WebPushMessage: the payload, urgency, topic and time to live a Web Push sender sends |
Implemented and tested |
WebPushSender: the port of the web_push channel, for the bundle's sender or the application's own |
Implemented and tested |
PushSubscription, PushSubscriber, PushSubscriptions on DBAL or in memory: each recipient's browsers, endpoints on allowed push services |
Implemented and tested on SQLite |
MinishlinkWebPushSender and VapidKeys: encrypted, signed and posted on minishlink/web-push, expired subscriptions forgotten; phil:notifications:vapid-keys |
Implemented and tested against a mock push service |
PushSubscriptionController, the PhilNotifications:WebPush component, the web-push controller and the service worker |
Implemented and tested; the modules and the worker under Node |
AudienceProvider: recipients chosen by audience |
A port, for the application or a segments package |
| A news summary: the notifications of a period gathered for those who did not see them | Not started |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, enabling the bundle, the tables, the routes, Mercure, the controller and the stylesheet. |
| Configuration | Every option, with an example. |
| Sending | Types, the entry point, recipients and audiences, references, Messenger. |
| Channels | The centre, email, Web Push and its service worker, Notifier channels, broadcast channels, quiet hours and opt-outs. |
| Preferences | What a recipient chooses, where it is kept, and the port that replaces it. |
| Notification centre | The components, the endpoints, the toasts, the Stimulus controller, accessibility. |
| Digest and retention | The daily and weekly digests, the schedule, the purge. |
| Network | Receiving the notifications of the other sites of a network. |
| Extension points | What an application implements, configures, replaces or relies on. |
| Testing | The PHP and Node tests, the benchmarks and the mutation bar. |
| Reference | Every class and service of the bundle. |
Quick start
composer require phil/notifications-bundle
# config/packages/phil_notifications.yaml phil_notifications: recipient_directory: App\Notifications\Members # a RecipientDirectory: addresses and names types: comment.replied: channels: [site, email] collapse: true
$notifications->send('comment.replied', $author->id, new SubjectReference('comment', $reply->id), actor: $replier->id);
<twig:PhilNotifications:Bell /> <twig:PhilNotifications:Toasts />
Requirements
PHP 8.5 or later and Symfony 8.2 or later, with Symfony Notifier and Doctrine DBAL.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.