如何在Laravel中使用数据库进行邮件设置

时间:2015-05-14 05:24:34

标签: php laravel laravel-5

我想让用户远离编辑配置文件,所以我在管理面板中创建了用于设置邮件服务器,用户名,密码,端口,加密的Web界面。 我在Laravel 4.2中工作得很好,但现在当应用程序被重写为Laravel 5时,会出现错误:

Class 'Settings' not found in <b>F:\htdocs\app\config\mail.php</b> on line <b>18</b><br />

为此,我创建了一个服务提供者,制作了一个外观,将它们放在config / app.php中,Settings::get('var')/Settings::set('var')完美地工作,但不适用于邮件设置。

配置/ mail.php:

<?php return array(
            'driver' => Settings::get('mail_driver'),
            'host' => Settings::get('mail_host'),
            'port' => Settings::get('mail_port'),
            'from' => array('address' => Settings::get('mail_from_address'), 'name' => Settings::get('mail_from_name')),
            'encryption' => Settings::get('mail_encryption'),
            'username' => Settings::get('mail_username'),
            'password' => Settings::get('mail_password'),
            'sendmail' => Settings::get('mail_sendmail'),
            'pretend' => false,
            );

配置/ app.php:

'providers' => [

    ...

    'App\Providers\SettingsServiceProvider',

    ...

'aliases' => [

    ...

    'Settings' => 'App\Custom\Facades\Settings',
<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Custom\Settings;

class SettingsServiceProvider extends ServiceProvider {

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

/**
 * Register the application services.
 *
 * @return void
 */
public function register()
{
    $this->app->singleton('settings', function()
    {
        return new Settings;
    });
}

}
<?php namespace App\Custom;

use App\Setting;

class Settings {
public function get($var) {

    try{
        $setting = Setting::first();                

    } catch(exception $e)
    {
        return false;
    }

    return $setting->$var;

}

public function set($var, $val) {

    try{
        $setting = Setting::first();
        $setting->$var = $val;              
        $setting->save();               

    } catch(exception $e)
    {
        return false;
    }

    return true;

}   
}
<?php

namespace App\Custom\Facades;

use Illuminate\Support\Facades\Facade;

class Settings extends Facade {

    protected static function getFacadeAccessor() { return 'settings'; }

}

有关如何使用数据库实现Laravel邮件设置的任何想法吗?

4 个答案:

答案 0 :(得分:8)

要归档此内容,我通过扩展CustomMailServiceProvider创建了Illuminate\Mail\MailServiceProvider,以覆盖此方法:

protected function registerSwiftTransport(){
    $this->app['swift.transport'] = $this->app->share(function($app)
    {
    return new TransportManager($app);
    });
}

以下是完整的解决方案

  1. 我在app \ Providers
  2. 中创建了CustomMailServiceProvider.php

    namespace App\Providers;
    
    use Illuminate\Mail\MailServiceProvider;
    use App\Customs\CustomTransportManager;
    
    class CustomMailServiceProvider extends MailServiceProvider{
    
        protected function registerSwiftTransport(){
            $this->app['swift.transport'] = $this->app->share(function($app)
            {
                return new CustomTransportManager($app);
            });
        }
    }
    
    1. 我在app / customs目录中创建了CustomTransportManager.php - 注意:app / customs目录在默认的laravel 5目录结构中不存在,我创建了它
    2. namespace App\Customs;
      
      use Illuminate\Mail\TransportManager;
      use App\Models\Setting; //my models are located in app\models
      
      class CustomTransportManager extends TransportManager {
      
          /**
           * Create a new manager instance.
           *
           * @param  \Illuminate\Foundation\Application  $app
           * @return void
           */
          public function __construct($app)
          {
              $this->app = $app;
      
              if( $settings = Setting::all() ){
      
                  $this->app['config']['mail'] = [
                      'driver'        => $settings->mail_driver,
                      'host'          => $settings->mail_host,
                      'port'          => $settings->mail_port,
                      'from'          => [
                      'address'   => $settings->mail_from_address,
                      'name'      => $settings->mail_from_name
                      ],
                      'encryption'    => $settings->mail_encryption,
                      'username'      => $settings->mail_username,
                      'password'      => $settings->mail_password,
                      'sendmail'      => $settings->mail_sendmail,
                      'pretend'       => $settings->mail_pretend
                 ];
             }
      
          }
      }
      
      1. 最后,我用'Illuminate\Mail\MailServiceProvider',
      2. 替换了config / app.php中的'App\Providers\CustomMailServiceProvider',

答案 1 :(得分:2)

我添加了

$this->app['config']['services'] = [
        'mailgun' => [
            'domain' => $settings->mailgun_domain,
            'secret' => $settings->mailgun_secret,
        ]
        ];   

到CustomTransportManager __construct()以包含我用作邮件服务的mailgun API凭据

答案 2 :(得分:1)

我配置如上所述,但是出现以下错误。虽然我尝试了你的代码,但是发现Laravel 5.4的方法已被弃用,而是被告知要使用singleton。

Call to undefined method Illuminate\Foundation\Application::share()

以下是使用singleton而不是使用share方法的方法:

protected function registerSwiftTransport(){
    $this->app->singleton('swift.transport', function ($app){
        return new CustomTransportManager($app);
    });
}

答案 3 :(得分:0)

@DigitLimit,方法share()自Laravel 5.4以来已被删除。我不得不使用其他方法解决这个问题,我不确定它们是否完美。这是CustomMailServiceProvider类中的registerSwiftTransport()方法。

首先,我们需要确定在通过命令行调用app时是否未执行代码:“if(strpos(php_sapi_name(),'cli')=== false)”。如果我们不检查并且不防止在这种情况下设置新的参数,Artisan将在命令行中抛出错误。其次,我们需要以某种方式从数据库中获取设置。我使用我的方法getSettingValue()完成它,其中第一个参数是设置键,第二个参数是默认值,如果找不到设置。如您所见,我已将设置分配给$ this-&gt; app ['config'] ['mail']。 之后,我使用了singleton()方法:

protected function registerSwiftTransport(){
    if (strpos(php_sapi_name(), 'cli') === false) {
       $this->app['config']['mail'] = [
        'driver'        => Setting::getSettingValue('mail_driver', '****'),
        'host'          => Setting::getSettingValue('mail_host', '****'),
        'port'          => Setting::getSettingValue('mail_port', 25),
        'from'          => [
            'address'   => Setting::getSettingValue('mail_from_address', '****'),
            'name'      => Setting::getSettingValue('mail_from_name', '****'),
        ],
        'encryption'    => Setting::getSettingValue('mail_encryption', '***'),
        'username'      => Setting::getSettingValue('mail_username', '****'),
        'password'      => Setting::getSettingValue('mail_password', '****'),
     ];
   }

   $this->app->singleton('swift.transport', function ($app) { 
       return new Illuminate\Mail\TransportManager($app);
   });
}