Más con Symfony

4.10. Mensajes de correo electrónico como clases

En la introducción de este capítulo se ha mostrado cómo enviar emails desde una acción. Esta es probablemente la forma más sencilla de enviar emails en una aplicación de symfony y la forma que debes utilizar cuando sólo tienes que enviar unos pocos mensajes.

No obstante, si tu aplicación maneja muchos tipos diferentes de mensajes de correo electrónico, probablemente debas utilizar una estrategia diferente.

Nota Además, el uso de clases para los mensajes de correo electrónico significa que puedes reutilizar el mismo mensaje en diferentes aplicaciones, como por ejemplo en el frontend y en el backend.

Como los mensajes son objetos PHP normales, la forma más obvia de organizar tus mensajes consiste en crear una clase para cada uno de ellos:

// lib/email/ProjectConfirmationMessage.class.php
class ProjectConfirmationMessage extends Swift_Message
{
  public function __construct()
  {
    parent::__construct('Asunto', 'Cuerpo');

    $this
      ->setFrom(array('[email protected]' => 'Robot de la Aplicación'))
      ->attach('...')
    ;
  }
}

A continuación, enviar un mensaje desde una acción o desde cualquier otro punto de la aplicación es algo tan sencillo como instanciar la clase de mensaje adecuada:

$this->getMailer()->send(new ProjectConfirmationMessage());

Obviamente, puede ser muy útil crear una clase base que centralice todas las cabeceras comunes, como por ejemplo la cabecera From, o la inclusión de la misma firma en todos los mensajes:

// lib/email/ProjectConfirmationMessage.class.php
class ProjectConfirmationMessage extends ProjectBaseMessage
{
  public function __construct()
  {
    parent::__construct('Asunto', 'Cuerpo');

    // cabeceras específicas, adjuntos, ...
    $this->attach('...');
  }
}

// lib/email/ProjectBaseMessage.class.php
class ProjectBaseMessage extends Swift_Message
{
  public function __construct($asunto, $cuerpo)
  {
    $body .= <<<EOF
--

Email enviado por el Robot de mi Aplicación
EOF
    ;
    parent::__construct($asunto, $cuerpo);

    // añadir todas las cabeceras comunes
    $this->setFrom(array('[email protected]' => 'Robot de la Aplicación'));
  }
}

Si un mensaje depende de algunos objetos del modelo, también puedes pasarlos como argumentos de su constructor:

// lib/email/ProjectConfirmationMessage.class.php
class ProjectConfirmationMessage extends ProjectBaseMessage
{
  public function __construct($usuario)
  {
    parent::__construct('Confirmación para '.$usuario->getNombre(), 'Cuerpo');
  }
}