2
votes

I'm trying to send emails in a custom command with memory spooling. According to the documentation here:

http://symfony.com/doc/2.7/cookbook/console/sending_emails.html

This is handled automatically since Symfony 2.3 / swiftmailer 2.3.5, but it isn't working.

I've tried the standard way

$email = \Swift_Message::newInstance()
    ->setSubject('New Email')
    ->setFrom('[email protected]')
    ->setTo($recipients)
    ->setBody($message);
$container = $this->getContainer();
$container->get('mailer')->send($email);

Nothing gets sent.

I've also tried to manually flush the spool, which was the workaround in older versions, by adding this at the end of the command

$spool = $container->get('mailer')->getTransport()->getSpool();
$transport = $container->get('swiftmailer.transport.real');
$spool->flushQueue($transport);

That also did nothing.

Emails are sent from my controllers, so I know swiftmailer is configured properly.

I don't want to have to switch over to file spooling, but it seems like that is the only option at the moment.

edit: When using memory spooling, flushQueue is called from vendor/swiftmailer/swiftmailer/lib/classes/Swift/MemorySpool.php

I edited that function to var_dump the $transport variable it is using, and it's decided to use the null transport Swift_Transport_NullTransport which should only be used if disable_delivery is set on the config (or if the transport is set to null in the config)

I think this is the cause of the failed emails, so my new question is, why are Commands using the NullTransport?

edit 2: The problem appears to be coming from this line

$spool->flushQueue($this->container->get(sprintf('swiftmailer.mailer.%s.transport.real', $name)));

in swiftmailer-bundle/EventListener/EmailSenderListener.php

I only have one mailer setup in my config

swiftmailer:
    transport:      %mailer_transport%
    host:           %mailer_host%
    username:       %mailer_user%
    password:       %mailer_password%
    spool:          { type: memory }
    port:           %mailer_port%
    encryption:     %mailer_encryption%
    sender_address: %mailer_sender_address%

which is pulling the values from paramters.yml

mailer_transport: sendmail
mailer_host: smtp.sendgrid.net
mailer_user: [USERNAME]
mailer_password: [PASSWORD]
mailer_port: 465
mailer_encryption: ssl
mailer_sender_address: [email protected]

but for some reason the transport that gets returned for "swiftmailer.mailer.default.transport.real" is the null transport.

1

1 Answers

0
votes

I couldn't get this to work at all. Symfony/Swift would only use the NullTransport in Commands, the console gives me this for the default transport

$ php app/console debug:container
...
swiftmailer.mailer.default.transport.real        Swift_Transport_NullTransport 
...

so I gave up and switched to a different approach.

I'm using the FOS restbundle, so I moved the email commands I was trying to build over to a rest controller. Then I call them with curl from the command line

$ curl --request POST http://api.mydomain.com/api/emails/foo/bar.json

This allows me to automate the call to send out the emails using crontab.

I had to change the code a little bit, basic changes like this

// Command
$container = $this->getContainer();
$entityManager = $container->get('doctrine')->getManager();
// Controller
$entityManager = $this->getDoctrine()->getManager();

Using rest and curl is not how this is supposed to be done, but at least it works.