Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable mailer #1052

Merged
merged 1 commit into from Nov 14, 2018
Merged

Add configurable mailer #1052

merged 1 commit into from Nov 14, 2018

Conversation

Wharenn
Copy link
Contributor

@Wharenn Wharenn commented Oct 23, 2018

I am targeting this branch, because this is a new feature with no breaking change.

Changelog

### Added
- Added an optional `mailer` config option to use a custom mailer implementation

Subject

By default, SonataUserBundle is using the mailer service to send the account password reset email and keep the email building logic in a controller private method. It makes it hard to use a custom implementation like using another mailer than the default one or updating the email creation process.

This PR adds a Mailer class implementing the FOS MailerInterface and doing the same things the AdminResettingController class was. This default class can be replaced by any other user service implementing the MailerInterface by setting corresponding service id uner the mailer config key:

# config/package/sonata.yaml

sonata_user:
    mailer: custom.mailer.service.id

public function __construct(RouterInterface $router, EngineInterface $templating, \Swift_Mailer $mailer, string $fromEmail, string $emailTemplate)
{
$this->router = $router;
$this->templating = $templating;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the same order for the const arguments and the member vars

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I got it. It should be fixed now?

public function setUp(): void
{
$this->router = $this->createMock(RouterInterface::class);
$this->templating = $this->createMock(EngineInterface::class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the order is correct 🤗👍🏻

@Wharenn Wharenn mentioned this pull request Oct 24, 2018
2 tasks
Copy link
Member

@OskarStark OskarStark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocked by #1053

@SonataCI
Copy link
Collaborator

Could you please rebase your PR and fix merge conflicts?

@Wharenn
Copy link
Contributor Author

Wharenn commented Nov 6, 2018

This PR has been updated to reflect changes introduced by #1053. We are now using an alias in the DI to point to the configurable mailer.

Mailer Configuration
~~~~~~~~~~~~~~~~~~~~

You can define a custom mailer to send reset password emails. Your mailer will have to implement ``FOS\UserBundle\Mailer\MailerInterface``.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -115,6 +116,7 @@ public function getConfigTreeBuilder()
->scalarNode('default_avatar')->defaultValue('bundles/sonatauser/default_avatar.png')->end()
->end()
->end()
->scalarNode('mailer')->defaultValue(Mailer::class)->end()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a call to info documenting what this is

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;

class Mailer implements MailerInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final?

/**
* @var RouterInterface
*/
protected $router;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use private as much as possible

class Mailer implements MailerInterface
{
/**
* @var RouterInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refactor this to UrlGeneratorInterface, since you are not matching any urls.

src/Resources/config/mailer.xml Outdated Show resolved Hide resolved
@@ -226,6 +226,28 @@ public function testConfigureGoogleAuthenticatorEnabled(): void
$this->assertContainerBuilderHasServiceDefinitionWithArgument('sonata.user.google.authenticator.provider', 0, 'bar');
}

/**
* @group legacy
* @expectedDeprecation The 'Google\Authenticator' namespace is deprecated in sonata-project/GoogleAuthenticator since version 2.1 and will be removed in 3.0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is weird that you need to do this 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it also seems weird to me, but this deprecation is risen everytime the load method is used :/

/**
* @var RouterInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $router;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

greg0ire
greg0ire previously approved these changes Nov 7, 2018
OskarStark
OskarStark previously approved these changes Nov 8, 2018
@Hanmac
Copy link
Contributor

Hanmac commented Nov 12, 2018

I don't know how much this is already uses FOS stuff, but would it make sense to use the FOSUserEvents for password reset too?

and should that be part of your actions or your new mailer?

@Wharenn
Copy link
Contributor Author

Wharenn commented Nov 12, 2018

@Hanmac we discussed this in #1053 and agreed to use FOS events :) We decided to postpone the implementation to another PR to be able to close the mailer subject before. I already have some wip on the FOS event implementation but I'm waiting for the completion of the mailer subject before pushing it as a PR.

@Hanmac
Copy link
Contributor

Hanmac commented Nov 12, 2018

@Wharenn oh we already did? then it is okay.

i was just wondering where the events should be, in the mailer or in the actions?

@Wharenn
Copy link
Contributor Author

Wharenn commented Nov 12, 2018

IMO in the actions as they can also be used to hook userland behaviors on every action workflow. This is the way they are implemented in FOSUserBundle. I think the incoming PR will go deeper about the subject.

@Wharenn
Copy link
Contributor Author

Wharenn commented Nov 14, 2018

Hi @sonata-project/contributors can we move forward on this PR?

core23
core23 previously approved these changes Nov 14, 2018
public function configureTranslationDomain($config, ContainerBuilder $container): void
{
$container->setParameter('sonata.user.admin.user.translation_domain', $config['admin']['user']['translation']);
$container->setParameter('sonata.user.admin.group.translation_domain', $config['admin']['group']['translation']);
}

/**
* @param array $config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you removed this but didn't add the typehint in the signature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

kunicmarko20
kunicmarko20 previously approved these changes Nov 14, 2018
Copy link
Contributor

@kunicmarko20 kunicmarko20 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

kunicmarko20
kunicmarko20 previously approved these changes Nov 14, 2018
*/
public function fixImpersonating(array $config)
public function fixImpersonating(array $config): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

* @return mixed
*/
public function configureGoogleAuthenticator($config, ContainerBuilder $container)
public function configureGoogleAuthenticator(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

* @param ContainerBuilder $container
*/
public function configureClass($config, ContainerBuilder $container): void
public function configureClass(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

* @param ContainerBuilder $container
*/
public function configureAdminClass($config, ContainerBuilder $container): void
public function configureAdminClass(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

* @param ContainerBuilder $container
*/
public function configureTranslationDomain($config, ContainerBuilder $container): void
public function configureTranslationDomain(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

* @param ContainerBuilder $container
*/
public function configureController($config, ContainerBuilder $container): void
public function configureController(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

/**
* @param array $config
*/
public function configureMailer(array $config, ContainerBuilder $container): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this private

*/
protected function aliasManagers(ContainerBuilder $container, $managerType): void
protected function aliasManagers(ContainerBuilder $container, string $managerType): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BC break

@Wharenn
Copy link
Contributor Author

Wharenn commented Nov 14, 2018

@core23 fixed BCs


private function configureMailer(array $config, ContainerBuilder $container): void
{
$container->setAlias('sonata.user.mailer', $config['mailer']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonuspoint: Make an alias for the MailerInterface too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are implementing the FOS MailerInterface, this would lead to expose to autowiring the FOS MailerInterface from this bundle. Is this really what we want?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right. Just ignore it 😅

@greg0ire greg0ire merged commit 55a4450 into sonata-project:4.x Nov 14, 2018
@greg0ire
Copy link
Contributor

Thanks @Wharenn !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants