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.
9 Comments
Comments are closed.
Suggestion in order to improve your mail manager implementation :
Pass directly contact_email, from_email and from_name parameters to MailManager constructor. You won’t need to pass them each time you call sendEmail method (or only to override param values)…
Injecting service container into MailManager is definitely not the right way and obsolete here.
Check hautzisystemmailbundle 🙂
Thanks for sharing! I use absolutely the same approach as described in the article! I also use bunches of classes to support optional unsubscribe relevant to a template name.
Why do you need to inject the Service container in the MailManager service ? I don’t get it…
Using the title “right way” and then injecting the container doesnt match IMHO.
Fixed 🙂
Oh my goodness! Awesome article dude! Thank you, However I am having troubles with your
RSS. I don’t understand why I am unable to join it. Is there anybody having identical RSS issues?
Anyone who knows the solution will you kindly
respond? Thanks!!
[…] Related: Send Emails in Symfony2: The Right Way […]