首页 > 解决方案 > 队列作业未保存到租户数据库且未使用租户 SMTP

问题描述

我有一个多租户设置,允许每个租户将自己的 SMTP 信息保存在设置表中。现在正在保存的作业被发送到系统数据库而不是租户。这导致了一个问题,因为服务提供商设置为将 boot() 上的邮件配置配置为数据库中提供的每个值。运行电子邮件作业的工作人员确实发送但使用存储的系统 SMTP 值而不是租户 - 我认为这只是因为它正在与当前作业的连接相同的数据库中查找。

服务提供者

class TenantEmail extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
        Config::set('mail.host', setting('admin.email_host'));
        Config::set('mail.port', setting('admin.email_port'));
        Config::set('mail.encryption', setting('admin.email_encrypt'));
        Config::set('mail.username', setting('admin.email_username'));
        Config::set('mail.password', setting('admin.email_password'));
    }
}

发送电子邮件作业

查看有关 Hyn 的文档看起来我可以在调度期间强制设置租户网站 ID,但这并没有什么不同。

class SendEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $user;
    public $sub;
    public $content;
    public $unsubscribeUrl;
    public $replyAddress;
    public $website_id;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($row, $subject, $message, $unsubscribeUrl, $replyTo,int $website_id)
    {
        //
        $this->user = $row;
        $this->sub = $subject;
        $this->content = $message;
        $this->unsubscribeUrl = $unsubscribeUrl;
        $this->replyAddress = $replyTo;
        $this->website_id = $website_id;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
        $email = new ConnectEmail($this->user, $this->sub, $this->content, $this->unsubscribeUrl, $this->replyAddress);
        Mail::to($this->user->email_address, $this->user->name)->send($email);
    }
}

标签: laravelmulti-tenantlaravel-5.8

解决方案


也许不是最干净的方法,但我能够通过在发送作业时在我的电子邮件控制器中传递 SMTP 信息来解决这个问题。

$smtp = [
   'host' => setting('admin.email_host'),
   'port' => setting('admin.email_port'),
   'encryption' => setting('admin.email_encrypt'),
   'username' => setting('admin.email_username'),
   'password' => setting('admin.email_password')
 ];
 $emailJob = (new SendEmail($row, $subject, $message, $unsubscribeUrl, $replyTo, $websiteId, $smtp));
 dispatch($emailJob)->delay($scheduleSend);

然后在我的 SendEmail 作业中,我只需将 $smtp 包含在 ConnectEmail 中,并将其传递给可邮寄,在 init 构造中我只需添加:

if(!empty($smtp)){
   Config::set('mail.host', $smtp['host']);
   Config::set('mail.port', $smtp['port']);
   Config::set('mail.encryption', $smtp['encryption']);
   Config::set('mail.username', $smtp['username']);
   Config::set('mail.password', $smtp['password']);
}

然后排队并使用动态 SMTP 信息发送作业而不会出现问题。


推荐阅读