How to send emails with Symfony 1.3 / 1.4

In this post we will see how to send emails with Swift Mailer through Symfony.

As we mentioned in an earlier post, Symfony comes with an already integrated mailer library. And, send an email is as simple as we can see below:

1
2
3
4
<?php
public function executeSendEmail() {
    $this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');
}

Or, you can chose for compose the message and then send it with the Send() method:

1
2
3
4
5
<?php
public function executeSendEmail() {
    $this->getMailer()->compose('from@example.com', 'to@example.com', 'Subject', 'Body');
    $this->getMailer()->send();
}

Furthermore, if we need to add a little more of complexity like attach a file, it is as simple as we can see below:

1
2
3
4
5
6
<?php
public function executeSendEmail() {
    $this->getMailer()->compose('from@example.com', 'to@example.com', 'Subject', 'Body')
        ->attach(Swift_Attachment::fromPath('/path/to/a/file.zip'));
    $this->getMailer()->send();
}

As we can observe in the previously used methods Symfony handles mailing issues with a Mailer object, which is got it with the getMailer() method, already ready to use in the controller due to that the mailer object already is part of the Symfony’s core.

Configuration

By default, the send() method tries to use the local SMTP server to send the message, but, of course, as a lot of Symfony stuff this is totally configurable.

As we mentioned previously the Mailer object is part of the Symfony’s core. These objects are automatically built, configured and handled them by the framework. All of the core objects are configurable by the factories.yml file.

The default configuration looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mailer:
  class: sfMailer
  param:
    logging: %SF_LOGGING_ENABLED%
    charset: %SF_CHARSET%
    delivery_strategy: realtime
    transport:
      class: Swift_SmtpTransport
      param:
        host: localhost
        port: 25
        encryption: ~
        username: ~
        password: ~

When a new application is built, the factories.yml file overwrites the default configuration with some sensitive environments variables:

1
2
3
4
5
6
7
8
9
test:
  mailer:
    param:
      delivery_strategy: none

dev:
  mailer:
    param:
      delivery_strategy: none

The delivery_strategy option tells to the framework how to deliver the messages. By default, Symfony comes with 4 different strategies:

  • realtime: The messages are delivered in real time.
  • single_address: The messages are delivered to just one single email address.
  • spool: The messages are stored in a queue.
  • none: The messages are just ignored.

It does not matter what the strategy is, the messages are always logged them in the log and they are available in the “mailer” tab in the web debug toolbar.

Mail Transport

The emails are always send them through a transport. You can configure the transport that you want just editing the factories.yml file. The default configuration is:

1
2
3
4
5
6
7
8
transport:
  class: Swift_SmtpTransport
  param:
    host:       localhost
    port:       25
    encryption: ~
    username:   ~
    password:   ~

We can chose between 3 different classes:

  • Swift_SmtpTransport: Uses the SMTP server to send messages.
  • Swift_SendmailTransport: Uses sendmail to send messages.
  • Swift_MailTransport: Uses the PHP native function mail() to send the messages.

In the “Transport Types” section into the official Swift Mailer documentation we can find everything we need about the transport classes and their different parameters.

Source: Symfony’s site

What is new in Symfony 1.3 / 1.4

At the end of this month it goes out the last release of Symfony and here we will review what are the new news. If you have already used 1.2 version you will notice a couple of improvements have been added.

Between the new functionalities, the most highlighted are:

Mailer

Symfony 1.3/1.4 comes with a new integrated mailer based on SwiftMailer 4.1. And, to send an email is as easy as we show below using the composeAndSend() method:

1
2
3
4
5
6
<?php
public function executeSendEmail()
{
    $this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');
}
?>

If you need more flexibility and you need to attach a file, you can use the compose() method and then send it:

1
2
3
4
5
6
7
8
9
10
<?php
public function executeSendEmail()
{
    $message = $this->getMailer()
        ->compose('from@example.com', 'to@example.com', 'Subject', 'Body')
        ->attach(Swift_Attachment::fromPath('/path/to/a/file.zip'));
   
    $this->getMailer()->send($message);
}
?>

Swift Mailer is a great and powerful library, and if you want to know more about it you can check its documentation.

Security

In these versions when you use the generate:app command, the security is already actived by default. The escaping_strategy value is already activated by default, but you can deactivate it with the –escaping-strategy option. Also, for the csrf_secret option, the framework already comes with a random generated keyword and you can change it in the setting.yml configuration file.

Widgets

Labels by default: When a label is auto-generated from the field name, the label is defined without the _id suffix (if it has it). For instance, for the client_id field name, the generated label will be ‘client’ now (it was client_id before).

sfWidgetFormInputText: Now the sfWidgetFormInput class is abstract, and the text input fields should be created with sfWidgetFormInputText.

Forms

sfForm::useFileds(): This new method remove all the form fields, except those passed as argument. This ease the fields visualization in the form view without the need of make an unset() of the unwanted fields. For instance, when we add a new field in the base form, this one do not appear automatically in the form view at least we add it explicitly as an argument of this method:

1
2
3
4
5
6
7
8
9
<?php
class ArticleForm extends BaseArticleForm
{
    public function configure()
    {
        $this->useFields(array('title', 'content'));
    }
}
?>

By default, the array is used to change the fields order; we can pass a second argument as a false value to deactivate this automatic sort.

sfForm::getEmbeddedForm($name): Now we can access a particular embedded form using the getEmbeddedForm() method.

Autoloaders

All the Symfony’s autoloaders are case-insensitive now, since PHP is case-insensitive as well.

Default ORM

Symfony 1.3/1.4 comes with Doctrine as its default ORM.
If we want to use Propel as ORM, we should use the –orm=Propel option:

1
:$ php symfony generate:project foo --orm=Propel

And if we want to do not use Doctrine neither Propel, we can use the –orm=none option:

1
:$ php symfony generate:project foo --orm=none

These are the most highlighted features to me :D. There are a lot more improvements related to widgets, validators, routing, and much more CLI task as well.