Skip to content

Commit cf31ae1

Browse files
Merge pull request #56665 from nextcloud/backport/55473/stable31
[stable31] fix(CalDAV): imip set language per user
2 parents 7de2181 + 3d44ec4 commit cf31ae1

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

apps/dav/lib/CalDAV/Schedule/IMipPlugin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function schedule(Message $iTipMessage) {
165165
$iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email';
166166
return;
167167
}
168-
$this->imipService->setL10n($attendee);
168+
$this->imipService->setL10nFromAttendee($attendee);
169169

170170
// Build the sender name.
171171
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property

apps/dav/lib/CalDAV/Schedule/IMipService.php

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OCP\IConfig;
1515
use OCP\IDBConnection;
1616
use OCP\IL10N;
17+
use OCP\IUserManager;
1718
use OCP\L10N\IFactory as L10NFactory;
1819
use OCP\Mail\IEMailTemplate;
1920
use OCP\Security\ISecureRandom;
@@ -44,6 +45,7 @@ public function __construct(
4445
private ISecureRandom $random,
4546
private L10NFactory $l10nFactory,
4647
private ITimeFactory $timeFactory,
48+
private readonly IUserManager $userManager,
4749
) {
4850
$language = $this->l10nFactory->findGenericLanguage();
4951
$locale = $this->l10nFactory->findLocale($language);
@@ -870,18 +872,35 @@ public function getLastOccurrence(VCalendar $vObject) {
870872
}
871873

872874
/**
873-
* @param Property|null $attendee
875+
* @param Property $attendee
874876
*/
875-
public function setL10n(?Property $attendee = null) {
876-
if ($attendee === null) {
877-
return;
877+
public function setL10nFromAttendee(Property $attendee) {
878+
$language = null;
879+
$locale = null;
880+
// check if the attendee is a system user
881+
$userAddress = $attendee->getValue();
882+
if (str_starts_with($userAddress, 'mailto:')) {
883+
$userAddress = substr($userAddress, 7);
878884
}
879-
880-
$lang = $attendee->offsetGet('LANGUAGE');
881-
if ($lang instanceof Parameter) {
882-
$lang = $lang->getValue();
883-
$this->l10n = $this->l10nFactory->get('dav', $lang);
885+
$users = $this->userManager->getByEmail($userAddress);
886+
if ($users !== []) {
887+
$user = array_shift($users);
888+
$language = $this->config->getUserValue($user->getUID(), 'core', 'lang', null);
889+
$locale = $this->config->getUserValue($user->getUID(), 'core', 'locale', null);
884890
}
891+
// fallback to attendee LANGUAGE parameter if language not set
892+
if ($language === null && isset($attendee['LANGUAGE']) && $attendee['LANGUAGE'] instanceof Parameter) {
893+
$language = $attendee['LANGUAGE']->getValue();
894+
}
895+
// fallback to system language if language not set
896+
if ($language === null) {
897+
$language = $this->l10nFactory->findGenericLanguage();
898+
}
899+
// fallback to system locale if locale not set
900+
if ($locale === null) {
901+
$locale = $this->l10nFactory->findLocale($language);
902+
}
903+
$this->l10n = $this->l10nFactory->get('dav', $language, $locale);
885904
}
886905

887906
/**

apps/dav/tests/unit/CalDAV/Schedule/IMipServiceTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\AppFramework\Utility\ITimeFactory;
1717
use OCP\IConfig;
1818
use OCP\IDBConnection;
19+
use OCP\IUserManager;
1920
use OCP\L10N\IFactory as L10NFactory;
2021
use OCP\Security\ISecureRandom;
2122
use PHPUnit\Framework\MockObject\MockObject;
@@ -48,6 +49,9 @@ class IMipServiceTest extends TestCase {
4849
/** @var IMipService */
4950
private $service;
5051

52+
/** @var IUserManager|MockObject */
53+
private $userManager;
54+
5155
/** @var VCalendar */
5256
private $vCalendar1a;
5357
/** @var VCalendar */
@@ -67,6 +71,7 @@ protected function setUp(): void {
6771
$this->l10nFactory = $this->createMock(L10NFactory::class);
6872
$this->l10n = $this->createMock(LazyL10N::class);
6973
$this->timeFactory = $this->createMock(ITimeFactory::class);
74+
$this->userManager = $this->createMock(IUserManager::class);
7075
$this->l10nFactory->expects(self::once())
7176
->method('findGenericLanguage')
7277
->willReturn('en');
@@ -80,11 +85,13 @@ protected function setUp(): void {
8085
$this->db,
8186
$this->random,
8287
$this->l10nFactory,
83-
$this->timeFactory
88+
$this->timeFactory,
89+
$this->userManager
8490
);
8591

8692
// construct calendar with a 1 hour event and same start/end time zones
8793
$this->vCalendar1a = new VCalendar();
94+
/** @var \Sabre\VObject\Component\VEvent $vEvent */
8895
$vEvent = $this->vCalendar1a->add('VEVENT', []);
8996
$vEvent->UID->setValue('96a0e6b1-d886-4a55-a60d-152b31401dcc');
9097
$vEvent->add('DTSTART', '20240701T080000', ['TZID' => 'America/Toronto']);
@@ -101,6 +108,7 @@ protected function setUp(): void {
101108

102109
// construct calendar with a 1 hour event and different start/end time zones
103110
$this->vCalendar1b = new VCalendar();
111+
/** @var \Sabre\VObject\Component\VEvent $vEvent */
104112
$vEvent = $this->vCalendar1b->add('VEVENT', []);
105113
$vEvent->UID->setValue('96a0e6b1-d886-4a55-a60d-152b31401dcc');
106114
$vEvent->add('DTSTART', '20240701T080000', ['TZID' => 'America/Toronto']);
@@ -118,9 +126,11 @@ protected function setUp(): void {
118126
// construct calendar with a full day event
119127
$this->vCalendar2 = new VCalendar();
120128
// time zone component
129+
/** @var \Sabre\VObject\Component\VTimeZone $vTimeZone */
121130
$vTimeZone = $this->vCalendar2->add('VTIMEZONE');
122131
$vTimeZone->add('TZID', 'America/Toronto');
123132
// event component
133+
/** @var \Sabre\VObject\Component\VEvent $vEvent */
124134
$vEvent = $this->vCalendar2->add('VEVENT', []);
125135
$vEvent->UID->setValue('96a0e6b1-d886-4a55-a60d-152b31401dcc');
126136
$vEvent->add('DTSTART', '20240701');
@@ -138,9 +148,11 @@ protected function setUp(): void {
138148
// construct calendar with a multi day event
139149
$this->vCalendar3 = new VCalendar();
140150
// time zone component
151+
/** @var \Sabre\VObject\Component\VTimeZone $vTimeZone */
141152
$vTimeZone = $this->vCalendar3->add('VTIMEZONE');
142153
$vTimeZone->add('TZID', 'America/Toronto');
143154
// event component
155+
/** @var \Sabre\VObject\Component\VEvent $vEvent */
144156
$vEvent = $this->vCalendar3->add('VEVENT', []);
145157
$vEvent->UID->setValue('96a0e6b1-d886-4a55-a60d-152b31401dcc');
146158
$vEvent->add('DTSTART', '20240701');

0 commit comments

Comments
 (0)