Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Hello Symfony Mailer

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.

The year is 1995: internet connection speeds are reaching a blistering 56 kbit/s, GeoCities is transforming everyone into an accomplished web designer, and sending emails... is all the rage.

Quick, fast-forward 25 years! Self-driving cars are a reality, you can download an entire HD movie in seconds, we can send rockets into space and then land them safely back on Earth and... yes, love it or hate it... sending emails is still all the rage... or at least... something nobody can avoid.

Yep, emails are still a huge part of our life and pretty much every app needs to send at least some... if not a lot of emails. But sending emails has always been kind of a pain - it feels like an old process. On top of that, emails are hard to preview, a pain to debug, there are multiple ways to deliver them - do I need an SMTP server? - each email has text and HTML parts, and don't even get me started about styling emails and embedding CSS in a way that will work in all mail clients. Oof.

But then, out of the ashes of this ancient practice grew... a hero. Ok it's actually just a Symfony component - but a cool one! Enter Symfony Mailer: a fresh & modern library that makes something old - sending emails - feel... new! Seriously, Mailer actually makes sending emails fun again and handles the ugliest details automatically. Will you love sending emails after this tutorial? Yea... I think you kinda might!

Setting up the App

As always, unless you're just "mailing it in", you should totally code along with me. Dial onto the internet, download the course code from this page and unzip it with WinRAR 1.54b. Inside, you'll find a start/ directory with the same code that you see here. Open up the README.md file to find all the setup details. The last step will be to open a terminal, move into the project and use the Symfony Binary to start a web server:

symfony serve

If you don't have the Symfony binary, you can grab it at Symfony.com/download. Once that's running, open your favorite browser - mine is Netscape Navigator - and go to https://localhost:8000 to see... The Space Bar! A news site for aliens... and the app that you probably recognize from other Symfony 4 tutorials here on the site.

In this tutorial, we'll be using Symfony 4.3. There are a few cool features that are coming in Symfony 4.4 and 5.0... but don't worry! I'll point those out along the way: they aren't big changes, mostly some nice debugging features.

Installing Mailer

Like most things in Symfony, the Mailer component is not installed by default. No problem, find your terminal, open a new tab and run:

composer require symfony/mailer

Notice that I didn't just use composer require mailer... using the "mailer" alias. Remember: Symfony Flex lets us say things like composer require forms or composer require templating and then it maps that to a recommended package. But at the time of this recording, composer require mailer would not download the Mailer component. Nope, it would download Swift Mailer... was was the recommended library for sending emails with Symfony before Symfony 4.3: that's when the Mailer component was introduced.

And even when you're Googling for documentation about Symfony's Mailer, be careful: you might end up on the docs for using SwiftMailer inside Symfony. The Mailer docs might be the second or third result.

Anyways after this installs, yea! We get some nice, post-install instructions. We'll talk about all of this.

The first step... is to create and configure an Email object! Let's do that next... then send it!

Leave a comment!

38
Login or Register to join the conversation
mofogasy Avatar
mofogasy Avatar mofogasy | posted 3 months ago

Hello, can't find a way to use the course script:
when i run composer update, i get

Your requirements could not be resolved to an installable set of packages.


with several problems with included bundles: nexylan/slack-bundle,symfony/property-access

and when i try for exmple composer update nexylan/slack-bundle
I get the same error msg

and when i try composer update nexylan/slack-bundle --ignore-platform-reqs
I get Script cache:clear returned with error code 255

I also tried --with-all-dependencies, composer require nexylan/slack-bundle:2.3.0 , composer update "symfony/*" --with-all-dependencies , composer require doctrine/doctrine-cache-bundle --with-all-dependencies

nothing work

Is there an order in updating packages ?

Is there an updated version of this course ?

Reply

Hey grenouille!

Sorry about the trouble! The content of this tutorial is still valid, but the code itself is showing its age :/. That's why, when you download the course code, we have a tooltip that mentions that it only works on PHP 7.

