Code snippets for symfony 1.x

Navigation

How to send Emails from the model or from a task

For sf1.3/1.4 only.

It seems that the symfony mailer system is tied to the sfContext resource via the factory handler (correct me if I'm wrong).

It might be a problem when you want to send an email from one of your model methods because sfContext has no instance in cli mode.

It can also be an issue if you want to build a task that send emails. Sample: a nightly cron job that alert users by email when their free trial period is over.

The best way I've found is to provide an access to the mailer system linked to the ProjectConfiguration class.

Add a static protected "$mailer" variable and a static public method "getMailer()" :

class ProjectConfiguration extends sfProjectConfiguration
{
  static protected
    $mailer  = null # Symfony mailer system
    ;
 
  /**
   * Returns the project mailer
   */
  static public function getMailer()
  {
    if (null !== self::$mailer)
    {
      return self::$mailer;
    }
 
    // If sfContext has instance, returns the classic mailer resource
    if (sfContext::hasInstance() && sfContext::getInstance()->getMailer())
    {
      self::$mailer = sfContext::getInstance()->getMailer();
    }
    else
    {
      // Else, initialization
      if (!self::hasActive())
      {
        throw new sfException('No sfApplicationConfiguration loaded');
      }
      require_once sfConfig::get('sf_symfony_lib_dir').'/vendor/swiftmailer/classes/Swift.php';
      Swift::registerAutoload();
      sfMailer::initialize();
      $applicationConfiguration = self::getActive();
 
      $config = sfFactoryConfigHandler::getConfiguration($applicationConfiguration->getConfigPaths('config/factories.yml'));
 
      self::$mailer = new $config['mailer']['class']($applicationConfiguration->getEventDispatcher(), $config['mailer']['param']);
    }
 
    return self::$mailer;
  }
}
 

Now if you want to send an email from a task or from a model class:

ProjectConfiguration::getMailer()->composeAndSend(/* your email params*/);
 

In your unit tests, if you want to test which emails have been sent:

$sentEmails = ProjectConfiguration::getMailer()->getLogger()->getMessages();
 

Regards.

by Éric Rogé on 2009-12-11, tagged mailer  swift 

Comments on this snippet

gravatar icon
#1 joran joran on 2009-12-12 at 03:11

what about the getMailer() method of the sfCommandApplicationTask class ?

gravatar icon
#2 joran joran on 2009-12-12 at 03:27

or if you are not in a CLI task, you could add a listener to the 'mailer.configure' event notified by the sfMailer class [http://trac.symfony-project.org/browser/tags/RELEASE_1_4_1/lib/mailer/sfMailer.class.php#L152]