PHPackages                             thesetj/laravel-notification-foundation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. thesetj/laravel-notification-foundation

ActiveLibrary

thesetj/laravel-notification-foundation
=======================================

Foundation package for Laravel notifications providing base classes, contracts, traits, and channels for FCM, SMS, and database delivery.

v1.0.0(yesterday)00MITPHP ^8.1

Since Jul 22Compare

[ Source](https://github.com/TheSETJ/laravel-notification-foundation)[ Packagist](https://packagist.org/packages/thesetj/laravel-notification-foundation)[ RSS](/packages/thesetj-laravel-notification-foundation/feed)WikiDiscussions Synced today

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

laravel-notification-foundation
===============================

[](#laravel-notification-foundation)

A foundation package for building Laravel notifications. Instead of writing `toDatabase()`, `toFcm()`, and `toSms()` from scratch in every notification, you populate a shared data bag using fluent setters in the constructor — the package delivers it to each active channel automatically.

Channels are registered globally in a published service provider (similar to middleware in `bootstrap/app.php`) and can be toggled on or off per notification instance.

Installation
------------

[](#installation)

```
composer require thesetj/laravel-notification-foundation
```

Publish the service provider stub:

```
php artisan vendor:publish --tag=notification-foundation-provider
```

Register it in `bootstrap/providers.php` (Laravel 11+) or `config/app.php`:

```
App\Providers\NotificationFoundationServiceProvider::class,
```

The zero-override pattern
-------------------------

[](#the-zero-override-pattern)

The default `toDatabase()`, `toFcm()`, and `toSms()` implementations read directly from what you set via the fluent API. For most notifications, no payload methods need to be written at all — the entire notification is just a constructor:

```
use NotificationFoundation\BaseNotification;

class OrderShippedNotification extends BaseNotification
{
    public function __construct(Order $order, User $recipient)
    {
        // Shared data is merged into every active channel's payload automatically
        $sharedData = [
            'order_id'   => (string) $order->id,
            'order_code' => $order->code,
            'user_name'  => $recipient->name,
        ];

        $this->setSharedData($sharedData)
             // FCM gets a tailored title and body on top of shared data
             ->setDataForFcmChannel([
                 'title' => 'Your order has shipped',
                 'body'  => "Order #{$order->code} is on its way.",
             ])
             // Database relies on shared data alone — no extra data needed
             // SMS is off by default in the service provider; turn it on for this notification
             ->useSmsChannel()
             ->setDataForSmsChannel([
                 'body' => "Hi {$recipient->name}, order #{$order->code} has shipped.",
             ])
             // This order does not trigger an email
             ->useEmailChannel(false);
    }
}
```

`setSharedData()` is merged into every active channel's payload automatically. Individual channels can add their own data on top, or rely on shared data alone. No `toDatabase()`, `toFcm()`, or `toSms()` methods needed.

Overriding a payload method
---------------------------

[](#overriding-a-payload-method)

Override only what you need. The data bag and shared data are still available:

```
class OrderShippedNotification extends BaseNotification
{
    public function __construct(private Order $order)
    {
        $this->setSharedData(['order_id' => (string) $order->id]);
    }

    public function toFcm(mixed $notifiable): FcmMessage
    {
        return FcmMessage::create()
            ->title('Your order has shipped')
            ->body("Order #{$this->order->id} is on its way.")
            ->setData($this->getSharedData())
            ->android(['priority' => 'high'])
            ->apns(['headers' => ['apns-priority' => '10']]);
    }
}
```

Per-instance channel toggling
-----------------------------

[](#per-instance-channel-toggling)

Every registered channel — built-in or custom — automatically gets fluent toggle methods:

```
(new OrderShippedNotification($order))
    ->useFcmChannel(false)
    ->useSmsChannel(true)
    ->useEmailChannel();        // any registered channel works the same way
```

```
$notification->enableSmsChannel()->disableFcmChannel();
```

The default active state per channel is set in the service provider (see below).

Channel registration
--------------------

[](#channel-registration)

Edit the published `App\Providers\NotificationFoundationServiceProvider`. Comment out or remove what you don't need, and add your own channels:

```
public function boot(): void
{
    BaseNotification::registerChannel('database', 'database', true);
    BaseNotification::registerChannel('fcm', FcmChannel::class, true);
    BaseNotification::registerChannel('sms', SmsChannel::class, false);

    // Custom channels get the same toggle and data-setter API automatically
    // BaseNotification::registerChannel('mail', 'mail', false);
    // BaseNotification::registerChannel('slack', SlackChannel::class, false);
}
```

The third argument is the default state (`true` = active, `false` = inactive).

Driver binding
--------------

[](#driver-binding)

`FcmChannel` and `SmsChannel` delegate delivery to driver contracts. Bind your implementations in a service provider:

```
use NotificationFoundation\Contracts\FcmDriverContract;
use NotificationFoundation\Contracts\SmsDriverContract;

$this->app->bind(FcmDriverContract::class, YourFcmDriver::class);
$this->app->bind(SmsDriverContract::class, YourSmsDriver::class);
```

### FCM driver

[](#fcm-driver)

Implement `FcmDriverContract`. The contract's `send()` method receives either a single token string or an array of tokens, so it can serve as a gateway to whatever internal structure your provider requires:

```
use NotificationFoundation\Contracts\FcmDriverContract;
use NotificationFoundation\Messages\FcmMessage;

class MyFcmDriver implements FcmDriverContract
{
    public function send(FcmMessage $message, string|array $tokens): void
    {
        if (is_array($tokens)) {
            $this->sendMany($message, $tokens);
        } else {
            $this->sendOne($message, $tokens);
        }
    }

    private function sendOne(FcmMessage $message, string $token): void
    {
        // send $message->toArray($token) to the FCM HTTP v1 API
    }

    private function sendMany(FcmMessage $message, array $tokens): void
    {
        // use a batch API if your provider supports it, or loop sendOne()
        foreach ($tokens as $token) {
            $this->sendOne($message, $token);
        }
    }
}
```

### SMS driver

[](#sms-driver)

Implement `SmsDriverContract`. The `send()` method can likewise act as a gateway — if your SMS provider supports bulk sending, add a private `sendMany()` and dispatch from `send()` based on whether `$message->getTo()` is a single number or a list:

```
use NotificationFoundation\Contracts\SmsDriverContract;
use NotificationFoundation\Messages\SmsMessage;

class MyProvider implements SmsDriverContract
{
    public function send(SmsMessage $message): void
    {
        // deliver $message->getContent() to $message->getTo()
        // optionally route to sendOne() / sendMany() based on recipient type
    }
}
```

FCM routing
-----------

[](#fcm-routing)

Add `routeNotificationForFcm()` to your notifiable model:

```
public function routeNotificationForFcm($notification): string|array
{
    return $this->fcm_tokens; // single token or array for multi-device
}
```

SMS routing
-----------

[](#sms-routing)

Add `routeNotificationForSms()` to your notifiable model, or set the recipient directly on the message:

```
// On the notifiable model:
public function routeNotificationForSms($notification): string
{
    return $this->phone_number;
}

// Or in toSms():
return SmsMessage::create('Your OTP is 1234')->to($notifiable->phone);
```

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/93e1e4f044f32a32ead63966767afacc51eee3e229724b055e39299be20dde36?d=identicon)[TheSETJ](/maintainers/TheSETJ)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/thesetj-laravel-notification-foundation/health.svg)

```
[![Health](https://phpackages.com/badges/thesetj-laravel-notification-foundation/health.svg)](https://phpackages.com/packages/thesetj-laravel-notification-foundation)
```

###  Alternatives

[illuminate/events

The Illuminate Events package.

13557.0M2.2k](/packages/illuminate-events)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k30.2M151](/packages/laravel-cashier)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k55.0M631](/packages/laravel-scout)[illuminate/broadcasting

The Illuminate Broadcasting package.

7127.2M220](/packages/illuminate-broadcasting)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[spatie/laravel-health

Monitor the health of a Laravel application

87512.0M177](/packages/spatie-laravel-health)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