To get it work on PHP 8, it's likely tricky. The problem isn't the code in the tutorial itself... but just that you likely need to update a *bunch* of dependencies in order for *those* to be compatible with PHP 8. And if you do manage to update those... sometimes they differ from what we use in the tutorial. For me, doing the following... *seems* to work

1. Run composer require psr/cache:^1.0.0 --ignore-platform-reqs
2. Update all symfony libs in composer.json from 4.3.* to 4.4.* (including the extra.symfony.require key)
3. Run composer up --ignore-platform-reqs.

This, at least, seems to get the dependencies installed without any errors. So, no guarantees, but maybe this will help :).

Cheers!

Reply
mofogasy Avatar

Thanks for the detailed answer! that's nice.

Problem not solved yey though.
When I run composer require psr/cache:^1.0.0 --ignore-platform-reqs, I get some warnings about packages being abandoned then Executing script cache:clear [KO]
and Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Class "Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle" not found in C:\siteEcommerceApema\demo\envoiMail\start\src\Kernel.php
Since I want to use it as reference for my php 8 project, I d prefer stay with this version

Do you have another recent tutorial/project including mail sending ,please?

Reply

Hey grenouille!

Sorry for the slow reply, and darn! I had tried those commands locally with PHP 8.1 and it worked fine for me :/. Unfortunately, we don't have any other tutorials that show sending mail. We just need to give this tutorial a "fresh up" at some point, though the fundamentals of sending emails haven't changed (it's just the darn, annoying old code :/).

Reply
Mariem E. Avatar
Mariem E. Avatar Mariem E. | posted 2 years ago

Hi everyone,

How can I debug email with The SentMessage object and the TransportInterface provider ? the documentation doesn't say much .
Do you guys have an idea ?

Reply

Hey Mariem,

Here's a little info abotu debugging:
- https://symfony.com/doc/cur...
- https://symfony.com/doc/cur...

Also, all exceptions that implement TransportExceptionInterface has getDebug() method, see: https://github.com/symfony/...

It depends on what version of Symfony you're on, so this thread might be interesting for you as well: https://symfonycasts.com/sc... and thanks to this PR https://github.com/symfony/... MessageHandler now has return statement, i.e. you can get that SentMessage object from HandledStamp::getResult().

I hope this helps!

Cheers!

Reply
Default user avatar

Hey,

How can i send auto email periodicly on production? Is messenger provide it without run any command or without cronjob?

Reply

Hey Joseph

If you don't want to send the email right away when you dispatch the event, you can create a DelayMessage with the amount of seconds you want it to be delayed
Check it out how to do so here https://symfony.com/doc/cur...

Cheers!

Reply
Abdallah O. Avatar
Abdallah O. Avatar Abdallah O. | posted 2 years ago

Hi SymfonyCasts , when i upgrade the project which i build with you in the previous chapters to 4.3 , i lose the profiler (web Tool Bar) , this don't happen in 4.2 . (i want to continue on this project , i wish to not strat anothor one for the mailer) , Thanks.

Reply
Abdallah O. Avatar

Hi again , i deleted my previous vendor and composer.json with his lock , and used the one of this project , it worked after some modifications (The toolbar still here) , now i wonder should i learn webpack ENCORE first then move to the mailer or just learn the mailer then encore ?

Reply

Hey Ouahib,

I'm glad you were able to got it working, good job! Most probably it was some version incompatibilities.

> now i wonder should i learn webpack ENCORE first then move to the mailer or just learn the mailer then encore?

Great question! Actually, we made this course not much tight to Webpack Encore. So, if your main goal for now is to learn Mailer first - you're totally good to start it! We moved a few Encore-specific problems with Mailer right to the end of this tutorial to do not confuse users who do not work with Webpack Encore but give some advices and workarounds for those who do. You may watch this course at the end and if last chapters would be fuzzy for you - you can go watch a tutorial about Webpack Encore and then return back to re-watch those Encore-specific chapters again to get more clue.

And of course I would recommend you to watch Encore course as well later - this is an awesome tool!

I hope this helps!

Cheers!

Reply
Abdallah O. Avatar
Abdallah O. Avatar Abdallah O. | victor | posted 2 years ago

Thank You Victor.

Reply
Dung L. Avatar
Dung L. Avatar Dung L. | posted 2 years ago

Hello SymfonyCasts,

I got this error, trying hard to resolve it but no success, can you please help?

C:\xampp\htdocs\finish>composer require symfony/mailer
Restricting packages listed in "symfony/symfony" to "4.3.*"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.3.*"
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Conclusion: don't install symfony/mailer v4.3.9
- Conclusion: don't install symfony/mailer v4.3.8
- Conclusion: don't install symfony/mailer v4.3.7
- Conclusion: don't install symfony/mailer v4.3.6
- Conclusion: don't install symfony/mailer v4.3.5
- Conclusion: don't install symfony/mailer v4.3.4
- Conclusion: don't install symfony/mailer v4.3.3
- Conclusion: don't install symfony/mailer v4.3.2
- Conclusion: don't install symfony/mailer v4.3.1
- Installation request for symfony/mailer ^4.0 -> satisfiable by symfony/mailer[v4.3.0, v4.3.1, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.3.9].
- Conclusion: remove symfony/event-dispatcher v4.1.6
- symfony/mailer v4.3.0 requires symfony/event-dispatcher ^4.3 -> satisfiable by symfony/event-dispatcher[v4.3.0, v4.3.1, v4.3.2, v4.3.3, v4.3.4, v4.3.5, v4.3.6, v4.3.7, v4.3.8, v4.3.9].
- Can only install one of: symfony/event-dispatcher[v4.3.0, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.1, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.2, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.3, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.4, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.5, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.6, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.7, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.8, v4.1.6].
- Can only install one of: symfony/event-dispatcher[v4.3.9, v4.1.6].
- Installation request for symfony/event-dispatcher (locked at v4.1.6) -> satisfiable by symfony/event-dispatcher[v4.1.6].


Installation failed, reverting ./composer.json to its original content.

C:\xampp\htdocs\finish>composer require symfony/mailer
Reply

Hey Dung,

Symfony Mailer is a new component that was introduced in Symfony 4.3. From the console output I suppose you have Symfony 4.1 installed. To be able to install and use Symfony Mailer - you will need to upgrade your Symfony application to version 4.3 at least. Then you should be able to install Mailer on it.

I hope it helps! If you're not on Symfony 4.1 but on Symfony 4.3 already and still have this problem - please, let me know!

Cheers!

Reply
Dung L. Avatar

Hello Victor Bocharsky , I now thinking of upgrading my project to symfony 5 if possible from my current project Symfony 4.1.6 ? Or I will have to do incremental upgrade to 4.3 then 4.4 then version 5?

Can you also point to a preferable SymfonyCasts tutorial or a Symfony documentation that show how to upgrade to these specific version?

Best regards,
Dung.

Reply

Hey Dung,

Yeah, very good question! Well, at least you should update to the latest minor version, i.e. 4.4.x in your case. Then, fix all the deprecations you found in your code, and only then try to upgrade to 5.0. Btw, I'd recommend you to look at our new screencast course about how to upgrade to Symfony 5.0! Actually, we follow the exact this strategy there :) See https://symfonycasts.com/sc...

Good luck with upgrading!

Cheers!

Reply
Dung L. Avatar

Thank you Victor, I will give it a try.
Dung.

Reply
Dung L. Avatar

Hello Victor Bocharsky

You are right that i am on


C:\xampp\htdocs\finish>php bin/console --version
Symfony 4.1.6 (kernel: src, env: dev, debug: true)

C:\xampp\htdocs\finish>

But can you tell me how you know that it is 4.1.6. I read the error message and for the life of me I will never understand it :) - a simple error but the message is so confusing!

