Skip to content

Commit b692ba4

Browse files
quentin.desabremarien-probesys
authored andcommitted
fix: Use the user locale to translate the emails
1 parent 0b95459 commit b692ba4

File tree

5 files changed

+133
-51
lines changed

5 files changed

+133
-51
lines changed

app/src/Command/ReportSendMailCommand.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Entity\Msgrcpt;
77
use App\Amavis\MessageStatus;
88
use App\Repository\MsgrcptSearchRepository;
9+
use App\Service\LocaleService;
910
use App\Service\MessageService;
1011
use Doctrine\Persistence\ManagerRegistry;
1112
use Symfony\Component\Console\Attribute\AsCommand;
@@ -38,6 +39,7 @@ public function __construct(
3839
private MsgrcptSearchRepository $msgrcptSearchRepository,
3940
private MessageService $messageService,
4041
private UrlGeneratorInterface $urlGenerator,
42+
private LocaleService $localeService,
4143
) {
4244
parent::__construct();
4345
}
@@ -80,7 +82,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8082
if (!$from) {
8183
$from = $this->defaultMailFrom;
8284
}
83-
$fromName = $this->translator->trans('Entities.Report.mailFromName');
85+
86+
$locale = $this->localeService->getUserLocale($user);
87+
$fromName = $this->translator->trans('Entities.Report.mailFromName', locale: $locale);
88+
8489
$fromAddress = new Address($from, $fromName);
8590

8691
$mailTo = $user->getEmail();
@@ -94,8 +99,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9499
$bodyTextPlain = preg_replace('/<br(\s+)?\/?>/i', "\n", $body);
95100
$bodyTextPlain = strip_tags($bodyTextPlain);
96101

