Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Creating, Configuring & Sending the Email Object

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Time to send... an email! After a user registers for a new account, we should probably send them a welcome email. The controller for this page lives at src/Controller/SecurityController.php... find the register() method.

This is a very traditional controller: it creates a Symfony form, processes it, saves a new User object to the database and ultimately redirects when it finishes.

Let's send an email right here: right after the user is saved, but before the redirect. How? It's gorgeous. Start with $email = (new Email()) - the one from the Mime namespace.

... lines 1 - 10
use Symfony\Component\Mime\Email;
... lines 12 - 16
class SecurityController extends AbstractController
{
... lines 19 - 46
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
{
... lines 49 - 51
if ($form->isSubmitted() && $form->isValid()) {
... lines 53 - 70
$em->flush();
$email = (new Email())
... lines 74 - 84
}
... lines 86 - 89
}
}

Mime & Mailer Components

Actually, this is a good moment to mention that when we talk about the Mailer component in Symfony, we're actually talking about two components: Mailer and Mime. The Mime component is all about creating & configuring the email itself and Mailer is all about sending that email. But mostly... that's not too important: just don't be surprised when you're using objects from this Mime namespace.

Configuring the Email

I've put the new Email object in parentheses on purpose: it allows us to immediately chain off of this to configure the message. Pretty much all the methods on the Email class are... delightfully boring & familiar. Let's set the ->from() address to, how about, alienmailer@example.com, the ->to() to the address of the user that just registered - so $user->getEmail() - and this email needs a snazzy subject!

Welcome to the Space Bar!

... lines 1 - 10
use Symfony\Component\Mime\Email;
... lines 12 - 16
class SecurityController extends AbstractController
{
... lines 19 - 46
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
{
... lines 49 - 72
$email = (new Email())
->from('alienmailcarrier@example.com')
->to($user->getEmail())
->subject('Welcome to the Space Bar!')
... lines 77 - 89
}
}

Pure poetry. Finally, our email needs content! If you've sent emails before, then you might know that an email can have text content, HTML content or both. We'll talk about HTML content soon. But for now, let's set the ->text() content of the email to:

Nice to meet you

And then open curly close curly, $user->getFirstName(), and, of course, a ❤️ emoji.

... lines 1 - 10
use Symfony\Component\Mime\Email;
... lines 12 - 16
class SecurityController extends AbstractController
{
... lines 19 - 46
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
{
... lines 49 - 72
$email = (new Email())
->from('alienmailcarrier@example.com')
->to($user->getEmail())
->subject('Welcome to the Space Bar!')
->text("Nice to meet you {$user->getFirstName()}! ❤️");
... lines 78 - 89
}
}

There are a bunch more methods on this class, like cc(), addCc(), bcc() and more... but most of these are dead-easy to understand. And because it's such a simple class, you can look inside to see what else is possible, like replyTo(). We'll talk about many of these - like attaching files - later.

So... that's it! That's what it looks like to create an email. I hope this "wow'ed" you... and disappointed you in its simplicity... all at the same time.

Sending the Email

Ok... so now... how do we send this email? As soon as we installed the Mailer component, Symfony configured a new mailer service for us that we can autowire by using - surprise! - the MailerInterface type-hint.

Let's add that as one of the arguments to our controller method: MailerInterface $mailer.

