2012-10-29 5 views
9

Ho scritto un comando console personalizzato per interrogare il mio database, produrre un rapporto e inviarlo via e-mail a un indirizzo; tuttavia non riesco a inviare correttamente l'e-mail. Posso inviare e-mail bene dai normali controller altrove nella mia applicazione, e posso anche inviarlo dal mio comando console se creo e configuro manualmente un'istanza Swift_Mailer e non la prendo tramite il contenitore.Impossibile inviare e-mail dal comando personalizzato Symfony2 ma possibile da altrove nell'app

Ecco una versione ridotta del mio comando da console:

<?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('[email protected]') 
      ->setTo('[email protected]') 
      ->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 è configurato per inviare tramite SMTP nel mio file di app/config/config.yml (delivery_address: [email protected] è impostato anche in app/config/config_dev.yml):

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

Quando eseguendo il comando, stampa 1 sulla riga di comando, che presumo significhi che ha avuto successo. Tuttavia sto monitorando i log del mio server di posta allo stesso tempo e non si connette nemmeno.

Per confermare che la mia configurazione è stata caricata nella mailer, ho cambiato la bobina memory-file e messaggi sono lo spooling sul file system durante l'esecuzione del comando e posso lavare con successo la bobina sulla riga di comando con php app/console swiftmailer:spool:send .

Qualcuno ha qualche idea su cosa sta succedendo qui, o qualche suggerimento su come posso eseguire il debug ulteriormente? Nulla appare nel mio file app/logs/dev.log. Sto usando Symfony 2.1.3-DEV.

risposta

27

Dall'iscrizione di alcuni codici Symfony e SwiftMailer, è possibile vedere che lo spool di memoria viene svuotato nell'evento kernel.terminate che si verifica dopo l'invio di una risposta. Non sono sicuro che funzioni per i comandi, ma potrei sbagliarmi.

Prova ad aggiungere questo codice alla fine del vostro comando e vedere se aiuta:

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

il lavaggio manuale della bobina come questo sembra funzionare, credo che la 'isn evento kernel.terminate'' t sparato all'interno dei comandi della console, quindi. Grazie! – Kris

+1

Un'altra opzione è disabilitare lo spool dal file di configurazione, è possibile farlo solo per la riga di comando. L'ho fatto come soluzione temporanea (sì giusto) e ha funzionato per me. – Jens

+0

Come sempre, ottima risposta Elnur! :) – DonCallisto

2

Invece di memoria per i file di spool uso di spool. Modifica la 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 } 
-1

Basta aggiungere questo alla fine della tua azione eseguire:

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