简体   繁体   中英

Laravel update email config on the fly

I need to be able to send email using Mailgun from one domain, switch settings, then send another from another domain. However, updating the settings before sending the second email does not work, the second email still gets sent using the first emails settings.

Initial settings are set in Config.mail and Config.services , this all works fine.

// send first email
try { 
    Mail::send(--stuff here--) 
} catch (Exception $e) { ... }

// update config using the sandbox account details
Config::set('mail.username', 'postmaster@secret.mailgun.org');
Config::set('mail.password', 'password');
Config::set('services.mailgun.domain', 'domain.mailgun.org'); 
Config::set('services.mailgun.secret', 'key-secret');

// send second email
try { 
    Mail::send(--stuff here--) 
} catch (Exception $e) { ... }
// Second email has now been sent using the first emails config settings 

If I comment out the first email send, then change the settings as above, the second email get's sent correctly from the sandbox account. If I leave the first email in, it gets sent from a domain I have on MailGun.

Does anyone have any experience with this?

Thanks for the answer above. Unfortunately in Laravel 5.4 share() was removed and this would no longer work. Updated version of the code above that works in 5.4 using a singleton instead of share() .

config(['mail.driver' => 'mailgun']);
config(['services.mailgun.domain' => mail_domain]);
config(['services.mailgun.secret' => mail_secret]);

$app = \App::getInstance();

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

$mailer = new \Swift_Mailer($app['swift.transport']->driver());
\Mail::setSwiftMailer($mailer);

\Mail::to(me@example.com)->send(new TrialCreated($params));
    config([
        'mail.host' => 'smtp.yandex.ru',
        'mail.port' => 465,
        'mail.encryption' =>'ssl',
        'mail.username' => 'username',
        'mail.password' => 'password'
    ]);

    $app = App::getInstance();

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

    $mailer = new \Swift_Mailer($app['swift.transport']->driver());
    Mail::setSwiftMailer($mailer);

    $msg = Mail::send('mail.view', ['key' => 'value'], function(Message $message) {
        $message
            ->to('user@mail.com', 'Name')
            ->subject('Subject');
    });

My scenario was a little simpler. I just needed to choose a different driver. This worked in Laravel 6.10. Perhaps you could adapt it to fit your needs.

app/Traits/MailDriver.php

namespace App\Traits;

trait MailDriver
{
    public function driver($driver)
    {
        config()->set('mail.driver', $driver); // Configure as necessary.

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

        \Mail::setSwiftMailer(new \Swift_Mailer(app()['swift.transport']->driver()));

        return $this;
    }
}

app/Mail/TestMail.php

namespace App\Mail;

...

class TestMail extends Mailable
{
    use \App\Traits\MailDriver;     // Use trait above

    public function build()
    {
        return $this
            ->driver('ses')         // Change driver here
            ->from('info@site.com')
            ->view('emails.ses');
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM