PHP code example of offload-project / laravel-notification-preferences

1. Go to this page and download the library: Download offload-project/laravel-notification-preferences library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

offload-project / laravel-notification-preferences example snippets


use OffloadProject\NotificationPreferences\Concerns\HasNotificationPreferences;

class User extends Authenticatable
{
    use HasNotificationPreferences;
}

return [
    'channels' => [
        'mail' => ['label' => 'Email', 'enabled' => true],
        'database' => ['label' => 'In-App', 'enabled' => true],
    ],

    'groups' => [
        'system' => [
            'label' => 'System Notifications',
            'description' => 'Important system updates',
            'default_preference' => 'opt_in',
            'order' => 1,
        ],
    ],

    'notifications' => [
        \App\Notifications\OrderShipped::class => [
            'group' => 'system',
            'label' => 'Order Shipped',
            'description' => 'When your order ships',
            'order' => 1,
        ],
    ],
];

$user->notify(new OrderShipped($order));

// Set a preference
$user->setNotificationPreference(OrderShipped::class, 'mail', false);

// Check a preference
$enabled = $user->getNotificationPreference(OrderShipped::class, 'mail');

// Get all preferences
$preferences = $user->getNotificationPreferences();

// Get structured table for UI
$table = $user->getNotificationPreferencesTable();

// Disable all emails
$user->setChannelPreferences('mail', false);

// Mute all marketing notifications for email
$user->setGroupPreferences('marketing', 'mail', false);

// Disable all channels for a notification type
$user->setNotificationChannelPreferences(OrderShipped::class, false);

// Reset all preferences to defaults
$user->resetNotificationPreferences();

use OffloadProject\NotificationPreferences\Concerns\ChecksNotificationPreferences;

class OrderShipped extends Notification
{
    use ChecksNotificationPreferences;

    public function via($notifiable)
    {
        return $this->allowedChannels($notifiable, ['mail', 'database', 'broadcast']);
    }
}

'notifications' => [
    SecurityAlert::class => [
        'group' => 'security',
        'label' => 'Security Alerts',
        'force_channels' => ['mail', 'database'],
    ],
],

use OffloadProject\NotificationPreferences\Contracts\AuthorizesNotification;

class OrderShipped extends Notification implements AuthorizesNotification
{
    public static function notificationAbility(): string
    {
        return 'view-orders';
    }
}

'notifications' => [
    \Vendor\Package\SomeNotification::class => [
        'group' => 'system',
        'label' => 'Vendor notification',
        'ability' => 'view-orders',
    ],
],

Gate::define('view-orders', function (User $user, ?OrderShipped $notification = null) {
    // $notification is null when called from the preferences UI (no instance exists)
    if ($notification) {
        return $user->can('view', $notification->order);
    }
    return $user->can('view-orders');
});

'notifications' => [
    OrderShipped::class => [
        'group' => 'system',
        'label' => 'Order Shipped',
        'default_channels' => ['mail', 'database'], // Only these enabled by default
    ],
],

use OffloadProject\NotificationPreferences\Events\NotificationPreferenceChanged;

Event::listen(NotificationPreferenceChanged::class, function ($event) {
    // $event->preference - The NotificationPreference model
    // $event->user - The user who changed the preference
    // $event->wasCreated - Whether this was a new preference or update
});

use OffloadProject\NotificationPreferences\Events\NotificationAuthorizationDenied;

Event::listen(NotificationAuthorizationDenied::class, function ($event) {
    // $event->notifiable   - The user the notification was being sent to
    // $event->notification - The notification instance
    // $event->channel      - The channel that was blocked
    // $event->ability      - The Gate ability that failed
});

use OffloadProject\NotificationPreferences\Facades\NotificationPreferences;

// Check if a channel is enabled
NotificationPreferences::isChannelEnabled($user, OrderShipped::class, 'mail');

// Set a preference
NotificationPreferences::setPreference($user, OrderShipped::class, 'mail', false);

// Get structured table for UI
NotificationPreferences::getPreferencesTable($user);

// Discover registered configuration
NotificationPreferences::getRegisteredChannels();    // ['mail', 'database']
NotificationPreferences::getRegisteredGroups();      // ['system', 'marketing']
NotificationPreferences::getRegisteredNotifications(); // [OrderShipped::class, ...]

use OffloadProject\NotificationPreferences\Contracts\NotificationPreferenceManagerInterface;

