No matter what your app is about, at one you point you will have to send emails in Symfony2. Even though this process might seem straightforward and easy to apply, it can actually get pretty tricky. Here’s how you can send emails in Symfony2 by properly splitting your functionality and templates.

 

1. Mailer parameters

First off, you’re going to need to add some email data into your parameters.yml file that will tell Swift Mailer which SMTP server to use. At this point, it would be advised to create an account at an email sending service. For this short tutorial, we’re going to use SendGrid.

mailer_transport: smtp
mailer_host: smtp.sendgrid.net
mailer_user: your_sendgrid_username
mailer_password: 'your_sendgrid_password'
mailer_port: 587

contact_email: contact@yourapp.com
from_email: hello@yourapp.com
from_name: YourApp

As you can see, we’ve also added three parameters that will help us to send emails in Symfony2: contact email, from email and from name.

 

2. Send emails in Symfony2 using a MailManager

Having a MailManager is helpful because the code needed to send emails will only reside in a single place. Thus, it will be way easier to maintain. Here’s how you should build the MailManager class:

<?php

namespace AppBundle\Lib;

class MailManager
{
    protected $mailer;
    protected $twig;

    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig)
    {
        $this->mailer = $mailer;
        $this->twig = $twig;
    }

    /**
     * Send email
     *
     * @param   string   $template      email template
     * @param   mixed    $parameters    custom params for template
     * @param   string   $to            to email address or array of email addresses
     * @param   string   $from          from email address
     * @param   string   $fromName      from name
     *
     * @return  boolean                 send status
     */
    public function sendEmail($template, $parameters, $to, $from, $fromName = null)
    {
        $template = $this->twig->loadTemplate('AppBundle:Mail:' . $template . '.html.twig');

        $subject  = $template->renderBlock('subject', $parameters);
        $bodyHtml = $template->renderBlock('body_html', $parameters);
        $bodyText = $template->renderBlock('body_text', $parameters);

        try {
            $message = \Swift_Message::newInstance()
                ->setSubject($subject)
                ->setFrom($from, $fromName)
                ->setTo($to)
                ->setBody($bodyHtml, 'text/html')
                ->addPart($bodyText, 'text/plain')
            ;
            $response = $this->mailer->send($message);

        } catch (\Exception $ex) {
            return $ex->getMessage();
        }

        return $response;
    }
}

In the sendEmail function, you can easily define a $template variable which will hold whatever template you need, depending on the type of email. You’ll see the MailManager in action in the 4th and last section of this short tutorial, where you’ll use it to send a contact email.

Oh, and don’t forget to register the service in services.yml:

mail_manager:
    class:     AppBundle\Lib\MailManager
    arguments: ["@mailer", "@twig"]

 

Related: Symfony2 Facebook and Google Login: The Easy Way

 

3. Define a simple template

In this section you’ll be building the three main blocks any email should have (subject, html and text) and store them in a template which you’ll extend as needed.

{# src/AppBundle/Mail/template.html.twig #}

{% block subject %}
    default subject
{% endblock %}

{% block body_text %}
    default text    
{% endblock %}

{% block body_html %}
    <p>default body</p>
{% endblock %}

 

4. A sample email sending action

Now that you have everything set, you can go ahead and build your first mail sending action. As an example, here’s how a contact action should look like. It will send emails to the email address defined in parameters.yml.

public function contactAction(Request $request)
    {
        $form = $this->createForm(new ContactType());

        $form->handleRequest($request);

        //this is where we define which template to use
        $template = 'contact';

        if($form->isValid()){
            //Get data from the submitted form
            $data = $form->getData();
            $mail_params = array(
                'firstName' => $data["firstName"],
                'lastName'  => $data["lastName"],
                'message'   => $data["message"],
                'phoneNumber' => $data["phoneNumber"],
                'email'     => $data["email"]
            );

            //grab the addresses defined in parameters.yml
            $to = $this->container->getParameter('contact_email');
            $from =  $this->container->getParameter('from_email');
            $fromName = $this->container->getParameter('from_name');

            //use the MailManager service to send emails
            $message = $this->container->get('mail_manager');
            $message->sendEmail($template, $mail_params, $to, $from, $fromName);

            return $this->redirectToRoute('contact');
        }

        return $this->render('AppBundle:StaticPages:contact.html.twig',array(
            'form' => $form->createView()
        ));
    }

Since you’ll be using the contact email body, you will need to build it by extending the template defined at step #3:

{% extends "AppBundle:Mail:template.html.twig" %}

{% block subject %}
    YourApp Contact Message
{% endblock %}

{% block body_text %}
    {% autoescape false %}
        Name: {{ firstName }} {{ lastName }}
        Message: {{ message }}
        Phone Number: {{ phoneNumber }}
        Email address: {{ email }}
    {% endautoescape %}
{% endblock %}

{% block body_html %}
    {% autoescape false %}
        <p>Name: {{ firstName }} {{ lastName }}</p>
        <p>Message: {{ message }}</p>
        <p>Phone Number: {{ phoneNumber }}</p>
        <p>Email address: {{ email }}</p>
    {% endautoescape %}
{% endblock %}

 

And there you have it – an easy way to build and maintain your emails. If you know of any other easier system used to send emails in Symfony2, please let me know in the comment section below.