15

I'm using Laravel 4, I would like to change the mail configuration (like driver/host/port/...) in the controller as I would like to save profiles in databases with different mail configuration. This is the basic send mail using configuration from config/mail.php

Mail::send(
    'emails.responsable.password_lost',
    array(),
    function($message) use ($responsable){
        $message->to($responsable->email, $responsable->getName());
        $message->subject(Lang::get('email.password_lost'));
    });

I've tried to put something like but it didn't work

 $message->port('587');

Thanks for your support!

Jean

jibe
  • 645
  • 1
  • 4
  • 17

4 Answers4

27

You can set/change any configuration on the fly using Config::set:

Config::set('key', 'value');

So, to set/change the port in mail.php you may try this:

Config::set('mail.port', 587); // default

Note: Configuration values that are set at run-time are only set for the current request, and will not be carried over to subsequent requests. Read more.

Update: A hack for saving the config at runtime.

The Alpha
  • 143,660
  • 29
  • 287
  • 307
  • I am facing similar kind of problem. I have created a service provider `MailServiceProvider` and declared `Config::set('mail.port', 587);` `Config::set('mail.driver', smtp)` like this in the `register()` function. But it doesn't seems to work. Help Appreciated :) Original Question: [link](https://stackoverflow.com/questions/45146260/not-able-to-echo-from-service-provider-to-mail-php-laravel) – Saurabh Jul 18 '17 at 05:56
  • You shouldn't change configuration settings at runtime like that. Use a database instead. – Dragas Jun 21 '18 at 12:36
  • @Saurabh Config::set() works in boot(), at least for me – ymakux Jul 09 '20 at 16:02
  • you will need this `use Illuminate\Support\Facades\Config;` – Matías Cánepa Dec 14 '21 at 18:40
10

I know is kind of late but an approach could be providing a swift mailer to the laravel mailer.

<?php

$transport = (new \Swift_SmtpTransport('host', 'port'))
    ->setEncryption(null)
    ->setUsername('username')
    ->setPassword('secret');

$mailer = app(\Illuminate\Mail\Mailer::class);
$mailer->setSwiftMailer(new \Swift_Mailer($transport));

$mail = $mailer
    ->to('user@laravel.com')
    ->send(new OrderShipped);
Francisco Daniel
  • 989
  • 10
  • 13
5

The selected answer didn't work for me, I needed to add the following for the changes to be registered.

Config::set('key', 'value');
(new \Illuminate\Mail\MailServiceProvider(app()))->register();
Hillel Coren
  • 429
  • 2
  • 10
  • 28
  • This solution was helpfull when I was working on Laravel 4.2. I'm not using Laravel anymore, you may want to open another thread to have an answer on Laravel 5+. good luck! – jibe Jan 22 '18 at 14:49
  • This seems not to work if you are using a queue worker. – Snake_py Jul 22 '22 at 08:06
1

If you want to create a Laravel 7 application where users are allowed to register and sign in on your application and you intend to enable each user with the ability to send emails through your platform, using their own unique email address and password.

THE SOLUTION:

  1. Laravel Model: first you’ll need to create a database table to store the user’s email configuration data. Next, you’ll need an Eloquent Model to retrieve an authenticated user’s id to fetch their email configuration data dynamically.
  2. Laravel ServiceProvider: next, create a service provider that would query the database for the user’s email configurations using a scope method within your Model class and would set it as their default mail configuration. Do not register this service provider within your config/app.php
  3. Laravel MiddleWare: also create a middleware that would run when a user has been authenticated and register the ServiceProvider.

IMPLEMENTING THE MODEL:

Make a migration. Run these from the command line php artisan make:migration create_user_email_configurations_table. Then:

Schema::create('user_email_configurations', function (Blueprint $table) {
  $table->id();
  $table->string('user_id');
  $table->string('name');
  $table->string('address');
  $table->string('driver');
  $table->string('host');
  $table->string('port');
  $table->string('encryption');
  $table->string('username');
  $table->string('password');
  $table->timestamps();
});

Finalize and create your model. Runphp artisan migrate and php artisan make:model userEmailConfiguration. Now add a scope method into your model.

<?php
  namespace App;
  use Illuminate\Support\Facades\Auth;
  use Illuminate\Database\Eloquent\Model;

class userEmailConfiguration extends Model
{
  protected $hidden = [
    'driver',
    'host',
    'port',
    'encryption',
    'username',
    'password'
  ];
  public function scopeConfiguredEmail($query) {
    $user = Auth::user();
    return $query->where('user_id', $user->id);
  }
}

IMPLEMENTING THE SERVICEPROVIDER

Run this from the command line - php artisan make:provider MailServiceProvider

<?php
  namespace App\Providers;
  use Illuminate\Support\ServiceProvider;
  use App\userEmailConfiguration;
  use Config;
class MailServiceProvider extends ServiceProvider
{
  public function register()
  {
    $mail = userEmailConfiguration::configuredEmail()->first();
    if (isset($mail->id))
    {
      $config = array(
        'driver'     => $mail->driver,
        'host'       => $mail->host,
        'port'       => $mail->port,
        'from'       => array('address' => $mail->address, 'name' => $mail->name),
        'encryption' => $mail->encryption,
        'username'   => $mail->username,
        'password'   => $mail->password
      );
      Config::set('mail', $config);
    }
  }
  public function boot()
  {
  }
}

IMPLEMENTING THE MIDDLEWARE

Run the following command - php artisan make:middleware MailService

<?php
  namespace App\Http\Middleware;
  use Closure;
  use App;
class MailService
{
  public function handle($request, Closure $next)
  {
    $app = App::getInstance();
    $app->register('App\Providers\MailServiceProvider');
    return $next($request);
  }
}

Now that we’ve implemented all that, register your middleware within your $routedMiddleware array in your kennel.php as mail. Then call it up within your authenticated routes middleware:

Sample:

Route::group(['middleware' => [ 'auth:api' ]], function () {
  Route::post('send/email', 'Controller@test_mail')->middleware('mail');
});

Here's my original post over medium - Enable Unique And Dynamic SMTP Mail Settings For Each User — Laravel 7

Ikechukwu
  • 1,135
  • 1
  • 13
  • 30