diff --git a/composer.json b/composer.json index c694b2d6..7d7acd65 100644 --- a/composer.json +++ b/composer.json @@ -7,14 +7,16 @@ "php-di/php-di": "^6.0", "rubellum/slim-blade-view": "^0.1.1", "morris/lessql": "^1.0", - "gettext/gettext": "^4.8", + "gettext/gettext": "^5.5.4", "eluceo/ical": "^2.2.0", "erusev/parsedown": "^1.7", "gumlet/php-image-resize": "^2.0", "ezyang/htmlpurifier": "^4.13", "jucksearm/php-barcode": "^1.0", "guzzlehttp/guzzle": "^7.0", - "mike42/escpos-php": "^3.0" + "mike42/escpos-php": "^3.0", + "gettext/translator": "^1.0", + "gettext/json": "^1.0" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 3b3f5444..bddde59e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "35840e48e78e30b63f589addfdb50f92", + "content-hash": "d057a6ab1ad847ba7cb44de95f05a97f", "packages": [ { "name": "doctrine/inflector", @@ -328,35 +328,28 @@ }, { "name": "gettext/gettext", - "version": "v4.8.4", + "version": "v5.5.4", "source": { "type": "git", "url": "https://github.com/php-gettext/Gettext.git", - "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1" + "reference": "77baf40326b4eac0230cd11ee75680969dcbe72a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", - "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", + "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/77baf40326b4eac0230cd11ee75680969dcbe72a", + "reference": "77baf40326b4eac0230cd11ee75680969dcbe72a", "shasum": "" }, "require": { "gettext/languages": "^2.3", - "php": ">=5.4.0" + "php": "^7.2|^8.0" }, "require-dev": { - "illuminate/view": "*", - "phpunit/phpunit": "^4.8|^5.7|^6.5", - "squizlabs/php_codesniffer": "^3.0", - "symfony/yaml": "~2", - "twig/extensions": "*", - "twig/twig": "^1.31|^2.0" - }, - "suggest": { - "illuminate/view": "Is necessary if you want to use the Blade extractor", - "symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator", - "twig/extensions": "Is necessary if you want to use the Twig extractor", - "twig/twig": "Is necessary if you want to use the Twig extractor" + "brick/varexporter": "^0.2.1", + "friendsofphp/php-cs-fixer": "^2.15", + "oscarotero/php-cs-fixer-config": "^1.0", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0" }, "type": "library", "autoload": { @@ -377,7 +370,7 @@ } ], "description": "PHP gettext manager", - "homepage": "https://github.com/oscarotero/Gettext", + "homepage": "https://github.com/php-gettext/Gettext", "keywords": [ "JS", "gettext", @@ -388,24 +381,68 @@ ], "support": { "email": "oom@oscarotero.com", - "issues": "https://github.com/oscarotero/Gettext/issues", - "source": "https://github.com/php-gettext/Gettext/tree/v4.8.4" + "issues": "https://github.com/php-gettext/Gettext/issues", + "source": "https://github.com/php-gettext/Gettext/tree/v5.5.4" }, - "funding": [ + "time": "2020-12-20T13:37:30+00:00" + }, + { + "name": "gettext/json", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-gettext/Json.git", + "reference": "13f0d7c8cdd1fe80515d5c40722e18f568225891" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-gettext/Json/zipball/13f0d7c8cdd1fe80515d5c40722e18f568225891", + "reference": "13f0d7c8cdd1fe80515d5c40722e18f568225891", + "shasum": "" + }, + "require": { + "gettext/gettext": "^5.0.0", + "php": "^7.2|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "oscarotero/php-cs-fixer-config": "^1.0", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gettext\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://paypal.me/oscarotero", - "type": "custom" - }, - { - "url": "https://github.com/oscarotero", - "type": "github" - }, - { - "url": "https://www.patreon.com/misteroom", - "type": "patreon" + "name": "Oscar Otero", + "email": "oom@oscarotero.com", + "homepage": "http://oscarotero.com", + "role": "Developer" } ], - "time": "2021-03-10T19:35:49+00:00" + "description": "Json format for gettext", + "homepage": "https://github.com/php-gettext/Json", + "keywords": [ + "gettext", + "i18n", + "json", + "loader", + "translation" + ], + "support": { + "email": "oom@oscarotero.com", + "issues": "https://github.com/php-gettext/Json/issues", + "source": "https://github.com/php-gettext/Json/tree/v1.0.1" + }, + "time": "2021-01-22T17:59:51+00:00" }, { "name": "gettext/languages", @@ -472,6 +509,66 @@ }, "time": "2019-11-13T10:30:21+00:00" }, + { + "name": "gettext/translator", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-gettext/Translator.git", + "reference": "0a80844789e6a4ffad417d2053bbb56c83b02803" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-gettext/Translator/zipball/0a80844789e6a4ffad417d2053bbb56c83b02803", + "reference": "0a80844789e6a4ffad417d2053bbb56c83b02803", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.15", + "gettext/gettext": "^5.0.0", + "oscarotero/php-cs-fixer-config": "^1.0", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "suggest": { + "gettext/gettext": "Is necessary to load and generate array files used by the translator" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gettext\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oscar Otero", + "email": "oom@oscarotero.com", + "homepage": "http://oscarotero.com", + "role": "Developer" + } + ], + "description": "Gettext translator functions", + "homepage": "https://github.com/php-gettext/Translator", + "keywords": [ + "gettext", + "i18n", + "php", + "translator" + ], + "support": { + "email": "oom@oscarotero.com", + "issues": "https://github.com/php-gettext/Translator/issues", + "source": "https://github.com/php-gettext/Translator/tree/v1.0.1" + }, + "time": "2020-12-01T18:51:46+00:00" + }, { "name": "gumlet/php-image-resize", "version": "2.0.0", diff --git a/package.json b/package.json index e4738510..f73036d4 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "datatables.net-select": "^1.3.1", "datatables.net-select-bs4": "^1.3.1", "fullcalendar": "^3.10.1", - "gettext-translator": "2.1.0", + "gettext-translator": "^3.0.1", "jquery": "3.5.1", "jquery-lazy": "^1.7.11", "jquery-serializejson": "^2.9.0", diff --git a/public/js/grocy.js b/public/js/grocy.js index 9c1a4c7c..7eb781b7 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -231,11 +231,11 @@ U = function(relativePath) return Grocy.BaseUrl.replace(/\/$/, '') + relativePath; } -Grocy.Translator = new Translator(); // Dummy, real instance is loaded async below +Grocy.Translator = new window.translator.default(); // Dummy, real instance is loaded async below Grocy.Api.Get("system/localization-strings?v=" + Grocy.Version, function(response) { - Grocy.Translator = new Translator(response); + Grocy.Translator = new window.translator.default(response); }, function(xhr) { @@ -250,7 +250,7 @@ __t = function(text, ...placeholderValues) Grocy.Api.Post('system/log-missing-localization', { "text": text2 }); } - return Grocy.Translator.__(text, ...placeholderValues) + return Grocy.Translator.gettext(text, ...placeholderValues); } __n = function(number, singularForm, pluralForm) { @@ -260,7 +260,7 @@ __n = function(number, singularForm, pluralForm) Grocy.Api.Post('system/log-missing-localization', { "text": singularForm2 }); } - return Grocy.Translator.n__(singularForm, pluralForm, number, number) + return Grocy.Translator.ngettext(singularForm, pluralForm, number, number); } if (!Grocy.ActiveNav.isEmpty()) diff --git a/services/LocalizationService.php b/services/LocalizationService.php index 1bf1d274..43f3b7b9 100644 --- a/services/LocalizationService.php +++ b/services/LocalizationService.php @@ -2,9 +2,12 @@ namespace Grocy\Services; +use Gettext\Headers; use Gettext\Translation; use Gettext\Translations; use Gettext\Translator; +use Gettext\Loader\PoLoader; +use Gettext\Generator\JsonGenerator; class LocalizationService { @@ -35,9 +38,9 @@ class LocalizationService public function GetPluralCount() { - if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null) + if ($this->Po->getHeaders()->getPluralForm() !== null) { - return $this->Po->getPluralForms()[0]; + return $this->Po->getHeaders()->getPluralForm()[0]; } else { @@ -47,9 +50,9 @@ class LocalizationService public function GetPluralDefinition() { - if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null) + if ($this->Po->getHeaders()->getPluralForm() !== null) { - return $this->Po->getPluralForms()[1]; + return $this->Po->getHeaders()->getPluralForm()[1]; } else { @@ -59,7 +62,7 @@ class LocalizationService public function GetPoAsJsonString() { - return $this->Po->toJsonString(); + return (new JsonGenerator())->generateString($this->Po); } public function __construct(string $culture) @@ -113,69 +116,69 @@ class LocalizationService private function LoadLocalizations() { $culture = $this->Culture; + $loader = new PoLoader(); if (GROCY_MODE === 'dev') { - $this->PotMain = Translations::fromPoFile(__DIR__ . '/../localization/strings.pot'); + $this->PotMain = $loader->loadFile(__DIR__ . '/../localization/strings.pot'); - $this->Pot = Translations::fromPoFile(__DIR__ . '/../localization/chore_period_types.pot'); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/chore_assignment_types.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/component_translations.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/stock_transaction_types.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/strings.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/userfield_types.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/permissions.pot')); - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/locales.pot')); + $this->Pot = $loader->loadFile(__DIR__ . '/../localization/chore_period_types.pot'); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/chore_assignment_types.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/component_translations.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/stock_transaction_types.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/strings.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/userfield_types.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/permissions.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/locales.pot')); if (GROCY_MODE !== 'production') { - $this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/demo_data.pot')); + $this->Pot = $this->Pot->mergeWith($loader->loadFile(__DIR__ . '/../localization/demo_data.pot')); } } - $this->PoUserStrings = new Translations(); - $this->PoUserStrings->setDomain('grocy/userstrings'); + $this->PoUserStrings = Translations::create('grocy'); - $this->Po = Translations::fromPoFile(__DIR__ . "/../localization/$culture/strings.po"); + $this->Po = $loader->loadFile(__DIR__ . "/../localization/$culture/strings.po"); if (file_exists(__DIR__ . "/../localization/$culture/chore_assignment_types.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_assignment_types.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/chore_assignment_types.po")); } if (file_exists(__DIR__ . "/../localization/$culture/component_translations.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/component_translations.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/component_translations.po")); } if (file_exists(__DIR__ . "/../localization/$culture/stock_transaction_types.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/stock_transaction_types.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/stock_transaction_types.po")); } if (file_exists(__DIR__ . "/../localization/$culture/chore_period_types.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_period_types.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/chore_period_types.po")); } if (file_exists(__DIR__ . "/../localization/$culture/userfield_types.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/userfield_types.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/userfield_types.po")); } if (file_exists(__DIR__ . "/../localization/$culture/permissions.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/permissions.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/permissions.po")); } if (file_exists(__DIR__ . "/../localization/$culture/locales.po")) { - $this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/locales.po")); + $this->Po = $this->Po->mergeWith($loader->loadFile(__DIR__ . "/../localization/$culture/locales.po")); } if (GROCY_MODE !== 'production' && 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($loader->loadFile(__DIR__ . "/../localization/$culture/demo_data.po")); } $quantityUnits = null; @@ -192,18 +195,16 @@ class LocalizationService { foreach ($quantityUnits as $quantityUnit) { - $translation = new Translation('', $quantityUnit['name']); - $translation->setTranslation($quantityUnit['name']); - $translation->setPlural($quantityUnit['name_plural']); - $translation->setPluralTranslations(preg_split('/\r\n|\r|\n/', $quantityUnit['plural_forms'])); + $translation = Translation::create($quantityUnit['name'], $quantityUnit['name'], $quantityUnit['name_plural']); + $translation->translate($quantityUnit['name']); + $translation->translatePlural($quantityUnit['name_plural'], ...preg_split('/\r\n|\r|\n/', $quantityUnit['plural_forms'])); - $this->PoUserStrings[] = $translation; + $this->PoUserStrings->add($translation); } $this->Po = $this->Po->mergeWith($this->PoUserStrings); } - $this->Translator = new Translator(); - $this->Translator->loadTranslations($this->Po); + $this->Translator = Translator::createFromTranslations($this->Po); } } diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index 0ee3a4c5..e5d9c7ce 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -700,7 +700,7 @@ - + @if(!empty($__t('summernote_locale') && $__t('summernote_locale') != 'x'))@endif diff --git a/yarn.lock b/yarn.lock index 40741098..6f700440 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1716,12 +1716,10 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -gettext-translator@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/gettext-translator/-/gettext-translator-2.1.0.tgz#946047649b7df4ef00522787bb78792667e4de2f" - integrity sha512-RD9HifZKtlRtFScA0VWESzLKQxxRmaRU0IFg6cFZgMP0MMgzfHpWO7MipUyRbMxDFm8adbQqCcFLBV47tjT6Ug== - dependencies: - sprintf-js "^1.0.3" +gettext-translator@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/gettext-translator/-/gettext-translator-3.0.1.tgz#6e315a24f2baea56f86a215abb5be0ff2e641baa" + integrity sha512-rqCbHfglrIL/Siinsylwc2eAbgrSPvGL5Dofo3WPoCQkxljoafDzw0n91TuTGmaYPkrp8S1fIDxOmX5fkpsNeQ== gl-mat2@^1.0.1: version "1.0.1" @@ -3755,7 +3753,7 @@ split-ca@^1.0.1: resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" integrity sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY= -sprintf-js@^1.0.3, sprintf-js@^1.1.2: +sprintf-js@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==