diff --git a/app/migrations/Version20231218175905.php b/app/migrations/Version20231218175905.php new file mode 100644 index 000000000..f05dcb8c1 --- /dev/null +++ b/app/migrations/Version20231218175905.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE draw_acme__user ADD preferred_locale VARCHAR(255) DEFAULT \'en\' NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE draw_acme__user DROP preferred_locale'); + } +} diff --git a/app/src/DataFixtures/AppFixtures.php b/app/src/DataFixtures/AppFixtures.php index 65994ffd4..cffaaeedb 100644 --- a/app/src/DataFixtures/AppFixtures.php +++ b/app/src/DataFixtures/AppFixtures.php @@ -78,6 +78,7 @@ public function load(ObjectManager $manager): void $user->setPlainPassword('password'); if (1 === $number) { $user->setTags([$inactiveTag]); + $user->setPreferredLocale('fr'); } $manager->persist($user); } diff --git a/app/src/Entity/User.php b/app/src/Entity/User.php index e5eb9d380..62a8f140e 100644 --- a/app/src/Entity/User.php +++ b/app/src/Entity/User.php @@ -21,6 +21,7 @@ use Draw\Bundle\UserBundle\Security\TwoFactorAuthentication\Entity\ConfigurationTrait; use Draw\Bundle\UserBundle\Security\TwoFactorAuthentication\Entity\TwoFactorAuthenticationUserInterface; use Draw\Component\EntityMigrator\MigrationTargetEntityInterface; +use Draw\Component\Mailer\Recipient\LocalizationAwareInterface; use Draw\Component\Messenger\DoctrineMessageBusHook\Entity\MessageHolderInterface; use Draw\Component\Messenger\DoctrineMessageBusHook\Entity\MessageHolderTrait; use Draw\DoctrineExtra\Common\Collections\CollectionUtil; @@ -34,7 +35,7 @@ #[ORM\Table(name: 'draw_acme__user')] #[ORM\HasLifecycleCallbacks] #[UniqueEntity(fields: ['email'])] -class User implements MessageHolderInterface, SecurityUserInterface, TwoFactorAuthenticationUserInterface, PasswordChangeUserInterface, LockableUserInterface, TwoFactorInterface, ByEmailInterface, ByTimeBaseOneTimePasswordInterface, MigrationTargetEntityInterface +class User implements MessageHolderInterface, SecurityUserInterface, TwoFactorAuthenticationUserInterface, PasswordChangeUserInterface, LockableUserInterface, TwoFactorInterface, ByEmailInterface, ByTimeBaseOneTimePasswordInterface, MigrationTargetEntityInterface, LocalizationAwareInterface { use ByEmailTrait; use ByTimeBaseOneTimePasswordTrait; @@ -148,9 +149,11 @@ class User implements MessageHolderInterface, SecurityUserInterface, TwoFactorAu private Collection $userTags; #[Assert\NotNull] - #[Serializer\ReadOnlyProperty] private string $requiredReadOnly = 'value'; + #[ORM\Column(type: 'string', nullable: false, options: ['default' => 'en'])] + private string $preferredLocale = 'en'; + public function __construct() { $this->address = new Address(); @@ -176,6 +179,18 @@ public function setId(string $id): void $this->id = $id; } + public function getPreferredLocale(): string + { + return $this->preferredLocale; + } + + public function setPreferredLocale(string $preferredLocale): static + { + $this->preferredLocale = $preferredLocale; + + return $this; + } + /** * @see UserInterface */ diff --git a/config/serializer/Entity/User.yaml b/config/serializer/Entity/User.yaml index 5d6edee3d..627b10b28 100644 --- a/config/serializer/Entity/User.yaml +++ b/config/serializer/Entity/User.yaml @@ -49,5 +49,7 @@ App\Entity\User: exclude: true emailAuthCodeGeneratedAt: exclude: true + preferredLocale: + exclude: true twoFactorAuthenticationEnabledProviders: exclude: true diff --git a/packages/mailer/Email/CallToActionEmail.php b/packages/mailer/Email/CallToActionEmail.php index 16ef3a9a2..f4406945c 100644 --- a/packages/mailer/Email/CallToActionEmail.php +++ b/packages/mailer/Email/CallToActionEmail.php @@ -4,8 +4,10 @@ use Symfony\Bridge\Twig\Mime\TemplatedEmail; -class CallToActionEmail extends TemplatedEmail +class CallToActionEmail extends TemplatedEmail implements LocalizeEmailInterface { + use LocalizeEmailTrait; + private ?string $callToActionLink = null; public array $translationTokens = []; diff --git a/packages/mailer/Email/LocalizeEmailTrait.php b/packages/mailer/Email/LocalizeEmailTrait.php new file mode 100644 index 000000000..5331da80a --- /dev/null +++ b/packages/mailer/Email/LocalizeEmailTrait.php @@ -0,0 +1,20 @@ +locale = $locale; + + return $this; + } + + public function getLocale(): ?string + { + return $this->locale; + } +} diff --git a/packages/mailer/Recipient/LocalizationAwareInterface.php b/packages/mailer/Recipient/LocalizationAwareInterface.php new file mode 100644 index 000000000..a2b699647 --- /dev/null +++ b/packages/mailer/Recipient/LocalizationAwareInterface.php @@ -0,0 +1,8 @@ +handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $mailer->send(new ForgotPasswordEmail($form->get('email')->getData())); + $mailer->send( + (new ForgotPasswordEmail($form->get('email')->getData())) + ->setLocale($request->getLocale()) + ); return new RedirectResponse($this->generateUrl('admin_check_email')); } diff --git a/packages/user-bundle/Email/ToUserEmailTrait.php b/packages/user-bundle/Email/ToUserEmailTrait.php index aab30815b..a499d7247 100644 --- a/packages/user-bundle/Email/ToUserEmailTrait.php +++ b/packages/user-bundle/Email/ToUserEmailTrait.php @@ -2,10 +2,27 @@ namespace Draw\Bundle\UserBundle\Email; +use Draw\Bundle\UserBundle\Entity\SecurityUserInterface; +use Draw\Component\Mailer\Email\LocalizeEmailTrait; +use Draw\Component\Mailer\Recipient\LocalizationAwareInterface; + trait ToUserEmailTrait { + use LocalizeEmailTrait; + private string|int|null $userId = null; + public function toUser(SecurityUserInterface $user): self + { + $this->userId = $user->getId(); + + if ($user instanceof LocalizationAwareInterface) { + $this->setLocale($user->getPreferredLocale()); + } + + return $this; + } + public function setUserId(string|int $userId): self { $this->userId = $userId; diff --git a/packages/user-bundle/MessageHandler/NewUserSendEmailMessageHandler.php b/packages/user-bundle/MessageHandler/NewUserSendEmailMessageHandler.php index 2ed125b89..6a00d1d92 100644 --- a/packages/user-bundle/MessageHandler/NewUserSendEmailMessageHandler.php +++ b/packages/user-bundle/MessageHandler/NewUserSendEmailMessageHandler.php @@ -5,6 +5,7 @@ use Doctrine\ORM\EntityRepository; use Draw\Bundle\UserBundle\Email\UserOnboardingEmail; use Draw\Bundle\UserBundle\Message\NewUserMessage; +use Draw\Component\Mailer\Recipient\LocalizationAwareInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -29,14 +30,18 @@ public function __invoke(NewUserMessage $message): void { $user = $this->drawUserEntityRepository->find($message->getUserId()); - if (null === $user) { - return; - } - if (!method_exists($user, 'getEmail') || empty($user->getEmail())) { return; } - $this->mailer->send((new UserOnboardingEmail())->setUserId($message->getUserId())); + $this->mailer->send( + (new UserOnboardingEmail()) + ->setUserId($message->getUserId()) + ->setLocale( + $user instanceof LocalizationAwareInterface ? + $user->getPreferredLocale() : + null + ) + ); } } diff --git a/packages/user-bundle/MessageHandler/PasswordChangeRequestedSendEmailMessageHandler.php b/packages/user-bundle/MessageHandler/PasswordChangeRequestedSendEmailMessageHandler.php index 80844a210..a75a5d5f2 100644 --- a/packages/user-bundle/MessageHandler/PasswordChangeRequestedSendEmailMessageHandler.php +++ b/packages/user-bundle/MessageHandler/PasswordChangeRequestedSendEmailMessageHandler.php @@ -6,6 +6,7 @@ use Draw\Bundle\UserBundle\Email\PasswordChangeRequestedEmail; use Draw\Bundle\UserBundle\Entity\PasswordChangeUserInterface; use Draw\Bundle\UserBundle\Message\PasswordChangeRequestedMessage; +use Draw\Component\Mailer\Recipient\LocalizationAwareInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -38,6 +39,14 @@ public function __invoke(PasswordChangeRequestedMessage $message): void return; } - $this->mailer->send((new PasswordChangeRequestedEmail())->setUserId($user->getId())); + $this->mailer->send( + (new PasswordChangeRequestedEmail()) + ->setUserId($user->getId()) + ->setLocale( + $user instanceof LocalizationAwareInterface + ? $user->getPreferredLocale() + : null + ) + ); } } diff --git a/packages/user-bundle/Resources/translations/DrawEmail.en.yaml b/packages/user-bundle/Resources/translations/DrawEmail.en.yaml index 1bd013b5a..e1d656c3a 100644 --- a/packages/user-bundle/Resources/translations/DrawEmail.en.yaml +++ b/packages/user-bundle/Resources/translations/DrawEmail.en.yaml @@ -32,7 +32,7 @@ email: subject: 'Welcome' top_section: |
Your account have been created.
-
Please click on the button below to finally your account creation.
+Please click on the button below to finalise your account creation.
call_to_action_text: 'Finalise my account creation' bottom_section: |Follow the instruction on the site to finalise your account creation.
diff --git a/packages/user-bundle/Resources/translations/DrawEmail.fr.yaml b/packages/user-bundle/Resources/translations/DrawEmail.fr.yaml index 9a9dfe882..84c366be0 100644 --- a/packages/user-bundle/Resources/translations/DrawEmail.fr.yaml +++ b/packages/user-bundle/Resources/translations/DrawEmail.fr.yaml @@ -20,3 +20,12 @@ email: bottom_section: |Si vous n'êtes pas l'auteur de cette demande, peut-être que quelqu'un à fait une erreur.
Peut-être seriez vous intéressé par notre site web ? Cliquer sur le lien plus haut pour en savoir plus.
+ + user_onboarding: + subject: 'Bienvenue' + top_section: | +Votre compte a été créé.
+
Veuillez cliquer sur le bouton ci-dessous pour finaliser la création de votre compte.
+ call_to_action_text: 'Finaliser la création de mon compte' + bottom_section: | +Suivez les instructions sur le site pour finaliser la création de votre compte.