diff --git a/app.php b/app.php index 7680c71c..67c95210 100644 --- a/app.php +++ b/app.php @@ -69,5 +69,11 @@ $errorMiddleware = $app->addErrorMiddleware(true, false, false); $errorMiddleware->setDefaultErrorHandler( new \Grocy\Controllers\ExceptionController($app, $container) ); - +if (GROCY_MODE === 'production') +{ + $app->add(new \Grocy\Middleware\LocaleMiddleware($container)); +} +else { + define(GROCY_LOCALE, GROCY_CULTURE); +} $app->run(); diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 8538fe6c..a24b9363 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -110,7 +110,7 @@ class BaseController protected function getLocalizationService() { - return LocalizationService::getInstance(GROCY_CULTURE); + return LocalizationService::getInstance(GROCY_LOCALE); } protected function getApplicationservice() diff --git a/middleware/LocaleMiddleware.php b/middleware/LocaleMiddleware.php new file mode 100644 index 00000000..fd3fe5cb --- /dev/null +++ b/middleware/LocaleMiddleware.php @@ -0,0 +1,65 @@ +getLocale($request); + define('GROCY_LOCALE', $locale); + return $handler->handle($request); + } + + protected function getLocale(Request $request) + { + $cookies = $request->getCookieParams(); + if (isset($cookies[self::LOCALE_COOKIE_NAME])) { + $locale = $cookies[self::LOCALE_COOKIE_NAME]; + if (in_array($locale, scandir(__DIR__ . '/../localization'))) { + return $locale; + } + } + $langs = join(',', $request->getHeader('Accept-Language')); + + // src: https://gist.github.com/spolischook/0cde9c6286415cddc088 + $prefLocales = array_reduce( + explode(',', $langs), + function ($res, $el) { + list($l, $q) = array_merge(explode(';q=', $el), [1]); + $res[$l] = (float) $q; + return $res; + }, []); + arsort($prefLocales); + + $availableLocales = scandir(__DIR__ . '/../localization'); + foreach ($prefLocales as $locale => $q) { + if(in_array($locale, $availableLocales)) + { + return $locale; + } + // e.g. en_GB + if(in_array(substr($locale, 0, 5), $availableLocales)) + { + return substr($locale, 0, 5); + } + // e.g: cs + // or en + // or de + if(in_array(substr($locale, 0, 2), $availableLocales)) + { + return substr($locale, 0, 2); + } + } + return GROCY_CULTURE; + } +} diff --git a/public/js/grocy.js b/public/js/grocy.js index 91e38909..c87d7d5a 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -670,3 +670,10 @@ $(Grocy.UserPermissions).each(function (index, item) $('.permission-'+item.permission_name).addClass('disabled').addClass('not-allowed'); } }); +Grocy.SetLanguage = function (lang) { + var expires = new Date(); + // Expires "never" (= 30 years) + expires.setDate(expires.getDate() + 365*30); + document.cookie = "LOCALE=" + lang + "; SameSite=Lax; expires="+expires.toUTCString(); + location.reload(); +} diff --git a/services/BaseService.php b/services/BaseService.php index 781fd339..b5c98df0 100644 --- a/services/BaseService.php +++ b/services/BaseService.php @@ -35,7 +35,7 @@ class BaseService protected function getLocalizationService() { - return LocalizationService::getInstance(GROCY_CULTURE); + return LocalizationService::getInstance(GROCY_LOCALE); } protected function getStockservice() diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index 0796eaae..529da314 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -1,5 +1,5 @@ - + @@ -52,7 +52,7 @@ Grocy.BaseUrl = '{{ $U('/') }}'; Grocy.CurrentUrlRelative = "/" + window.location.href.split('?')[0].replace(Grocy.BaseUrl, ""); Grocy.ActiveNav = '@yield('activeNav', '')'; - Grocy.Culture = '{{ GROCY_CULTURE }}'; + Grocy.Culture = '{{ GROCY_LOCALE }}'; Grocy.Currency = '{{ GROCY_CURRENCY }}'; Grocy.CalendarFirstDayOfWeek = '{{ GROCY_CALENDAR_FIRST_DAY_OF_WEEK }}'; Grocy.CalendarShowWeekNumbers = {{ BoolToString(GROCY_CALENDAR_SHOW_WEEK_OF_YEAR) }};