无法从自定义Symfony2命令中发送电子邮件,但可以从应用程序的其他位置发送

时间:2012-10-29 12:55:35

标签: php symfony swiftmailer

我编写了一个自定义控制台命令来查询我的数据库,生成报告并通过电子邮件发送到一个地址;但是我似乎无法成功发送电子邮件。我可以从我的应用程序中的其他地方的普通控制器中发送电子邮件,如果我手动创建和配置Swift_Mailer实例而不是通过容器获取它,我也可以从我的控制台命令中发送它。

这是我的控制台命令的精简版:

<?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配置为通过我的app/config/config.yml文件中的SMTP发送(delivery_address: dev@domain.com也设置为app/config/config_dev.yml):

swiftmailer:
    transport: smtp
    host: smtp.domain.com
    username: username
    password: password
    spool:
        type: memory

运行命令时,它会将1打印到命令行,我认为这意味着它成功了。但是,我同时监控邮件服务器的日志,甚至没有连接。

要确认我的配置已加载到邮件程序中,我将假脱机从memory更改为file,并且在运行命令时将消息假脱机到文件系统并且我可以成功刷新使用php app/console swiftmailer:spool:send命令行中的假脱机。

有没有人对这里发生的事情有任何想法,或者有关我如何进一步调试的建议?我的app/logs/dev.log文件中没有显示任何内容。我正在使用Symfony 2.1.3-DEV。

3 个答案:

答案 0 :(得分:27)

从挖掘一些Symfony和SwiftMailer代码,我可以看到内存假脱机在发送响应后发生的kernel.terminate事件上刷新。我不确定它是否适用于命令,但我可能错了。

尝试在命令末尾添加此代码,看看它是否有帮助:

$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'));

答案 1 :(得分:2)

而不是内存假脱机使用文件假脱机。 修改您的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 }

答案 2 :(得分:-1)

只需将其添加到执行操作的末尾:

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