snebes / notifications-bundle
为 Symfony 项目提供的 snebes/notifications-bundle 集成
Requires
- php: ^7.1.3
- snebes/notifications: ^v1.0
Requires (Dev)
- doctrine/doctrine-bundle: ^1.11
- doctrine/orm: ^2.0
- phpunit/phpunit: ^7.5|^8.0
- symfony/console: ^3.4|^4.0
- symfony/framework-bundle: ^3.4|^4.0
- symfony/maker-bundle: ^1.4
- symfony/phpunit-bridge: ^3.4|^4.0
- symfony/swiftmailer-bundle: ^3.0
Suggests
- doctrine/doctrine-bundle: Allows database channel
- symfony/swiftmailer-bundle: Allows email channel
This package is auto-updated.
Last update: 2024-09-22 18:07:17 UTC
README
snebes/notifications-bundle 为您的 Symfony 项目提供了 snebes/notifications 的集成。Notifications 是一个抽象层,受到 Laravel 的启发,它允许您轻松添加对电子邮件和网页界面消息的支持。
此捆绑包预安装的示例 Symfony 应用程序可用。请查看 snebes/notifications-demo。
先决条件
此捆绑包需要 Symfony 3.4+,并使用 doctrine/doctrine-bundle 和 symfony/swiftmailer-bundle 来提供通知。
安装
将 snebes/notifications-bundle 添加到您的 composer.json 文件
composer require snebes/notifications-bundle
注册捆绑包
Symfony 3
在 app/AppKernel.php 中注册捆绑包
public function registerBundles() { return array( // ... new SN\Bundle\NotificationsBundle\SNNotificationsBundle(), ); }
Symfony 4
在 config/bundles.php 中注册捆绑包。Flex 将为您完成此操作。
return [ // ... SN\Bundle\NotificationsBundle\SNNotificationsBundle::class => ['all' => true], ];
创建通知
每个通知由一个类(通常存储在 src/Notifications 目录中)表示。如果您在应用程序中看不到此目录,当您运行 make:sn:notification 命令时,它将为您创建。
bin/console make:sn:notification
此命令将在您的 src/Notifications 目录中放置一个新的通知类。每个通知类包含一个 via 方法和多个消息构建方法(例如 toMail 或 toArray),这些方法将通知转换为针对特定通道优化的消息。
发送通知
可以通过 NotificationSender 服务发送通知。
<?php namespace App\Service; use App\Entity\User; use App\Notifications\OrderNotification; use SN\Notifications\NotificationSender; class UserService { private $notificationSender; public function __construct(NotificationSender $notificationSender) { $this->notificationSender = $notificationSender; } public function send(User $user) { $this->notificationSender->send($user, new OrderNotification()); } }
此组件提供了辅助函数,使类,如上面的 User 类,可以接受通知。《NotifiableTrait》为任何类添加了接收数据库或邮件消息的能力。
要从实体引用数据库通知,需要为 Doctrine 配置一个 $notification 字段以映射关系。
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use SN\Bundle\NotificationsBundle\Entity\Notification; use SN\Notifications\Contracts\NotifiableInterface; use SN\Notifications\NotifiableTrait; /** * @ORM\Entity() */ class User implements NotifiableInterface { use NotifiableTrait; /** * This field is used by the Mail channel. * * @var string */ private $email = 'demo@example.com'; /** * This field is used by the SMS channel. * * @var string */ private $phoneNumber = '+1 555 555 5555'; /** * @var Notification[] * * @ORM\ManyToMany(targetEntity=Notification::class) * @ORM\JoinTable(name="user_notifications") */ private $notifications; }
指定交付渠道
每个通知类都有一个 via 方法,用于确定通知将在哪些渠道上交付。通知可以在 mail 和 database 渠道上发送。
via 方法接收一个 NotifiableInterface 实例,这将是一个即将发送通知的类的实例。您可以使用 NotifiableInterface 来确定通知应该在哪些渠道上交付。
/** * Get the notification's delivery channels. * * @param NotifiableInterface $notifiable * * @return array */ public function via(NotifiableInterface $notifiable): array { return $notifiable->doNotSendEmail() ? ['database'] : ['database', 'mail']; }
邮件通知
如果通知支持作为电子邮件发送,则该类应实现 MailableInterface 并定义一个 toMail 方法。此方法将接收一个 NotifiableInterface 实体,并应返回一个 SN\Notifications\Contracts\EmailInterface; 实例。让我们看看一个 toMail 方法的示例。
<?php namespace App\Notification; use SN\Notifications\Contracts\EmailInterface; use SN\Notifications\Contracts\MailableInterface; use SN\Notifications\Contracts\NotifiableInterface; use SN\Notifications\Contracts\NotificationInterface; use SN\Notifications\Email\Address; use SN\Notifications\Email\Email; class OrderNotification implements NotificationInterface, MailableInterface { /** * Get the notification's delivery channels. * * @param NotifiableInterface $notifiable * * @return array */ public function via(NotifiableInterface $notifiable): array { return ['mail']; } /** * Get the mail representation of the notification. * * @param NotifiableInterface $notifiable * * @return EmailInterface */ public function toMail(NotifiableInterface $notifiable): EmailInterface { return (new Email()) ->from(new Address('orders@example.com')) ->subject('Thank you for your order.') ->text('We are processing your order right now!'); } }
在此示例中,我们创建了一个具有主题和文本行的电子邮件。由 Email 对象提供的这些方法使格式化小型交易性电子邮件变得简单快捷。邮件通道将自动为每个 NotifiableInterface 填充 to 地址。
自定义收件人
当通过 mail 通道发送通知时,通知系统将自动在您的 NotifiableInterface 实体上查找 email 属性。您可以通过在实体上定义一个 routeNotificationForMail 方法来自定义用于发送通知的电子邮件地址。
<?php namespace App\Entity; use SN\Notifications\Contracts\NotifiableInterface; use SN\Notifications\Contracts\NotificationInterface;use SN\Notifications\NotifiableTrait; class User implements NotifiableInterface { use NotifiableTrait; /** * Route notifications for the mail channel. * * @param NotificationInterface $notification * * @return string */ public function routeNotificationForMail(NotificationInterface $notification) { return $this->getEmailAddress(); } }
数据库通知
先决条件
数据库通知通道将通知信息存储在数据库表中。这个表将包含通知类型以及描述通知的自定义JSON数据。
您可以通过查询表来在应用程序的用户界面中显示通知。但在您这样做之前,您需要创建一个数据库表来存储您的通知。您可以使用doctrine:migration:diff命令生成一个具有适当表模式的迁移。
bin/console doctrine:migration:diff bin/console doctrine:migration:migrate
数据库通知格式化
如果通知支持存储在数据库表中,则类应该实现ArrayableInterface并定义一个toArray方法。此方法将接收一个NotifiableInterface实体,并应该返回一个纯PHP数组。返回的数组将被编码为JSON并存储在通知表的data列中。让我们看看一个toArray方法的例子。
<?php namespace App\Notification; use SN\Notifications\Contracts\ArrayableInterface; use SN\Notifications\Contracts\NotifiableInterface; use SN\Notifications\Contracts\NotificationInterface; class OrderNotification implements NotificationInterface, ArrayableInterface { /** * Get the notification's delivery channels. * * @param NotifiableInterface $notifiable * * @return array */ public function via(NotifiableInterface $notifiable): array { return ['mail']; } /** * Get the mail representation of the notification. * * @param NotifiableInterface $notifiable * * @return array */ public function toArray(NotifiableInterface $notifiable): array { return [ 'order_id' => $this->orderId, 'amount' => $this->amount, ]; } }
访问通知
一旦通知存储在数据库中,您需要一种方便的方式来从您的可通知实体中访问它们。包含在此组件中的NotifiableTrait包含对$notifications关系的辅助器,该关系返回实体的通知。要获取通知,您可以使用getNotifications、getUnreadNotifications和getReadNotifications方法。默认情况下,通知将按createdAt时间戳排序。
$user = $this->getUser(); foreach ($user->getUnreadNotifications() as $notification) { echo $notification->data['message']; }
标记通知为已读
通常,当用户查看通知时,您会想将其标记为“已读”。SSN\Bundle\NotificationsBundle\Entity\Notification实体类提供了一个setReadAt方法,该方法更新通知数据库记录上的readAt列。
$user = $this->getUser(); foreach ($user->getUnreadNotifications() as $notification) { $notification->setReadAt(new \DateTime()); }
通知事件
当发送通知时,组件会分发多个事件,您可以使用这些事件来修改通知的处理方式。
NotificationEvents::SENDING
事件类:SN\Notifications\Event\NotificationSendingEvent
在发送通知之前会分发此事件。它用于向通知添加更多信息或阻止通知发送。
执行此命令以找出已注册的此事件的监听器和它们的优先级。
bin/console debug:event-dispatcher sn.notifications.sending
NotificationEvents::SEND
事件类:SN\Notifications\Event\NotificationSendEvent
在发送通知时,会分发此事件。其主要用途是将通知发送到所需的通道,这是此组件内部使用通道的方式。
执行此命令以找出已注册的此事件的监听器和它们的优先级。
bin/console debug:event-dispatcher sn.notifications.send
NotificationEvents::SENT
事件类:SN\Notifications\Event\NotificationSentEvent
在通知成功发送后,会分发此事件。它用于在发送的通知上执行任务。
执行此命令以找出已注册的此事件的监听器和它们的优先级。
bin/console debug:event-dispatcher sn.notifications.sent
NotificationEvents::EXCEPTION
事件类:SN\Notifications\Event\NotificationExceptionEvent
在处理通知时出现错误时,会立即分发此事件。它用于从错误中恢复或修改通知。
执行此命令以找出已注册的此事件的监听器和它们的优先级。
bin/console debug:event-dispatcher sn.notifications.exception
自定义通道
此组件附带了一些通知通道,但您可能想编写自己的通道来通过其他方法发送通知。分发的通知事件使其变得简单。要开始,定义一个类,该类侦听或订阅NotificationEvents::SEND事件。
<?php namespace App\Channel; use SN\Notifications\Event\NotificationSendEvent; use SN\Notifications\NotificationEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class CustomChannel implements EventSubscriberInterface { /** * @return array */ public static function getSubscribedEvents(): array { return [ NotificationEvents::SEND => 'send', ]; } /** * Send the given notification. * * @param NotificationSendEvent $event */ public function send(NotificationSendEvent $event): void { $notifiable = $event->getNotifiable(); $notification = $event->getNotification(); // Send notification to the $notifiable. } }
一旦定义了您的通知通道类,您就可以从任何通知的via方法返回该类名。