yii2tech/activemail

此包已被废弃,不再维护。未建议替代包。

Yii2 框架的项目安装支持扩展

资助包维护!
klimov-paul
Patreon

安装: 8 006

依赖: 0

建议者: 0

安全: 0

星星: 18

观察者: 5

分支: 5

开放问题: 0

类型:yii2-extension

1.0.0 2017-04-24 13:52 UTC

This package is auto-updated.

Last update: 2022-01-10 10:40:43 UTC


README

12951949

ActiveMail 扩展 for Yii 2


此扩展为 Yii2 提供了“活动邮件消息”概念实现。活动消息是一个模型,它知道所有必要的自组成数据,并且可以自己发送。

有关许可证信息,请参阅 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

要求

此扩展需要任何 Yii2 邮件发送实现,例如 yiisoft/yii2-swiftmailer

安装

安装此扩展的首选方式是通过 composer

运行以下命令之一:

php composer.phar require --prefer-dist yii2tech/activemail

或者

"yii2tech/activemail": "*"

将以下内容添加到您的 composer.json 文件的 require 部分。

注意:您应该单独安装特定的邮件发送扩展,例如 'yiisoft/yii2-swiftmailer'。

用法

此扩展为 Yii2 提供了“活动邮件消息”概念实现。ActiveMessage 是一个模型,它知道所有必要的自组成数据,并且可以自己发送。它允许基于存储在 PHP 文件或数据库中的模板进行电子邮件消息组成。

为了使用此扩展,您需要将邮件模板存储组件添加到您的应用程序中

return [
    'components' => [
        'mailTemplateStorage' => [
            'class' => 'yii2tech\activemail\TemplateStoragePhp',
            'templatePath' => '@app/mail/templates',
        ],
        // ...
    ],
    // ...
];

ActiveMessage

每个特定的活动消息都应该扩展 [[\yii2tech\activemail\ActiveMessage]] 类,实现至少所有抽象方法,这保证了特定活动消息为每个必要部分具有默认值。作为常规模型,它可以包含通过公共字段定义的属性。可以为这些属性设置验证规则。例如

namespace app\mail\active;

use yii2tech\activemail\ActiveMessage;
use Yii;

class ContactUs extends ActiveMessage
{
    public $name;
    public $email;
    public $message;
    public $subject;

    public function rules()
    {
        return [
            [$this->attributes, 'required'],
            ['email', 'email'],
        ];
    }

    public function defaultFrom()
    {
        return Yii::$app->params['applicationEmail'];
    }

    public function defaultTo()
    {
        return Yii::$app->params->mail['adminEmail'];
    }

    public function defaultSubject()
    {
        return 'Contact: {subject}';
    }

    public function defaultBodyHtml()
    {
        return <<<BODY
Email: <a href="mailto:{email}">{email}</a><br>
Name: {name}<br>
<hr>
{subject}
<hr>
{message}
BODY;
    }
}

一旦声明了活动消息,就可以在控制器中将其用作常规模型

use app\mail\active\ContactUs;

// ...

public function actionContact()
{
    $model = new ContactUs();
    if ($model->load(Yii::$app->request->post()) && $model->send()) {
        Yii::$app->session->setFlash('contactFormSubmitted');
        return $this->refresh();
    }
    return $this->render('contact', [
        'model' => $model,
    ]);
}

[[\yii2tech\activemail\ActiveMessage]] 使用基于视图文件的常规 Yii2 邮件组成机制。默认情况下,它使用此扩展提供的内部视图。但是,为了正常工作,它显然需要布局视图存在。每个特定的活动消息都可以通过 viewName() 方法声明指定自己的视图。此类视图的最基本内容如下

<?php
/* @var $this yii\web\View */
/* @var $activeMessage yii2tech\activemail\ActiveMessage */

echo $activeMessage->getBodyHtml();
?>

处理占位符

活动消息的每个部分(如主题或正文)都可能包含格式为 {placeholderName} 的占位符。在消息组成过程中,这些占位符将替换为它们的实际值。实际占位符是通过 templatePlaceholders() 方法定义的。默认情况下,它使用当前活动消息属性值,但您可以通过覆盖它来添加额外的占位符

public function templatePlaceholders()
{
    return array_merge(
        parent::templatePlaceholders(),
        [
            'nowDate' => date('Y-m-d')
        ]
    );
}

