Skip to content

Commit c70ecfd

Browse files
authored
Merge pull request #3068 from stof/symfony_mailer
Add a mailer implementation based on symfony/mailer
2 parents 4c0a2a8 + dd15a76 commit c70ecfd

File tree

5 files changed

+131
-11
lines changed

5 files changed

+131
-11
lines changed

DependencyInjection/FOSUserExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ private function loadRegistration(array $config, ContainerBuilder $container, Xm
207207
unset($config['confirmation']['from_email']);
208208
}
209209
$container->setParameter('fos_user.registration.confirmation.from_email', [$fromEmail['address'] => $fromEmail['sender_name']]);
210+
$container->setParameter('fos_user.registration.confirmation.from_address', $fromEmail);
210211

211212
$this->remapParametersNamespaces($config, $container, [
212213
'confirmation' => 'fos_user.registration.confirmation.%s',
@@ -234,6 +235,7 @@ private function loadResetting(array $config, ContainerBuilder $container, XmlFi
234235
unset($config['email']['from_email']);
235236
}
236237
$container->setParameter('fos_user.resetting.email.from_email', [$fromEmail['address'] => $fromEmail['sender_name']]);
238+
$container->setParameter('fos_user.resetting.email.from_address', $fromEmail);
237239

238240
$this->remapParametersNamespaces($config, $container, [
239241
'' => [

Mailer/TwigSymfonyMailer.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSUserBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FOS\UserBundle\Mailer;
13+
14+
use FOS\UserBundle\Model\UserInterface;
15+
use Symfony\Component\Mailer\MailerInterface as SymfonyMailerInterface;
16+
use Symfony\Component\Mime\Address;
17+
use Symfony\Component\Mime\Email;
18+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
19+
use Twig\Environment;
20+
21+
/**
22+
* @author Christophe Coevoet <stof@notk.org>
23+
*/
24+
final class TwigSymfonyMailer implements MailerInterface
25+
{
26+
private SymfonyMailerInterface $mailer;
27+
private UrlGeneratorInterface $router;
28+
private Environment $twig;
29+
private array $parameters;
30+
31+
public function __construct(SymfonyMailerInterface $mailer, UrlGeneratorInterface $router, Environment $twig, array $parameters)
32+
{
33+
$this->mailer = $mailer;
34+
$this->router = $router;
35+
$this->twig = $twig;
36+
$this->parameters = $parameters;
37+
}
38+
39+
public function sendConfirmationEmailMessage(UserInterface $user): void
40+
{
41+
$template = $this->parameters['template']['confirmation'];
42+
$url = $this->router->generate('fos_user_registration_confirm', ['token' => $user->getConfirmationToken()], UrlGeneratorInterface::ABSOLUTE_URL);
43+
44+
$context = [
45+
'user' => $user,
46+
'confirmationUrl' => $url,
47+
];
48+
49+
$this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], $user->getEmail());
50+
}
51+
52+
public function sendResettingEmailMessage(UserInterface $user): void
53+
{
54+
$template = $this->parameters['template']['resetting'];
55+
$url = $this->router->generate('fos_user_resetting_reset', ['token' => $user->getConfirmationToken()], UrlGeneratorInterface::ABSOLUTE_URL);
56+
57+
$context = [
58+
'user' => $user,
59+
'confirmationUrl' => $url,
60+
];
61+
62+
$this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], $user->getEmail());
63+
}
64+
65+
/**
66+
* @param array<string, mixed> $context
67+
* @param array{address: string, sender_name: string} $fromEmail
68+
*/
69+
private function sendMessage(string $templateName, array $context, array $fromEmail, string $toEmail): void
70+
{
71+
$template = $this->twig->load($templateName);
72+
$subject = $template->renderBlock('subject', $context);
73+
$textBody = $template->renderBlock('body_text', $context);
74+
75+
$htmlBody = '';
76+
77+
if ($template->hasBlock('body_html', $context)) {
78+
$htmlBody = $template->renderBlock('body_html', $context);
79+
}
80+
81+
$message = (new Email())
82+
->subject($subject)
83+
->from(new Address($fromEmail['address'], $fromEmail['sender_name']))
84+
->to($toEmail)
85+
->text($textBody)
86+
;
87+
88+
if (!empty($htmlBody)) {
89+
$message->html($htmlBody);
90+
}
91+
92+
$this->mailer->send($message);
93+
}
94+
}

Resources/config/mailer.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
<parameter key="fos_user.resetting.email.from_email" type="collection">
1414
<parameter key="no-resetting@acme.com">Acme Ltd</parameter>
1515
</parameter>
16+
<parameter key="fos_user.registration.confirmation.from_address" type="collection">
17+
<parameter key="address">no-registration@acme.com</parameter>
18+
<parameter key="sender_name">Acme Ltd</parameter>
19+
</parameter>
20+
<parameter key="fos_user.resetting.email.from_address" type="collection">
21+
<parameter key="address">no-resetting@acme.com</parameter>
22+
<parameter key="sender_name">Acme Ltd</parameter>
23+
</parameter>
1624
</parameters>
1725

1826
<services>
@@ -33,6 +41,22 @@
3341
<tag name="fos_user.requires_swift" />
3442
</service>
3543

44+
<service id="fos_user.mailer.twig_symfony" class="FOS\UserBundle\Mailer\TwigSymfonyMailer" public="false">
45+
<argument type="service" id="mailer" />
46+
<argument type="service" id="router" />
47+
<argument type="service" id="twig" />
48+
<argument type="collection">
49+
<argument key="template" type="collection">
50+
<argument key="confirmation">%fos_user.registration.confirmation.template%</argument>
51+
<argument key="resetting">%fos_user.resetting.email.template%</argument>
52+
</argument>
53+
<argument key="from_email" type="collection">
54+
<argument key="confirmation">%fos_user.registration.confirmation.from_address%</argument>
55+
<argument key="resetting">%fos_user.resetting.email.from_address%</argument>
56+
</argument>
57+
</argument>
58+
</service>
59+
3660
<service id="fos_user.mailer.noop" class="FOS\UserBundle\Mailer\NoopMailer" public="false" />
3761
</services>
3862

Resources/doc/emails.rst

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,18 @@ a form to enter in a new password.
3838
Default Mailer Implementations
3939
------------------------------
4040

41-
The bundle comes with 2 mailer implementations. They are listed below
41+
The bundle comes with 3 mailer implementations. They are listed below
4242
by service id:
4343

44+
- ``fos_user.mailer.twig_symfony`` uses symfony/mailer to send emails and Twig blocks to render the message.
4445
- ``fos_user.mailer.twig_swift`` uses Swiftmailer to send emails and Twig blocks to render the message.
4546
- ``fos_user.mailer.noop`` is a mailer implementation which performs no operation, so no emails are sent.
4647

4748
.. note::
4849

4950
The ``fos_user.mailer.noop`` mailer service should be used in the case
5051
where you do not want the bundle to send emails and you do not want to
51-
include the SwiftmailerBundle in your app.
52+
include an actual mailer in your app.
5253

5354
Configuring the Sender Email Address
5455
------------------------------------
@@ -103,13 +104,12 @@ the password reset request email:
103104
Sending HTML mails
104105
------------------
105106

106-
The default mailer only supports sending plain text messages. If you want
107-
to send multipart messages, the easiest solution is to use the TwigSwiftMailer
108-
implementation instead. It expects your twig template to define 3 blocks:
107+
The default mailers supports sending multipart messages. They expect your twig template
108+
to define 3 blocks:
109109

110110
- ``subject`` containing the email subject
111111
- ``body_text`` rendering the plain text version of the message
112-
- ``body_html`` rendering the html mail
112+
- ``body_html`` rendering the html mail (this block is optional)
113113

114114
Here is how you can use it, you can use either of the two methods
115115
of referencing the email template below.
@@ -120,7 +120,7 @@ of referencing the email template below.
120120
fos_user:
121121
# ...
122122
service:
123-
mailer: fos_user.mailer.twig_swift
123+
mailer: fos_user.mailer.twig_symfony
124124
resetting:
125125
email:
126126
template: email/password_resetting.email.twig
@@ -166,10 +166,8 @@ You can view the default email templates at
166166
Using A Custom Mailer
167167
---------------------
168168

169-
The default mailer service used by FOSUserBundle relies on the Swiftmailer
170-
library to send mail. If you would like to use a different library to send
171-
emails, want to send HTML emails or simply change the content of the email you
172-
may do so by defining your own service.
169+
If you would like to use a different library to send emails, want to send HTML emails
170+
or simply change the content of the email you may do so by defining your own service.
173171

174172
First you must create a new class which implements ``FOS\UserBundle\Mailer\MailerInterface``
175173
which is listed below.

composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
"friendsofphp/php-cs-fixer": "^3.0.2, !=3.5.0",
5252
"swiftmailer/swiftmailer": "^4.3 || ^5.0 || ^6.0",
5353
"symfony/console": "^4.4 || ^5.0 || ^6.0",
54+
"symfony/mailer": "^4.4 || ^5.0 || ^6.0",
55+
"symfony/mime": "^4.4 || ^5.0 || ^6.0",
5456
"symfony/phpunit-bridge": "^6.1",
5557
"symfony/yaml": "^4.4 || ^5.0 || ^6.0"
5658
},

0 commit comments

Comments
 (0)