问题
I have written a custom console command to query my database, produce a report and e-mail it to an address; however I can not seem to successfully send the e-mail. I can send e-mail fine from within normal controllers elsewhere within my application, and I can also send it from within my console command if I manually create and configure a Swift_Mailer instance and not get it via the container.
Here is a stripped down version of my console command:
<?php
namespace Foo\ReportBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ExpiryCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('report:expiry')
->setDescription('Compile and send e-mail listing imminent expiries');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
/* ... */
$message = \Swift_Message::newInstance()
->setSubject('Expiry report')
->setFrom('DoNotReply@domain.com')
->setTo('recipient@domain.com')
->setBody($body);
$mailer = $this->getContainer()->get('mailer');
/* This works...
$transport = \Swift_SmtpTransport::newInstance('smtp.domain.com', 25)
->setUsername('username')
->setPassword('password');
$mailer = \Swift_Mailer::newInstance($transport);
*/
$result = $mailer->send($message);
$output->writeln($result);
}
}
Swiftmailer is configured to send via SMTP within my app/config/config.yml
file (delivery_address: dev@domain.com
is also set in app/config/config_dev.yml
):
swiftmailer:
transport: smtp
host: smtp.domain.com
username: username
password: password
spool:
type: memory
When running the command, it prints 1
to the command line, which I assume it means it was successful. However I'm monitoring my mail server's logs at the same time, and it's not even connecting.
To confirm that my configuration was being loaded into the mailer, I changed the spool from memory
to file
and messages are being spooled to the file system when running the command and I can successfully flush the spool on the command line with php app/console swiftmailer:spool:send
.
Does anyone have any ideas as to what's happening here, or any suggestions as to how I can debug it further? Nothing is appearing in my app/logs/dev.log
file. I'm using Symfony 2.1.3-DEV.
回答1:
From digging some Symfony and SwiftMailer code, I can see that the memory spool is flushed on the kernel.terminate
event that occurs after a response was sent. I'm not sure it works for the commands, but I may be wrong.
Try adding this code at the end of your command and see if it helps:
$transport = $this->container->get('mailer')->getTransport();
if (!$transport instanceof \Swift_Transport_SpoolTransport) {
return;
}
$spool = $transport->getSpool();
if (!$spool instanceof \Swift_MemorySpool) {
return;
}
$spool->flushQueue($this->container->get('swiftmailer.transport.real'));
回答2:
Instead of memory spool use file spool.
Modify your app/config/config.yml
:
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: file, path: %kernel.root_dir%/spool }
回答3:
Just add this to the end of your execute action:
$container = $this->getContainer();
$mailer = $container->get('mailer');
$spool = $mailer->getTransport()->getSpool();
$transport = $container->get('swiftmailer.transport.real');
$spool->flushQueue($transport);
来源:https://stackoverflow.com/questions/13122096/unable-to-send-e-mail-from-within-custom-symfony2-command-but-can-from-elsewhere