根据 Laravel 5 中的用户更改 SMTP 用户
Change SMTP user according to the user in Laravel 5
我想将不同的 SMTP 主机分配给不同的经过身份验证的用户,以便特权用户可以通过专用的 SMTP 服务器更快地发送邮件。
我可以像这样更改服务提供商中的主机:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->extend('swift.transport', function ($transportManager, $app) {
$app->make('config')->set('mail.host', 'just.testing.com');
return new TransportManager($app);
});
}
}
但是因为我需要经过身份验证的用户,所以我创建了一个侦听 "Authenticated" 事件的侦听器并将代码移动到那里:
class ChangeSmtpServer
{
public function handle($event)
{
app()->extend('swift.transport', function ($transportManager, $app) use ($event) {
$app->make('config')->set('mail.host', $event->user->smtp_server);
return new TransportManager($app);
});
}
}
这次没有更改主机...所以在服务提供者内部我可以覆盖设置但不能在侦听器内部覆盖。
知道为什么吗?
您的代码适用于我的设置。实际上,如果您将它保留在 AppServiceProvider 中,它应该仍然有效,因为 Laravel 只会在相关时解析绑定。因此,在您实际尝试发送邮件之前,与邮件驱动程序配置相关的代码不会是 运行。到那时,您的用户将已经通过身份验证。然而...
这仅在您同步发送邮件时有效。当您想从队列工作人员发送时,不会有任何经过身份验证的用户,并且永远不会调用经过身份验证的事件。您需要一种方法来跟踪发送 e-mail.
的用户
这是我的解决方案:
向您的 Mail class 构造函数(App\Mail 中的构造函数)添加一个发件人参数,该参数接受发送 e-mail.
的用户对象
public $sender;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(User $sender)
{
$this->sender = $sender;
}
然后添加配置 SwiftMailer 实例的方法
private function usingSendersSmtp()
{
$mailTransport = app()->make('mailer')
->getSwiftMailer()
->getTransport();
if ($mailTransport instanceof \Swift_SmtpTransport) {
/** @var \Swift_SmtpTransport $mailTransport */
$mailTransport->setHost($this->sender->smtp_host);
$mailTransport->setUsername($this->sender->smtp_username);
$mailTransport->setPassword($this->sender->smtp_password);
// Port and authentication can also be configured... You get the picture
}
return $this;
}
最后在您的构建方法中调用它:
public function build()
{
return $this->usingSendersSmtp()
->view('test');
}
发送邮件时,将您的 class 实例化为 new YourMailClass(auth()->user())
,然后使用 Mail facade 将其发送或排队给任何您喜欢的人。创建一个继承 Illuminate\Mail\Mailable 的抽象 class 并将这些额外的内容移到那里可能是个好主意,这样您就不必在其他所有邮件中都复制它 class。希望这对您有所帮助!
我想将不同的 SMTP 主机分配给不同的经过身份验证的用户,以便特权用户可以通过专用的 SMTP 服务器更快地发送邮件。
我可以像这样更改服务提供商中的主机:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->extend('swift.transport', function ($transportManager, $app) {
$app->make('config')->set('mail.host', 'just.testing.com');
return new TransportManager($app);
});
}
}
但是因为我需要经过身份验证的用户,所以我创建了一个侦听 "Authenticated" 事件的侦听器并将代码移动到那里:
class ChangeSmtpServer
{
public function handle($event)
{
app()->extend('swift.transport', function ($transportManager, $app) use ($event) {
$app->make('config')->set('mail.host', $event->user->smtp_server);
return new TransportManager($app);
});
}
}
这次没有更改主机...所以在服务提供者内部我可以覆盖设置但不能在侦听器内部覆盖。
知道为什么吗?
您的代码适用于我的设置。实际上,如果您将它保留在 AppServiceProvider 中,它应该仍然有效,因为 Laravel 只会在相关时解析绑定。因此,在您实际尝试发送邮件之前,与邮件驱动程序配置相关的代码不会是 运行。到那时,您的用户将已经通过身份验证。然而...
这仅在您同步发送邮件时有效。当您想从队列工作人员发送时,不会有任何经过身份验证的用户,并且永远不会调用经过身份验证的事件。您需要一种方法来跟踪发送 e-mail.
的用户这是我的解决方案:
向您的 Mail class 构造函数(App\Mail 中的构造函数)添加一个发件人参数,该参数接受发送 e-mail.
的用户对象public $sender;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(User $sender)
{
$this->sender = $sender;
}
然后添加配置 SwiftMailer 实例的方法
private function usingSendersSmtp()
{
$mailTransport = app()->make('mailer')
->getSwiftMailer()
->getTransport();
if ($mailTransport instanceof \Swift_SmtpTransport) {
/** @var \Swift_SmtpTransport $mailTransport */
$mailTransport->setHost($this->sender->smtp_host);
$mailTransport->setUsername($this->sender->smtp_username);
$mailTransport->setPassword($this->sender->smtp_password);
// Port and authentication can also be configured... You get the picture
}
return $this;
}
最后在您的构建方法中调用它:
public function build()
{
return $this->usingSendersSmtp()
->view('test');
}
发送邮件时,将您的 class 实例化为 new YourMailClass(auth()->user())
,然后使用 Mail facade 将其发送或排队给任何您喜欢的人。创建一个继承 Illuminate\Mail\Mailable 的抽象 class 并将这些额外的内容移到那里可能是个好主意,这样您就不必在其他所有邮件中都复制它 class。希望这对您有所帮助!