如何在发送电子邮件之前获取模板化电子邮件的渲染正文?

3

在发送邮件之前,我想获取邮件的渲染结果。

我创建了一个带有htmlTemplatecontextTemplatedEmail,用于发送正常工作,但是如何获取生成的模板与上下文以将其保存到数据库中?(客户需求)

我尝试了getBody(),但似乎只适用于文本模板,因为我得到了消息必须具有文本或HTML部分或附件。

$email = new TemplatedEmail();
$email->htmlTemplate($htmlTemplate);
$email->from($from)->to(...$to)->subject($subject);
$email->context($context);

dd($email->getBody());

我想使用渲染方法,但是我在服务中,不确定存储在数据库中是否是一个好的方式。

4个回答

2
Symfony只有在通过事件监听器实际发送邮件时才会渲染消息。负责执行渲染的类是BodyRenderer来自Twig Bridge
但您可以自行渲染消息。您拥有模板和上下文变量,因此只需在发送邮件时注入Twig,将模板渲染为字符串并对其进行任何必要的操作。
您还可以注册自己的MessageEvent::class监听器,并将其设置为比Twig Bundle注册的监听器优先级低(它使用默认优先级),以便在该监听器之后执行,然后就可以访问已经渲染的消息正文了。这(非常)略微复杂一些,但您可以获得一些性能提升,因为您不需要再次渲染模板。
使用哪种方法取决于应用程序、约束条件等。但重要的是要意识到消息正文实际上是在哪个部分被渲染的,或者如果您想在此之前渲染它,则需要自己进行渲染。

0
这里是一个解决方案(用于将模板化电子邮件记录到数据库,但可以轻松定制为其他任何东西)使用EventListener。
use App\Entity\EmailLog;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;

#[AsEventListener(event: MessageEvent::class, method: 'onEmailSent', priority: -1)]
class EmailLogListener
{
    public function __construct(
        private EntityManagerInterface $entityManager
    ) {}

    public function onEmailSent(MessageEvent $event): void
    {
        $message = $event->getMessage();
        if (!$message instanceof Email) {
            return;
        }

        $log = new EmailLog();
        $log
            ->setSentFrom(array_map(function (Address $address) {
                return $address->getAddress();
            }, $message->getFrom()))
            ->setSentTo(array_map(function (Address $address) {
                return $address->getAddress();
            }, $message->getTo()))
            ->setSubject($message->getSubject())
            ->setText($message->getHtmlBody());

        $this->entityManager->persist($log);
        $this->entityManager->flush();
    }
}

0

0
受到https://stackoverflow.com/a/58932244/1936720的启发,你也可以使用以下方法强制渲染。
$renderer = new BodyRenderer($twig);
$renderer->render($email);

这是它可能的工作方式:
use Twig\Environment;
use Symfony\Bridge\Twig\Mime\BodyRenderer;
....
public function __construct(
    private readonly Environment            $twig,
)
....
$email = (new TemplatedEmail())->....;
....
$renderer = new BodyRenderer($this->twig);
$renderer->render($email);
....
$email->getHtmlBody()   // won't be empty anymore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接