mirror of
https://github.com/grocy/grocy.git
synced 2026-05-12 16:00:10 +02:00
Optimized locale handling
This commit is contained in:
parent
4307bbf5d5
commit
c3122609f2
8
app.php
8
app.php
|
|
@ -105,15 +105,7 @@ if (!empty(GROCY_BASE_PATH))
|
||||||
$app->setBasePath(GROCY_BASE_PATH);
|
$app->setBasePath(GROCY_BASE_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GROCY_MODE === 'production' || GROCY_MODE === 'dev')
|
|
||||||
{
|
|
||||||
$app->add(new LocaleMiddleware($container, $app->getResponseFactory()));
|
$app->add(new LocaleMiddleware($container, $app->getResponseFactory()));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
define('GROCY_LOCALE', GROCY_DEFAULT_LOCALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
$authMiddlewareClass = GROCY_AUTH_CLASS;
|
||||||
$app->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
$app->add(new $authMiddlewareClass($container, $app->getResponseFactory()));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
|
|
||||||
- Fixed accent insensitive searching using the general table search field was broken
|
- Fixed accent insensitive searching using the general table search field was broken
|
||||||
- Fixed that it wasn't possible to log in using passwords containing special escape sequences (e.g. `<<`)
|
- Fixed that it wasn't possible to log in using passwords containing special escape sequences (e.g. `<<`)
|
||||||
|
- Fixed that the initially created location and quantity units weren't localized (only applies to new installations)
|
||||||
|
|
||||||
### API
|
### API
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@ Setting('MODE', 'production');
|
||||||
|
|
||||||
// The directory name of one of the available localization folders
|
// The directory name of one of the available localization folders
|
||||||
// in the "/localization" directory (e.g. "en" or "de")
|
// in the "/localization" directory (e.g. "en" or "de")
|
||||||
|
// Grocy uses the first available locale / setting in this order
|
||||||
|
// 1. Browser prefered locale
|
||||||
|
// 2. The one set in user settings
|
||||||
|
// 3. The one defined here below
|
||||||
Setting('DEFAULT_LOCALE', 'en');
|
Setting('DEFAULT_LOCALE', 'en');
|
||||||
|
|
||||||
// This is used to define the first day of a week for calendar views,
|
// This is used to define the first day of a week for calendar views,
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,6 @@ msgstr ""
|
||||||
msgid "Tinned food cupboard"
|
msgid "Tinned food cupboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Fridge"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Piece"
|
|
||||||
msgid_plural "Pieces"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
||||||
|
|
||||||
msgid "Pack"
|
|
||||||
msgid_plural "Packs"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
||||||
|
|
||||||
msgid "Glass"
|
msgid "Glass"
|
||||||
msgid_plural "Glasses"
|
msgid_plural "Glasses"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
|
|
|
||||||
|
|
@ -2473,3 +2473,19 @@ msgstr ""
|
||||||
|
|
||||||
msgid "After this product was once in stock and when the desired quantity unit cannot be selected here, first create a corresponding unit conversion"
|
msgid "After this product was once in stock and when the desired quantity unit cannot be selected here, first create a corresponding unit conversion"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# Default / initially created location
|
||||||
|
msgid "Fridge"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# Default / initially created quantity unit
|
||||||
|
msgid "Piece"
|
||||||
|
msgid_plural "Pieces"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
# Default / initially created quantity unit
|
||||||
|
msgid "Pack"
|
||||||
|
msgid_plural "Packs"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,24 @@ class LocaleMiddleware extends BaseMiddleware
|
||||||
{
|
{
|
||||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||||
{
|
{
|
||||||
$locale = $this->getLocale($request);
|
define('GROCY_LOCALE', $this->GetLocale($request));
|
||||||
define('GROCY_LOCALE', $locale);
|
|
||||||
return $handler->handle($request);
|
return $handler->handle($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getLocale(Request $request)
|
private function GetLocale(Request $request)
|
||||||
{
|
{
|
||||||
|
// demo and prerelease modes are fixed to the default locale
|
||||||
|
if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
|
||||||
|
{
|
||||||
|
return GROCY_DEFAULT_LOCALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer user setting
|
||||||
if (defined('GROCY_AUTHENTICATED') && GROCY_AUTHENTICATED)
|
if (defined('GROCY_AUTHENTICATED') && GROCY_AUTHENTICATED)
|
||||||
{
|
{
|
||||||
$locale = UsersService::GetInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
|
$locale = UsersService::GetInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
|
||||||
|
|
||||||
if (isset($locale) && !empty($locale))
|
if (isset($locale) && !empty($locale))
|
||||||
{
|
{
|
||||||
if (in_array($locale, scandir(__DIR__ . '/../localization')))
|
if (in_array($locale, scandir(__DIR__ . '/../localization')))
|
||||||
|
|
@ -30,11 +38,9 @@ class LocaleMiddleware extends BaseMiddleware
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$langs = implode(',', $request->getHeader('Accept-Language'));
|
// Otherwise use Browser prefered locale
|
||||||
|
$browserPreferedLocales = array_reduce(
|
||||||
// Src: https://gist.github.com/spolischook/0cde9c6286415cddc088
|
explode(',', implode(',', $request->getHeader('Accept-Language'))),
|
||||||
$prefLocales = array_reduce(
|
|
||||||
explode(',', $langs),
|
|
||||||
function ($res, $el)
|
function ($res, $el)
|
||||||
{
|
{
|
||||||
list($l, $q) = array_merge(explode(';q=', $el), [1]);
|
list($l, $q) = array_merge(explode(';q=', $el), [1]);
|
||||||
|
|
@ -43,10 +49,10 @@ class LocaleMiddleware extends BaseMiddleware
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
arsort($prefLocales);
|
arsort($browserPreferedLocales);
|
||||||
|
|
||||||
$availableLocales = scandir(__DIR__ . '/../localization');
|
$availableLocales = scandir(__DIR__ . '/../localization');
|
||||||
foreach ($prefLocales as $locale => $q)
|
foreach ($browserPreferedLocales as $locale => $q)
|
||||||
{
|
{
|
||||||
if (in_array($locale, $availableLocales))
|
if (in_array($locale, $availableLocales))
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +72,7 @@ class LocaleMiddleware extends BaseMiddleware
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Falback to default locale
|
||||||
return GROCY_DEFAULT_LOCALE;
|
return GROCY_DEFAULT_LOCALE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ class DatabaseMigrationService extends BaseService
|
||||||
|
|
||||||
public function MigrateDatabase()
|
public function MigrateDatabase()
|
||||||
{
|
{
|
||||||
define('GROCY_DATABASE_MIGRATIONS_RUNNING', true);
|
|
||||||
|
|
||||||
DatabaseService::GetInstance()->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))");
|
DatabaseService::GetInstance()->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))");
|
||||||
|
|
||||||
$migrationFiles = [];
|
$migrationFiles = [];
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ use Gettext\Translator;
|
||||||
|
|
||||||
class LocalizationService extends BaseService
|
class LocalizationService extends BaseService
|
||||||
{
|
{
|
||||||
public function __construct(string $culture)
|
public function __construct(string $locale)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->Culture = $culture;
|
$this->Locale = $locale;
|
||||||
$this->LoadLocalizations($culture);
|
$this->LoadLocalizations($locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $Po;
|
protected $Po;
|
||||||
|
|
@ -22,8 +22,8 @@ class LocalizationService extends BaseService
|
||||||
protected $PotMain;
|
protected $PotMain;
|
||||||
protected $Translator;
|
protected $Translator;
|
||||||
protected $TranslatorQu;
|
protected $TranslatorQu;
|
||||||
protected $Culture;
|
protected $Locale;
|
||||||
private static $instanceMap = [];
|
private static $InstanceMap = [];
|
||||||
|
|
||||||
public function CheckAndAddMissingTranslationToPot($text)
|
public function CheckAndAddMissingTranslationToPot($text)
|
||||||
{
|
{
|
||||||
|
|
@ -112,31 +112,24 @@ class LocalizationService extends BaseService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetInstance(string $culture = '')
|
public static function GetInstance(string $locale = '')
|
||||||
{
|
{
|
||||||
if (empty($culture))
|
if (empty($locale))
|
||||||
{
|
{
|
||||||
if (defined('GROCY_LOCALE'))
|
$locale = GROCY_LOCALE;
|
||||||
{
|
|
||||||
$culture = GROCY_LOCALE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$culture = GROCY_DEFAULT_LOCALE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($culture, self::$instanceMap))
|
if (!in_array($locale, self::$InstanceMap))
|
||||||
{
|
{
|
||||||
self::$instanceMap[$culture] = new self($culture);
|
self::$InstanceMap[$locale] = new self($locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$instanceMap[$culture];
|
return self::$InstanceMap[$locale];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function LoadLocalizations()
|
private function LoadLocalizations()
|
||||||
{
|
{
|
||||||
$culture = $this->Culture;
|
$locale = $this->Locale;
|
||||||
|
|
||||||
if (GROCY_MODE === 'dev')
|
if (GROCY_MODE === 'dev')
|
||||||
{
|
{
|
||||||
|
|
@ -153,47 +146,46 @@ class LocalizationService extends BaseService
|
||||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/demo_data.pot'));
|
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/demo_data.pot'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Po = Translations::fromPoFile(__DIR__ . "/../localization/$culture/strings.po");
|
$this->Po = Translations::fromPoFile(__DIR__ . "/../localization/$locale/strings.po");
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/chore_assignment_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/chore_assignment_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_assignment_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/chore_assignment_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/component_translations.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/component_translations.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/component_translations.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/component_translations.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/stock_transaction_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/stock_transaction_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/stock_transaction_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/stock_transaction_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/chore_period_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/chore_period_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_period_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/chore_period_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/userfield_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/userfield_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/userfield_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/userfield_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/permissions.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/permissions.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/permissions.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/permissions.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/locales.po"))
|
if (file_exists(__DIR__ . "/../localization/$locale/locales.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/locales.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/locales.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load demo data localizations also during database migrations since e.g. default quantity units are created localized by that
|
if (GROCY_MODE !== 'production' && file_exists(__DIR__ . "/../localization/$locale/demo_data.po"))
|
||||||
if ((GROCY_MODE !== 'production' || defined('GROCY_DATABASE_MIGRATIONS_RUNNING')) && file_exists(__DIR__ . "/../localization/$culture/demo_data.po"))
|
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/demo_data.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$locale/demo_data.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Translator = new Translator();
|
$this->Translator = new Translator();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user