9

I'm using SwiftMailer bundle with Symfony 2. I pass my smtp user/password settings in config.yml file, it works great, but I need to take this settings from database, when I'm sending mail. I can acces this params:

$mailer = $this->getContainer()->get('mailer')->getTransport();

But is it possible to change them on runtime ? I dont see any setter methods. many thanks!

j0k
  • 22,600
  • 28
  • 79
  • 90
Ivan
  • 175
  • 2
  • 7

4 Answers4

6

Many thanks, but it's not the solution i was looking, on kernel request I don't know which account I'll use. I needed to change settings inside my send mail loop. I found pretty cool solution:

foreach ($locations as $location) {
    // get settings for account
    $user = $location->getSmtpUser();
    $pass = $location->getSmtpPass();

    // switch to new settings
    $transport = $this->getContainer()->get('mailer')->getTransport();            
    $ext = $transport->getExtensionHandlers();
    $auth_handler = $ext[0];            
    $auth_handler->setUserName($user);
    $auth_handler->setPassword($pass);

    // send message using new settings
    $message = \Swift_Message::newInstance()
         ->setSubject( $subject )
         ->setFrom( $from )
         ->setTo( $email )
         ->setBody( $body )
         ->setContentType('text/html');

       $this->getContainer()->get('mailer')->send( $message );    
}
Ivan
  • 175
  • 2
  • 7
3

You can create a kernel.request event listener, inject swiftmailer.transport.real and set smpt info e.g

Listener class

namespace Namespace\Of\YourListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class YourListener implements EventSubscriberInterface
{

    /**
     * @var Swift_Transport_EsmtpTransport
     */
    private $transport;

    /**
     * @var Doctrine\ORM\EntityManager
     */
    private $em;

    public function __construct($transport, $em)
    {
        $this->transport = $transport;
        $this->em = $em;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        //fetch info from db
        $this->transport->setHost("host");
        $this->transport->setPort("port");
        $this->transport->setUserName("username");
        $this->transport->setPassword("pass");
    }

    static public function getSubscribedEvents()
    {
        return array(
            KernelEvents::REQUEST => array('onKernelRequest', 0)
        );
    }

}

Service decleration,

your_listener:
    class: FQCN\Of\YourListener
    tags:
        - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
    arguments: [@swiftmailer.transport.real, @doctrine.orm.entity_manager]
Mun Mun Das
  • 14,992
  • 2
  • 44
  • 43
2

I know this is a bit old, but I wanted to get an answer in in-case it helps somebody else. We are using the file spooler with an SMTP transport and needed to have customized SMTP server connections depending on site.

Our solution was to modify Swiftmailer to allow for some additional data on each message as well as tying it into Symfony2's Event Dispatcher. This allowed us to extract the connection info from each message at the time of the spool flushing.

We made it into a bundle so it can be leveraged by others. You can read about it here.

Wpigott
  • 814
  • 1
  • 7
  • 21
2

In fact, you should call $transport->stop(); because in other way Swift Mailer will not reconnect and old setting will be used during 1 script execution

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Andrew Zhilin
  • 1,654
  • 16
  • 11
  • Hi which answer are you referring to? Thanks! – Acyra Mar 15 '14 at 04:10
  • 2
    any from listed above. If you change Swift settings dynamically - you should call stop after it to apply changes :) – Andrew Zhilin Dec 10 '14 at 18:50
  • You saved a lot of time for me buddy :) Thank you very much! I tried to send emails in a loop with different auth settings and was getting the error `Expected response code 250 but got code 553` all the time. – leealex Mar 09 '18 at 08:26