Development

RFC/1.2/email

You must first sign up to be able to contribute.

Version 21 (modified by nicolas, 9 years ago)
fixed typo

Request For Comments: sending emails with symfony 1.2

There should be a standard way to send emails within symfony 1.2. This wiki page aims to get your feedback and ideas about the way the SwiftMailer library goodness should be integrated.

If you want to comment a paragraph, just add a bullet below it with your name, like this:

 * comment from __John Doe__
   * Maybe this is dumb

Which will be rendered as:

  • comment from John Doe
    • Maybe this is dumb

The main goals of this integration are:

  1. Being able to use a different mailer dependending of the environment
  2. Being able to set any source as a template for an email
  3. Being able to quickly and easily send email(s) within a controller
  4. Being able to reuse existing emails
  5. The symfony API on top of Swift must be minimal. The goal is to integrate symfony and Swift and make it simplier to use Swift within symfony.

Environments Handling

Maybe in dev mode you doesn't want to send real email, but just want to generate them and store them on your local filesystem (or anywhere you want), eg. as the sfEmailPlugin already does.

That would be possible using the factories.yml file, like this (draft):

prod:
 mailer:
   class: sfMailerSmtp
   param:
     server:         foo.bar.tld
     port:           25
     username:       foo
     password:       bar
     default_sender: Toto Mailer <toto@toto.com>
all:
 mailer:
   class: sfMailerConnectionFileSystem:
   param:
     path: %SF_LOG_DIR%/emails
  • comment from Bernhard Schussek
    • Does sfMailerSmtp extend Swift? Is it possible to retrieve the mailer somehow in an action? Can I pass custom Swift connections to it?
    • (nicolas) yes,
  • comment from David Stendardi
    • What about Connection rotator feature in Swift ? It would be very nice to have the way to define multiple different connections in the config file like :
              connections:
                smtp:
                  host: mailer.internal
                  username: foo
                  password: bar
      
      • (nicolas) of this will possible using the factories.yml file and set the class as a Swift_Connection_Rotator derived one, with according settings
    • Another nice to have feature : use the beforeSendEvent to bypass recipients and avoid the risk of sending emails to real users ;-)
      • The "local email file storage" feature will help debugging emails in a given environment (says, dev)

Email Templates Source

Any source should be useable as a template source for emails. For example, we should be able to use an action (with or without a dedicated layout), a component, a partial, a string, a file, etc.

API Proposal:

<?php
$email = new sfEmail();
// then
$email->setHtmlTemplate(new sfEmailTemplateAction('mymodule','myaction'));
// or
$email->setTextTemplate(new sfEmailTemplatePartial('mymodule', 'mypartial'));
// or
$email->setTextTemplate(new sfEmailTemplateComponent('mymodule', 'mycomponent'));
// or
$email->setTextTemplate(new sfEmailTemplateString('hello world'));
// and maybe
$email->setTemplate('text/html', new sfEmailTemplateString('hello world'));
// why not
$email->setTemplate('application/pdf', new sfEmailTemplateFile('/tmp/toto.pdf'));
// there could be also sfEmailTemplateCallback() and so on
// then
$email->send();
?>

  • comment from Bernhard Schussek
    • Does (once again) sfEmail extend Swift_Message? What is the use case for providing actions and components as message source templates? As I can't really see any, I recommend passing just the partial name as string or the raw mail body.
      • Partials are not sufficient to me. Maybe you will want to set an email layout, and for that purpose using actions templates + use_layout=true can be a good solution
  • comment from David Stendardi
    • Does sfEmail will support layouts ? ex :
            <?php $message->setLayout('default'); ?>
      
      
      • see my response above ;-)

Email templates

Using the formats handling feature provided by symfony 1.1, we could easily map a mime-type with its related sf_format equivalent to have native templates naming convention. For example, if I use these templates resolvers:

$email->setBodyTemplate(new sfEmailTemplateAction('mail', 'confirmRegister'));

The templates used for each part (html and plain text) will be:

apps/
  myapp/
    modules/
      templates/
        confirmSuccess.php     # text/html template (symfony default)
        confirmSuccess.txt.php # text/plain format template

Ease of Use

As most of the time we send emails within an action (let's call it a controller), the email creation/instanciation and sending should be really short and easy.

For example in a sample buy action of a foo module:

<?php
class fooActions extends sfActions
{
 public function executeBuy($request)
 {
   if ($request->isMethod('post'))
   {
     $email = new myEmail();
     $email->setVars(array($request->getAttribute('stuff')));
     $email->send('titi@toto.com');
   }
 }
}
?>

  • comment from David Stendardi
    • what about autoconfigure the sfEmail with templates picked in the owner action template directory.
    • see my suggestion above regarding formats handling. Would it be okay for you?

Second proposal:

<?php
class fooActions extends sfActions
{
 public function executeBuy($request)
 {
   if ($request->isMethod('post'))
   {
     $email = new myEmail();
     $email->setVars(array($request->getAttribute('stuff')));
     $this->context->getMailer('foo')->send($email);
   }
 }
}
?>

As the mailer will be available from the context, this might be the most Swift-philosophy compliant way to send emails.

Reuse Existing Emails

May the proposed API be looking a bit verbose, so it should be possible to create dedicated email classes easily:

Proposal:

<?php
class myEmail extends sfEmail
{
 public function configure()
 {
   // configure the email here, eg.
   $this->setSubject('Hello there');
   $this->setTemplate('text/html', new sfEmailTemplateAction('mail', 'foo'));
 }
}
?>

  • comment from David Stendardi
    • A nice to have feature would be the ability to configure messages via yml configuration like :
          prod:
            [...]
            messages:
              default: 
                subject_prefix : [foo]
          dev:
            [...]
            messages:
              default:
                subject_prefix : [test]
      
              myModule/myAction:
                subject: foo
                from: foo@bar.net
                cci: bar@foo.net
      
      • Maybe this is a place for a plugin?

Extending or Using Swift?

  • comment from Fabian Lange
    • Actually I think the idea from the dev-list, to just extend the Swift mailer to inherit functionality is nice. For a project I did once a very simple (and perhaps also a bit dirty) wrapper that uses swift. attached.
      • Thanks for the suggestion and sample code. Actually I definitely plan to make email and mailer classes inheriting from related Swift classes, just implementing what's missing in a symfony context :)

Attachments