avris/micrus-mailer

Mailer module for the Micrus framework

v4.0.0 2018-01-28 10:36 UTC

This package is auto-updated.

Last update: 2022-11-29 02:30:38 UTC


README

This is a module for Micrus framework that allows you to easily send emails.

Installation

Run:

composer require avris/micrus-mailer

Then register the module in your App\App:registerModules:

yield new \Avris\Micrus\Mailer\MailerModule;

Finally, run:

bin/env

You will be asked for a transport string and it will be saved in the .env file, for example:

  • null://localhost -- won't send any actual emails
  • smtp://user:password@server.com
  • gmail://user:password@localhost

If you're using GMail, remember to allow less secure apps and create an app password.

Manually creating and sending an email

$mail = new Mail();
$mail->addTo(new Address('email@example.com'));
$mail->addCc(new Address('max@mustermann.de'));
$mail->setSubject('Subject');
$mail->setBody('...');
$mail->setAltBody('...');
$mail->embedImage('logo', $this->getRootDir() . '/assets/images/logo.png');
$mail->embedImage('banner', $this->getRootDir() . '/assets/images/banner.png');
$mail->addAttachment($this->getRootDir() . '/assets/pdf/registration.pdf');

$mailer->send($mail);

Mail Builder

By following some simple conventions and using the MailBuilder service, you can greatly simplify the process of creating an email.

Let's say you want to create a template Welcome.

You should first put the email subject in the translation key mail:Welcome.subject. For instance in the filetranslations/mail.en.yml create such a structure:

Welcome:
  subject: Welcome to [[main.title]]
  

Now, the content of the email should go in the Mail/Welcome.html.twig template:

<!DOCTYPE html>
<div class="mail-container">
    <h1>
        <a href="{{ app.request.absoluteBase }}" target="_blank">
            <img src="cid:logo"/>
            {{ 'main.title'|l }}
        </a>
    </h1>
    <p>
        Hello, {{ username }}!<br/>
        Welcome to our site! Click <a href="{{ tokenUrl }}" target="_blank"> to confirm your account.
    </p>
    <p class="signature">
        Best,<br>
        Team of {{ 'main.title'|l }}
    </p>
</div>

You could also put the template directly in mail:Welcome.body.

Similar goes for the alternative body: it will be taken either from the Mail/Welcome.text.twig template, or from the mail:Welcome.altBody translation key. If none of those is given, it will be generated from the HTML body.

Finally, you should create:

final class WelcomeTemplate implements MailTemplateInterface
{
    /** @var string */
    private $projectDir;

    public function __construct(string $envProjectDir)
    {
        $this->projectDir = $envProjectDir;
    }

    public function getName(): string
    {
        return 'Welcome'
    }

    public function extend(Mail $mail): Mail
    {
        $mail->embedImage('logo', $this->projectDir . '/assets/images/logo.png');

        return $mail;
    }
}

This class allows to to encapsulate all the additional stuff you might want to do to with an email, like attaching images, or predefining BCC to admins. You might want to extract such logic to some BaseTemplate.

Now in the controller you can just write:

public function sendMailAction(MailBuilder $mailBuilder, Mailer $mailer)
{
    $mail = $mailBuilder->build(
        $this->get(WelcomeTemplate::class),
        $user->getLocale(),
        [
            'username' => $user->getUsername(),
            'tokenUrl' => $token,
        ]
    );
    $mail->addTo($user); // $user needs to implement AddressInterface
    $mailer->spool($mail);
    
    return new Response($mail); // casting to string generates a preview of the email
}

Note that you can overwrite the locale of an email, in order to, for instance, send an email in German to a German user, even if the locale of the current request is English.

If you create a file mail.css in your public directory, it will be used to automatically inline that CSS in the email's HTML. You can change the name of this file in config/assets.yml, option mailCss

Senders

The mailer uses a low-level sender service (implementing Avris\Micrus\Mailer\Sender\SenderInterface) to perform the actual sending. So far only PHPMailer is supported, but potentially this module might also be used with SwiftMailer, plain SMTP connection, ExactTarget adapter, Amazon SES adapter etc.

Spooling

Because it takes a while to send an email, it's often a good idea to just save it during the user's request and then perform the sending in the background, for instance using a cronjob. By default, Mailer spools the emails in memory in order to then send in during request termination (after user already received their response).

You can change it to the filesystem spool by registering an alias in config/services.yml:

Avris\Micrus\Mailer\Spool\SpoolInterface: Avris\Micrus\Mailer\Spool\FilesystemSpool

To then send out the spool, you might set up a cronjob to run every minute:

* * * * *  /var/www/yourproject/current/bin/micrus mailer:spool:send

If you want to force sending directly, just execute $mailer->send($mail) instead of $mailer->spool($mail).

Logger MailerHandler

This module also provides a Monolog handler, so that your logs can automatically be sent to the admin's email.

For an example configuration (which only sends the logs if an error occured), please check out the Micrus Demo Project (files config/_logger.yml and config/prod/_logger.yml).

Config

In config/mailer.yml you can specify the address from which your emails will be sent and the list of admins that should receive the logs from the MailerHandler:

from: micrus@micrus.dev
fromName: Micrus App
logger:
  subject: '[Micrus] An Error Occurred! %message%'
  admins:
    andre@avris.it: Andre

Copyright