Symfony:记录 Mailer 创建的所有邮件
Symfony: Logging all Mails created by Mailer
出于各种原因,我 want/need 记录了通过我在 Symfony 5 上运行的网站发送的所有电子邮件。
到目前为止,我所拥有的是一个订阅者,它在创建 MessageEvent class 时创建一个类型为 EmailLogEntry 的实体(至少这是我从 (MessageEvent::class
) 中了解到的 - 如果我知道,请纠正我错了)。我还使用此订阅者使用默认系统地址填写缺少的电子邮件地址。
现在,发送电子邮件后,我想调整我的实体并调用 $email->setSent(true);
,但我不知道如何订阅尝试发送电子邮件的事件。为了代码的可重用性,我不想在我实际调用 $this->mailer->send($email);
的服务中这样做(是的,它是多个,因为有多个来源生成邮件)。
我现在的问题是:
- 谁能告诉我如何订阅 Mailers 发送事件?
- 一般来说,我如何弄清楚我可以订阅哪些事件?内核事件列在文档中,但是所有其他被触发的事件呢?
顺便说一句,我目前的订阅者代码:
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() 事件。
作为解决方法,这是我现在的代码:
这是我的 Mailer 服务的摘录。
// 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();
}
}
EmailLog 是我创建的实体。当我分别保存发件人、收件人和主题时,会有轻微的悬垂。但是,为了遵守消费者数据保护,我计划在 30 天后自动清除消息字段,同时保留其他字段 6 个月。
我现在也没有使用订阅者,主要是因为网站访问者可以请求消息副本,而我也不想记录它。另外,由于我想生成可重用的代码,我可能会在某些时候面临邮件可能包含个人消息的问题,我当然不想记录这些邮件。
出于各种原因,我 want/need 记录了通过我在 Symfony 5 上运行的网站发送的所有电子邮件。
到目前为止,我所拥有的是一个订阅者,它在创建 MessageEvent class 时创建一个类型为 EmailLogEntry 的实体(至少这是我从 (MessageEvent::class
) 中了解到的 - 如果我知道,请纠正我错了)。我还使用此订阅者使用默认系统地址填写缺少的电子邮件地址。
现在,发送电子邮件后,我想调整我的实体并调用 $email->setSent(true);
,但我不知道如何订阅尝试发送电子邮件的事件。为了代码的可重用性,我不想在我实际调用 $this->mailer->send($email);
的服务中这样做(是的,它是多个,因为有多个来源生成邮件)。
我现在的问题是:
- 谁能告诉我如何订阅 Mailers 发送事件?
- 一般来说,我如何弄清楚我可以订阅哪些事件?内核事件列在文档中,但是所有其他被触发的事件呢?
顺便说一句,我目前的订阅者代码:
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() 事件。
作为解决方法,这是我现在的代码: 这是我的 Mailer 服务的摘录。
// 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();
}
}
EmailLog 是我创建的实体。当我分别保存发件人、收件人和主题时,会有轻微的悬垂。但是,为了遵守消费者数据保护,我计划在 30 天后自动清除消息字段,同时保留其他字段 6 个月。
我现在也没有使用订阅者,主要是因为网站访问者可以请求消息副本,而我也不想记录它。另外,由于我想生成可重用的代码,我可能会在某些时候面临邮件可能包含个人消息的问题,我当然不想记录这些邮件。