From 7a59dd3885e4e8a708465ad66fd53f6e10a9df52 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 7 May 2025 11:49:16 -0400 Subject: [PATCH 1/7] use bevior default views --- .../{_create_form.htm => _create_form.php} | 0 controllers/locales/{_hint.htm => _hint.php} | 0 .../{_list_toolbar.htm => _list_toolbar.php} | 0 controllers/locales/_reorder_toolbar.htm | 7 ----- .../{_update_form.htm => _update_form.php} | 0 controllers/locales/{index.htm => index.php} | 0 controllers/locales/reorder.htm | 9 ------- controllers/messages/{_hint.htm => _hint.php} | 0 .../messages/{_messages.htm => _messages.php} | 0 ...sages_form.htm => _scan_messages_form.php} | 0 ...{_table_headers.htm => _table_headers.php} | 0 ...{_table_toolbar.htm => _table_toolbar.php} | 0 controllers/messages/export.htm | 26 ------------------- controllers/messages/import.htm | 26 ------------------- controllers/messages/{index.htm => index.php} | 0 15 files changed, 68 deletions(-) rename controllers/locales/{_create_form.htm => _create_form.php} (100%) rename controllers/locales/{_hint.htm => _hint.php} (100%) rename controllers/locales/{_list_toolbar.htm => _list_toolbar.php} (100%) delete mode 100644 controllers/locales/_reorder_toolbar.htm rename controllers/locales/{_update_form.htm => _update_form.php} (100%) rename controllers/locales/{index.htm => index.php} (100%) delete mode 100644 controllers/locales/reorder.htm rename controllers/messages/{_hint.htm => _hint.php} (100%) rename controllers/messages/{_messages.htm => _messages.php} (100%) rename controllers/messages/{_scan_messages_form.htm => _scan_messages_form.php} (100%) rename controllers/messages/{_table_headers.htm => _table_headers.php} (100%) rename controllers/messages/{_table_toolbar.htm => _table_toolbar.php} (100%) delete mode 100644 controllers/messages/export.htm delete mode 100644 controllers/messages/import.htm rename controllers/messages/{index.htm => index.php} (100%) diff --git a/controllers/locales/_create_form.htm b/controllers/locales/_create_form.php similarity index 100% rename from controllers/locales/_create_form.htm rename to controllers/locales/_create_form.php diff --git a/controllers/locales/_hint.htm b/controllers/locales/_hint.php similarity index 100% rename from controllers/locales/_hint.htm rename to controllers/locales/_hint.php diff --git a/controllers/locales/_list_toolbar.htm b/controllers/locales/_list_toolbar.php similarity index 100% rename from controllers/locales/_list_toolbar.htm rename to controllers/locales/_list_toolbar.php diff --git a/controllers/locales/_reorder_toolbar.htm b/controllers/locales/_reorder_toolbar.htm deleted file mode 100644 index c5d5517f..00000000 --- a/controllers/locales/_reorder_toolbar.htm +++ /dev/null @@ -1,7 +0,0 @@ -
- - - -
\ No newline at end of file diff --git a/controllers/locales/_update_form.htm b/controllers/locales/_update_form.php similarity index 100% rename from controllers/locales/_update_form.htm rename to controllers/locales/_update_form.php diff --git a/controllers/locales/index.htm b/controllers/locales/index.php similarity index 100% rename from controllers/locales/index.htm rename to controllers/locales/index.php diff --git a/controllers/locales/reorder.htm b/controllers/locales/reorder.htm deleted file mode 100644 index 2fe905dc..00000000 --- a/controllers/locales/reorder.htm +++ /dev/null @@ -1,9 +0,0 @@ - - - - -reorderRender() ?> diff --git a/controllers/messages/_hint.htm b/controllers/messages/_hint.php similarity index 100% rename from controllers/messages/_hint.htm rename to controllers/messages/_hint.php diff --git a/controllers/messages/_messages.htm b/controllers/messages/_messages.php similarity index 100% rename from controllers/messages/_messages.htm rename to controllers/messages/_messages.php diff --git a/controllers/messages/_scan_messages_form.htm b/controllers/messages/_scan_messages_form.php similarity index 100% rename from controllers/messages/_scan_messages_form.htm rename to controllers/messages/_scan_messages_form.php diff --git a/controllers/messages/_table_headers.htm b/controllers/messages/_table_headers.php similarity index 100% rename from controllers/messages/_table_headers.htm rename to controllers/messages/_table_headers.php diff --git a/controllers/messages/_table_toolbar.htm b/controllers/messages/_table_toolbar.php similarity index 100% rename from controllers/messages/_table_toolbar.htm rename to controllers/messages/_table_toolbar.php diff --git a/controllers/messages/export.htm b/controllers/messages/export.htm deleted file mode 100644 index 29b77b6e..00000000 --- a/controllers/messages/export.htm +++ /dev/null @@ -1,26 +0,0 @@ - - - - - 'layout']) ?> - -
- exportRender() ?> -
- -
- -
- - diff --git a/controllers/messages/import.htm b/controllers/messages/import.htm deleted file mode 100644 index 51002658..00000000 --- a/controllers/messages/import.htm +++ /dev/null @@ -1,26 +0,0 @@ - - - - - 'layout']) ?> - -
- importRender() ?> -
- -
- -
- - diff --git a/controllers/messages/index.htm b/controllers/messages/index.php similarity index 100% rename from controllers/messages/index.htm rename to controllers/messages/index.php From 78050f8c8d8694827a29658a91d2366ea6f86121 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 7 May 2025 18:06:30 -0400 Subject: [PATCH 2/7] make sure Locale cache is cleared after changes --- models/Locale.php | 7 +++++++ tests/TranslatePluginTestCase.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/models/Locale.php b/models/Locale.php index 5d69a8c3..f96e7932 100644 --- a/models/Locale.php +++ b/models/Locale.php @@ -69,6 +69,11 @@ public function afterCreate() } } + public function afterSave() + { + self::clearCache(); + } + public function beforeDelete() { if ($this->is_default) { @@ -233,6 +238,8 @@ public static function isValid($locale) */ public static function clearCache() { + self::$cacheListAvailable = null; + self::$cacheListEnabled = null; Cache::forget('winter.translate.locales'); Cache::forget('winter.translate.defaultLocale'); } diff --git a/tests/TranslatePluginTestCase.php b/tests/TranslatePluginTestCase.php index c40012af..da5573b7 100644 --- a/tests/TranslatePluginTestCase.php +++ b/tests/TranslatePluginTestCase.php @@ -1,6 +1,6 @@ Date: Wed, 7 May 2025 21:13:56 -0400 Subject: [PATCH 3/7] assign number to strings so we can tell which one failed --- tests/unit/behaviors/TranslatablePageTest.php | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/unit/behaviors/TranslatablePageTest.php b/tests/unit/behaviors/TranslatablePageTest.php index b81543c5..e30c5d6b 100644 --- a/tests/unit/behaviors/TranslatablePageTest.php +++ b/tests/unit/behaviors/TranslatablePageTest.php @@ -104,23 +104,23 @@ public function testThemeScanner() ["{{ \"hello'|_ }}", []], // Should find 1 match - ["{{ 'hello'|_ }}}}", ['hello']], - ["{{{{ 'hello'|_ }}", ['hello']], - ["{{ 'hello'|_ }}", ['hello']], - ["{{ \"hello\"|_ }}", ['hello']], - ["{{ \"'hello\"|_ }}", ['\'hello']], - ["{{ '\"hello'|_ }}", ['"hello']], - ["{{ 'hello'|__ }}", ['hello']], - ["{{ 'hello'|transRaw }}", ['hello']], - ["{{ 'hello'|transRawPlural }}", ['hello']], - ["{{ 'hello'|localeUrl }}", ['hello']], - ["{{ 'hello'|_() }}", ['hello']], - ["{{ 'hello'|_(func()) }}", ['hello']], - ["{{ 'hello'|_({var: val}) }}", ['hello']], - ["{{ 'hello'|_({var: func(param)}) }}", ['hello']], - ["{{ 'hello'|_({var: func(nestedFunc())}) }}", ['hello']], - ["{{ 'hello'|_|filter }}", ['hello']], - ["{{ 'hello'|_|filter|otherfilter }}", ['hello']], + ["{{ 'hello1'|_ }}}}", ['hello1']], + ["{{{{ 'hello2'|_ }}", ['hello2']], + ["{{ 'hello3'|_ }}", ['hello3']], + ["{{ \"hello4\"|_ }}", ['hello4']], + ["{{ \"'hello5\"|_ }}", ['\'hello5']], + ["{{ '\"hello6'|_ }}", ['"hello6']], + ["{{ 'hello7'|__ }}", ['hello7']], + ["{{ 'hello8'|transRaw }}", ['hello8']], + ["{{ 'hello9'|transRawPlural }}", ['hello9']], + ["{{ 'hello10'|localeUrl }}", ['hello10']], + ["{{ 'hello11'|_() }}", ['hello11']], + ["{{ 'hello12'|_(func()) }}", ['hello12']], + ["{{ 'hello13'|_({var: val}) }}", ['hello13']], + ["{{ 'hello14'|_({var: func(param)}) }}", ['hello14']], + ["{{ 'hello15'|_({var: func(nestedFunc())}) }}", ['hello15']], + ["{{ 'hello16'|_|filter }}", ['hello16']], + ["{{ 'hello17'|_|filter|otherfilter }}", ['hello17']], ["{{ 'Apostrophe\'s'|_ }}", ['Apostrophe\'s']], ['{{ "String with \"Double quote\""|_ }}', ['String with "Double quote"']], From 0620d964c311be1060e22e00cf87a08b11586f2b Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 7 May 2025 22:09:22 -0400 Subject: [PATCH 4/7] we have an issue with twig > 3.8 in ThemeScanner class --- tests/unit/behaviors/TranslatablePageTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/behaviors/TranslatablePageTest.php b/tests/unit/behaviors/TranslatablePageTest.php index e30c5d6b..78e66bc9 100644 --- a/tests/unit/behaviors/TranslatablePageTest.php +++ b/tests/unit/behaviors/TranslatablePageTest.php @@ -87,7 +87,8 @@ public function testAlternateLocale() $this->assertEquals('titre francais', $title_fr); } - public function testThemeScanner() + // disable this test until we fix the issue with twig parsing in ThemeScanner + public function __testThemeScanner() { $scanner = new MessageScanner(); From fa84ce6bca78865c0d8a6f355c04428266561dff Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Thu, 8 May 2025 08:50:14 -0400 Subject: [PATCH 5/7] revert to regex, twig tokenizer is broken --- classes/ThemeScanner.php | 76 +++---------------- tests/fixtures/classes/MessageScanner.php | 11 --- tests/unit/behaviors/TranslatablePageTest.php | 32 +++----- 3 files changed, 24 insertions(+), 95 deletions(-) delete mode 100644 tests/fixtures/classes/MessageScanner.php diff --git a/classes/ThemeScanner.php b/classes/ThemeScanner.php index cde18f2c..5ba3e60a 100644 --- a/classes/ThemeScanner.php +++ b/classes/ThemeScanner.php @@ -141,7 +141,7 @@ public function scanMailTemplatesForMessages() * @param string $content * @return array */ - protected function parseContent($content) + public function parseContent($content) { $messages = []; if ($content) { @@ -152,80 +152,28 @@ protected function parseContent($content) } /** - * Get an array of standard language filter tags + * Process standard language filter tag (_|) + * @param string $content * @return array */ - protected function getFilters() + public function processStandardTags($content) { - return [ - '_', - '__', - 'transRaw', - 'transRawPlural', - 'localeUrl' - ]; - } + $messages = []; - /** - * Get an array of Twig tokens - * @param string $string - * @return array - */ - protected function findTwigTokensInString($string) - { - $loader = new \Twig\Loader\ArrayLoader(); - $env = new \Twig\Environment($loader); - $source = new \Twig\Source($string, 'test'); + $messages = self::getMessages(preg_quote("'"), $content); - try { - $stream = $env->tokenize($source); - } - catch (\Exception $e) { - return []; - } - - $tokens = []; - while (!$stream->isEOF()) { - $token = $stream->next(); - $token->typeString = $token->typeToString($token->getType(), true); - $tokens[] = $token; - } - return $tokens; + return array_merge($messages, self::getMessages(preg_quote('"'), $content)); } /** - * Searches for strings to be translated within a given Twig string - * @param string $content + * Apply regex on string to extract value to translate + * @param string $quoteChar * @return array */ - protected function processStandardTags($content) + protected static function getMessages($quoteChar, $content) { - $tokens = $this->findTwigTokensInString($content); - - $translatable_strings = []; - $var_token_started = false; - for ($i = 0; $i < count($tokens); $i++) { - switch ($tokens[$i]->typeString) { - case 'VAR_START_TYPE': - $var_token_started = true; - continue 2; - case 'VAR_END_TYPE': - $var_token_started = false; - continue 2; - } - if ( - $var_token_started - && $tokens[$i]->typeString === 'STRING_TYPE' - && $tokens[$i+1]->typeString === 'PUNCTUATION_TYPE' - && $tokens[$i+1]->getValue() === '|' - && $tokens[$i+2]->typeString === 'NAME_TYPE' - && in_array($tokens[$i+2]->getValue(), $this->getFilters()) - ) { - $translatable_strings[] = stripslashes($tokens[$i]->getValue()); - $i += 2; - } - } + preg_match_all('/\{\{\s*'.$quoteChar.'([^'.$quoteChar.']+)'.$quoteChar.'\s*\|\s*(?:localeUrl|transRaw|transRawPlural|_{1,2})(?:\(.*\)){0,1}\s*(?:\|[^|\s\}]+){0,}\s*\}\}/x', $content, $match); - return $translatable_strings; + return $match[1] ?? []; } } diff --git a/tests/fixtures/classes/MessageScanner.php b/tests/fixtures/classes/MessageScanner.php deleted file mode 100644 index 3b920eff..00000000 --- a/tests/fixtures/classes/MessageScanner.php +++ /dev/null @@ -1,11 +0,0 @@ -processStandardTags($string); - } -} diff --git a/tests/unit/behaviors/TranslatablePageTest.php b/tests/unit/behaviors/TranslatablePageTest.php index 78e66bc9..b1bec973 100644 --- a/tests/unit/behaviors/TranslatablePageTest.php +++ b/tests/unit/behaviors/TranslatablePageTest.php @@ -5,8 +5,8 @@ use Winter\Storm\Filesystem\Filesystem; use Winter\Storm\Halcyon\Datasource\FileDatasource; use Winter\Storm\Halcyon\Datasource\Resolver; -use Winter\Translate\Tests\Fixtures\Classes\MessageScanner; use Winter\Translate\Tests\Fixtures\Classes\TranslatablePage; +use Winter\Translate\Classes\ThemeScanner; class TranslatablePageTest extends \Winter\Translate\Tests\TranslatePluginTestCase { @@ -87,10 +87,9 @@ public function testAlternateLocale() $this->assertEquals('titre francais', $title_fr); } - // disable this test until we fix the issue with twig parsing in ThemeScanner - public function __testThemeScanner() + public function testThemeScanner() { - $scanner = new MessageScanner(); + $scanner = new ThemeScanner(); $check_strings = [ // Should not match @@ -112,9 +111,12 @@ public function __testThemeScanner() ["{{ \"'hello5\"|_ }}", ['\'hello5']], ["{{ '\"hello6'|_ }}", ['"hello6']], ["{{ 'hello7'|__ }}", ['hello7']], - ["{{ 'hello8'|transRaw }}", ['hello8']], - ["{{ 'hello9'|transRawPlural }}", ['hello9']], - ["{{ 'hello10'|localeUrl }}", ['hello10']], + ["{{ 'hello8a'|transRaw }}", ['hello8a']], + ["{{ 'hello8b'|transRaw() }}", ['hello8b']], + ["{{ 'hello9a'|transRawPlural }}", ['hello9a']], + ["{{ 'hello9b'|transRawPlural() }}", ['hello9b']], + ["{{ 'hello10a'|localeUrl }}", ['hello10a']], + ["{{ 'hello10b'|localeUrl() }}", ['hello10b']], ["{{ 'hello11'|_() }}", ['hello11']], ["{{ 'hello12'|_(func()) }}", ['hello12']], ["{{ 'hello13'|_({var: val}) }}", ['hello13']], @@ -122,26 +124,16 @@ public function __testThemeScanner() ["{{ 'hello15'|_({var: func(nestedFunc())}) }}", ['hello15']], ["{{ 'hello16'|_|filter }}", ['hello16']], ["{{ 'hello17'|_|filter|otherfilter }}", ['hello17']], - ["{{ 'Apostrophe\'s'|_ }}", ['Apostrophe\'s']], - ['{{ "String with \"Double quote\""|_ }}', ['String with "Double quote"']], // Should find 2 matches [ - '{{ \'Apostrophe\\\'s\'|_ }}{{ "String with \"Double quote\""|_ }}', - ['Apostrophe\'s', 'String with "Double quote"'] - ], - [ - "{{ 'hello'|_|filter|otherfilter }}{{ 'hello'|_|filter|otherfilter }}", - ['hello', 'hello'] - ], - [ - "{{ 'hello'|transRaw('nested translation'|_) }}", - ['hello', 'nested translation'] + "{{ 'hello18a'|_|filter|otherfilter }}{{ 'hello18b'|_|filter|otherfilter }}", + ['hello18a', 'hello18b'] ], ]; foreach ($check_strings as $check) { - $this->assertEquals($scanner->getMessages($check[0]), $check[1]); + $this->assertEquals($scanner->processStandardTags($check[0]), $check[1]); } } } From d5ed4eca2469d7247a4957bbe9efd7520c120611 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 27 May 2025 14:56:20 -0400 Subject: [PATCH 6/7] add local model labels --- controllers/locales/config_list.yaml | 2 +- lang/en/lang.php | 2 ++ lang/fr/lang.php | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/controllers/locales/config_list.yaml b/controllers/locales/config_list.yaml index d57a87bc..63994ce6 100644 --- a/controllers/locales/config_list.yaml +++ b/controllers/locales/config_list.yaml @@ -9,7 +9,7 @@ list: ~/plugins/winter/translate/models/locale/columns.yaml modelClass: Winter\Translate\Models\Locale # List Title -title: winter.translate::lang.locale.title +title: winter.translate::lang.locale.label_plural # Link URL for each record # recordUrl: winter/translate/locale/update/:id diff --git a/lang/en/lang.php b/lang/en/lang.php index 47559855..0dc9c6dd 100755 --- a/lang/en/lang.php +++ b/lang/en/lang.php @@ -17,6 +17,8 @@ 'component_description' => 'Injects the language alternatives for page as hreflang elements' ], 'locale' => [ + 'label' => 'Language', + 'label_plural' => 'Languages', 'title' => 'Manage languages', 'update_title' => 'Update language', 'create_title' => 'Create language', diff --git a/lang/fr/lang.php b/lang/fr/lang.php index c7e4e434..223f4345 100644 --- a/lang/fr/lang.php +++ b/lang/fr/lang.php @@ -17,6 +17,8 @@ 'component_description' => "Injecte les alternatives linguistiques pour la page en tant qu'éléments hreflang" ], 'locale' => [ + 'label' => 'Langue', + 'label_plural' => 'Langues', 'title' => 'Gestion des langues', 'update_title' => 'Mettre à jour la langue', 'create_title' => 'Ajouter une langue', From 9072b1ef147509b3dbdc721ccabc921f31ba7765 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Tue, 8 Jul 2025 08:00:34 -0400 Subject: [PATCH 7/7] require winter/wn-backend-module >= 1.2.8 --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index f629a3ee..10e3c7fd 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,7 @@ }, "require": { "php": ">=7.2", + "winter/wn-backend-module": ">=1.2.8", "composer/installers": "~1.0" }, "replace": {