infotech/yii-message-renderer

Yii 1.1 的消息渲染组件

v1.1.1 2017-05-23 09:45 UTC

This package is not auto-updated.

Last update: 2024-09-28 19:58:11 UTC


README

几乎每个产品都需要发送消息(如电子邮件、短信等)的功能,基于用户模板。

这个库提供了解决与消息模板化相关问题的概念性解决方案,例如

  • 定义消息绘制上下文(确定替换项集及其从模型或数据库查询结果中提取的顺序);
  • 实际绘制消息(填充模板数据);
  • 输出替换项的帮助;
  • 流式绘制大量消息(使用 CDataProviderIterator)。

使用方法

要将库连接到产品,请通过 composer 请求它

php composer.phar require infotech/yii-message-renderer

应用程序的关键组件是 MessageRendererComponent 组件。

要使用该组件,必须在应用程序配置中连接它

    ...
    'components' => array(
        'messageRenderer' => array(
            'class' => 'Infotech\MessageRenderer\MessageRendererComponent',
            'contexts' => [
                'SomeMessageContext',
                'AnotherMessageContext',
            ]
        ),
        ...
    ),
    ...

其中 SomeMessageContextAnotherMessageContext 是消息绘制上下文的类名,我们将在下面介绍。

现在,要绘制一条消息,只需编写

    Yii::app()->messageRenderer->render($contextType, $templateStringOrArray, $data);

要绘制多条消息,则需要使用

    foreach (Yii::app()->messageRenderer->renderBatch($contextType, $templateStringOrArray, $dataProvider) as $message) {
        // тип данных $message зависит от реализации метода `renderTemplate()` контекста
    }

消息绘制上下文

每个消息绘制上下文类都是抽象 Infotech\MessageRenderer\MessageContext 的派生类,并定义了替换项的组成和数据提取方式。

类上下文接口中有方法 renderTemplate($templateStringOrArray, $data),它接受模板字符串(或模板字符串数组)和填充模板的数据,并返回绘制的字符串(或具有相同键的绘制字符串数组)。

以下是一个上下文类的示例。假设我们有一个 User 模型,还有一个 Task 与 "assignee"(BELONGS_TOUser)和 "reporter"(BELONGS_TOUser)的关系。

class TaskMessageContext extends \Infotech\MessageRenderer\MessageContext
{

    public function placeholdersConfig()
    {
        return array(
            '_НОМЕР_ЗАДАЧИ_' => array(
                'title' => 'Номер задачи',
                'description' => 'Номер задачи. Например, "#142"',
                'fetcher' => function (Task $task) { return '#' . $task->id; },
            ),
            '_СТАТУС_ЗАДАЧИ_' => array(
                'title' => 'Статус задачи',
                'description' => 'Статус задачи. Например, "выполняется"',
                'fetcher' => 'statusName',
            ),
            '_ТЕМА_ЗАДАЧИ_' => array(
                'title' => 'Тема задачи',
                'description' => 'Тема задачи. Например, "Увеличить логотип на главной странице"',
                'fetcher' => 'subject',
            ),
            '_ИМЯ_ИСПОЛНИТЕЛЯ_' => array(
                'title' => 'Имя исполнителя',
                'description' => 'Имя сотрудника, на которого назначена задача (в именительном падеже). Например, "Василий Кузнецов"',
                'fetcher' => 'assignee.full_name',
                'empty' => '(не назначен)',
            ),
            '_ИМЯ_ПОЛЬЗОВАТЕЛЯ_' => array(
                'title' => 'Имя пользователя',
                'description' => 'Имя сотрудника, выполняющего действие над задачей (в именительном падеже). Например, "Константин Отрубов"',
                'fetcher' => function () { return Yii::app()->getUser()->getModel()->fullName; },
            ),
            '_ПОЧТА_ПОЛЬЗОВАТЕЛЯ_' => array(
                'title' => 'E-mail пользователя',
                'description' => 'E-mail сотрудника, выполняющего действие над задачей. Например, "otrubov@example.com"',
                'fetcher' => function () { return Yii::app()->getUser()->getModel()->email; },
            ),
        );
    }

    public function getType()
    {
        return 'task';
    }

    public function getName()
    {
        return 'Задачи';
    }
}

现在,我们假设已经将上下文注册到组件配置中。

现在,为了发送关于任务状态变化的电子邮件通知,我们将编写

$task = ...; // задача, изменившая статус
// достали шаблон из БД или иного источника
$template = array( 
    'message' => '_ИМЯ_ПОЛЬЗОВАТЕЛЯ_ перевел задачу в статус "_СТАТУС_ЗАДАЧИ_"',
    'subject' => 'Изменение статуса задачи №_НОМЕР_ЗАДАЧИ_',
    'from' => 'notifier@example.com',
    'to' => '_ПОЧТА_ПОЛЬЗОВАТЕЛЯ_',
);

$emailData = Yii::app()->messageRenderer->render('task_issue', $template, $task);

Yii::app()->mailer->send($emailData['message'], $emailData['subject'], $emailData['to'], $emailData['from']);

要发送批量邮件,我们将编写

$tasks = ...; // Traversable с задачами, изменившими статус
// достали шаблон из БД или иного источника
$template = array( 
    'message' => '_ИМЯ_ПОЛЬЗОВАТЕЛЯ_ перевел задачу в статус "_СТАТУС_ЗАДАЧИ_"',
    'subject' => 'Изменение статуса задачи №_НОМЕР_ЗАДАЧИ_',
    'from' => 'notifier@example.com',
    'to' => '_ПОЧТА_ПОЛЬЗОВАТЕЛЯ_',
);

$messagesIterator = Yii::app()->messageRenderer->renderBatch('task_issue', $template, $tasks);

foreach ($messagesIterator as $emailData) {
    if ($emailData['to']) {
        Yii::app()->mailer->send($emailData['message'], $emailData['subject'], $emailData['to'], $emailData['from']);
    }
}