gpt4 book ai didi

laravel - 如何在运行时全局更改 SMTP 详细信息?

转载 作者:行者123 更新时间:2023-12-04 01:58:05 26 4
gpt4 key购买 nike

我正在使用 Laravel 5.5。该网站的本质是一个“多站点”架构,其中多个网站/域从同一代码库运行。

我在发送电子邮件时遇到了问题。我需要更改 from nameaddress 以及 transport (SMTP 等)选项,具体取决于正在查看哪个网站。我将这些详细信息存储在配置文件中。

最简单的方法是在我调用 Mail::send/Mail::queue 并更新它们之前将这些详细信息提取到 Controller 中。然而,这又带来了 2 个问题:

  1. 我在代码中非常依赖于每次发送任何电子邮件时都要记住实际执行此操作。简而言之,它不遵守 DRY。
  2. 我将被迫使用 Mail::send 而不是 Mail::queue,因为队列不知道来自它被排队 的时间仅从它被处理 开始。

我怎样才能以干净的方式实现我在这里想要做的事情?

我考虑过使用更新 SMTP 详细信息的自定义类来扩展我的所有“可邮寄”类,但看起来您无法在类启动后更新 SMTP/传输信息;您只能更新 from nameaddress

最佳答案

我设法找到了一种方法来做到这一点。

我的可邮寄类 ( ContactFormMailable ) 扩展了一个自定义类,如下所示:

<?php

namespace CustomGlobal\Mail;

use CustomGlobal\Mail\CustomMailable;
use CustomGlobal\ContactForm;

class ContactFormMailable extends CustomMailable
{
public $contact_form;

/**
* Create a new message instance.
*
* @return void
*/
public function __construct(ContactForm $contact_form)
{
$this->contact_form = $contact_form;
}

/**
* Build the message.
*
* @return $this
*/
public function build()
{
$view = $this->get_custom_mail_view('contact_form', $this->contact_form);

return $this->subject('Contact Form Enquiry')
->view($view);
}
}

你会注意到我调用 get_custom_mail_view .这是我的扩展类,用于计算我需要用于邮件的 View 和模板,具体取决于正在查看的网站。在这里我还设置了我的配置文件夹的位置。

<?php

namespace CustomGlobal\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use Swift_Mailer;
use Swift_SmtpTransport;
use CustomGlobal\Website;
use CustomGlobal\Territory;

class CustomMailable extends Mailable
{
use Queueable, SerializesModels;

public $layout_view_to_serve;
public $host_folder;

/**
* Override Mailable functionality to support per-user mail settings
*
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @return void
*/
public function send(Mailer $mailer)
{
app()->call([$this, 'build']);

$config = config($this->host_folder .'.mail');
// Set SMTP details for this host
$host = $config['host'];
$port = $config['port'];
$encryption = $config['encryption'];

$transport = new Swift_SmtpTransport( $host, $port, $encryption );
$transport->setUsername($config['username']);
$transport->setPassword($config['password']);
$mailer->setSwiftMailer(new Swift_Mailer($transport));

$mailer->send($this->buildView(), $this->buildViewData(), function ($message) use($config) {
$message->from([$config['from']['address'] => $config['from']['name']]);
$this->buildFrom($message)
->buildRecipients($message)
->buildSubject($message)
->buildAttachments($message)
->runCallbacks($message);
});
}

/**
* Calculate the template we need to serve.
* $entity can be any object but it must contain a
* $website_id and $territory_id, as that is used
* to calculate the path.
*/
public function get_custom_mail_view($view_filename, $entity)
{
if(empty($view_filename)) {
throw new Exception('The get_custom_mail_view method requires a view to be passed as parameter 1.');
}

if(empty($entity->website_id) || empty($entity->territory_id)) {
throw new Exception('The get_custom_mail_view method must be passed an object containing a website_id and territory_id value.');
}

// Get the website and territory
$website = Website::findOrFail($entity->website_id);
$territory = Territory::findOrFail($entity->territory_id);

$view_to_serve = false;
$layout_view_to_serve = false;

// Be sure to replace . with _, as Laravel doesn't play nice with dots in folder names
$host_folder = str_replace('.', '_', $website->website_domain);
$this->host_folder = $host_folder; // Used for mail config later

/***
Truncated for readability. What's in this area isn't really important to this answer.
***/

$this->layout_view_to_serve = $layout_view_to_serve;

return $view_to_serve;
}
}

重要的是要记住邮件可以排队。如果你这样做是另一种方式,比如在运行时设置配置,那么你会发现运行队列的进程没有运行时配置更改的可见性/范围,你最终会从你的默认值。

我找到了一些与此类似的答案,这对我有所帮助,但它们都没有完全起作用,而且有些已经过时(Swift_SmtpTransport 自这些答案以来发生了很大变化)。

希望这可以帮助其他人。

关于laravel - 如何在运行时全局更改 SMTP 详细信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49276799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com