Una de las tareas más comunes en una aplicación web es el tema de este post “envio de emails”. Por suerte a partir de Symfony 1.3 el envío de emails ah sido simplificado completamente gracias a la integración con Swift Mailer, una librería muy completa para esta funcionalidad.
El objeto mailer está disponible en las tareas de Symfony mediante el método sfCommandApplicationTask::getMailer(). Acceder al mailer y enviar emails es sumamente sencillo como se muestra en el siguiente ejemplo:
public function execute($arguments = array(), $options = array())
{
$mailer = $this->getMailer();
$mailer->composeAndSend($remitente, $destinatario, $asunto, $contenido);
}
Nota
Como la configuración del mailer se obtiene a partir de la configuración de la aplicación, para utilizar el mailer es obligatorio que la tarea utilice una opción llamada
application.
Nota
Si utilizas la estrategia de envío
spool, los emails sólo se envían cuando se ejecuta la tareaproject:send-emails.
Normalmente el contenido del email no se encuentra en una variable mágica llamada $contenido esperando a que lo envíes, sino que debes generarlo de alguna forma antes de enviarlo. En Symfony no existe una forma estándar de generar el contenido de los emails, pero puedes seguir los consejos mostrados en las próximas secciones para facilitar tu trabajo.
Delegar la generación del contenido
Se puede crear en la tarea un método protegido que devuelva el contenido del email que se va a enviar:
public function execute($arguments = array(), $options = array())
{
$this->getMailer()->composeAndsend($remitente, $destinatario, $asunto, $this->getContenido());
}
protected function getContenido()
{
return 'Hola Mundo';
}
Utilizar el plugin decorator del Swift Mailer
Swift Mailer incluye un plugin llamado Decorator que básicamente es un sistema de plantillas muy simple pero eficiente. Este plugin recibe los datos que dependen del destinatario y los sustituye en el contenido del email preparado.
Puedes leer la documentación de Swift Mailer para obtener más información.
Utilizar un sistema de plantillas externo
Integrar una librería externa de plantillas es muy sencillo. Se puede utilizar por ejemplo el nuevo componente de plantillas que forma parte del proyecto Symfony Components. Descarga el código del componente, copialo por ejemplo en el directorio lib/vendor/templating/ y utiliza el siguiente código en la plantilla:
protected function getContenido($template, $vars = array())
{
$engine = $this->getTemplateEngine();
return $engine->render($template, $vars);
}
protected function getTemplateEngine()
{
if (is_null($this->templateEngine))
{
$loader = new sfTemplateLoaderFilesystem(sfConfig::get('sf_app_dir').'/templates/emails/%s.php');
$this->templateEngine = new sfTemplateEngine($loader);
}
return $this->templateEngine;
}
Combinando lo mejor de cada uno
Todavía existe otra forma de hacerlo. El plugin Decorator de Swift Mailer es genial porque se encarga de realizar las sustituciones que dependen del destinatario del mensaje. Esto significa que en el contenido del mensaje se definen los elementos que dependen del destinatario y Swift Mailer se encarga de reemplazar los tokens con el valor correcto en función del destinatario del email que se envía. El siguiente código muestra cómo integrarlo con el componente de las plantillas:
public function execute($arguments = array(), $options = array())
{
$message = Swift_Message::newInstance();
// obtiene la lista de usuarios
foreach($users as $user)
{
$replacements[$user->getEmail()] = array(
'{username}' => $user->getEmail(),
'{specific_data}' => $user->getSomeUserSpecificData(),
);
$message->addTo($user->getEmail());
}
$this->registerDecorator($replacements);
$message
->setSubject('User specific data for {username}!')
->setBody($this->getMessageBody('user_specific_data'));
$this->getMailer()->send($message);
}
protected function registerDecorator($replacements)
{
$this->getMailer()->registerPlugin(new Swift_Plugins_DecoratorPlugin($replacements));
}
protected function getMessageBody($template, $vars = array())
{
$engine = $this->getTemplateEngine();
return $engine->render($template, $vars);
}
protected function getTemplateEngine($replacements = array())
{
if (is_null($this->templateEngine))
{
$loader = new sfTemplateLoaderFilesystem(sfConfig::get('sf_app_template_dir').'/emails/%s.php');
$this->templateEngine = new sfTemplateEngine($loader);
}
return $this->templateEngine;
}
El archivo apps/frontend/templates/emails/user_specific_data.php contiene el siguiente código:
Hi {username}!
We just wanted to let you know your specific data:
{specific_data}
¡Y eso es todo! Ahora ya dispones un completo sistema de plantillas para crear el contenido de tus emails.