Uporządkowane wysyłanie e-maili w projekcie symfony

Author: Wojtek Sznapka (wojciech.sznapka) | wrzesień 27th, 2010
avatar

Niemal każdy projekt, z jakim miałem do czynienia, zawierał fragmenty, w których były wysyłane e-maile. Najczęściej czynność ta jest wykonywana w kontrolerze aplikacji (klasa actions), a treścią wiadomości jest wyrenderowany partial. To rozwiązanie jest dobre do czasu, gdy chcemy wysłać tego samego e-maila z dwóch różnych aplikacji (np. z frontend i z backend), czy z taska. Warto wtedy przyjrzeć się wbudowanemu systemowi do wysyłania emaili jaki oferuje symfony 1.4 (korzystającym z Switf Mailer).

Aby nasze maile były uniwersalne i dostępne w każdej aplikacji tworzymy dla każdej wiadomości  osobną klasę dziedziczącą z Swift_Message i umieszczamy ją w głównym folderze lib

class MyTextMessage extends Swift_Message
{
  public function __construct($name, $address)
  {
    parent::__construct();
    $this->setFrom('foo@bar.com');
    $this->setTo($address);
    $this->setSubject('My text message');
    $body  = sprintf("Hi %s!\nHow are you?", $name);
    $this->setBody($body);
  }
}

Taką wiadomość możemy łatwo wysłać w ten sposób (z akcji lub z taska):

$this->getMailer()->send(new MyTextMessage('Barack', 'barack@obama.com'));

Jak widać metoda ta jest prosta i przyjemna. Trochę trudniej jest w przypadku e-maili, których zawartość jest w formacie HTML. Musimy wtedy użyć klasy sfPHPView, udostępnianej przez symfony

$templatesDir = sfConfig::get('sf_root_dir') . '/data/mailTemplates/';
$view = new sfPHPView(sfContext::getInstance(), null, null, null);
$view->setTemplate($templatesDir . 'MyMessageTemplate.php');
$view->getAttributeHolder()->add(array('name' => 'Barack'));
$view->setDecorator(false);
$body = $view->render();

Szablon e-maila z pliku /data/mailTemplates/MyMessageTemplate.php może wyglądać następująco

<h1>Hi <?php echo $name ?></h1>
<p>How are you?</p>

Klasa do wysyłania e-maili w formie HTML będzie wyglądała następująco

class MyHtmlMessage extends Swift_Message
{
  public function __construct($name, $address)
  {
    parent::__construct();
    $this->setFrom('foo@bar.com');
    $this->setTo($address);
    $this->setSubject('My text message');
    $body = $this->_buildBody('Barack');
    $this->setBody($body);
  }

  protected function _buildBody($name)
  {
    $templatesDir = sfConfig::get('sf_root_dir') . '/data/mailTemplates/';
    $view = new sfPHPView(sfContext::getInstance(), null, null, null);
    $view->setTemplate($templatesDir . 'MyMessageTemplate.php');
    $view->getAttributeHolder()->add(array('name' => $name));
    $view->setDecorator(false);
    return $view->render();
  }
}

Tak stworzony mechanizm można w łatwy sposób podpiąć pod eventy oferowane przez symfony, czyniąc go jeszcze bardziej elastycznym. Oczywiście w takim podejściu możemy wykorzystać dobrodziejstwa programowania obiektowego, tworząc klasy bazowe e-maili czy rozszerzać istniejące e-maile przy pomocy dziedziczenia.

Opis tej metody można również znaleźć w podręczniku symfony (Email Messages as Classes).

Tags: , ,

Podyskutuj na ten temat:

3 Responses to “Uporządkowane wysyłanie e-maili w projekcie symfony”

  1. avatar kinga pisze:

    a tym, którzy chcą bezproblemowo wysłać ;) paczkę kurierem, szybko i tanio, polecam serwis http://www.kurjerzy.pl/

  2. avatar hribo pisze:

    how would you add image into this kind of email message?
    i was trying to do following:

    $cid = $this->embed(Swift_Image::fromPath(‘images/logo.jpg’));

    but after this line it gets error:
    Fatal error: Call to a member function has() on a non-object in /var/www/symfony/_symfony_core/symfony-1.4.9/lib/vendor/swiftmailer/classes/Swift/Mime/SimpleMimeEntity.php on line 572

    do you know where is the problem?
    thank you

Leave a Reply