tobento / app-notifier
应用通知支持。
Requires
- php: >=8.0
- psr/container: ^2.0
- symfony/vonage-notifier: ^6.0
- tobento/app: ^1.0.7
- tobento/app-database: ^1.0
- tobento/app-mail: ^1.0
- tobento/app-migration: ^1.0
- tobento/app-queue: ^1.0
- tobento/service-autowire: ^1.0.9
- tobento/service-clock: ^1.0
- tobento/service-collection: ^1.0
- tobento/service-notifier: ^1.0
- tobento/service-repository-storage: ^1.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^9.5
- tobento/service-console: ^1.0.3
- tobento/service-container: ^1.0
- tobento/service-filesystem: ^1.0.5
- tobento/service-routing: ^1.1.3
- tobento/service-translation: ^1.0.3
- vimeo/psalm: ^4.0
README
使用Notifier Service对应用进行通知支持的插件。
目录
入门
运行此命令以添加正在运行的应用通知项目的最新版本。
composer require tobento/app-notifier
要求
- PHP 8.0 或更高版本
文档
应用
如果您使用的是骨架,请查看 App Skeleton。
您还可以查看 App 以了解有关应用的更多信息。
通知启动
通知启动执行以下操作
- 安装和加载通知配置文件
- 实现通知接口
use Tobento\App\AppFactory; use Tobento\Service\Notifier\NotifierInterface; use Tobento\Service\Notifier\ChannelsInterface; use Tobento\Service\Notifier\QueueHandlerInterface; use Tobento\App\Notifier\AvailableChannelsInterface; use Tobento\App\Notifier\NotificationsInterface; use Tobento\App\Notifier\Storage\NotificationFormattersInterface; // Create the app $app = (new AppFactory())->createApp(); // Add directories: $app->dirs() ->dir(realpath(__DIR__.'/../'), 'root') ->dir(realpath(__DIR__.'/../app/'), 'app') ->dir($app->dir('app').'config', 'config', group: 'config') ->dir($app->dir('root').'public', 'public') ->dir($app->dir('root').'vendor', 'vendor'); // Adding boots $app->boot(\Tobento\App\Notifier\Boot\Notifier::class); $app->booting(); // Implemented interfaces: $notifier = $app->get(NotifierInterface::class); $channels = $app->get(ChannelsInterface::class); $queueHandler = $app->get(QueueHandlerInterface::class); $availableChannels = $app->get(AvailableChannelsInterface::class); $notificationFormatters = $app->get(NotificationFormattersInterface::class); $notifications = $app->get(NotificationsInterface::class); // Run the app $app->run();
通知配置
通知配置位于默认 App Skeleton 配置位置下的 app/config/notifier.php
文件中,您可以在其中指定应用的通知通道。
创建和发送通知
use Tobento\Service\Notifier\NotifierInterface; use Tobento\Service\Notifier\Notification; use Tobento\Service\Notifier\Recipient; class SomeService { public function send(NotifierInterface $notifier): void { // Create a Notification that has to be sent: // using the "email" and "sms" channel $notification = new Notification( subject: 'New Invoice', content: 'You got a new invoice for 15 EUR.', channels: ['mail', 'sms'], ); // The receiver of the notification: $recipient = new Recipient( email: 'mail@example.com', phone: '15556666666', ); // Send the notification to the recipient: $notifier->send($notification, $recipient); } }
有关更多信息,请查看 Notifier Service - Creating And Sending Notifications 部分。
支持的通道
默认支持以下通道
-
短信通道 - Vonage,您只需在 通知配置 文件中配置dns。
排队通知
发送通知可能是一个耗时任务,您可以通过排队通知消息以在后台发送来减轻这个问题。
要排队通知消息,只需将 队列参数 添加到您的消息
示例
use Tobento\Service\Notifier\NotifierInterface; use Tobento\Service\Notifier\Notification; use Tobento\Service\Notifier\Recipient; use Tobento\Service\Notifier\Parameter\Queue; class SomeService { public function send(NotifierInterface $notifier): void { // Create a Notification that has to be sent: // using the "email" and "sms" channel $notification = (new Notification( subject: 'New Invoice', content: 'You got a new invoice for 15 EUR.', channels: ['mail', 'sms'], ))->parameter(new Queue( // you may specify the queue to be used: name: 'secondary', // you may specify a delay in seconds: delay: 30, // you may specify how many times to retry: retry: 3, // you may specify a priority: priority: 100, // you may specify if you want to encrypt the message: encrypt: true, )); // The receiver of the notification: $recipient = new Recipient( email: 'mail@example.com', phone: '15556666666', ); // Send the notification to the recipient: $notifier->send($notification, $recipient); } }
通知启动 自动启动 App Queue Boot 以支持开箱即用的消息排队。
您只需在 队列配置 文件中配置您的队列。
可用通道
可用的通道可用于限制某些服务的通道或显示其名称和/或标题。默认情况下,将在 app/config/notifier.php
文件中指定的所有通道都将可用。
use Tobento\App\Notifier\AvailableChannelsInterface; $channels = $app->get(AvailableChannelsInterface::class); var_dump($channels->has(channel: 'sms')); // bool(true) var_dump($channels->titleFor(channel: 'sms')); // string(3) "Sms" var_dump($channels->names()); // array(3) {[0]=> string(4) "mail" [1]=> string(3) "sms" [2]=> string(7) "storage"} var_dump($channels->titles()); // array(3) {[0]=> string(4) "Mail" [1]=> string(3) "Sms" [2]=> string(7) "Storage"} var_dump($channels->titlesToString(separator: ', ')); // string(18) "Mail, Sms, Storage" // Add a new title for a channel returning a new instance: $channels = $channels->withTitle(channel: 'sms', title: 'SMS Channel'); var_dump($channels->titleFor(channel: 'sms')); // string(11) "SMS Channel" // Returns a new instance with the channels mapped. $channels = $channels->map(fn($title, $name) => strtoupper($title)); var_dump($channels->titlesToString(separator: ', ')); // string(26) "MAIL, SMS CHANNEL, STORAGE" // Returns a new instance with the channels sorted by its name: $channels = $channels->sortByName(); // Returns a new instance with the channels sorted by its title: $channels = $channels->sortByTitle(); // Count channels: var_dump($channels->count()); // int(3) // Returns a new instance with with only the channels specified: $channels = $channels->only(['sms', 'mail']); // Returns a new instance with the channels except those specified: $channels = $channels->except(['sms', 'mail']); // Iteration: foreach($channels->all() as $name => $title) {} // or just: foreach($channels as $name => $title) {}
存储通知格式化程序
存储通知格式化程序可用于格式化由 存储通道 存储的通知。
通用格式化程序
您可以使用通用格式化程序,它使用以下存储消息数据
use Tobento\Service\Notifier\Notification; use Tobento\Service\Notifier\Message; $notification = (new Notification()) ->addMessage('storage', new Message\Storage([ 'message' => 'You received a new order.', 'action_text' => 'View Order', 'action_route' => 'orders.view', 'action_route_parameters' => ['id' => 555], ]));
在 app/config/notifier.php
'formatters' => [ \Tobento\App\Notifier\Storage\GeneralNotificationFormatter::class, ],
如果已安装 App Http - Routing Boot,则将使用 action_route
和 action_route_parameters
数据来生成消息 URL。
如果您已安装App Translation Boot,则格式化程序将翻译message
和action_text
数据。
通用格式化程序示例
您可以为通知创建自己的通用格式化程序
use Tobento\App\Notifier\Storage\NotificationFormatterInterface; use Tobento\App\Notifier\Storage\Notification; class GeneralNotificationFormatter implements NotificationFormatterInterface { public function format(Notification $notification): Notification { // General data available: $id = $notification->id(); $name = $notification->name(); $recipientId = $notification->recipientId(); $recipientType = $notification->recipientType(); $readAt = $notification->get('read_at'); $createdAt = $notification->get('created_at'); $subject = $notification->get('data.subject', ''); $content = $notification->get('data.content', ''); // Format: return $notification ->withMessage($subject.': '.$content); } }
在 app/config/notifier.php
'formatters' => [ GeneralNotificationFormatter::class, ],
特定格式化程序示例
您可以为仅特定通知创建特定格式化程序
use Tobento\App\Notifier\Storage\NotificationFormatterInterface; use Tobento\App\Notifier\Storage\Notification; use Tobento\Service\Translation\TranslatorInterface; use Tobento\Service\Routing\RouterInterface; class NewOrderNotificationFormatter implements NotificationFormatterInterface { public function __construct( protected TranslatorInterface $translator, protected RouterInterface $router, ) {} public function format(Notification $notification): Notification { // You may only format specific notifications if (!$notification->name() instanceof NewOrderNotification) { return $notification; } // Stop further formatters to format notification: $notification->stopPropagation(true); // Retrieve specific message data: $orderId = $notification->get('data.order_id'); // Format: return $notification ->withMessage($this->translator->trans('New order received')) ->withAddedAction( text: $this->translator->trans('View Order'), url: $this->router->url('orders.view', ['id' => $orderId]), ); } }
在 app/config/notifier.php
'formatters' => [ NewOrderNotificationFormatter::class, GeneralNotificationFormatter::class, ],
自定义通知
您可以通过在app/config/notifier.php
文件中定义它们来轻松自定义通知
use Tobento\Service\Notifier\Parameter\Queue; use Tobento\Service\Notifier\NotificationInterface; 'notifications' => [ // using a custom notification: UserRegisterNotification::class => CustomUserRegisterNotification::class, // using a notification factory: UserRegisterNotification::class => UserRegisterNotificationFactory::class, // using a closure: UserRegisterNotification::class => function (UserRegisterNotification $notification): NotificationInterface { return $notification->parameter(new Queue()); }, // if named notification: 'register' => CustomUserRegisterNotification::class, ],
创建自定义通知
use Tobento\Service\Notifier\AbstractNotification; use Tobento\Service\Notifier\RecipientInterface; use Tobento\Service\Notifier\Message; class CustomUserRegisterNotification extends AbstractNotification implements Message\ToSms { public function __construct( protected UserRegisterNotification $notification, // ... ) {} public function toSms(RecipientInterface $recipient, string $channel, SomeService $service): Message\SmsInterface { return new Message\Sms( subject: 'Thanks for your registration', ); } }
创建通知工厂
use Tobento\App\Notifier\NotificationFactoryInterface; use Tobento\Service\Notifier\NotificationInterface; class UserRegisterNotificationFactory implements NotificationFactoryInterface { public function createNotification(NotificationInterface $notification): NotificationInterface { // create custom notification: // or modify original: return $notification; } }
清除通知命令
如果您已安装App Console,则可以使用notifications:clear
命令清除支持它的所有渠道的通知,例如存储渠道。
清除所有支持渠道的通知
php ap notifications:clear
清除所有特定渠道的通知
php ap notifications:clear --channel=foo --channel=bar
可用选项