Symfony:记录由Mailer创建的所有邮件

Symfony:记录由Mailer创建的所有邮件,symfony,mailer,subscriber,Symfony,Mailer,Subscriber,出于各种原因,我希望/需要记录通过我的网站发送的所有电子邮件,该网站运行在Symfony 5上 到目前为止,我所拥有的是一个订阅服务器,它在创建MessageEvent类时创建了EmailLogEntry类型的实体(至少这是我从(MessageEvent::class)中了解到的,如果我错了,请纠正我)。我还使用此订户用默认系统地址填写缺少的电子邮件地址 现在,在发送电子邮件后,我想调整我的实体并调用$email->setSent(true),但我不知道如何订阅尝试发送电子邮件的事件。对于代码的

出于各种原因,我希望/需要记录通过我的网站发送的所有电子邮件,该网站运行在Symfony 5上

到目前为止,我所拥有的是一个订阅服务器,它在创建MessageEvent类时创建了EmailLogEntry类型的实体(至少这是我从(
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