使用数据库中的值进行动态邮件配置[Laravel]

时间:2017-07-17 13:58:08

标签: php mysql laravel

我在Laravel应用程序SettingsServiceProvider中创建了一个服务提供程序。这会缓存数据库中的设置表。

$settings = $cache->remember('settings', 60, function() use ($settings)
    {
        return $settings->pluck('value', 'name')->all();
    });

config()->set('settings', $settings);

settings表:

enter image description here

我能够像这样回应表中的值:

{{ config('settings.sitename') }}  //returns Awesome Images

这适用于App\Http\Controllers

中的任何刀片文件或控制器

问题:

我试图像这样回复App\config\mail.php的价值:

'driver' => config('settings.maildriver'),
'host' => config('settings.mailhost'),

但是我收到了这个错误:

Missing argument 1 for Illuminate\Support\Manager::createDriver()

更新

我创建了一个新的服务提供商MailServiceProvider来覆盖Mail.php中的设置,如下所示:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Config;

class MailServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        Config::set('mail.driver', config('settings.maildriver'));
        Config::set('mail.host', config('settings.mailhost'));
        Config::set('mail.port', config('settings.mailport'));
        Config::set('mail.encryption', config('settings.mailencryption'));
        Config::set('mail.username', config('settings.mailusername'));
        Config::set('mail.password', config('settings.mailpassword'));

    }
}

但我仍然得到同样的错误!!

在创建swiftmailer传输之前,有没有办法在运行中覆盖默认邮件配置(在app/config/mail.php中)(例如配置存储在数据库中)?

4 个答案:

答案 0 :(得分:21)

在这个问题上挣扎了3天终于找到了解决问题的方法。

首先,我创建了一个表ssh-add /home/yourusername/.ssh/your.pem 并用我的值填充它。 然后我创建了一个提供程序mails

MailConfigServiceProvider.php

然后在<?php namespace App\Providers; use Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\ServiceProvider; class MailConfigServiceProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { // } /** * Register the application services. * * @return void */ public function register() { if (\Schema::hasTable('mails')) { $mail = DB::table('mails')->first(); if ($mail) //checking if table is not empty { $config = array( 'driver' => $mail->driver, 'host' => $mail->host, 'port' => $mail->port, 'from' => array('address' => $mail->from_address, 'name' => $mail->from_name), 'encryption' => $mail->encryption, 'username' => $mail->username, 'password' => $mail->password, 'sendmail' => '/usr/sbin/sendmail -bs', 'pretend' => false, ); Config::set('mail', $config); } } } }

中注册
config\app.php

答案 1 :(得分:2)

也许对某些人有用,但是我如下解决了它;

ServiceProvider方法下的boot中;

$settings = Cache::remember('settings', 60, function () {
    return Setting::pluck('value', 'name')->all();
});

config()->set('settings', $settings); // optional

config()->set('mail', array_merge(config('mail'), [
    'driver' => 'mailgun',
    'from' => [
        'address' => $settings['mail_from_address'],
        'name' => $settings['mail_from_name']
    ]
]));

config()->set('services', array_merge(config('services'), [
    'mailgun' => [
        'domain' => $settings['mailgun_domain'],
        'secret' => $settings['mailgun_secret']
    ]
]));

我在原始配置中使用了array_merge,所以我们只覆盖了需要的值。同样,我们可以在Cache方法中使用boot外观。

答案 2 :(得分:1)

遵循说明here是解决此问题的正确方法,以防万一如果您通过不同的SMTP配置发送每个请求的多封电子邮件,Config::set()无法正常工作,则第一封电子邮件将使用正确的设置,而同一请求中所有即将发送的电子邮件将使用第一封电子邮件的相同配置,因为Mail服务是作为单例提供的,因此仅使用初始配置。

由于同样的原因,这也可能影响通过Laravel队列工作人员发送的电子邮件。

答案 3 :(得分:0)

经过大量研究,我终于找到了动态邮件配置的最佳方法。

我将我的邮件配置数据保存在 settings 表中,请查看表结构。

enter image description here

Helpers/AaapHelper.php

<?php

namespace App\Helpers;

use App\Setting;

class AppHelper
{

    public static function setMailConfig(){

        //Get the data from settings table
        $settings = Setting::pluck('description', 'label'); 

        //Set the data in an array variable from settings table
        $mailConfig = [
            'transport' => 'smtp',
            'host' => $settings['smtp_host'],
            'port' => $settings['smtp_port'],
            'encryption' => $settings['smtp_security'],
            'username' => $settings['smtp_username'],
            'password' => $settings['smtp_password'],
            'timeout' => null
        ];

        //To set configuration values at runtime, pass an array to the config helper
        config(['mail.mailers.smtp' => $mailConfig]);
    }
}

app\Http\Controllers\SettingController.php

<?php
namespace App\Http\Controllers;

use App\Helpers\AppHelper;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;

class SettingController extends Controller
{

    public function sendMail()
    {
        try
        {
            //Set mail configuration
            AppHelper::setMailConfig();

            $data = ['name' => "Virat Gandhi"];

            Mail::send(['text' => 'mail'], $data, function ($message)
            {
                $message->to('abc@gmail.com', 'Lorem Ipsum')
                    ->subject('Laravel Basic Testing Mail');
                $message->from('xyz@gmail.com', $data['name']);
            });
            return redirect()->back()->with('success', 'Test email sent successfully');
        }
        catch(\Exception $e)
        {
            return redirect()->back()->withErrors($e->getMessage());
        }
    }
}

说明

当通过 sendMail 函数发送邮件时,它会首先通过 helper 配置邮件。