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

mpbci0fu  于 2023-08-06  发布在  其他
关注(0)|答案(4)|浏览(114)

我想在发送电子邮件之前获得渲染。
我用htmlTemplatecontext创建了一个TemplatedEmail,它可以很好地发送,但如何获得生成的模板与上下文保存在数据库中?(客户需求)
我尝试了getBody(),但似乎只能与文本模板一起工作,因为我得到了A message must have a text or an HTML part or attachments.

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

dd($email->getBody());

字符串
我想使用render方法,但我在一个服务中,不确定这是否是一个存储在数据库中的好方法。

daupos2t

daupos2t1#

Symfony仅在实际发送消息时通过Event Listener呈现消息。负责渲染的类是BodyRendererfrom the Twig Bridge
但是没有什么能阻止你自己呈现消息。
你有模板和上下文变量,所以你可以简单地在发送的任何地方注入Twig,将模板呈现为一个字符串,然后做任何你需要的事情。
您也可以注册自己的MessageEvent::class监听器,将其设置为比the one registered by the Twig Bundle低的优先级(它使用默认优先级),因此它会在the one registered by the Twig Bundle之后**执行,然后您可以访问消息体,因为它已经被呈现了。这(非常)稍微复杂一点,但是由于不需要两次渲染模板,因此可以获得一些性能。
使用哪种方法取决于您的应用程序、约束等。但重要的是要意识到在这个过程的哪一部分你会发现身体实际上被渲染了,或者如果你想在那之前渲染它,你可以自己渲染。

vsdwdz23

vsdwdz232#

有关将来的信息,可以使用此处的文档在服务中呈现模板https://symfony.com/doc/current/templates.html#rendering-a-template-in-services

igetnqfo

igetnqfo3#

下面是使用EventListener的解决方案(用于将模板化的电子邮件记录到DB,但可以轻松地自定义为其他任何内容)

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();
    }
}

字符串

67up9zun

67up9zun4#

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

相关问题