Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 377 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
multiple mail configurations

#1
I configured laravel's mail service with mandrill driver. No problems here!

Now, at certain point of my application, I need to send a mail via gmail.

I did something like:

// backup current mail configs
$backup = Config::get('mail');

// rewrite mail configs to gmail stmp
$new_configs = array(
'driver' => 'smtp',
// ... other configs here
);
Config::set('mail', $new_configs);

// send the email
Mail::send(...

// restore configs
Config::set('mail', $backup);

This doens't work, laravel always uses the mandrill configurations. Looks like he initiates mail service at script startup and ignores whatever you do during execution.

How do you change mail service configs/behaviour during execution?



Reply

#2
You can create a new `Swift_Mailer` instance and use that:

// Backup your default mailer
$backup = Mail::getSwiftMailer();

// Setup your gmail mailer
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl');
$transport->setUsername('your_gmail_username');
$transport->setPassword('your_gmail_password');
// Any other mailer configuration stuff needed...

$gmail = new Swift_Mailer($transport);

// Set the mailer as gmail
Mail::setSwiftMailer($gmail);

// Send your message
Mail::send();

// Restore your original mailer
Mail::setSwiftMailer($backup);
Reply

#3
You can set on the fly mail settings:

Config::set('mail.encryption','ssl');
Config::set('mail.host','smtps.example.com');
Config::set('mail.port','465');
Config::set('mail.username','[email protected]');
Config::set('mail.password','password');
Config::set('mail.from', ['address' => '[email protected]' , 'name' => 'Your Name here']);

Maybe you can store settings values in config/customMail.php and retrive them whith Config::get('customMail')

Reply

#4
A bit late to the party but just wanted to extend the accepted answer and throw in my 2 cents, in case it saves someone time. In my scenario each logged in user had their own SMTP settings BUT I was sending mails using a queue, which caused the settings to go back to default after setting them. It also created some concurrent emails issues. In short, the problem was

$transport = Swift_SmtpTransport::newInstance($user->getMailHost(), $user->getMailPort(), $user->getMailEncryption());
$transport->setUsername($user->getMailUser());
$transport->setPassword($user->getMailPassword());
$mailer = new Swift_Mailer($transport);
Mail::setSwiftMailer($mailer);
//until this line all good, here is where it gets tricky

Mail::send(new CustomMailable());//this works
Mail::queue(new CustomMailable());//this DOES NOT WORK

After few moments of keyboard bashing I realized that the queue is running on a separate process and therefore Mail::setSwiftMailer does not affect it at all. It simply picks up the default settings.
Therefore the configuration change had to happen at the actual moment of sending the email and not when queuing it.

My solution was to extend the Mailable Class as following.

app\Mail\ConfigurableMailable.php

<?php

namespace App\Mail;

use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Mail\Mailable;
use Swift_Mailer;
use Swift_SmtpTransport;

class ConfigurableMailable extends Mailable
{
/**
* Override Mailable functionality to support per-user mail settings
*
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @return void
*/
public function send(Mailer $mailer)
{
$host = $this->user->getMailHost();//new method I added on User Model
$port = $this->user->getMailPort();//new method I added on User Model
$security = $this->user->getMailEncryption();//new method I added on User Model

$transport = Swift_SmtpTransport::newInstance( $host, $port, $security);
$transport->setUsername($this->user->getMailUser());//new method I added on User Model
$transport->setPassword($this->user->getMailPassword());//new method I added on User Model
$mailer->setSwiftMailer(new Swift_Mailer($transport));

Container::getInstance()->call([$this, 'build']);
$mailer->send($this->buildView(), $this->buildViewData(), function ($message) {
$this->buildFrom($message)
->buildRecipients($message)
->buildSubject($message)
->buildAttachments($message)
->runCallbacks($message);
});
}
}

And then changed `CustomMail` to extend `ConfigurableMailable` instead of `Mailable`:

`class CustomMail extends ConfigurableMailable {}`

This makes sure that even calling `Mail::queue(new CustomMail())` will set the per-user mail settings right before sending. Of course you will have to inject the current user to the CustomMail at some point i.e `Mail::queue(new CustomMail(Auth::user()))`

While this may not be the ideal solution (i.e if trying to send bulk email it is better to config the mailer once and not on every email sent), I like its simplicity and the fact that we do not need to change the global `Mail` or `Config` settings at all, only the `$mailer` instance is being affected.

Hope you find it useful!

Reply

#5
Even easier it is to execute following code, just before sending an email, after
you have written over the mail-configuration with config :

app()->forgetInstance('swift.transport');
app()->forgetInstance('swift.mailer');
app()->forgetInstance('mailer');

Reply

#6
Using only `setSwiftMailer` as explained by Bogdan didn't work for me, because then the `from` and `adress` options where still taken from `config/mail.php`. Also it wasn't working with queues.

I created a package called [multiMail](

[To see links please register here]

) to solve this.

One can setup the mail adress and host/provider/username/passwort etc in `/config/multimail.php` and then one can send the mails using

\MultiMail::from('[email protected]')->send(new MailableDummy()));
\MultiMail::from('[email protected]')->send(new MailableDummy()));

or queue it

\MultiMail::from('[email protected]')->queue(new MailableDummy()));







Reply

#7
For **Laravel 6** you should use it like this:

// Backup your default mailer
$backup = Mail::getSwiftMailer();

// Setup your gmail mailer
$gmail = new \Swift_SmtpTransport('smtp.gmail.com', 465, 'ssl');

// Set the mailer as gmail
Mail::setSwiftMailer(new \Swift_Mailer($gmail));

// Send your message
Mail::send();

// Restore your original mailer
Mail::setSwiftMailer($backup);
Reply

#8
For [**Laravel version 7.x**][1] and above, you can now state the mail driver to use while sending an email. All you need to configure all your connections & credentials properly in `config/mail.php`. Once configured, you can specify the name of the driver via `mailer()` function as below:

Mail::mailer('postmark')
->to($request->user())
->send(new OrderShipped($order));

I hope it helps someone.

[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through