class NotificationPreferenceController
{
    public function __construct(
        private NotificationPreferenceManagerInterface $manager
    ) {}

    public function update(Request $request)
    {
        $this->manager->setPreference(
            $request->user(),
            $request->notification_type,
            $request->channel,
            $request->enabled
        );
    }
}

[
    [
        'group' => 'system',
        'label' => 'System Notifications',
        'description' => 'Important system updates',
        'notifications' => [
            [
                'type' => 'App\Notifications\OrderShipped',
                'label' => 'Order Shipped',
                'description' => 'When your order ships',
                'channels' => [
                    'mail' => ['enabled' => true, 'forced' => false],
                    'database' => ['enabled' => true, 'forced' => false],
                ],
            ],
        ],
    ],
]

// app/Http/Middleware/HandleInertiaRequests.php
public function share(Request $request): array
{
    return [
        ...parent::share($request),
        'notificationPreferences' => fn () => $request->user()?->getNotificationPreferencesTable(),
    ];
}

// config/notification-preferences.php
'cache_ttl' => 1440, // minutes (default: 24 hours)

use OffloadProject\NotificationPreferences\Contracts\NotificationPreferenceManagerInterface;

$manager = app(NotificationPreferenceManagerInterface::class);

// Clear all cached preferences for a user
$manager->clearUserCache($userId);

// Clear the memoized config cache (useful after runtime config changes)
$manager->clearConfigCache();

use OffloadProject\NotificationPreferences\Exceptions\InvalidNotificationTypeException;
use OffloadProject\NotificationPreferences\Exceptions\InvalidChannelException;
use OffloadProject\NotificationPreferences\Exceptions\InvalidGroupException;

try {
    $user->setNotificationPreference('UnregisteredNotification', 'mail', false);
} catch (InvalidNotificationTypeException $e) {
    // "Notification type 'UnregisteredNotification' is not registered...
    //  Add it to the 'notifications' array in 'config/notification-preferences.php'."
}

try {
    $user->setNotificationPreference(OrderShipped::class, 'sms', false);
} catch (InvalidChannelException $e) {
    // "Channel 'sms' is not registered... Available channels: mail, database."
}

try {
    $user->setGroupPreferences('nonexistent', 'mail', false);
} catch (InvalidGroupException $e) {
    // "Group 'nonexistent' is not registered... Available groups: system, marketing."
}

use OffloadProject\NotificationPreferences\Concerns\HasUnsubscribeUrl;

class OrderShipped extends Notification
{
    use HasUnsubscribeUrl;

    public function toMail($notifiable): MailMessage
    {
        return $this->withUnsubscribeHeaders(
            (new MailMessage)
                ->line('Your order has shipped!')
                ->action('Unsubscribe', $this->getUnsubscribeUrl($notifiable)),
            $notifiable
        );
    }
}

// From the user model
$url = $user->notificationUnsubscribeUrl(OrderShipped::class);
$url = $user->notificationResubscribeUrl(OrderShipped::class);

// From the facade
use OffloadProject\NotificationPreferences\Facades\NotificationPreferences;

$url = NotificationPreferences::unsubscribeUrl($user, OrderShipped::class);
$url = NotificationPreferences::resubscribeUrl($user, OrderShipped::class);

// For a specific channel (defaults to 'mail')
$url = NotificationPreferences::unsubscribeUrl($user, OrderShipped::class, 'database');

// config/notification-preferences.php
'unsubscribe' => [
    // Whether to register unsubscribe routes
    'enabled' => true,

    // Route prefix for unsubscribe/resubscribe endpoints
    'route_prefix' => 'notification-preferences',

    // Middleware for the unsubscribe routes
    'middleware' => ['web'],

    // Signed URL TTL in minutes (null for permanent/non-expiring)
    'url_ttl' => null,

    // Redirect to this URL after unsubscribing (with status, notification_type, and channel query params)
    // Set to null to return a JSON response instead
    'redirect_url' => null,

    // Enable resubscribe functionality
    'resubscribe_enabled' => true,
],

'redirect_url' => '/notification-settings',
// Redirects to: /notification-settings?status=unsubscribed&notification_type=App\Notifications\OrderShipped&channel=mail
bash
php artisan vendor:publish --tag=notification-preferences-config
php artisan vendor:publish --tag=notification-preferences-migrations
php artisan migrate
bash
php artisan notification-preferences:uninstall --force
composer remove offload-project/laravel-notification-preferences
rm config/notification-preferences.php