Blog

Welcome to our blog, where we share news related to Sylius and post about technology & eCommerce.

Sending configurable e-mails in Symfony

By Mateusz Zalewski | 02/10/2015

Every developer, during their adventure with PHP programming has been struggling with sending emails in a web application. However using PHP send() function is often insufficient for common web applications, when you need templates, variables, configurations etc.

Fortunately, Sylius provides SyliusMailerBundle and Mailer component, with some awesome features:

  • E-Mails configurable via YAML and Doctrine entities
  • Various adapters, including TwigSwiftMailer
  • Simple interface for sending e-mails with variables
  • Flexible system of events for sending and rendering e-mails

Of course, this bundle and component are fully decoupled and can be used in any Symfony application.

Installation and configuration

Installation is pretty easy, thanks to Composer manager. To add bundle to your composer.json, use following command:

$ composer require sylius/mailer-bundle

Adding required bundles to the kernel

To make SyliusMailerBundle work, you ought to add it and its dependencies to your kernel. You should also add SyliusResourceBundle, if you're not using it.

<?php

public function registerBundles()
{
    $bundles = array(
        new FOS\RestBundle\FOSRestBundle(),
        new JMS\SerializerBundle\JMSSerializerBundle($this),
        new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
        new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),

        new Sylius\Bundle\MailerBundle\SyliusMailerBundle(),
        new Sylius\Bundle\ResourceBundle\SyliusResourceBundle(),

        // Other bundles...
        new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
    );
}

Container configuration

Last step is adding some crucial directives to your container configuration.

sylius_mailer:
    driver: doctrine/orm
    sender:
        name: My website
        address: no-reply@my-website.com

stof_doctrine_extensions:
    orm:
        default:
            timestampable: true

Updating database schema

php app/console doctrine:schema:update --force

Beware of using this command - it should be executed only in dev environment, while in production you should use Doctrine migrations system.

That's it! SyliusMailerBundle is now fully configured and you can start using it in your application.

Sending emails

SyliusMailerBundle uses Swiftmailer library to send e-mail as default. However, you can implement your own adapters and use a different library.

Configuration of new e-mail sending is pretty easy and consist of few simple steps. Let's say you want to send emails with newsletters to shop subscribers.

Template

First, we should create its template. As default, SyliusMailerBundle uses twig renderer, so we need to create proper .twig file and place it in a specific directory.

// AppBundle/Resources/views/Email/newsletter.html.twig

{% block body %}
    Hello {{ name }}!

    A new newsletter has been announced. Check this out <a href="{{ link }}">here</a>.
{% endblock %}

E-mail configuration

Every e-mail should be configured under sylius_mailer in your app/config/config.yml file.

sylius_mailer:
    driver: doctrine/orm
    sender:
        name: My website
        address: no-reply@my-website.com
    emails:
        newsletter:
            subject: {{ month }} newsletter
            template: AppBundle/Resources/views/Email:newsletter.html.twig

You can also specify if template is enabled, as well as configure custom sender for specific mail.

sylius_mailer:
    driver: doctrine/orm
    sender:
        name: My website
        address: no-reply@my-website.com
    emails:
        newsletter:
            subject: {{ month }} newsletter
            template: AppBundle/Resources/views/Email:newsletter.html.twig
            enabled: true/false
            sender:
                name: Custom sender
                address: custom.sender@my-website.com

Whole sylius_mailer configuration reference is available in SyliusMailerBundle documentation.

Sending

Most common ways to send e-mail are:

  • using controller action
  • using listener

Of course, you can use sender service anywhere (e.g. commands), as every usual service.

Service responsible for sending e-mails is registered as sylius.email_sender, so it can be easily retrieved in controller action. All you must do, is use send($mail, array $recipientsEmails, array $parameters) function.

<?php

namespace App\AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;

class NewsletterController
{
    public function sendNewsletterAction(Request $request)
    {
        // Your code.

        $this->get('sylius.email_sender')->send('newsletter', array('recipient1@website.com'), array('month' => $month, 'name' => $userName, 'link' => $newsletterLink));
    }
}

Of course, you can rely on event system and inject sylius.email_sender service to proper listener.

<?php

namespace App\AppBundle\Controller;

use App\Event\NewsletterCreatedEvent;
use Sylius\Component\Mailer\Sender\SenderInterface;

class NewsletterNotificationListener
{
    /**
     * @var SenderInterface
     */
    private $sender;

    /**
     * @param SenderInterface $sender
     */
    public function __construct(SenderInterface $sender)
    {
        $this->sender = $sender;
    }

    /**
     * @param NewsletterCreatedEvent $event
     * @param array                  $recipients
     */
    public function onNewsletterCreation(NewsletterCreatedEvent $event, array $recipients)
    {
        $month = $event->getNewsletter()->getMonth();
        $link = $event->getNewsletter()->getLink();
        $userName = $event->getUser()->getName();

        $this->sender->send('newsletter', $recipients, array('month' => $month, 'name' => $userName, 'link' => $link));
    }
}

And that's all! Emails are send and you can be sure that your's shop subscribers are going to receive them.

Custom adapter

Of course, using Swiftmailer is not the only way to send e-mail messages. You may want to use external API or implement some custom, amazing algorithm. Fortunately, you can do this thanks to adapter system implemented in SyliusMailerBundle. Moreover, writing and configuring custom adapter is really simple and requires less effort than you can imagine.

Three simple steps are:

Implement adapter

<?php

namespace App\Mailer\Adapter;

use Sylius\Component\Mailer\Sender\AdapterInterface;
use Sylius\Component\Mailer\Model\EmailInterface

class CustomAdapter implements AdapterInterface
{
    /**
     * @param EmailInterface $email
     * @param array          $recipients
     * @param array          $data
     */
    public function send(EmailInterface $email, array $recipients, array $data = array())
    {
        // Your custom logic.
    }
}

Register newly created adapter as service

services:
    app.email_sender.adapter.custom:
        class: App\Mailer\Adapter\CustomAdapter

Configure it

sylius_mailer:
    adapter: app.email_sender.adapter.custom

And that's all! Now e-mails will be sent using your custom adapter.

Summary

Sending e-mails in web application is one of the basic challenges that every developer must face. SyliusMailerBundle tries to make it easier. We hope that with this bundle sending e-mails will be annoying never again.

We'll be grateful for any feedback. Please leave them in the comments below. Thanks!

 

Get started

Create your next Symfony eCommerce project with Sylius

We provide the foundation and components needed to build applications that sell online. A cutting edge technology, loved by developers.

Get started

twitter Latest tweet

Our core team is going to #Berlin next week to take part in @codetalkshh #eCommerce & @Coding_Berlinhttps://t.co/Aa6KjiI7Oo

@Sylius 10