聚会有点晚了,但只是想扩展接受的答案并投入我的 2 美分,以防它节省某人的时间。在我的场景中,每个登录用户都有自己的 SMTP 设置,但我使用队列发送邮件,这导致设置在设置后恢复为默认值。它还产生了一些并发的电子邮件问题。简而言之,问题是
$transport = Swift_SmtpTransport::newInstance($user->getMailHost(), $user->getMailPort(), $user->getMailEncryption());
$transport->setUsername($user->getMailUser());
$transport->setPassword($user->getMailPassword());
$mailer = new Swift_Mailer($transport);
Mail::setSwiftMailer($mailer);
//until this line all good, here is where it gets tricky
Mail::send(new CustomMailable());//this works
Mail::queue(new CustomMailable());//this DOES NOT WORK
在敲了几下键盘之后,我意识到队列正在一个单独的进程上运行,因此 Mail::setSwiftMailer 根本不会影响它。它只是选择默认设置。
因此,配置更改必须在发送电子邮件的实际时刻发生,而不是在排队时发生。
我的解决方案是扩展 Mailable 类,如下所示。
app\Mail\ConfigurableMailable.php
<?php
namespace App\Mail;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Mail\Mailable;
use Swift_Mailer;
use Swift_SmtpTransport;
class ConfigurableMailable extends Mailable
{
/**
* Override Mailable functionality to support per-user mail settings
*
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @return void
*/
public function send(Mailer $mailer)
{
$host = $this->user->getMailHost();//new method I added on User Model
$port = $this->user->getMailPort();//new method I added on User Model
$security = $this->user->getMailEncryption();//new method I added on User Model
$transport = Swift_SmtpTransport::newInstance( $host, $port, $security);
$transport->setUsername($this->user->getMailUser());//new method I added on User Model
$transport->setPassword($this->user->getMailPassword());//new method I added on User Model
$mailer->setSwiftMailer(new Swift_Mailer($transport));
Container::getInstance()->call([$this, 'build']);
$mailer->send($this->buildView(), $this->buildViewData(), function ($message) {
$this->buildFrom($message)
->buildRecipients($message)
->buildSubject($message)
->buildAttachments($message)
->runCallbacks($message);
});
}
}
然后将CustomMail改为扩展ConfigurableMailable而不是Mailable:
class CustomMail extends ConfigurableMailable {}
这确保即使调用Mail::queue(new CustomMail()) 也会在发送前设置每个用户的邮件设置。当然,您必须在某个时候将当前用户注入 CustomMail,即Mail::queue(new CustomMail(Auth::user()))
虽然这可能不是理想的解决方案(即,如果尝试发送批量电子邮件,最好只配置一次邮件,而不是在发送的每封电子邮件上),但我喜欢它的简单性以及我们不需要更改全局Mail 或Config 设置,只有$mailer 实例受到影响。
希望你觉得它有用!