如何在Yii2中发送之前获取HTML电子邮件内容


How do I get HTML email content before sending in Yii2?

我想用tracker替换HTML电子邮件中的所有链接。据我所知,有一个EVENT_BEFORE_SEND事件。所以我创建了一些行为,可以像下面的一样使用

$mailer = 'Yii::$app->mailer;
/* @var $mailer 'yii'mail'BaseMailer */
$mailer->attachBehavior('archiver', [
   'class' => 'app'MailTracker::class
]);

以下是MyTracker类的内容。

class MailTracker extends Behavior {
    public function events() {
        return [
            'yii'mail'BaseMailer::EVENT_BEFORE_SEND => 'trackMail',
        ];
    }
    /**
     * @param 'yii'mail'MailEvent $event
     */
     public function trackMail($event) {
        $message = $event->message;
        $htmlOutput = $this->how_do_i_get_the_html_output();
        $changedOutput = $this->changeLinkWithTracker($htmlOutput);
        $message->getHtmlBody($changedOutput);
     }
}

现在的问题是'yii'mail'BaseMailer没有提供在发送之前呈现HTML输出的方法。

如何做到这一点?

更新

我能得到这个的唯一方法就是通过这种巧妙的方式。

    /* @var $message 'yii'swiftmailer'Message */
    if ($message instanceof 'yii'swiftmailer'Message) {
        $swiftMessage = $message->getSwiftMessage();
        $r = new 'ReflectionObject($swiftMessage);
        $parentClassThatHasBody = $r->getParentClass()
                ->getParentClass()
                ->getParentClass(); //'Swift_Mime_SimpleMimeEntity
        $body = $parentClassThatHasBody->getProperty('_immediateChildren');
        $body->setAccessible(true);
        $children = $body->getValue($swiftMessage);
        foreach ($children as $child) {
            if ($child instanceof 'Swift_MimePart &&
                    $child->getContentType() == 'text/html') {
                $html = $child->getBody();
                break;
            }
        }
        print_r($html);
    }

我发现的一种方法是使用render()而不是compose()。因此,我们需要在发送之前呈现消息字符串,然后再次组合它。

$string = Yii::$app->mailer->render('path/to/view', ['params' => 'foo'], 'path/to/layout');

Yii文档:yii''mail''BaseMailer::render()

为了编辑您的电子邮件内容,您可以尝试使用ckeditor进行视图编辑器。Ckeditor可帮助您根据需要编辑内容。

https://github.com/2amigos/yii2-ckeditor-widget

在发送电子邮件之前编辑内容。

我用preg_match和替换创建了一个变通方法,以防对任何人都有帮助。

$message = 'Yii::$app->mailer->compose('templateName', ['data' => $data])->toString();
// Workaround cause Swift_Mailer doesn't have getBody()
preg_match("/<body>(.*)<'/body>/si", $message, $matches);
$delimitedHtmlBody = $matches[1];
$htmlBody = str_replace("='r'n", '', $delimitedHtmlBody);
$htmlBody = str_replace("=3D", '=', $htmlBody);