damianociarla/notification-bundle
Composer 安装命令:
composer require damianociarla/notification-bundle
包简介
DCSNotificationBundle is a Symfony2 bundle that allows you to send notifications of any type to any recipient
README 文档
README
DCSNotificationBundle is a Symfony2 bundle that allows you to send notifications.
Usage example
To illustrate how the bundle works, we will go through an example. We have a Blog application which permits logged users to add comments to published posts.
When a reader leaves a message under one of the posts, the author of the post and all the previous commenters receive an email about the new comment. Since we are responsible developers, we give to all commenters the option to disable the notification.
The flow
The DCSNotificationBundle exposes tree important services:
dcs_notification.service.notificationwhich, through thenotify()method, takes care of handling the notificationdcs_notification.manager.componentresponsible of creating thesubjectof the notificationdcs_notification.service.notifierwhich, through theprocess()method processes the notification
For each type of notification we are responsible for creating a notifier and a transporter that know how to manage the notification.
Configuration
To use the DSCNotificationBunde we need to configure the bundle and our notifiers.
An example configuration of the bundle could be the following:
dcs_notification:
db_driver: orm
class:
model:
component: Blog\NotificationBundle\Entity\Component
component_setting: Blog\NotificationBundle\Entity\ComponentSetting
notification: Blog\NotificationBundle\Entity\Notification
notification_component: Blog\NotificationBundle\Entity\NotificationComponent
recipient: Blog\NotificationBundle\Entity\Recipient
transporters:
mail:
id: blog_notification.transporter.mail
actions:
new_comment:
transporters:
mail:
id: mail
config:
template: BlogNotificationBundle:Email:new_comment.html.twig
dcs_notification is the key for the DCSNotificationBundle configuration. To use the bundle John first configured the mandatory keys:
db_driverset toormwill tell Symfony 2 to use Doctrine ORMclasscontains the list of model classes. If we don't need nothing fancy, we can just extend the base classes provided by the bundle:Blog\NotificationBundle\Entity\Component extends DCS\NotificationBundle\Entity\ComponentBlog\NotificationBundle\Entity\ComponentSetting extends DCS\NotificationBundle\Entity\ComponentSettingBlog\NotificationBundle\Entity\Notification extends DCS\NotificationBundle\Entity\NotificationBlog\NotificationBundle\Entity\NotificationComponent extends DCS\NotificationBundle\Entity\NotificationComponentBlog\NotificationBundle\Entity\Recipient extends DCS\NotificationBundle\Entity\Recipient
transportersdefines a list of transporters associated with valid servicesactionsare the list of accessible actions, configured with the transporters associated
To be able to use the bundle we need to configure the notifiers. This is an example configuration:
services:
blog.notification_bundle.notifier.new_comment:
class: Blog\NotificationBundle\Notifier\NewCommentNotifier
tags:
- { name: dcs_notification.notifier }
In this way we added the blog.notification_bundle.notifier.new_comment notifier.
Notifying the notification
The dcs_notification.service.notification service represents the entry point of the notification flow. The service is used through the notify() method as follows:
$commentComponent = $this->componentManager->findOrCreateComponent($comment, $comment->getId()); $this->notificationService->notify($commentComponent, 'new_comment', array('url' => $currentUrl));
The first argument of the notify() method is called subject. This could be anything, as long as it's wrapped in a DCS\NotificationBundle\Model\ComponentManagerInterface type object. In the example we decided to pass the comment to the notify() method because the comment has a lot of information on what's happening: the comment itself, the author of the comment, the post to which the comment was made to, and, from the post, the author of the post, the other comments left on the posts and, finally, all the authors of the other comments. The second argument is new_comment and is called the action of the notice. We will get back on the action later. The third argument is not mandatory and contains additional data to which we want to be able to access later.
The notify() method doesn't actually process the notification but saves it as "pending".
A different way to pass data the notify() method:
We could have decided to implement the notification in a different way, passing the comment in the third argument and being more generic with the subject:
$commentComponent = $this->componentManager->findOrCreateComponent('the_comment_subject', $comment->getId()); $this->notificationService->notify( $commentComponent, 'new_comment', array( 'url' => $currentUrl, 'id' => $comment->getId() ) );
This change would affect how we process the notification.
Processing pending notifications
The dcs_notification.manager.notification service exposes the findAllNotificationToSend() method, which returns al the pending notifications.
Having the list of pending notification, these can be processed using the dcs_notification.service.notifier service as follows:
$notificationsToSend = $this->getContainer()->get('dcs_notification.manager.notification')->findAllNotificationToSend($limit); $notifierService = $this->getContainer()->get('dcs_notification.service.notifier'); foreach ($notificationsToSend as $notification) { $notifierService->process($notification); }
The code above could be used in a command-line command set to be run periodically using using cron.
Notifiers
At this point we have a list of pending notifications being processed one at a time. When the process() method is called, two important things happen:
- each notifier is being asked if knows how to manage the current notification and, if the result is positive, the the notification is passed to it
- the transporter is called
A notifier is a class implementing the DCS\NotificationBundle\Notifier\NotifierInterface interface.
In our example, we have a new notification with the new_comment action and a valid notifier could be used to manage the recipients of the notification:
<?php namespace Blog\NotificationBundle\Notifier; use DCS\NotificationBundle\Model\NotificationComponentInterface; use DCS\NotificationBundle\Model\NotificationInterface; use DCS\NotificationBundle\Model\NotificationManagerInterface; use DCS\NotificationBundle\Notifier\Collection\RecipientCollectionInterface; use DCS\NotificationBundle\Notifier\NotifierInterface; use Blog\PostBundle\Entity\Post; use Blog\PostBundle\Entity\Comment; use Blog\PostBundle\Repository\CommentRepository; use Blog\UserBundle\Entity\User; class NewCommentNotifier implements NotifierInterface { protected $notificationManager; protected $projectRepository; function __construct(NotificationManagerInterface $notificationManager, CommentRepository $commentRepository) { $this->notificationManager = $notificationManager; $this->commentRepository = $commentRepository; } public function supports(NotificationInterface $notification) { return $notification->getAction() == 'new_comment'; } public function notify(NotificationInterface $notification, RecipientCollectionInterface $recipients) { $notificationComponents = $this->notificationManager->findAllNotificationComponent($notification); /** @var NotificationComponentInterface $notificationComponent */ foreach ($notificationComponents as $notificationComponent) { if ($notificationComponent->getType() == 'comment') { /** @var Comment $comment */ $comment = $notificationComponent->getComponent()->getData(); if ($comment instanceof Comment) { $commentAuthor = $comment->getAuthor(); $post = $comment->getPost(); $postAuthor = $post->getAuthor(); if ($comment->getAuthor()->getId() != $postAuthor->getId()) { $recipients->add('Blog\UserBundle\Entity\User', $postAuthor->getId()); } $commenters = $this->commentRepository->findAllCommentersToPost($post); /** @var User $member */ foreach ($commenters as $commenter) { if ($commenter->getId() != $postAuthor->getId() && $commenter->getId() != $postAuthor->getId()) { $recipients->add('Blog\UserBundle\Entity\User', $commenter->getId()); } } } } } } }
Whit the Blog\NotificationBundle\Notifier\CommentNotifier class we are now able to add the correct recipients to the notification: the author of the post and all the commenters. The notification is ready to be sent to the transporter.
Transporters
A transporter is a class implementing the DCS\NotificationBundle\Transporter\TransporterInterface interface. The interface asks the developer to implement two methods: setConfiguration() and send():
<?php namespace DCS\NotificationBundle\Transporter; use DCS\NotificationBundle\Model\NotificationInterface; use DCS\NotificationBundle\Model\RecipientInterface; interface TransporterInterface { public function setConfiguration($config); public function send(NotificationInterface $notification, array $additionalData, RecipientInterface $recipient); }
If we look back at the actions.new_comment.transporters.mail.config configuration, we have defined an option which specifies the template associated with the transporter. The options are injected in the blog_notification.transporter.mail service through the setConfiguration() method.
The send() method is responsible of doing the actual work of sending the notification. Will accept a $notification object, a $components array and a $recipient object.
$notificationobject contains the notification subject that needs to be sent$additionalDatacontains the data passed to the third parameter of the$notificationService->notify()method$recipientis the recipient
An example implementation of the send() method could be the following:
public function send(NotificationInterface $notification, array $additionalData, RecipientInterface $recipient) { if (!isset($this->config['template'])) { throw new \Exception('Template must be set in this transporter'); } $recipient = $recipient->getComponent()->getData(); $templateName = $this->config['template']; $attach = array(); $context = array( 'siteUrlHttp' => $this->siteUrlHttp, 'subject' => $notification->getSubject()->getData(), 'notification' => $notification, 'recipient' => $recipient, ); $email = null; if ($recipient instanceof User) { $email = $recipient->getEmailCanonical(); } elseif (is_array($recipient) && isset($recipient['email']) && is_scalar($recipient['email'])) { $email = $recipient['email']; } if (!empty($email)) { $this->sendMessage($templateName, $context, $email, $attach); } } private function sendMessage($templateName, $context, $toEmail, array $attach = null) { // send the email }
damianociarla/notification-bundle 适用场景与选型建议
damianociarla/notification-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 431 次下载、GitHub Stars 达 0, 最近一次更新时间为 2014 年 11 月 13 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「Symfony2」 「cron」 「schedule」 「notification」 「recipient」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 damianociarla/notification-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 damianociarla/notification-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 damianociarla/notification-bundle 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Symfony bundle to monitor and execute commands
Enables the creation of cron-jobs tasks to be consumed by symfony/messenger
Scheduling extension for Yii2 framework
A Deployment/Change Log Schedule and Notes system for SilverStripe sites
Monitoring for scheduled jobs
Temporal frequency library
统计信息
- 总下载量: 431
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 18
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2014-11-13