102+
$subject = $this->translator->trans('Message.Report.defaultMailSubject', locale: $locale) . $mailTo;
103+
97104
$message = new Email();
98-
$message->subject($this->translator->trans('Message.Report.defaultMailSubject') . $mailTo)
105+
$message->subject($subject)
99106
->from($fromAddress)
100107
->to($toAddress)
101108
->html($body)->text(strip_tags($bodyTextPlain));
@@ -140,16 +147,18 @@ private function createEmailContent(User $user, array $untreatedMessageRecipient
140147
$nbSpammed = $this->msgrcptSearchRepository->countByType($user, MessageStatus::SPAMMED);
141148

142149
$domain = $user->getDomain();
150+
$locale = $this->localeService->getUserLocale($user);
143151

144152
if ($domain && !empty($domain->getMessageAlert())) {
145153
$body = $domain->getMessageAlert();
146154
} else {
147-
$body = $this->translator->trans('Message.Report.defaultAlertMailContent');
155+
$body = $this->translator->trans('Message.Report.defaultAlertMailContent', locale: $locale);
148156
}
149157

150158
$tableMessages = $this->twig->render('report/table_mail_msgs.html.twig', [
151159
'untreatedMessageRecipients' => $untreatedMessageRecipients,
152160
'user' => $user,
161+
'locale' => $locale,
153162
]);
154163

155164
$url = $this->urlGenerator->generate('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);

app/src/Command/SendAuthMailRequestCommand.php

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use App\Repository\MsgsRepository;
1212
use App\Service\CryptEncryptService;
1313
use App\Service\LogService;
14+
use App\Service\LocaleService;
1415
use Doctrine\ORM\EntityManagerInterface;
1516
use Symfony\Component\Console\Attribute\AsCommand;
1617
use Symfony\Component\Console\Command\Command;
@@ -42,6 +43,7 @@ public function __construct(
4243
private CryptEncryptService $cryptEncryptService,
4344
private MailerInterface $mailer,
4445
private UrlGeneratorInterface $urlGenerator,
46+
private LocaleService $localeService,
4547
#[Autowire(param: 'app.amavisd-release')]
4648
public readonly string $amavisdRelease,
4749
#[Autowire(param: 'app.domain_mail_authentification_sender')]
@@ -124,10 +126,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
124126
continue;
125127
}
126128

129+
$maddr = $messageRecipients[0]->getRid();
130+
$user = null;
131+
if ($maddr) {
132+
$user = $userRepository->findOneBy(['email' => $maddr->getEmailClear()]);
133+
}
134+
127135
$mailFrom = $this->getMailFrom($domain);
128136
$fromName = $this->getMailFromName($messageRecipients[0]);
129-
$mailBody = $this->createAuthEmailContent($domain, $message, $messageRecipients);
130-
$email = $this->createAuthEmail($message, $mailFrom, $fromName, $mailBody);
137+
138+
$mailBody = $this->createAuthEmailContent($domain, $message, $messageRecipients, $user);
139+
$email = $this->createAuthEmail($message, $mailFrom, $fromName, $mailBody, $user);
131140

132141
if ($email === null) {
133142
continue;
@@ -140,7 +149,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
140149
$message->getMailIdAsString(),
141150
$mailBody['html_body']
142151
);
143-
$subject = $this->getSubject($message);
152+
$subject = $this->getSubject($message, $user);
144153
$output->writeln(
145154
date('Y-m-d H:i:s')
146155
. "\t{$fromName} <{$mailFrom}>"
@@ -165,8 +174,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
165174
* @param Msgrcpt[] $messageRecipients
166175
* @return string[]
167176
*/
168-
private function createAuthEmailContent(Domain $domain, Msgs $msg, array $messageRecipients): array
177+
private function createAuthEmailContent(Domain $domain, Msgs $msg, array $messageRecipients, ?User $user): array
169178
{
179+
$locale = $this->localeService->getUserLocale($user);
180+
170181
$token = $this->cryptEncryptService->encrypt(
171182
$msg->getMailIdAsString()
172183
. '%%%' . $msg->getSecretId()
@@ -180,7 +191,7 @@ private function createAuthEmailContent(Domain $domain, Msgs $msg, array $messag
180191
if (!empty($domain->getMailmessage())) {
181192
$body = $domain->getMailmessage();
182193
} else {
183-
$body = $this->translator->trans('Message.Captcha.defaultMailContent');
194+
$body = $this->translator->trans('Message.Captcha.defaultMailContent', locale: $locale);
184195
}
185196

186197
$recipientsMailAdresses = array_map(function (Msgrcpt $recipient) {
@@ -212,12 +223,14 @@ private function createAuthEmailContent(Domain $domain, Msgs $msg, array $messag
212223
/**
213224
* Set the subject of the mail send captcha from original subject
214225
*/
215-
private function getSubject(Msgs $msg): string
226+
private function getSubject(Msgs $msg, ?User $user): string
216227
{
228+
$locale = $this->localeService->getUserLocale($user);
229+
217230
if ($msg->getSubject()) {
218231
$subject = 'Re : ' . $msg->getSubject();
219232
} else {
220-
$subject = $this->translator->trans('Message.Captcha.defaultMailSubject');
233+
$subject = $this->translator->trans('Message.Captcha.defaultMailSubject', locale: $locale);
221234
}
222235
return $subject;
223236
}
@@ -230,11 +243,13 @@ private function createAuthEmail(
230243
Msgs $message,
231244
string $mailFrom,
232245
?string $fromName,
233-
array $body
246+
array $body,
247+
?User $user,
234248
): ?Email {
249+
$locale = $this->localeService->getUserLocale($user);
235250
$mailTo = $message->getSid()->getEmailClear();
236251
try {
237-
$subject = $this->getSubject($message);
252+
$subject = $this->getSubject($message, $user);
238253
$email = new Email();
239254

240255
$fromAddress = $fromName ? new Address($mailFrom, $fromName) : new Address($mailFrom);

app/src/MessageHandler/CreateAlertMessageHandler.php

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use App\Entity\User;
1010
use App\Entity\Domain;
1111
use App\Entity\Maddr;
12+
use App\Service\LocaleService;
1213
use Doctrine\ORM\EntityManagerInterface;
1314
use Symfony\Component\Console\Output\ConsoleOutput;
1415
use Symfony\Component\Mailer\MailerInterface;
@@ -25,18 +26,21 @@ class CreateAlertMessageHandler
2526
private string $defaultMailFrom;
2627
private TranslatorInterface $translator;
2728
private MailerInterface $mailer;
29+
private LocaleService $localeService;
2830

2931
public function __construct(
3032
EntityManagerInterface $entityManager,
3133
ParameterBagInterface $params,
3234
TranslatorInterface $translator,
3335
MailerInterface $mailer,
36+
LocaleService $localeService,
3437
) {
3538
$this->entityManager = $entityManager;
3639
$this->output = new ConsoleOutput();
3740
$this->defaultMailFrom = $params->get('app.domain_mail_authentification_sender');
3841
$this->translator = $translator;
3942
$this->mailer = $mailer;
43+
$this->localeService = $localeService;
4044
}
4145

4246
public function __invoke(CreateAlertMessage $message): void
@@ -94,14 +98,8 @@ private function handleOutMsg(CreateAlertMessage $message): void
9498
->getResult();
9599

96100
foreach ($users as $user) {
97-
// Set the locale for the translator
98-
if ($user->getPreferedLang() !== null) {
99-
$locale = $user->getPreferedLang();
100-
} elseif ($user->getDomain() && $user->getDomain()->getDefaultLang() !== null) {
101-
$locale = $user->getDomain()->getDefaultLang();
102-
} else {
103-
$locale = 'fr';
104-
}
101+
// Get the locale for the user using LocaleService
102+
$locale = $this->localeService->getUserLocale($user);
105103

106104
// if $user has ROLE_ADMIN then check if they are an admin for the concerned domain
107105
if ($user && in_array('ROLE_ADMIN', $user->getRoles())) {
@@ -168,14 +166,8 @@ private function handleOutMsg(CreateAlertMessage $message): void
168166
);
169167
} elseif ($target === 'user') {
170168
if ($senderUser) {
171-
// Set the locale for the translator
172-
if ($senderUser->getPreferedLang() !== null) {
173-
$locale = $senderUser->getPreferedLang();
174-
} elseif ($senderUser->getDomain() && $senderUser->getDomain()->getDefaultLang() !== null) {
175-
$locale = $senderUser->getDomain()->getDefaultLang();
176-
} else {
177-
$locale = 'fr';
178-
}
169+
// Get the locale for the user using LocaleService
170+
$locale = $this->localeService->getUserLocale($senderUser);
179171

180172
if ($senderUser->getDomain()->getSendUserAlerts() === false) {
181173
$this->output->writeln('Alerts disabled for user: ' . $senderUser->getId());
@@ -272,14 +264,8 @@ private function handleSqlLimitReport(CreateAlertMessage $message): void
272264

273265
// Create a single alert for all admins and superadmins
274266
foreach ($users as $user) {
275-
// Set the locale for the translator
276-
if ($user->getPreferedLang() !== null) {
277-
$locale = $user->getPreferedLang();
278-
} elseif ($user->getDomain() && $user->getDomain()->getDefaultLang() !== null) {
279-
$locale = $user->getDomain()->getDefaultLang();
280-
} else {
281-
$locale = 'fr';
282-
}
267+
// Get the locale for the user using LocaleService
268+
$locale = $this->localeService->getUserLocale($user);
283269

284270
// Collect all sender users' email addresses
285271
$senderEmails = [];
@@ -361,17 +347,8 @@ private function handleSqlLimitReport(CreateAlertMessage $message): void
361347
'email' => $fromAddr,
362348
]);
363349
if ($senderUser) {
364-
// Set the locale for the translator
365-
if ($senderUser->getPreferedLang() !== null) {
366-
$locale = $senderUser->getPreferedLang();
367-
} elseif (
368-
$senderUser->getDomain() &&
369-
$senderUser->getDomain()->getDefaultLang() !== null
370-
) {
371-
$locale = $senderUser->getDomain()->getDefaultLang();
372-
} else {
373-
$locale = 'fr';
374-
}
350+
// Get the locale for the user using LocaleService
351+
$locale = $this->localeService->getUserLocale($senderUser);
375352

376353
$processedSenders[$fromAddr] = true;
377354

app/src/Service/LocaleService.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace App\Service;
4+
5+
use App\Entity\User;
6+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
7+
8+
/**
9+
* @phpstan-type LocaleCode key-of<self::SUPPORTED_LOCALES>
10+
*/
11+
class LocaleService
12+
{
13+
public const SUPPORTED_LOCALES = [
14+
'en' => 'English',
15+
'fr' => 'Français',
16+
];
17+
18+
/** @var LocaleCode */
19+
private string $defaultLocale;
20+
21+
/**
22+
* @return array<LocaleCode>
23+
*/
24+
public static function getSupportedLocalesCodes(): array
25+
{
26+
return array_keys(self::SUPPORTED_LOCALES);
27+
}
28+
29+
public function __construct(
30+
#[Autowire(env: 'DEFAULT_LOCALE')]
31+
string $defaultLocale,
32+
) {
33+
if ($this->isAvailable($defaultLocale)) {
34+
/** @var LocaleCode $defaultLocale */
35+
$this->defaultLocale = $defaultLocale;
36+
} else {
37+
$this->defaultLocale = 'en';
38+
}
39+
}
40+
41+
/**
42+
* @return LocaleCode
43+
*/
44+
public function getDefaultLocale(): string
45+
{
46+
return $this->defaultLocale;
47+
}
48+
49+
public function isAvailable(string $locale): bool
50+
{
51+
return isset(self::SUPPORTED_LOCALES[$locale]);
52+
}
53+
54+
/**
55+
* Get the locale for a user based on their preferences
56+
* Priority: User's preferred lang > Domain's default lang > Default locale
57+
*
58+
* @return LocaleCode
59+
*/
60+
public function getUserLocale(?User $user): string
61+
{
62+
if ($user === null) {
63+
return $this->defaultLocale;
64+
}
65+
66+
if ($user->getPreferedLang() !== null && $this->isAvailable($user->getPreferedLang())) {
67+
/** @var LocaleCode $locale */
68+
$locale = $user->getPreferedLang();
69+
return $locale;
70+
}
71+
72+
$domain = $user->getDomain();
73+
if ($domain && $domain->getDefaultLang() !== null && $this->isAvailable($domain->getDefaultLang())) {
74+
/** @var LocaleCode $locale */
75+
$locale = $domain->getDefaultLang();
76+
return $locale;
77+
}
78+
79+
return $this->defaultLocale;
80+
}
81+
}

app/templates/report/table_mail_msgs.html.twig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<td width="100" style="min-width: 100px;">
1616
<div style="width: 100px;">
1717
<a href="{{ url('portal_message_authorized',{'token':token,'partitionTag':messageRecipient.partitionTag,'mailId':messageRecipient.getMailIdAsString(),'recipientId':messageRecipient.rid.id}) }}"
18-
title={{ 'Message.Actions.AutorizedSender'|trans() }} style="font-size:16px;
18+
title={{ 'Message.Actions.AutorizedSender'|trans(locale: locale) }} style="font-size:16px;
1919
-moz-border-radius: 5px;
2020
-webkit-border-radius: 5px;
2121
border-radius: 5px;
@@ -26,15 +26,15 @@
2626
color: #fff;
2727
text-decoration: none;
2828
">
29-
{{ 'Message.Actions.Autorized'|trans() }}
29+
{{ 'Message.Actions.Autorized'|trans(locale: locale) }}
3030
</a>
3131
</div>
3232
</td>
3333

3434
<td width="100" style="min-width: 100px;">
3535
<div style="width: 100px;">
3636
<a href="{{ url('portal_message_restore',{'token':token,'partitionTag':messageRecipient.partitionTag,'mailId':messageRecipient.getMailIdAsString(),'recipientId':messageRecipient.rid.id}) }}"
37-
title="{{ 'Message.Actions.RestoreMessage'|trans() }}" style="font-size:16px;
37+
title="{{ 'Message.Actions.RestoreMessage'|trans(locale: locale) }}" style="font-size:16px;
3838
-moz-border-radius: 5px;
3939
-webkit-border-radius: 5px;
4040
border-radius: 5px;
@@ -44,7 +44,7 @@
4444
color: #fff;
4545
text-decoration: none;
4646
">
47-
{{ 'Message.Actions.Restore'|trans() }}</a>
47+
{{ 'Message.Actions.Restore'|trans(locale: locale) }}</a>
4848
</div>
4949
</td>
5050

0 commit comments

Comments
 (0)