Thanks!

Reply

Hey Dung,

Haha, I just noticed that "locked" version:

> Installation request for symfony/event-dispatcher (locked at v4.1.6)

So I supposed you're on 4.1 - it was that simple :p

Yeah, message is huge and probably confusing, but in general it says that Composer found out that you have some packages as your dependencies locked to versions that are not satisfied in order to install that "symfony/mailer" package. It mostly means that the new package you're going to install has the same dependencies but requires a newer version of them.

I hope it helps!

Cheers!

Reply
Dung L. Avatar

Hello Victor Bocharsky ,

when starting up symfony server I get the below message, I am wondering if I should say yes to upgrade it to later version so that I can install "symfony/mailer" package? I really do not want to mess up my entire project by answering yes to upgrade to 4.11.3?


C:\xampp\htdocs\finish>symfony serve

Version 4.11.3 is available. Do you want to update now (execution will continue after whatever you decide) ? [Y/n]:

Best regards,

Reply

Hey Dung,

You're confusing this message a bit :) This message is from the Symfony CLI, i.e. it asks you if you want to upgrade the version of your Symfony CLI binary program, not about upgrading your Symfony application at all! I.e. this means even if you answer "Yes" - your Symfony application won't be upgraded and you won't be able to install Mailer yet. Basically, it equals to running the command "symfony self:update", that's it. To upgrade your Symfony application - you would need to upgrade your *Composer dependencies* instead.