... lines 1 - 10
use Symfony\Component\Mailer\MailerInterface;
... lines 12 - 17
class SecurityController extends AbstractController
{
... lines 20 - 47
public function register(MailerInterface $mailer, Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
{
... lines 50 - 92
}
}

And... what methods does this object have on it? Oh, just one: $mailer->send() and pass this $email.

... lines 1 - 10
use Symfony\Component\Mailer\MailerInterface;
... lines 12 - 17
class SecurityController extends AbstractController
{
... lines 20 - 47
public function register(MailerInterface $mailer, Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $formAuthenticator)
{
... lines 50 - 52
if ($form->isSubmitted() && $form->isValid()) {
... lines 54 - 73
$email = (new Email())
->from('alienmailcarrier@example.com')
->to($user->getEmail())
->subject('Welcome to the Space Bar!')
->text("Nice to meet you {$user->getFirstName()}! ❤️");
$mailer->send($email);
... lines 81 - 87
}
... lines 89 - 92
}
}

I love how this looks. But... will it work? We haven't actually configured how emails should be sent but... ah, let's just see what happens. Move over and register: first name Fox (last name, Mulder, in case you're wondering), email: thetruthisoutthere@example.com, any password, agree to the terms that we definitely read and, register!

Ah! Error!

Environment variable not found: MAILER_DSN

Ok, fine! To actually deliver emails, we need to add some configuration via this environment variable. Let's talk about that next... including some awesome options for debugging emails while you're developing.

Leave a comment!

8
Login or Register to join the conversation
Default user avatar
Default user avatar mofogasy | posted 1 year ago | edited

Hi I have 3 projects with the exact same code and the one who's not wortking has this as dd($mailer):
`
-transport: Symfony\Component\Mailer\Transport\Transports {#469 ▼

-transports: array:1 [▼
  "main" =>...
   -started: false
    -restartCounter: null

...
-bus: Symfony\Component\Messenger\TraceableMessageBus {#466
`

while the other ones which are working have this :
`
-restartCounter: 1

-bus: null
`

does someone know ?

Reply

Hey @mofogasy

could you explain your problem a bit more. It's missing context and is hard to tell what's wrong

Cheers!

Reply

Hello! Many thanks! I followed the steps but on Symfony 6 but it doesn't work, nothing happens after submitting the form. I can see the updated database but can't send or receive emails! Here is my steps:

<b>.env</b>
MAILER_DSN=smtp://57295704278792:5a4d2b6a23bdda@smtp.mailtrap.io:2525?encryption=tls&auth_mode=login

<b>mycontroller.php</b>

use Symfony\Component\Mime\Email;
use Symfony\Component\Mailer\Bridge\Google\Transport;```

            $email = (new Email())
                 ->from('alienmailcarrier@example.com')
                ->to($contactUs->getEmailContact())->subject('You got mail!')
                ->text('Sending emails is fun again!')
            $mailer->send($email);```



But to be honest service's folder has not been created. But the bundle installation has been successes. I dk where is the problem. Sorry again if i am bothering you!!
Reply

Oh maybe because of Schickling Docker image and I should use mailcatcher?

Reply
Nikolay S. Avatar
Nikolay S. Avatar Nikolay S. | posted 3 years ago

Hello,
How can I configure cPanel-generated email to mailer dsn because I tried the following as dsn and it's not working:
MAILER_DSN=smtp://myemailaddress@mywebsite(.)com:myemailpassword@mail.mywebsite(.)com

Reply

Hey Niki,

Hm, let me clarify, you have 2 *valid* email addresses and you want to send emails from both? Like some emails send with smtp://myemailaddress@mywebsite(.)com and some emails send with myemailpassword@mail.mywebsite(.)com? Also, cPanel gives you the credentials with "(.)" in the domain? I suppose it's not a valid config and it should be "myemailaddress@mywebsite.com". Though, if you're talking about some cloud hosting that host this and they have support -I'd recommend you to write to them and ask to clarify what credentials you should use for the info that is given to you by cPanel.

Cheers!

Reply
Nikolay S. Avatar
Nikolay S. Avatar Nikolay S. | Victor | posted 3 years ago

I used (.) for formatting to avoid link transformation here its only a dot.
The smtp credetials which cpanel sents when i created the email inbox are:
Smtp: mail.mywebsitename.com
Username: myemailaddress@mywebsite.com
Password: the inbox’s password

And I cannot make the mailer dsn because its shows that it is invalid

MAILER_DSN=smtp://myemailaddress@myweb...:myemailpassword@mail.mywebsite.com

So i just wonder for the mailer dsn syntax for using cpanel email

Reply

Hey Nikolay S.!

Hmm. Let's see if we can figure this out!

And I cannot make the mailer dsn because its shows that it is invalid

What do you mean by "it shows that it is invalid". Do you get an error when you try to send an email? Something else? I thought maybe the extra @ symbol in the username might cause problems with parsing the DSN (since there is another @ symbol later). So, I tried it! I added this to my .env:


MAILER_DSN=smtp://myemailaddress@mywebsite.com:myemailpassword@mail.mywebsite.com

Obviously, that fake address won't really work. But I was able to verify that it parsed all the pieces correctly: https://imgur.com/a/XfWpvle

So, what exactly are you seeing with your site?

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial is built on Symfony 4.3, but will work well with Symfony 4.4 or 5.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "aws/aws-sdk-php": "^3.87", // 3.110.11
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
        "knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
        "knplabs/knp-snappy-bundle": "^1.6", // v1.6.0
        "knplabs/knp-time-bundle": "^1.8", // v1.9.1
        "league/flysystem-aws-s3-v3": "^1.0", // 1.0.23
        "league/flysystem-cached-adapter": "^1.0", // 1.0.9
        "league/html-to-markdown": "^4.8", // 4.8.2
        "liip/imagine-bundle": "^2.1", // 2.1.0
        "nexylan/slack-bundle": "^2.1,<2.2.0", // v2.1.0
        "oneup/flysystem-bundle": "^3.0", // 3.1.0
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.4.1
        "stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
        "symfony/asset": "^4.0", // v4.3.4
        "symfony/console": "^4.0", // v4.3.4
        "symfony/flex": "^1.9", // v1.17.6
        "symfony/form": "^4.0", // v4.3.4
        "symfony/framework-bundle": "^4.0", // v4.3.4
        "symfony/mailer": "4.3.*", // v4.3.4
        "symfony/messenger": "4.3.*", // v4.3.4
        "symfony/orm-pack": "^1.0", // v1.0.6
        "symfony/security-bundle": "^4.0", // v4.3.4
        "symfony/sendgrid-mailer": "4.3.*", // v4.3.4
        "symfony/serializer-pack": "^1.0", // v1.0.2
        "symfony/twig-bundle": "^4.0", // v4.3.4
        "symfony/twig-pack": "^1.0", // v1.0.0
        "symfony/validator": "^4.0", // v4.3.4
        "symfony/web-server-bundle": "^4.0", // v4.3.4
        "symfony/webpack-encore-bundle": "^1.4", // v1.6.2
        "symfony/yaml": "^4.0", // v4.3.4
        "twig/cssinliner-extra": "^2.12", // v2.12.0
        "twig/extensions": "^1.5", // v1.5.4
        "twig/inky-extra": "^2.12" // v2.12.0
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.2.2
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.7
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/browser-kit": "4.3.*", // v4.3.5
        "symfony/debug-bundle": "^3.3|^4.0", // v4.3.4
        "symfony/dotenv": "^4.0", // v4.3.4
        "symfony/maker-bundle": "^1.0", // v1.13.0
        "symfony/monolog-bundle": "^3.0", // v3.4.0
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.3.4
        "symfony/profiler-pack": "^1.0", // v1.0.4
        "symfony/var-dumper": "^3.3|^4.0" // v4.3.4
    }
}
userVoice