【问题标题】:How do I get HTML email content before sending in Yii2?在 Yii2 中发送之前如何获取 HTML 电子邮件内容?
【发布时间】:2015-02-26 03:52:31
【问题描述】:

我想用跟踪器替换 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 输出的方法。

如何做到这一点?

更新

我能做到这一点的唯一方法就是通过这种 hacky 方式。

    /* @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);
    }

【问题讨论】:

  • 我最终不得不做同样的事情。非常令人沮丧。
  • 为了避免使用反射,我设法通过调用 $message->getChildren()[0]->getBody() 获取邮件正文(未编码)

标签: php yii2 swiftmailer


【解决方案1】:

我发现的一种方法是使用render() 而不是compose()。 所以我们需要在发送前渲染消息字符串,然后再进行组合。

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      我创建了一个使用 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);
      

      【讨论】:

        猜你喜欢
        • 2013-04-05
        • 1970-01-01
        • 1970-01-01
        • 2012-01-28
        • 2014-07-13
        • 1970-01-01
        • 1970-01-01
        • 2018-08-06
        • 1970-01-01
        相关资源
        最近更新 更多