Therefore, I'd recommend you to upgrade your Symfony CLI to the latest version because it won't affect your application at all... but it's totally not required though good to do.

I hope this is clear for you now.

Cheers!

Reply
Dung L. Avatar

Yup, thanks Victor Bocharsky very much! Merry Christmas! :)

Reply

Hey Dung!

Merry Christmas to you too! :)

Cheers!

Reply
Dung L. Avatar

thanks for your explanation, i will keep learning ... :)

Reply
AymDev Avatar

Hello !

It's me again, struggling with installation with PHP 7.4 ;-)
Well, this time the installation goes well with Composer, but when I try to load the Fixtures I get:


In Parser.php line 3195:
Notice: Trying to access array offset on value of type null

Running composer update won't solve the issue, upgrading to Symfony 4.4 neither, I still get:


Cannot autowire service "App\Repository\ApiTokenRepository": argument "$registry" of method "__construct()" references interface
"Symfony\Bridge\Doctrine\RegistryInterface" but no such service exists. Did you create a class that implements this interface?

I changed the Repository classes constructor argument type hint to Doctrine\Common\Persistence\ManagerRegistry which is the only one I found working but is marked as deprecated by PHPStorm. Using Doctrine\Persistence\ManagerRegistry as recommended does not work.
Just sharing if it helps in any way !

Reply

Hey AymDev!

I know the first error :). It's because doctrine/annotations is not compatible with PHP 7.4 unless you have version 1.7.0 or higher. BUT, about a week ago, I made sure that this tutorial was updated. If you download the course code now, you will get doctrine/annotations 1.8.0. Do you get the error if you download the course code now and try the "start/" directory? Maybe you just downloaded it before I could fix the issue :).

The second error is caused by the composer update which you shouldn't (if you have my fix above) have to run. Basically, it updates DoctrineBundle from version 1 to 2, which has some breaking changes in it. Specifically here: https://github.com/doctrine... - as you can see, it recommends to make the change you did - changing the type-hints from Doctrine\Common\Persistence\ManagerRegistry to Doctrine\Common\Persistence\ManagerRegistry.

So then, why is Doctrine\Common\Persistence\ManagerRegistry deprecated? Sigh, that's because the doctrine/common package is being "split" into smaller repositories. This is a great change - but a few things right now are in "flux". In fact, using Doctrine\Persistence\ManagerRegistry instead WILL work, even though it's not documented in that upgrade file. You mentioned that this didn't work for you - but it should. You will need DoctrineBundle 2.0.3 or higher.

I hope that explains! Mostly, you should not have any issues right now if you download the start code in PHP 7.4. But now you have the whole story :)

Cheers!

Reply
AymDev Avatar

Hey weaverryan !

Thank you for the detailed explanations !
Unfortunately I re-downloaded the course code, and only ran composer install --no-cache, then ran DB migrations but got the same error during the fixtures loading.