[[\yii2tech\activemail\ActiveMessage]] 还声明了 templatePlaceholderHints() 方法,可以用来指定每个占位符的提示。在编辑邮件模板时,您可以使用它。

模板使用

[[\yii2tech\activemail\ActiveMessage]] 使用的主要好处是邮件模板功能。每个活动消息都可以有一个命名模板,它可以覆盖其默认的标题、正文等值。模板名称是通过 templateName() 方法定义的。默认情况下,使用活动消息类的基本名称。

实际的模板源是通过上面提到的“邮件模板存储”组件定义的。

以下模板存储可用:

  • [[\yii2tech\activemail\TemplateStoragePhp]] - 在PHP文件中存储模板
  • [[\yii2tech\activemail\TemplateStorageDb]] - 在关系型数据库中存储模板
  • [[\yii2tech\activemail\TemplateStorageMongoDb]] - 在MongoDB中存储模板
  • [[\yii2tech\activemail\TemplateStorageActiveRecord]] - 使用ActiveRecord查找模板

请参考特定的存储类以获取更多详细信息。

例如:假设我们使用 [[\yii2tech\activemail\TemplateStoragePhp]] 作为模板存储。为了为我们的 app\mail\active\ContactUs 活动消息定义模板,我们应在 '@app/mail/templates' 目录下创建一个名为 'ContactUs.php' 的文件,内容如下:

<?php

return [
    'subject' => 'Override',
    'htmlBody' => 'Override:<br>{message}',
];

完成此操作后,此文件中的 'subject' 和 'htmlBody' 值将覆盖由 app\mail\active\ContactUs 声明的默认值。

此功能在创建多语言网站时可能非常有用。在这种情况下,您可以像以下那样声明活动消息的 templateName() 方法:

class ContactUs extends ActiveMessage
{
    // ...

    public function templateName()
    {
        return Yii::$app->language . DIRECTORY_SEPARATOR . 'ContactUs';
    }
}

然后,您可以在子目录下创建多个名为 'ContactUs' 的模板,其名称与特定语言代码匹配,如 'en-US'、'de' 等。

使用数据库模板存储允许应用程序管理员在必要时通过插入对应行到表中覆盖邮件内容,通过删除它来恢复默认值。

注意:模板旨在覆盖默认的活动消息值,因此如果存储中缺少特定的模板,程序将不会触发任何错误或抛出任何异常。

模板管理

使用特殊的邮件模板系统的最常见原因是允许应用程序管理员通过Web界面编辑它们。为了简化此类功能的创建,此扩展提供了 [[\yii2tech\activemail\TemplateModelFinder]] 类,该类允许列出所有可用的活动消息和创建的模板。活动消息的搜索模型可能如下所示:

use yii\base\Model;
use yii\data\ArrayDataProvider;
use yii2tech\activemail\TemplateModelFinder;
use app\models\MailTemplate;

class MailTemplateSearch extends Model
{
    public $name;
    public $subject;

    public function search()
    {
        // get raw data
        $finder = new TemplateModelFinder([
            'activeRecordClass' => MailTemplate::className();
        ]);
        $models = $finder->findAllTemplateModels();

        // filter list :
        $filterModel = $this;
        $models = array_filter($models, function ($model) use ($filterModel) {
            /* @var $model MailTemplate */
            if (!empty($filterModel->name)) {
                if ($filterModel->name != $model->name) {
                    return false;
                }
            }
            if (!empty($filterModel->subject)) {
                if (strpos($model->subject, $filterModel->subject) === false) {
                    return false;
                }
            }
            return true;
        });

        // compose data provider
        return new ArrayDataProvider([
            'allModels' => $models,
            'sort' => [
                'attributes' => ['name', 'subject'],
            ],
        ]);
    }
}

邮件模板的Web控制器可能如下所示:

use yii\web\Controller;
use yii\web\NotFoundHttpException;
use Yii;
use app\models\MailTemplate;
use app\models\MailTemplateSearch;

class MailTemplateController extends Controller
{
    public function actionIndex()
    {
        $searchModel = new MailTemplateSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    public function actionUpdate($name)
    {
        $finder = new TemplateModelFinder([
            'activeRecordClass' => MailTemplate::className();
        ]);

        $model = $finder->findTemplateModel($name);
        if ($model === null) {
            throw new NotFoundHttpException('The requested page does not exist.');
        }

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['index']);
        }

        return $this->render('update', [
            'model' => $model,
        ]);
    }
}