Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use database for mail settings in Laravel

I'd like to keep users away from editing configuration files, so I've made web interface in admin panel for setting up Mail server, username, password, port, encryption.. I was working well in Laravel 4.2, but now when the app has been rewritten into Laravel 5, an error occurs:

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

For this purpose I've created a service provider, made a facade, put them in config/app.php, Settings::get('var')/Settings::set('var') work perfectly, but not for mail settings.


config/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,
            );

config/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'; }

}

Any ideas how to implement Laravel mail settings using database?

like image 779
mpet Avatar asked Dec 14 '22 14:12

mpet


1 Answers

To archive this I created CustomMailServiceProvider by extending Illuminate\Mail\MailServiceProvider so as to overwrite this method:

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

Here is the complete solution

  1. I created CustomMailServiceProvider.php in app\Providers

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. I created CustomTransportManager.php in app/customs directory - NB: app/customs directory doesn't exist in default laravel 5 directory structure, I created it

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. And finally, I replaced 'Illuminate\Mail\MailServiceProvider', in config/app.php with 'App\Providers\CustomMailServiceProvider',
like image 99
Emeka Mbah Avatar answered Dec 17 '22 03:12

Emeka Mbah