Multiple instances of Swiftmailer in Symfony2 - symfony

Symfony2 uses a Swiftmailer bundle to send emails.
To use and configure Swiftmailer in Symfony2, one has to use such a configuration as explained in the docs, e.g. by using YAML:
swiftmailer:
transport: smtp
encryption: ssl
auth_mode: login
host: smtp.gmail.com
username: your_username
password: your_password
The Swiftmailer is defined in Symfony2 as a service and an instance of it can be obtained in a controller as follows:
$mailerinstance = $this->get('mailer');
Now, let's suppose that two different configurations are required for the Swiftmailer, e.g. one that uses email spooling (e.g. for a scheduled newsletter) and another that sends immediately all the new emails (e.g. for the password lost service). Thus, I guess that two separated instances of the Swiftmailer should be defined. How can I do that in Symfony2?

There is no default symfony way to have 2 different instances. But you can just make a new class that extends swiftmailer, make it to be a service and just pass to the parent constructor your different configuration.

swiftmailer:
default_mailer: second_mailer
mailers:
first_mailer:
# ...
second_mailer:
# ...
// ...
// returns the first mailer
$container->get('swiftmailer.mailer.first_mailer');
// also returns the second mailer since it is the default mailer
$container->get('swiftmailer.mailer');
// returns the second mailer
$container->get('swiftmailer.mailer.second_mailer');
http://symfony.com/doc/current/reference/configuration/swiftmailer.html#using-multiple-mailers

Related

How to configure sending errors by e-mail with Symfony 5.1, Monolog and Mailer component?

