El envío de emails es uno de los usos más comunes de las tareas. Hasta Symfony 1.3 el envío de emails no era tan sencillo como debía ser. Afortunadamente la situación ha cambiado y ahora Symfony está completamente integrado con Swift Mailer, una librería muy completa para el envío de emails.
El objeto mailer está disponible en las tareas de Symfony mediante el método
sfCommandApplicationTask::getMailer()
. Por tanto, acceder al mailer y enviar
emails es tan 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 tarea project: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.
13.5.1. 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';
}
13.5.2. 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.
13.5.3. 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;
}
13.5.4. 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.