mrpritchett / laravel-notifications-subscriptions
通知订阅管理。
Requires
- php: ^7.2.5
- laravel/framework: ^6.0|^7.0|^8.0
README
Laravel Notification Subscriptions是一个直接集成到Laravel现有通知系统的包,并增加了管理用户对应用程序通知的订阅功能,并在不应发送时自动抑制它们。您可以订阅和取消订阅特定通知通道,创建可选通知,并通过另一个模型来范围您的订阅。
安装
要开始使用,请安装mrpritchett/laravel-notifications-subscriptions
包
composer require mrpritchett/laravel-notifications-subscriptions
运行迁移以创建notification_subscriptions
表
php artisan migrate
可选:通过运行并选择合适的提供者选项发布配置文件
php artisan vendor:publish
基本用法
此包使用监听器来监听您的应用程序中发送的任何通知。当通知被触发时,该包会检查是否应该根据用户的订阅发送该通知。如果不是,则抑制通知。
入门
此包假定您已经设置了Laravel的通知系统。如果您还没有阅读文档以开始。
将HasNotificationSubscriptions
特性添加到您的User
模型中
use Illuminate\Database\Eloquent\Model; use MRP\NotificationSubscriptions\Traits\HasNotificationSubscriptions; class User extends Model { use HasNotificationSubscriptions; // ... }
取消订阅
要取消特定Notification
的订阅,将那个通知的类名传递给unsubscribe
函数。
use App\Notifications\InvoicePaid; $user->unsubscribe(InvoicePaid::class); //You can also pass a string, but this is the preferred method.
上面的操作将取消用户对所有通道的订阅。您可以通过传递通道名称作为第二个参数来取消特定通道的订阅
use App\Notifications\InvoicePaid; $user->unsubscribe(InvoicePaid::class, 'mail');
现在,每当发送InvoicePaid
通知时,该包将自动检测用户已取消订阅并抑制该通知。例如
use App\Notifications\InvoicePaid; $user->notify(new InvoicePaid($invoice)); //This won't get sent.
可选通知
默认情况下,如果没有找到订阅/取消订阅记录,则将发送所有通知。这意味着您不需要明确地订阅用户到通知,您只需要取消订阅他们。
但是,在某些情况下,您可能想创建可选通知。为此,修改您的通知类并添加一个名为getOptInChannels
的函数
<?php namespace App\Notifications; // ... class InvoicePaid extends Notification { public function via($notifiable) { return ['mail', 'sms']; } public function getOptInChannels() { return ['sms']; } }
现在,除非用户明确订阅了该通道,否则该包将始终抑制sms
通道。
订阅
要订阅可选通知或将用户重新订阅之前已取消订阅的通知
use App\Notifications\InvoicePaid; $user->subscribe(InvoicePaid::class);
同样,您也可以应用一个通道
use App\Notifications\InvoicePaid; $user->subscribe(InvoicePaid::class, 'mail');
重置订阅
此包对您的应用程序如何管理通知和订阅没有任何假设。例如,如果您取消用户特定通知通道的订阅,然后稍后将其订阅到所有通道,则之前的记录不会被删除。要重置用户的通知
use App\Notifications\InvoicePaid; $user->resetSubscriptions(InvoicePaid::class);
您可以使用resetSubscriptions
进行链式调用
use App\Notifications\InvoicePaid; $user->resetSubscriptions(InvoicePaid::class)->subscribe(InvoicePaid::class);
检索订阅
您可以通过使用notificationSubscriptions()
关系来获取用户的订阅
$user->notificationSubscriptions();
模型范围
在某些应用程序中,您需要取消与特定模型相关的通知的用户的订阅。例如,如果用户是多个组织的一部分,他们可能只想取消单个组织的订阅。您可以通过在通知上应用模型范围来实现这一点
use App\Models\Organization; use App\Notifications\InvoicePaid; //... $organization = Organization::find(1); $user->unsubscribe(InvoicePaid::class, '*', $organization);
或者,对于单个通道
use App\Models\Organization; use App\Notifications\InvoicePaid; //... $organization = Organization::find(1); $user->unsubscribe(InvoicePaid::class, 'mail', $organization);
接下来,我们需要一种方法来检索当您的通知发送时的 Organization
。在您的通知类中添加一个名为 getSubscriptionModel
的函数,以便告诉它如何检索模型
<?php namespace App\Notifications; // ... class InvoicePaid extends Notification { public function __construct(Invoice $invoice) { $this->invoice = $invoice; } public function getSubscriptionModel($notifiable) { return $this->invoice->organization; } }
现在,当这个通知被发送时,它将检查模型范围并如果需要则应用它。您可以在 getSubscriptionModel
中添加自己的逻辑,甚至在某些情况下返回 null
以不应用订阅范围。
重置范围订阅
重置范围订阅上的通知
use App\Models\Organization; use App\Notifications\InvoicePaid; //... $organization = Organization::find(1); $user->resetSubscriptions(InvoicePaid::class, $organization);
检索范围订阅
检索与特定模型相关的订阅
use App\Models\Organization; //... $organization = Organization::find(1); $user->notificationSubscriptions()->model($organization);
高级用法
忽略订阅
如果您希望包完全忽略您的通知,并跳过任何抑制,请在您的通知类中将公共属性 $ignoreSubscriptions
设置为 true。
<?php namespace App\Notifications; // ... class InvoicePaid extends Notification { public function __construct(Invoice $invoice, $ignore = false) { $this->ignoreSubscriptions = $ignore; } }
use App\Notifications\InvoicePaid; $user->notify(new InvoicePaid($invoice, true)); //This will always get sent.
排除频道
您可能想要排除某些频道在检查退订时被考虑。默认情况下,我们已排除 database
频道。您可以在配置文件中配置此设置。
<?php return [ 'excluded_channels' => ['database'], ];
解析逻辑
该包使用以下逻辑来解决是否发送通知
-
如果
channel
在excluded_channels
中,发送通知。 -
如果通知有公共属性
$ignoreSubscriptions
设置为true
,则发送通知。 -
尝试检索特定频道的记录,如果没有找到,则尝试检索所有频道的记录(即
"*"
)。3a. 如果没有记录,并且频道不是自愿的,则发送通知。
3b. 如果有记录,则根据订阅的状态(已订阅或未订阅)发送通知。