codewiser/postie

订阅管理 Laravel 包

v1.2.1 2024-05-30 07:27 UTC

README

Postie 是一个仪表板,用户可以管理他们的订阅偏好。

应用程序中的每个 通知 都有相应的受众。这并不意味着受众中的每个人都会收到通知,但这是可能的。因此,Postie 允许用户决定使用哪些频道来发送通知。

Postie

安装

使用 Composer 包管理器将 Postie 安装到您的项目中

composer require codewiser/postie

安装 Postie 后,使用 postie:install Artisan 命令发布其资产

php artisan postie:install

在运行迁移之前,您可能想更改保存用户订阅偏好的表的名称。然后请参阅 config/postie.php

'table' => env('POSTIE_TABLE', 'subscriptions'),

配置表名后运行迁移

php artisan migrate

配置

安装 Postie 后,其服务提供者位于 App\Proviers\PostieServiceProvider

首先,提供有关用户可能管理的每个 通知 的信息。每个订阅都需要可用频道列表和可能的受众(作为构建器)。

use Codewiser\Postie\Subscription;
use Codewiser\Postie\PostieApplicationServiceProvider;

class PostieServiceProvider extends PostieApplicationServiceProvider
{
public function notifications(): array
    {
        return [
            Subscription::to(NewOrderNotification::class)
                ->via('mail', 'database')
                ->for(fn() => User::query()->where('role', 'sales-manager'))
        ];
}

其次,将 Notification::via() 方法替换为 \Codewiser\Postie\Notifications\Traits\Channelization 特性。通知 将使用相关 订阅 中定义的频道列表。

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Codewiser\Postie\Notifications\Traits\Channelization;

class NewOrderNotification extends Notification implements ShouldQueue
{
    use Queueable, Channelization;

    public function __construct(public Order $order)
    {
        //
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject("New order")
            ->line('User makes new order.');
    }

    public function toArray($notifiable)
    {
        return $this->order->toArray();
    }
}

订阅定义

订阅 是一个对象,它帮助您描述应用程序通知,以便 Postie 能够理解。

最初,传递通知类名、包含可能接收此类通知的用户和通知支持的频道列表的查询构建器就足够了。

use Codewiser\Postie\Subscription;

Subscription::to(Notification::class)
    ->via('mail')
    ->for(fn() => User::query())

此外,您还可以定义通知标题和描述。

use Codewiser\Postie\Subscription;

Subscription::to(DailyNewsNotification::class)
    ->via('mail')
    ->for(fn() => User::query())
    ->title('Daily News Notification')
    ->description('Sends most interesting news digest')

频道定义

当您设置 订阅 时,您可以传递频道作为简单的字符串。但有一种方法可以定义更复杂的频道表示。

您可以使用 \Codewiser\Postie\Channel 对象来描述具有自定义标题、图标等的频道。

use Codewiser\Postie\Channel;
use Codewiser\Postie\Subscription;

$mail = Channel::via('mail')
    ->icon('envelope')
    ->title('via email')
    ->subtitle('Sends emails');

Subscription::to(DailyNewsNotification::class)
    ->via($mail);

您可以定义频道默认状态。如果频道处于活动状态,则所有用户将接收通过此频道发送的通知,直到他们取消订阅。反之,如果频道处于非活动状态,则所有用户将不会通过此频道接收通知,直到他们订阅。

默认频道状态为活动。

use Codewiser\Postie\Channel;

$mail = Channel::via('mail')->passive();

如果您想禁用用户管理频道偏好的能力,您可以选择隐藏频道从用户界面中,或强制频道状态。

use Codewiser\Postie\Channel;

$mail = Channel::via('database')->hidden();
use Codewiser\Postie\Channel;

$mail = Channel::via('mail')->active()->forced();

分组订阅

您可以分组订阅以创建仪表板的侧菜单。如果已定义,订阅将继承组中的频道和受众。

use Codewiser\Postie\Group;
use Codewiser\Postie\Subscription;

Group::make('My group')
    ->icon('broadcast')
    ->via('mail', 'database')
    ->for(fn() => User::query())
    ->add(Subscription::to(DailyNewsNotification::class)
    ->add(Subscription::to(NewOrderNotification::class)

预览通知

您可以定义通知预览,因此用户可以看到通知将如何显示。

通知预览可以使用模型工厂等...

use Codewiser\Postie\Subscription;

Subscription::to(DailyNewsNotification::class)
    ->via('email')
    ->for(fn() => User::query())
    ->preview(function(string $channel, $notifiable) {
        
        $news = NewsItem::factory()->count(3)->make();
        
        $notification = new DailyNewsNotification($news);
        
        return match ($channel) {
            'mail' => $notification->toMail($notifiable),
            'telegram' => $notification->toTelegram($notifiable),
            'database', 'broadcast' => $notification->toArray($notifiable),
        };
    });

发送通知

使用 Postie,您可以直接发送通知而无需定义可通知者,因为 Postie 已经知道订阅者。

use Codewiser\Postie\Contracts\Postie;

class OrderController extends Controller
{
    public function store(OrderStoreRequest $request, Postie $postie) 
    {
        $order = Order::create($request->validated());
        
        $postie->send(new NewOrderNotification($order));   
    }
}

如果需要限制可通知者,您可以使用回调

use Codewiser\Postie\Contracts\Postie;

class OrderController extends Controller
{
    public function store(OrderStoreRequest $request, Postie $postie) 
    {
        $order = Order::create($request->validated());
        
        $postie->send(new NewOrderNotification($order), function($builder) use ($order) {
            if ($order->amount > 10) {
                return $builder->where('level', 'vip');
            } else {
                return $builder->whereNull('level');
            }
        });   
    }
}

您仍然可以使用 Facadenotify() 方法发送通知。由于 Notification 使用了 Channelization 特性,它将尊重用户偏好。

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