Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Enviar emails en un comando de Symfony

26 de junio de 2015

Saludos

Tengo creado una clase (Model) donde tengo toda la funcionalidad de enviar un email con los datos señalados.

Puede enviar los datos (diferente para cada área) requeridos a una área o varios áreas a la vez, traves de la aplicación, pero no se como ejecutarla desde un comando.

Me arroja este error.

[Symfony\Component\DependencyInjection\Exception\InactiveScopeException]     
  You cannot create a service ("templating.helper.assets") of an inactive scope ("request").

Ejecuto el comando:

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
 
use Intranet\AppBundle\Model\SendLicencia;
 
// ....
 
protected function execute(InputInterface $input, OutputInterface $output)
{
    $container = $this->getContainer();
    $licencia = new SendLicencia($container);
    $licencia->main();
    $output->writeln("Se envió la información.");
}

Respuestas

#1

En primer lugar, te recomiendo que cuando tengas algo de tiempo refactorices un poco el código de este comando. El problema está en que pasas todo el contenedor de dependencias en la variable $container. Esto se considera una mala práctica e incluso puede afectar ligeramente al rendimiento. La solución sería pasar las (pocas) cosas que necesitas: el servicio de Doctrine, el logger, etc. Si necesitas pasar muchas cosas (por ejemplo 10 servicios) eso es otra señal de que el código es demasiado complejo y deberías refactorizarlo.

Centrándonos en tu problema concreto, la causa de este error es la siguiente: en la plantilla Twig que usas para renderizar el contenido del email seguramente estás usando la función asset(). El problema es que esa función está pensada para cuando usas la plantilla en un entorno web. Pero en este caso la plantilla no se está usando en ese contexto, sino en una consola de comandos. Por tanto, no hay realmente una petición y asset() no puede funcionar bien.

La mejor solución es la que se explica en este artículo de la documentación oficial de Symfony: How to Generate URLs and Send Emails from the Console. Como ves, sólo tienes que definir tres opciones de configuración y listo. Si por lo que sea no te funciona esta solución, dímelo y te indico la solución alternativa.

@javiereguiluz

27 junio 2015, 10:01
#2

Saludos

Gracias por tu respuesta.

Mi duda como puedo refactorizar el código, necesito esto del contenedor:

  • doctrine
  • mailer
  • session
  • templating
  • redirect

Podría crear un servicio (¿cómo?) de modelo que envía (email) la información.

Gracias.

@dariongg

30 junio 2015, 16:16
#3

El servicio session me resulta raro, ya que estamos hablando de comandos de consola y emails, por lo que nunca va a haber una sesión de usuario. El redirect no sería un servicio, ya que es un atajo muy sencillo (puedes ver su código en el controlador base de Symfony).

Así que te quedaría inyectar doctrine, mailer y templating, que es algo bastante razonable para servicios complejos. Como posible mejora extra, quizás en vez de inyectar doctrine entero, podrías definir los repositorios que vas a usar como servicios y así inyectar solamente eso. Pero por ahora no me preocuparía de eso.

@javiereguiluz

30 junio 2015, 16:26