Laravel Dynamic Mail Configuration
Use case: from a Laravel application, use a dynamic (database driven) configuration for sending mails. Eventually, different for each user which is actually logged in.
Everywhere on the internet you find references to this thread on a forum, raccomanding to load the configuration and create a new Mailer to overwrite the one registered at bootstrap, but it is obsolete: the mentioned share
method no longer exists in Laravel 5.4.
Probably there is a different way to do the same thing, but I've achieved my goal in easier way: don't register at all the first (and broken) Mailer at bootstrap.
From config/app.php
I've removed the reference to Illuminate\Mail\MailServiceProvider::class
from the providers
array, and I've created a middleware class such as
<?php
namespace App\Http\Middleware;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Mail\TransportManager;
use Closure;
use Mail;
use Config;
use App;
class OverwriteMail
{
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
/*
$conf is an array containing the mail configuration, a described in
config/mail.php. Something like
[
'driver' => 'smtp',
'host' => 'smtp.mydomain.com',
'username' => foo',
'password' => 'bar'
...
]
*/
$conf = my_own_function();
Config::set('mail', $conf);
$app = App::getInstance();
$app->register('Illuminate\Mail\MailServiceProvider');
return $next($request);
}
}
In the middleware, I've already access to the current user's informations and I'm able to get the proper configuration. The magic, here, is to register the MailServiceProvider
once, just after altering the configuration.