diff --git a/classes/i18n/Locale.php b/classes/i18n/Locale.php index 24335cc75f9..663e0890edd 100644 --- a/classes/i18n/Locale.php +++ b/classes/i18n/Locale.php @@ -122,11 +122,10 @@ public function getLocale(): string return $this->locale; } $request = $this->_getRequest(); - $supportedLocales = array_values($this->_getSupportedLocales()); $locale = $request->getUserVar('setLocale') ?: (SessionManager::hasSession() ? SessionManager::getManager()->getUserSession()->getSessionVar('currentLocale') : null) ?: $request->getCookieVar('currentLocale') - ?: $request->getPreferredLanguage(count($supportedLocales) ? $supportedLocales : [LocaleInterface::DEFAULT_LOCALE]); + ?: $this->_getPreferredLocale(); $this->setLocale($locale); return $this->locale; } @@ -445,4 +444,19 @@ private function _getSupportedLocales(): array ?? array_map(fn (LocaleMetadata $locale) => $locale->locale, $this->getLocales()); return $this->supportedLocales = array_combine($locales, $locales); } + + /** + * Retrieve the preferred user locale from our supported locales using the Accept-Language header + * If there's no match, it falls back to the server's primary locale + */ + private function _getPreferredLocale(): ?string + { + $serverPreference = $this->getPrimaryLocale() ?: LocaleInterface::DEFAULT_LOCALE; + $supportedLocales = array_values($this->_getSupportedLocales()); + // Move the server preference to the top, in case the user preference doesn't match with the supported locales, the server one will be picked + if (is_int($index = array_search($serverPreference, $supportedLocales))) { + array_splice($supportedLocales, $index, 1); + } + return $this->_getRequest()->getPreferredLanguage([$serverPreference, ...$supportedLocales]); + } }