How to send an email with Symfony and use of events

Sending mails is a common task in the web development world, I mean, who doesn’t like emails?!

In this tutorial I’ll show you how to send emails from within your Symfony application, and explain you how to use Symfony events.

The default way of sending mails in Symfony is using the Swiftmailer bundle, it’s really easy to use and integrate.

Using Symfony Flex?

Since Symfony Flex ( Symfony 3.3 and higher ) it’s really easy to install 3rd party bundles:

composer require symfony/swiftmailer-bundle

If your Symfony version is than Symfony 3.3, please follow this link for instructions: https://github.com/symfony/swiftmailer-bundle/blob/master/Resources/doc/index.rst

The installation should add something like this in to your .env file:

# use this to disable email delivery
MAILER_URL=null://localhost

# use this to configure a traditional SMTP server
MAILER_URL=smtp://localhost:25?encryption=ssl&auth_mode=login&username=&password=

I always prefer to use SMTP as it’s the most reliable way of sending mails these days, sending from the server itself usually results in your mails gathering in someone’s spam folder.

Sending a mail

To send a mail in Symfony you will need to use the Swift Mailer service, with Symfony 3.4 and above you can autowire this:

<?php
  //... 
  private $mailer;

  public function __construct(\Swift_Mailer $mailer)
  {
    $this->mailer = $mailer;
  }
  //...

Now that you have the Swift Mailer service autowired you can actually start to use it, the settings configured above is what SwiftMailer will use to send the email.

It’s really easy to send mails:

<?php
  //...
  public function send()
  {
    //-- Path to template
    $template = 'mail/my-awesome-template.html.twig';

    //-- Params to pass to template
    $params = [
      'dynamicContent' => 'This is dynamic content right here'
    ];

    //-- Create the message
    $message = (new \Swift_Message('Web hints is awesome!'))
      ->setFrom('[email protected]')
      ->setTo('your-email-address')
      ->setBody(
        $this->twig->render($template, $params), 'text/html'
    );

    //-- Send the message
    $this->mailer->send($message);
  }
  //..

Sending mails when an event is triggered

Let’s say you just created an awesome article on your blog and want the world to know it, it would be possible to add the code to send a mail right after the point you created your post, and it would work! 

But, what if you have another area that also creates posts.. you just duplicated it right? 🙂

This is where event triggering/listening comes in and help us. You can actually create your own event and create your own listener for it but this way you will create overhead as you can actually use Symfony and Doctrine’s core events ( if you use Doctrine that is ).

How to use Symfony events

A list of Symfony events you can find here: https://symfony.com/doc/current/reference/events.html

The most common way to listen to a Symfony event is with an event listener, although a event subscriber could also be used.

Create your Event Listener class:

<?php

namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use App\Entity\Request as RequestEntity;

class RequestListener
{
  public function onKernelRequest(GetResponseForControllerResultEvent $event)
  {
    $requestEntity = $event->getControllerResult();
    $method = $event->getRequest()->getMethod();

    if (!$requestEntity instanceof Request || $method !== Request::METHOD_POST) {
      return;
    }

    //-- Do something, this is where you start your mailing. It will only be trigger when a POST request happens and the entity is of class Request (which is our custom Entity)
  }
}

Register your class:

services:
    App\EventListener\RequestListener:
        tags:
            - { name: kernel.event_listener, event: kernel.request }

Doctrine events and Event Subscriber

You can also use Doctrine Events and the Event Subscriber.

An event subscriber is basically the same as an Event Listener, but uses different structure so choose as you see fit.

A Doctrine event is an event that is bound to an entity, so it is not a Symfony event. Doctrine events are events triggered when an entity lifecycle is changed.

So if you want to do something with an entity just before it gets updated to the database, you can with Doctrine events.

A list of Doctrine events you can find here: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#lifecycle-events

If you want to learn more about Symfony, I created a beginners tutorial right here: A Symfony beginners tutorial on how to get started with Symfony.

Leave a Reply

avatar
  Subscribe  
Notify of