Do you have an example configuration to send logs by email with the Mailer component of Symfony 5.1.
In the Symfony blog we announce this feature, but I can't put the right config in monolog.yaml
https://symfony.com/blog/new-in-symfony-5-1-misc-improvements-part-3 :
That's why in Symfony 5.1 we added a new Monolog log handler which uses the Mailer component to send the logs via email.
Unfortunately this addition only covers the actuall MailerHandler class in the monolog-bridge. This does not cover the possibility to configure it in the monolog-bundle (that's the drawback if those components are distributed over multiple packages).
The PR for the change in the monolog-bundle is still open, and can be found here: Add Symfony Mailer support #354.
If you don't want to wait for the change in the monolog-bundle you could already use it by defining the handler as a service and then using it with the service type in the monolog configuration.
So define your service:
services:
# this configures the "mail" as a prototype, so you can
# define the sender and recipient mail addresses here
symfony_mailer_service_template:
class: Symfony\Component\Mime\Email
calls:
- ['from', ['webapp#example.com']]
- ['to', ['ops#example.com']]
- ['subject', ['Logs']]
symfony_mailer_service:
class: Symfony\Bridge\Monolog\Handler\MailerHandler
arguments:
- '#mailer.mailer'
- '#symfony_mailer_service_template'
- !php/const Monolog\Logger::DEBUG # log level
- true # bubble
And then in your mailer configuration you could use it like this:
monolog:
handlers:
main:
type: fingers_crossed
handler: deduplicated
deduplicated:
type: deduplication
handler: symfony_mailer
symfony_mailer:
type: service
id: symfony_mailer_service

FosUserBundle don't send email to resset password

I have a simple form to login and reminder password, I overwrite the FOSUser template and everything works fine, but when I want to email the password reminder I do not get it to the mail.
This looks like a swiftmailer and fos configuration in config.yml:
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
fos_user:
db_driver: orm
firewall_name: main
user_class: AirblogBundle\Entity\User
from_email:
address: "admin#admin.com"
sender_name: "Admin"
resetting:
email:
from_email:
address: noreply#yoursite.com
sender_name: No Reply
token_ttl: 0
After sending the email from the resetting/request path, I get the following information:
An email has been sent to ...#wp.pl. It contains a link you must click to reset your password.
Which seems correct because the address entered in the form has the same ending, but my mailbox does not receive any message.
ps: One more question, how to simply overwrite the Twig template, so the login and reminder of the hymn was on one page? Do you need to overwrite the controller?
Did you configure the needed parameters of SwiftMailerBundle well ?
First of all I suggest you to use Symfony's command to check your swift mailer configuration.
Specify the good arguments to send you a debug mail with reading the help command
php app/console swiftmailer:email:send --help
You should receive a mail on the email address you wrote in command.
After this step you can assume that your mail configuration is good
Reset your forget password request
One important (in the version installed on my project, composer requirement ~2.0) thing to know that is FOSUserBundle don't resend mail if you didn't click on the previous reset link sended BUT he display to you the message that he sended the mail.
If you want to "reset" your password request for a specific user
UPDATE user SET confirmation_token = NULL, password_requested_at = NULL WHERE username = "yourdebugusername"
Extending FOSUserBundle Twig templates
You should read this documentation
Basically you can override all the FOSUserTemplate under vendor/friendsofsymfony/user-bundle/Resources/views
I hope it's help !
For overriding FOSUser twig template looks the Symfony Doc

Disable swiftmailer per Controller action

I know i can disable e-mail delivery in my config file by setting:
swiftmailer:
disable_delivery: true
but i got a specific controller action where i'd like to disable email delivery through swiftmailer. Is there any way to do this?

Send emails via memory in controllers and spool in some commands in Symfony2

I need to use the spool option to send massive emails to my users, but i won't to change whole config of my app to spool because my register system send an email to the user and i want that this email be instant send.
Is any way to do this without change the global config for swiftmailer?
You can configure different emailers. For example:
swiftmailer:
default_mailer: spool_mailer
mailers:
spool_mailer:
spool:
type: file
path: /path/to/spool
# ...
instant_mailer:
# ...
Then use one emailer or the other depending on whether you want to spool or not:
//in your controller
$spoolMailer = $this->get('swiftmailer.mailer.spool_mailer');
$spoolMailer->send(...); //this will be spooled
$instantMailer = $this->get('swiftmailer.mailer.instant_mailer');
$instantMailer->send(...); //this will be sent instantly

How to define an additional mailer service to use the spool and send instant emails in Symfony2

In my Symfony2 web app I'm supposed to send two kind of emails: instant and bulk. The instant emails should be send right away while the bulk emails should be send using the spool. With the default configuration of the Swiftmailer in Symfony2 it is impossible to do that because there is only one mailer service.
Similar questions has been asked here in SO ( How to spool emails (in a task) and send normal emails in the moment in the other controllers? ) with no luck, but according to this github thread ( https://github.com/symfony/SwiftmailerBundle/issues/6 ) it is possible to create a second mailer service that can be configured totally different than the default one. Someone there (stof) recommended as a possible solution to follow the configuration found in the SwiftmailerBundle ( https://github.com/symfony/SwiftmailerBundle/blob/master/Resources/config/swiftmailer.xml ) to create this new service, but I don't know how exactly do that.
Does anyone know how to create an additional mailer service that I can configured as a spool while having the default mailer service to send regular (instant) emails?
I found the solution here
This is how I implemented it:
First, I configured the default mailer service to work as a spool to send bulk emails.
(config.yml)
swiftmailer:
transport: %mailer_transport%
encryption: %mailer_encryption%
auth_mode: %mailer_auth_mode%
host: %mailer_host%
username: %mailer_user%
password: %mailer_password%
spool:
type: file
path: "%kernel.root_dir%/spool"
Then, inside one of my bundles (CommonBundle) I registered a new service called "instant_mailer" that maps to the Swiftmailer class.
(service.yml)
instant_mailer:
class: %swiftmailer.class%
arguments: ["#?swiftmailer.transport.real"]
Finally, in my controller, whenever I want to send an email usning the spool I just do:
$mailer = $this->get('mailer');
And to send an instant email:
$mailer = $this->get('instant_mailer');

Resources