20

Slim 4 - Mail

 3 years ago
source link: https://odan.github.io/2020/04/11/slim4-sending-emails.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Daniel’s Dev Blog

Daniel's Dev Blog

Developer, Trainer, Open Source Contributor

Blog About me Donate

Slim 4 - Mail

Daniel Opitz

Daniel Opitz

11 Apr 2020

Table of contents

Requirements

Introduction

This tutorial explains how to integrate and use the Symfony Mailer component for creating and sending emails.

Installation

To install the component, run:

composer require symfony/mailer

Configuration

Emails are delivered via a “transport”. For this tutorial we deliver emails over SMTP.

Only for demonstration purposes I use a free Mailtrap account.

In Mailtrap you can create a forwarding rule to your real inbox. Mailtrap keeps a copy of your message in any case.

Add the email settings to your Slim settings array, e.g config/settings.php:

// E-Mail settings
$settings['smtp'] = [
    // use 'null' for the null adapter
    'type' => 'smtp',
    'host' => 'smtp.mailtrap.io',
    'port' => '25',
    'username' => 'my-username',
    'password' => 'my-secret-password',
];

Autowire the mailer using MailerInterface:

<?php

use Psr\Container\ContainerInterface;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Transport;
use Slim\App;
use Slim\Factory\AppFactory;

return [

    // ...
    
    // SMTP transport
    MailerInterface::class => function (ContainerInterface $container) {
        $settings = $container->get('settings')['smtp'];
        // or
        // $settings = $container->get('settings')['smtp'];
        
        // smtp://user:[email protected]:25
        $dsn = sprintf(
            '%s://%s:%s@%s:%s',
            $settings['type'],
            $settings['username'],
            $settings['password'],
            $settings['host'],
            $settings['port']
        );

        return new Mailer(Transport::fromDsn($dsn));
    },
];

If you don’t use the Configuration class, just use settings as container entry:

$settings = $container->get('settings')['smtp'];

Creating and Sending Messages

Let the DIC inject the MailerInterface object and create an new Email object:

<?php

namespace App\Domain\User\Service;

use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

final class ContactMailer
{
    /**
     * @var MailerInterface
     */
    private $mailer;

    public function __construct(MailerInterface $mailer)
    {
        $this->mailer = $mailer;
    }

    public function sendEmail(array $formData): void
    {
        // Validate form data
        $this->validate($formData);

        // Send email
        $email = (new Email())
            ->from('[email protected]')
            ->to('[email protected]')
            //->cc('[email protected]')
            //->bcc('[email protected]')
            //->replyTo('[email protected]')
            //->priority(Email::PRIORITY_HIGH)
            ->subject('Time for Symfony Mailer!')
            ->text('Sending emails is fun again!')
            ->html('<p>My HTML content</p>');

        $this->mailer->send($email);
    }

    private function validate(array $data): void
    {
        // ...
    }
}

Twig Integration

To render Twig templates in emails just add the a new container definition for BodyRendererInterface:class in config/container.php

use Symfony\Component\Mime\BodyRendererInterface;
use Slim\Views\Twig;
use Psr\Container\ContainerInterface;
// ...

BodyRendererInterface::class => function(ContainerInterface $container)
{
    return new BodyRenderer($container->get(Twig::class)->getEnvironment());
},

To define the contents of your email with Twig, use the TemplatedEmail class (and not the Email class). This class extends the normal Email class but adds some new methods for Twig templates.

Then inject the BodyRendererInterface instance via constructor injection where you need it.

Usage

use Symfony\Bridge\Twig\Mime\TemplatedEmail;

$email = (new TemplatedEmail())
    ->from('[email protected]')
    ->to(new Address('[email protected]'))
    ->subject('Thanks for signing up!')

    // path of the Twig template to render
    ->htmlTemplate('emails/signup.html.twig')

    // pass variables (name => value) to the template
    ->context([
        'username' => 'foo',
    ])
;

 // Render the email twig template
$this->bodyRenderer->render($email);

// Send email
$this->mailer->send($email);

Error handling

To catch all mailer errors, just add a try/catch block around the send method:

try {
    $this->mailer->send($email);
} catch (Exception $exception) {
   // handle error here...
}

Read more

© 2020 Daniel Opitz | Twitter


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK