我正在Symfony 5项目中使用SwiftMailer发送电子邮件。
我在控制器中使用它来发送重置密码的电子邮件,并且一切正常。我现在正在尝试在MessageHandler中使用它,这是我现在正在使用的代码:
final class SendEmailMessageHandler implements MessageHandlerInterface
{
private $mailer;
public function __construct(\Swift_Mailer $mailer)
{
$this->mailer = $mailer;
}
public function __invoke(SendEmailMessage $message)
{
$mail = (new \Swift_Message())
->setFrom($message->getFrom())
->setTo($message->getTo())
->setBody($message->getBody(), $message->getContentType())
->setSubject($message->getSubject());
$response = $this->mailer->send($mail);
}
}
可以,但是邮件永远不会到达我的邮箱。
这是我发送SendEmailMessage的方式:
class AskResetPassword extends AbstractController
{
use ResetPasswordControllerTrait;
private $resetPasswordHelper;
private $validator;
private $bus;
public function __construct(ResetPasswordHelperInterface $resetPasswordHelper, ValidatorInterface $validator, MessageBusInterface $bus)
{
$this->resetPasswordHelper = $resetPasswordHelper;
$this->validator = $validator;
$this->bus = $bus;
}
public function __invoke($data)
{
$emailConstraints = new Assert\Email();
$email = $data->getEmail();
if ($email) {
$errors = $this->validator->validate($email, $emailConstraints);
if (count($errors) === 0) {
return $this->processPasswordReset($email);
} else {
return new JsonResponse(['success' => false, 'error' => 'Invalid E-Mail format'], 404);
}
}
}
private function processPasswordReset($email)
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'email' => $email,
]);
$this->setCanCheckEmailInSession();
if (!$user) {
// Do not reveal whether a user account was found or not.
return new JsonResponse(['success' => true], 200);
}
try {
$resetToken = $this->resetPasswordHelper->generateResetToken($user);
} catch (ResetPasswordExceptionInterface $e) {
return new JsonResponse(['success' => false, 'error' => 'There was a problem handling your password reset request - ' . $e->getReason()]);
}
$message = new SendEmailMessage($email);
$message->setFrom('[email protected]');
$message->setBody(
$this->renderView('reset_password/email.html.twig', [
'resetToken' => $resetToken,
'tokenLifetime' => $this->resetPasswordHelper->getTokenLifetime()
])
);
$message->setSubject('Votre demande de changement de mot de passe');
$this->bus->dispatch($message);
return new JsonResponse(['success' => true], 200);
}
}
这是我的swiftmailer.yaml:
swiftmailer:
url: '%env(MAILER_URL)%'
spool: { type: 'memory' }
你能帮我吗?
我不记得确切的原因,在发布此消息时,我一直在努力寻找答案,但是swiftmailer类型必须是文件而不是内存。 GitHub issue引用了此。您还可以查看如何更改类型here。
答案是“请勿假脱机电子邮件,除非您以后要处理它们”。查看文档Spool Emails
假脱机程序是一种队列机制,它将一个接一个地处理您的消息队列。它是在swift-mailer重写并重新添加到symfony中时引入的。与提供抽象接口MessageBusInterface的Messenger Component结合使用时,它将委派给正确的后端服务,该服务可以是smtp中继,推送通知或任何其他类型的RPC,它们可能会触发单独的Web服务上的操作。
由于symfony向消息总线添加了新功能,因此添加此功能是为了将其用于消息队列和其他服务,在这些服务中,分别处理事务性电子邮件和通知。
要处理您的线轴,只需运行:
APP_ENV=prod php bin/console swiftmailer:spool:send
在典型的安装中,假脱机被禁用,当您在内存中启用假脱机时,它将等待请求完成并且内核即将退出。如果您要使用其他任何调试方法来中途终止内核,或者应用程序的其他组件和部分将内核保留在内存中,则不会触发事件,也不会发送邮件。
您可以在这里查看整个文档:Sending Emails