I'm not sure if I did anything wrong. I'd be happy to help and investigate but I don't have that precious time at the moment :-(
Thank you for everything you do !

Cheers !

Reply

Hey AymDev

Let's try something quick, I believe you got a cached version of the course code because of your browser's cache. Check inside your composer.lock the version of doctrine/annotations. It should be 1.8.0, if it's not, then I'm right and you will have to do a hard refresh on the page or clear your browser's cache for this site. If I'm wrong then, please check that you are using DoctrineBundle 2.0.3
If the problem still continues, please let us know.

Cheers!

Reply
AymDev Avatar

Hello Diego Aguiar

I downloaded the course code with an other browser with which I never downloaded the Mailer course code (so... no browser cache this time ? Or I'm missing a point about that maybe).

I checked the composer.lock and I always get doctrine/annotations v1.8.0 but I always get doctrine/doctrine-bundle v1.11.2 too which is wrong I guess.

Reply

If you see doctrine/annotations v1.8.0 then you got the newest code. About DoctrineBundle version, I'm not sure to be honest but if it's not working, you can try upgrading it to version 2 or just tweak the type-hint as you did before. I think it should do the trick

Reply

Hey AymDev

This is interesting. Can you tell me if it works on PHP7.3? I want to know if this has anything to do with PHP version

Cheers!

Reply
AymDev Avatar

Hey Diego Aguiar

I used a new installation of your source code (see my answer to Ryan) where the Fixtures loading failed.
I tried loading them using a 7.3.12 binary: /usr/bin/php7.3 ./bin/console d:f:l and it worked.

Cheers !

Reply

yeah, it's because of the bug the library has on PHP7.4. Please check my answer above :)

Reply
Andranik H. Avatar
Andranik H. Avatar Andranik H. | posted 2 years ago

Hi Ryan
Can you please say me, how can I configure monolog to send emails about errors via Symfony Mailer

Reply

Hey @Andranik!

Sorry for the slow reply. Mailer support in Monolog has not been merged yet - we were hoping it would happen for Symfony 4.4 (that was the cause of the delay), but it wasn't quite added in time. Here is the pull request: https://github.com/symfony/...

So, right now, it's not currently possible, unless you write your own custom handler. Actually, you could adapt/use the handler from that pull request. Here is what the codeconfig would (probably) look like - apologies if I get a detail wrong!

1) Copy the MailerHandler from the PR into, for example, a src/Logger/MailerHandler.php file (and update the namespace)

2) Modify the class. Instead of accepting a $messageTemplate 2nd argument, remove it. Instead, in the constructor,
set the property to some new Email (or TemplatedEmail) object:


public function __construct(MailerInterface $mailer, int $level = Logger::DEBUG, bool $bubble = true)
{
parent::__construct($level, $bubble);
$this->mailer = $mailer;
$this->messageTemplate = (new Email())
->from(...)
->to()
->subject('Error on the site!');
}

4) Configure as a handler


# config/packages/prod/monolog.yaml
monolog:
handlers:
# ...
my_mail_handler:
type: service
id: App\Logger\MailerHandler

That should be it - but I'm filling in some of the details right here in the comment box without trying them. So let me know if you run into any issues ;).

Cheers!

Reply

Hi Ryan, Glad this tutorial is coming up:)
Just a quick note: at 2:39, we didn't install the self-signed certificate of the Symfony binary, there is a problem to display the images on the website.
I added a .env.local file and overloaded the environment variable: SITE_BASE_URL.
Note: I don't know if SSL is a necessary condition to follow the tutorial.
Thank you, for the good work you did!

Reply

Hey C├ędric!

> Glad this tutorial is coming up:

Me too! :)

> I added a .env.local file and overloaded the environment variable: SITE_BASE_URL.

Hmm, yes, this was a perfect workaround. If you don't install the SSL cert with the binary (which is totally fine), then indeed, your images won't be displayed until you set SITE_BASE_URL=http://localhost:8000 in .env or .env.local (notice no "s" in http://). Thanks for the comment - this has tripped a few people up in other tutorials!

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
    }
}