namshi/notificator

一个轻量级的库,用于智能处理通知。

5.1.1 2018-06-05 22:11 UTC

README

Build Status

SensioLabsInsight

Notificator 是一个非常简单且轻量级的库,用于以智能的方式处理通知。

它从其他库和模式(Monolog 和事件分发)中汲取灵感,以提供一个领域驱动的精益通知库。

概念非常简单:你有一个通知 Manager,它注册了一些处理程序(可能是一个 电子邮件 处理程序,一个 Skype 处理程序等);你只需要创建一个通知类,定义哪些处理程序应该处理它,并通过管理器触发它。

在代码中比在文字中简单得多,请查看下面的文档!

安装

可以通过 composer 进行安装,因为库已经存在于 packagist 上。

该库为其 API 使用语义版本控制,因此建议使用稳定的次要版本(1.0、1.1 等)并通过 composer 声明依赖时坚持使用它

"namshi/notificator": "1.0.*",

用法

由于它简单而易于理解的概念(借鉴自其他库):你基本上有一个通知管理器,其中包含一些处理程序,然后你通过管理器触发(trigger())通知。在那个时刻,所有需要触发该通知的处理程序将负责在其上下文中触发它(可能是一个电子邮件,一个 Skype 消息等),并告诉管理器它们已经完成,以便管理器可以将通知转发给下一个处理程序。

<?php

// import namespaces
use Namshi\Notificator\Notification\Handler\NotifySend as NotifySendHandler;
use Namshi\Notificator\Manager;
use Namshi\Notificator\Notification\NotifySend\NotifySendNotification;

//  create the handler
$handler = new NotifySendHandler();

// create the manager and assign the handler to it
$manager = new Manager();
$manager->addHandler($handler);

$notification = new NotifySendNotification("...whatever message...");

//  trigger the notification
$manager->trigger($notification);

以下代码,在 ubuntu 上运行,将使用 notify-send 实用程序触发通知

notify-send

通知管理器

管理器是注册所有处理程序并触发通知的实体。

你可以很容易地设置和添加处理程序

<?php

$handler  = new MyHandler();
$handlers = array(
    new AnotherHandler(), new AnotherOneHandler(),
);

$manager = new Manager();

// add multiple handlers
$manager->setHandlers($handlers);

// add a single handler
$manager->addHandler($handler);

// reset the handlers
$manager->setHandlers(array());

创建新的通知

创建新的通知非常简单,因为它们是普通的 PHP 类。

它们 可能 扩展基本通知类,但这不是必需的。为了能够通过多个处理程序触发一个通知,建议扩展基本通知类,并实现不同的接口,这些接口稍后将由处理程序检查。

<?php

use Namshi\Notificator\Notification;
use Namshi\Notificator\NotificationInterface;

interface EchoedNotificationInterface extends NotificationInterface
{
    public function getMessage();
}

interface EmailNotificationInterface extends NotificationInterface
{
    public function getAddress();
    public function getSubject();
    public function getBody();
}

class DoubleNotification extends Notification implements EchoedNotificationInterface, EmailNotificationInterface
{
    protected $address;
    protected $body;
    protected $subject;

    public function __construct($address, $subject, $body, array $parameters = array())
    {
        parent::__construct($parameters);

        $this->address  = $address;
        $this->body     = $body;
        $this->subject  = $subject;
        $this->message  = $body;
    }

    public function getAddress()
    {
        return $this->address;
    }

    public function getSubject()
    {
        return $this->subject;
    }

    public function getBody()
    {
        return $this->body;
    }

    public function getMessage()
    {
        return $this->message;
    }
}

正如你可能已经看到的,上面的通知类旨在通过电子邮件 使用 echo 函数(相当无用地,但给你一个想法)来触发。

但工作还没有完成,因为你还需要为这个通知实现处理程序...

创建一个新的处理程序

假设我们想要创建处理上述通知的处理程序,通过回显它并发送电子邮件:这是一个实现两个类的问题,带有几个方法,shouldHandlehandle

让我们看看 EchoedNotificationHandler 应该是什么样子

use Namshi\Notificator\Notification\Handler\HandlerInterface;
use Namshi\Notificator\NotificationInterface;

