1

I have an issue regarding the use of SwiftMailer before a redirect. If I allow the controller making the request to return then emails are sent fine. For example:

function foo() {

    // ...

    $message = \Swift_Message::newInstance()
        ->setSubject($subject)
        ->setFrom($sender)
        ->setTo($recipient)
        ->setBody(strip_tags($html))
        ->addPart($html, 'text/html');
    $result = $this->app['mailer']->send($message);

    return '';
}

The above works so long as I return a non-null response.

However if I do the same but with a redirect like this:

function foo() {

    // ... 

    $message = \Swift_Message::newInstance()
        ->setSubject($subject)
        ->setFrom($sender)
        ->setTo($recipient)
        ->setBody(strip_tags($html))
        ->addPart($html, 'text/html');
    $result = $this->app['mailer']->send($message);

    simpleredirect($this->app['paths']['root']);
}

Then the message is not sent.

Note: the simpleredirect() function terminates the script, as is standard practice.

In both examples the $result comes back as the number of specified recipients. Therefore I can only assume that the mail is queued and some kind of dispatch runs on a conventional return which is missed out in the presence of a redirect.

I have a feeling that the SwiftMailer spool option might be enabled. However doing a few searches of my Bolt projects I cannot seem to find it being set anywhere. If spooling is enabled then the email won't be sent until the kernal termination phase, which the redirect (having die will avoid).

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
diggersworld
  • 12,770
  • 24
  • 84
  • 119

2 Answers2

1

OK I found how to do it:

$app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']);

By adding this line before the redirect it makes the kernal send the email.

Here is the reason:

The Swiftmailer provider sends the emails using the KernelEvents::TERMINATE event, which is fired after the response has been sent. However, as this event isn't fired for console commands, your emails won't be sent.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
diggersworld
  • 12,770
  • 24
  • 84
  • 119
  • The official recommended way for doing it is to execute a console command - http://symfony.com/doc/3.2/console/command_in_controller.html – Oleg Abrazhaev Aug 02 '17 at 12:35
0

Put a return before simpleredirect. This is required as every controller action must return Response object.

In case of return '', Symfony itself create Response object.

Apul Gupta
  • 3,044
  • 3
  • 22
  • 30