hyperf-ext / mail

Hyper 邮件发送组件。
MIT License
18 stars 8 forks source link

动态设置配置问题 #2

Open 233cy opened 3 years ago

233cy commented 3 years ago

我应该如何设置动态配置呢,类似smtp。可能A用户发需要用一套QQ的SMTP配置,B用户需要用网易的SMTP配置....以此类推 我在文档中没有找到可以动态设置配置信息的。 可虽然可以通过动态设置hyperf的配置信息,可因为是常驻内存,会出现错乱的问题。不太好。请问我应该怎么弄呢。

233cy commented 3 years ago

@EricYChu

ericyzhu commented 3 years ago

可以在 Mailable 类里按需动态设置 mailer 来实现

233cy commented 3 years ago

可以在 Mailable 类里按需动态设置 mailer 来实现

EMM,可以指条明路么。在Mailable里没有找到可以动态设置mailer的地方。

233cy commented 3 years ago

是这样子吗????

<?php

declare(strict_types=1);
/**
 * 这是一个eoms系统
 *
 * @link     https://www.hyperf.io || https://os.233cy.com
 * @contact  wfuren@qq.com
 */
namespace App\Utils\Plug\Mail;

use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use HyperfExt\Mail\Contracts\MailerInterface;
use HyperfExt\Mail\Contracts\MailManagerInterface;
use HyperfExt\Mail\Mailable;
use HyperfExt\Mail\MailManager;
use HyperfExt\Mail\SwiftMailerLoggerPlugin;
use InvalidArgumentException;
use Swift_DependencyContainer;
use Swift_Mailer;
use function App\Utils\getCnf;

/**
 * 邮件发送模板基础类.
 *
 * Mail     wfuren@qq.com
 * DateTime 2021-05-25 15:19:42
 */
class Template extends Mailable
{
    protected $fromAddress;

    protected $fromName;

    protected $cnf;

    protected $service;

    /**
     * 设置发信人信息
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:03:47.
     *
     * @param string $_address 发信人地址
     * @param string $_name 发信人名称
     */
    public function setFrom(string $_address, string $_name = null)
    {
        $this->fromAddress = $_address;
        $this->fromName = empty($_name) ? getCnf('wang_zhan_biao_ti') : $_name;
    }

    /**
     * 设置邮箱配置
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:04:03.
     *
     * @param array $_cnf 配置信息,只需要传入options中的内容即可
     * @param string $_service 选择的类型
     */
    public function setCnf(array $_cnf, string $_service): void
    {
        $config = config("mail.mailers.{$_service}");
        $config['options'] = $_cnf;
        $this->cnf = $config;
        $this->service = $_service;
    }

    /**
     * 用于同一初始化
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:05:07.
     */
    protected function initBuild(): Template
    {
        if ($this->fromAddress !== null) {
            $this->from($this->fromAddress, $this->fromName);
        }
        return $this;
    }

    /**
     * 重写解析邮箱方法(核心)
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:09:41.
     *
     * @param null|mixed $mailer
     */
    protected function resolveMailer($mailer = null): MailerInterface
    {
        $data = empty($mailer)
            ? ApplicationContext::getContainer()->get(MailManagerInterface::class)->mailer($this->mailer)
            : ($mailer instanceof MailManager ? $mailer->mailer($this->mailer) : $mailer);
        /* ******核心****** */
        $data->setSwiftMailer($this->reCreateSwiftMailer($this->cnf));
        /* ******核心****** */
        return $data;
    }

    /**
     * 拷贝与MailManager里的方法(核心),用于生成新的SwiftMailer。
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:24:52.
     */
    private function reCreateSwiftMailer(array $config)
    {
        if ($config['domain'] ?? false) {
            Swift_DependencyContainer::getInstance()
                ->register('mime.idgenerator.idright')
                ->asValue($config['domain']);
        }

        $swift = new Swift_Mailer($this->reCreateTransport($config));

        if (($loggerConfig = config('mail.logger')) && $loggerConfig['enabled'] === true) {
            $swift->registerPlugin(new SwiftMailerLoggerPlugin(
                ApplicationContext::getContainer()->get(LoggerFactory::class)->get(
                    $loggerConfig['name'] ?? 'mail',
                    $loggerConfig['group'] ?? 'default'
                )
            ));
        }

        return $swift;
    }

    /**
     * 拷贝MailManager中的方法(核心)
     * Mail     wfuren@qq.com
     * DateTime 2021-05-25 15:10:54.
     */
    private function reCreateTransport(array $config)
    {
        if (empty($config['transport'])) {
            throw new InvalidArgumentException('The mail transport must be specified.');
        }

        if (! class_exists($config['transport'])) {
            throw new InvalidArgumentException("Unsupported mail transport [{$config['transport']}].");
        }

        return make($config['transport'], ['options' => $config['options'] ?? []]);
    }
}