Symfony:记录由Mailer创建的所有邮件
出于各种原因,我希望/需要记录通过我的网站发送的所有电子邮件,该网站运行在Symfony 5上 到目前为止,我所拥有的是一个订阅服务器,它在创建MessageEvent类时创建了EmailLogEntry类型的实体(至少这是我从(Symfony:记录由Mailer创建的所有邮件,symfony,mailer,subscriber,Symfony,Mailer,Subscriber,出于各种原因,我希望/需要记录通过我的网站发送的所有电子邮件,该网站运行在Symfony 5上 到目前为止,我所拥有的是一个订阅服务器,它在创建MessageEvent类时创建了EmailLogEntry类型的实体(至少这是我从(MessageEvent::class)中了解到的,如果我错了,请纠正我)。我还使用此订户用默认系统地址填写缺少的电子邮件地址 现在,在发送电子邮件后,我想调整我的实体并调用$email->setSent(true),但我不知道如何订阅尝试发送电子邮件的事件。对于代码的
MessageEvent::class
)中了解到的,如果我错了,请纠正我)。我还使用此订户用默认系统地址填写缺少的电子邮件地址
现在,在发送电子邮件后,我想调整我的实体并调用$email->setSent(true)代码>,但我不知道如何订阅尝试发送电子邮件的事件。对于代码的可重用性,我不想在服务中这样做(是的,它是多个的,因为有多个源生成邮件),我实际上调用$this->mailer->send($email)代码>
我现在的问题是:
- 有人能告诉我如何订阅邮件发送活动吗
- 通常,我如何确定我可以订阅哪些活动?文档中列出了内核事件,但是其他所有触发的事件呢
顺便说一句,我目前的用户代码:
class SendMailSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
MessageEvent::class => [
['onMessage', 255],
['logMessage', 0],
],
];
}
public function logMessage(MessageEvent $event) {
$email = new EmailLogEntry();
[...]
}
}
谢谢。我的问题的答案是:目前您无法订阅Mailer的send()事件
作为一种解决方法,这是我目前的代码:
这是我邮件服务的摘录
// send email and log the whole message
private function logSendEmail($email) {
$log = new EmailLog();
// sender
$log->setSender(($email->getFrom()[0]->getName() ?:"")." <".$email->getFrom()[0]->getAddress().">");
// get recipient list
foreach($email->getTo() AS $to) {
$recipient[] = "To: ".$to->getName()." <".$to->getAddress().">";
}
foreach($email->getCc() AS $cc) {
$recipient[] = "CC: ".$cc->getName()." <".$cc->getAddress().">";
}
foreach($email->getBcc() AS $bcc) {
$recipient[] = "Bcc: ".$bcc->getName()." <".$bcc->getAddress().">";
}
$log->setRecipient(implode(";",$recipient));
// other message data
$log->setSubject($email->getSubject());
$log->setMessage(serialize($email->__serialize()));
$log->setMessageTime(new \DateTime("now"));
$log->setSent(0); // set Sent to 0 since mail has not been sent yet
// try to send email
try {
$this->mailer->send($email);
$log->setSent(1); // set sent to 1 if mail was sent successfully
}
// catch(Exception $e) {
// to be determined
// }
// and finally persist entity to database
finally {
$this->em->persist($log);
$this->em->flush();
}
}
//发送电子邮件并记录整个消息
专用函数logsendmail($email){
$log=新的EmailLog();
//寄件人
$log->setSender(($email->getFrom()[0]->getName()?:)。);
//获取收件人列表
foreach($email->getTo()作为$to){
$recipient[]=“收件人:”.$To->getName();
}
foreach($email->getCc()作为$cc){
$recipient[]=“抄送:”..$CC->getName();
}
foreach($email->getBcc()作为$bcc){
$recipient[]=“密件抄送:”.$Bcc->getName();
}
$log->setRecipient(内爆(“;”,$recipient));
//其他消息数据
$log->setSubject($email->getSubject());
$log->setMessage(序列化($email->_serialize());
$log->setMessageTime(新建\DateTime(“现在”);
$log->setSent(0);//由于邮件尚未发送,所以设置已发送到0
//尝试发送电子邮件
试一试{
$this->mailer->send($email);
$log->setSent(1);//如果邮件发送成功,则将发送设置为1
}
//捕获(例外$e){
//待定
// }
//最后将实体持久化到数据库
最后{
$this->em->persist($log);
$this->em->flush();
}
}
EmailLog是我创建的一个实体。当我分别保存发送者、接收者和主题时,有一点悬念。但是,根据消费者数据保护,我计划在30天后自动清除消息字段,同时保留其他字段6个月
到目前为止,我还没有使用订户,主要是因为网站访问者可以请求消息副本,而我对记录这一点也不感兴趣。此外,由于我希望生成可重用代码,我可能会在某个时候遇到邮件可能包含个人消息的问题,我当然不想记录这些邮件。中的想法与您的用例非常相似。你应该能够适应它。你也应该避免一次问太多问题。对于事件,请查看bin/console debug:event*
命令幸运的是,该链接是针对SwiftMailer的,我正在使用Symfony的本机新邮件程序。SwiftMailer有很多选项可以帮助我解决问题……这正是我说“适应它”的原因,因为尽管Symfony Mailer与SwiftMailer不同,但我相信它基本上是相同的,因为你可以使用装饰图案来包装它。特别是如果您总是使用MailerInterface
而不是Mailer
类型提示。它的实现也是非常宽容的,因为Mailer只有一个修饰(发送)功能。此外,装修是正确的方法。如需参考,请参阅(如有必要,可阅读装饰),您是否有MessageEvent的正确使用条款?这可能是它不起作用的一个原因。@Jakumi:好吧,我得查一下装饰图案的事——这是我第一次听说。这是我第一个基于Symfony的项目,到目前为止,我正在通过教程或类似的问题进行学习。关于使用条款:不,我没有。我发现关于使用Symfony\Component\Mailer\Event\MessageEvent;使用Symfony\Component\Mailer\Event\MessageEvents代码>但这就是我通过阅读邮件程序代码文件所能找到的全部内容。EventListener文件夹中的所有类也订阅MessageEvent::class
并使用MessageEvent