class EchoedNotificationHandler implements HandlerInterface
{
    public function shouldHandle(NotificationInterface $notification)
    {
        return $notification instanceOf EchoedNotificationInterface;
    }

    public function handle(NotificationInterface $notification)
    {
        echo $notification->getMessage();
    }
}

非常简单,对吧?

首先,我们需要检查这个处理程序是否处理给定的通知,这可以通过查看通知是否实现了已知接口来完成;其次,我们实际上触发通知。

同样的事情需要为 EmailNotificationHandler 做。

use Namshi\Notificator\Notification\Handler\HandlerInterface;
use Namshi\Notificator\NotificationInterface;

class EmailNotificationHandler implements HandlerInterface
{
    public function shouldHandle(NotificationInterface $notification)
    {
        return $notification instanceOf EmailNotificationInterface;
    }

    public function handle(NotificationInterface $notification)
    {
        mail($notification->getAddress(), $notification->getSubject(), $notification->getBody());
    }
}

如果你想在一个处理程序触发通知后停止通知传播,你只需要在处理程序的 handle 方法中返回 false

public function handle(NotificationInterface $notification)
{
    // do whatever you want with the notification
    // ...

    return false;
}

这将告诉管理器停止将通知传播到其他处理程序。

在 Symfony2 中

Namshi 目前在其 Symfony2 应用程序中使用此库。

将捆绑包添加到你的 AppKernel.php 中

     $bundles = array(
         ...
         new Namshi\Notificator\Symfony\NamshiNotificatorBundle()
     );

要注册新的处理器,请创建一个包含 notification.handler 标签的服务

namshi.notification.handler.email:
    class: Namshi\Notificator\Notification\Handler\Emailvision
    arguments:
      client: @namshi.email_client.emailvision
            
    tags:
        - { name: notification.handler }

namshi.email_client.emailvision:
    class: Namshi\Emailvision\Client
    arguments:
      config:
        test_email:
          random:   AAA
          encrypt:  BBB
          uidkey:   email
          stype:    NOTHING

此配置注册了 Emailvision 处理器。

RabbitMQ

如果您使用 Symfony2 和 RabbitMQBundle,您可以通过 RabbitMQ 使用此库触发通知,使用提供的消费者

将消费者声明为服务

namshi.notification.consumer:
    class: Namshi\Notificator\Messaging\RabbitMQ\Symfony2\Consumer
    arguments: [@namshi.notification.manager]

然后在 RabbitMQ 包中配置它

old_sound_rabbit_mq:
    consumers:
        notification:
            connection: default
            exchange_options: {name: 'notifications', type: direct}
            queue_options:    {name: 'notifications'}
            callback:         namshi.notification.consumer

然后您可以运行消费者

php app/console rabbitmq:consumer -w notification

发送通知时,您可以将它们序列化在 RabbitMQ 消息中

$publisher = $container->get('old_sound_rabbit_mq.notifications_producer');

$notification = new MyWhateverNotification("man, this comes from RabbitMQ and Symfony2!");

$publisher->publish(serialize($notification));

这就完了!

内置处理器

Namshi,我们根据我们的需求开发了一些非常简单、内置的处理器。请记住,构建此类库的主要原因是从我们的 SOA 的每个组件触发通知的能力,主要是通过 RabbitMQ。

您可以利用以下处理器

  • SwiftMailer,它允许您使用惊人的 SwiftMailer 通过任何 SMTP 服务器发送电子邮件通知(例如,亚马逊的 SES 或 SendGrid)
  • HipChat,它在 HipChat 房间中发布消息
  • Emailvision,它通过 Emailvision API 发送电子邮件
  • NotifySend,它在 Ubuntu 上触发通知
  • RabbitMQ,它通过 RabbitMQ 触发通知

如果您有一个新的处理器的想法,不要犹豫提交 pull request:当然,它们可以在您自己的代码中实现,但为什么不让它们与开源生态系统共享呢?

示例

您可以在 examples 目录下查看提供的几个示例

运行规格

在运行 composer install 之后运行 spec 套件,请执行以下操作

php vendor/bin/phpspec run --format=dot