Un po 'in ritardo per la festa ma volevo solo estendere la risposta accettata e buttare i miei 2 cent, nel caso in cui si salvasse qualcosa e tempo. Nel mio scenario ogni utente connesso aveva le proprie impostazioni SMTP, MA stavo inviando mail usando una coda, che ha fatto sì che le impostazioni tornassero ai valori predefiniti dopo averle impostate. Inoltre ha creato alcuni problemi di posta elettronica simultanea. In breve, il problema era
$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
Dopo alcuni momenti di tastiera bashing mi sono reso conto che la coda è in esecuzione su un processo separato e quindi Mail :: setSwiftMailer non influisce affatto. Prende semplicemente le impostazioni predefinite. Pertanto, la modifica della configurazione doveva avvenire al momento effettivo dell'invio dell'e-mail e non durante la messa in coda.
La mia soluzione era di estendere la Classe Mailable come segue.
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);
});
}
}
E poi cambiato CustomMail
di estendere ConfigurableMailable
invece di Mailable
:
class CustomMail extends ConfigurableMailable {}
Questo fa in modo che anche chiamando Mail::queue(new CustomMail())
effettuerà le impostazioni di posta elettronica per utente a destra prima di inviare. Ovviamente sarà necessario iniettare l'utente corrente su CustomMail ad un certo punto, ad esempio Mail::queue(new CustomMail(Auth::user()))
Anche se questa potrebbe non essere la soluzione ideale (ad esempio, se si tenta di inviare email di massa è meglio configurare il mailer una volta e non in ogni email inviata), mi piace la sua semplicità e il fatto che non abbiamo bisogno di modificare le impostazioni globali Mail
o Config
, solo l'istanza $mailer
è interessata.
Spero che lo trovi utile!
funziona come un fascino. per quelli che potrebbero cercare, SmtpTransport proviene da usare Swift_SmtpTransport come SmtpTransport; – cmancre
L'ho usato per fare la differenza tra e-mail "normali" e e-mail "di sistema". Funziona alla grande, grazie! – Jurgen
Risposta molto bella, grazie. – EGurelli