diff --git a/Api/AttributeProviderInterface.php b/Api/AttributeProviderInterface.php index b8b1bce..3f1392e 100644 --- a/Api/AttributeProviderInterface.php +++ b/Api/AttributeProviderInterface.php @@ -9,9 +9,9 @@ */ interface AttributeProviderInterface { - const string SKIP_TRANSLATION = 'skip_translation'; - const string SKIP_TRANSLATION_LABEL = 'Skip translation'; - const string SKIP_TRANSLATION_NOTE = 'Uncheck to re-translate'; - const string LAST_TRANSLATION = 'last_translation_date'; - const string LAST_TRANSLATION_LABEL = 'Last translation date'; + const SKIP_TRANSLATION = 'skip_translation'; + const SKIP_TRANSLATION_LABEL = 'Skip translation'; + const SKIP_TRANSLATION_NOTE = 'Uncheck to re-translate'; + const LAST_TRANSLATION = 'last_translation_date'; + const LAST_TRANSLATION_LABEL = 'Last translation date'; } diff --git a/Block/Adminhtml/CmsBlock/GenerateTranslationsButton.php b/Block/Adminhtml/CmsBlock/GenerateTranslationsButton.php index a3cef24..a12beae 100644 --- a/Block/Adminhtml/CmsBlock/GenerateTranslationsButton.php +++ b/Block/Adminhtml/CmsBlock/GenerateTranslationsButton.php @@ -16,7 +16,7 @@ class GenerateTranslationsButton extends GenericButton implements ButtonProviderInterface { - const string CMSBLOCK_TRANSLATION_CONTROLLER_PATH = 'automatic_translation/cms_block/generate'; + const CMSBLOCK_TRANSLATION_CONTROLLER_PATH = 'automatic_translation/cms_block/generate'; /** * @param Context $context diff --git a/Block/Adminhtml/CmsPage/GenerateTranslationsButton.php b/Block/Adminhtml/CmsPage/GenerateTranslationsButton.php index cc65367..d33f437 100644 --- a/Block/Adminhtml/CmsPage/GenerateTranslationsButton.php +++ b/Block/Adminhtml/CmsPage/GenerateTranslationsButton.php @@ -14,7 +14,7 @@ class GenerateTranslationsButton extends GenericButton implements ButtonProviderInterface { - const string CMSPAGE_TRANSLATION_CONTROLLER_PATH = 'automatic_translation/cms_page/generate'; + const CMSPAGE_TRANSLATION_CONTROLLER_PATH = 'automatic_translation/cms_page/generate'; /** * @param Context $context diff --git a/CHANGELOG.md b/CHANGELOG.md index b96d638..11be092 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,20 @@ # Automatic Translation +## [2.1.0] - 20/03/2026 +### Changed +- Minimum PHP version lowered from 8.3 to 8.2 +- Removed typed constants (PHP 8.3 feature) for 8.2 compatibility + +## [2.0.2] - 20/03/2026 +### Fixed +- Fixed CMS page plain text fields (title, heading, meta title, meta keywords, meta description) not being translated +- Added URL key (identifier) to CMS page translatable fields +- Fixed URL key slug sanitization using correct field name (identifier instead of url_key) +- Fixed TranslateParsedContent for string input: translates text before handling widget directives + +## [2.0.1] - 20/03/2026 +### Fixed +- Fixed product translate button passing null instead of 0 to isEnable() for default store + ## [2.0.0] - 12/03/2026 ### Changed - **BREAKING**: Minimum PHP version raised to 8.3 diff --git a/Helper/ModuleConfig.php b/Helper/ModuleConfig.php index 57ab06f..952cba0 100644 --- a/Helper/ModuleConfig.php +++ b/Helper/ModuleConfig.php @@ -12,31 +12,31 @@ class ModuleConfig extends AbstractHelper { - const string SECTION = 'ai_integration/automatic_translation'; - - const string GENERAL_GROUP = self::SECTION . '/general'; - const string CATALOG_GROUP = self::SECTION . '/catalog'; - const string ENGINE_GROUP = self::SECTION . '/translations_engine'; - - const string ENABLE = self::GENERAL_GROUP . '/enable'; - const string SOURCE_LANGUAGE = self::GENERAL_GROUP . '/source_language'; - const string DESTINATION_LANGUAGE = 'general/locale/code'; - - const string TXT_PRODUCT_ATTR = self::CATALOG_GROUP . '/text_attribute_to_translate'; - const string SELECT_PRODUCT_ATTR = self::CATALOG_GROUP . '/select_attribute_to_translate'; - const string ENABLE_PERIODIC = self::CATALOG_GROUP . '/enable_periodic_retranslation'; - const string RETRANSLATION_PERIOD = self::CATALOG_GROUP . '/retranslation_period'; - const string TRANSLATE_DISABLED = self::CATALOG_GROUP . '/translate_disabled'; - const string ENABLE_URL_REWRITE = self::CATALOG_GROUP . '/enable_url_rewrite'; - - const string ENGINE = self::ENGINE_GROUP . '/engine'; - const string DEEPL_AUTH_KEY = self::ENGINE_GROUP . '/deepl_auth_key'; - const string OPEN_AI_ORG_ID = self::ENGINE_GROUP . '/openai_org_id'; - const string OPEN_AI_API_KEY = self::ENGINE_GROUP . '/openai_api_key'; - const string OPEN_AI_PROJECT_ID = self::ENGINE_GROUP . '/openai_project_id'; - const string OPEN_AI_MODEL = self::ENGINE_GROUP . '/openai_model'; - const string GEMINI_API_KEY = self::ENGINE_GROUP . '/gemini_api_key'; - const string GEMINI_MODEL = self::ENGINE_GROUP . '/gemini_model'; + const SECTION = 'ai_integration/automatic_translation'; + + const GENERAL_GROUP = self::SECTION . '/general'; + const CATALOG_GROUP = self::SECTION . '/catalog'; + const ENGINE_GROUP = self::SECTION . '/translations_engine'; + + const ENABLE = self::GENERAL_GROUP . '/enable'; + const SOURCE_LANGUAGE = self::GENERAL_GROUP . '/source_language'; + const DESTINATION_LANGUAGE = 'general/locale/code'; + + const TXT_PRODUCT_ATTR = self::CATALOG_GROUP . '/text_attribute_to_translate'; + const SELECT_PRODUCT_ATTR = self::CATALOG_GROUP . '/select_attribute_to_translate'; + const ENABLE_PERIODIC = self::CATALOG_GROUP . '/enable_periodic_retranslation'; + const RETRANSLATION_PERIOD = self::CATALOG_GROUP . '/retranslation_period'; + const TRANSLATE_DISABLED = self::CATALOG_GROUP . '/translate_disabled'; + const ENABLE_URL_REWRITE = self::CATALOG_GROUP . '/enable_url_rewrite'; + + const ENGINE = self::ENGINE_GROUP . '/engine'; + const DEEPL_AUTH_KEY = self::ENGINE_GROUP . '/deepl_auth_key'; + const OPEN_AI_ORG_ID = self::ENGINE_GROUP . '/openai_org_id'; + const OPEN_AI_API_KEY = self::ENGINE_GROUP . '/openai_api_key'; + const OPEN_AI_PROJECT_ID = self::ENGINE_GROUP . '/openai_project_id'; + const OPEN_AI_MODEL = self::ENGINE_GROUP . '/openai_model'; + const GEMINI_API_KEY = self::ENGINE_GROUP . '/gemini_api_key'; + const GEMINI_MODEL = self::ENGINE_GROUP . '/gemini_model'; /** * @param EncryptorInterface $encryptor diff --git a/Model/Config/Source/SelectAttributes.php b/Model/Config/Source/SelectAttributes.php index 9bad819..9ef5add 100644 --- a/Model/Config/Source/SelectAttributes.php +++ b/Model/Config/Source/SelectAttributes.php @@ -9,11 +9,11 @@ class SelectAttributes implements OptionSourceInterface { - const array ATTRIBUTE_TYPES = [ + const ATTRIBUTE_TYPES = [ 'select', 'multiselect' ]; - const array ATTRIBUTES_TO_EXCLUDE = [ + const ATTRIBUTES_TO_EXCLUDE = [ 'custom_design', 'custom_layout', 'custom_layout_update_file', diff --git a/Model/Config/Source/TextAttributes.php b/Model/Config/Source/TextAttributes.php index ebc193a..3e52ff5 100644 --- a/Model/Config/Source/TextAttributes.php +++ b/Model/Config/Source/TextAttributes.php @@ -9,16 +9,16 @@ class TextAttributes implements OptionSourceInterface { - const string GALLERY_ALT_ATTRIBUTE_CODE = 'gallery_alt'; - const array GALLERY_ALT_IMAGE_ATTRIBUTE = [ + const GALLERY_ALT_ATTRIBUTE_CODE = 'gallery_alt'; + const GALLERY_ALT_IMAGE_ATTRIBUTE = [ 'value' => self::GALLERY_ALT_ATTRIBUTE_CODE, 'label' => 'Gallery image alt text' ]; - const array ATTRIBUTE_TYPES = [ + const ATTRIBUTE_TYPES = [ 'text', 'textarea' ]; - const array ATTRIBUTES_TO_EXCLUDE = [ + const ATTRIBUTES_TO_EXCLUDE = [ 'sku', 'tier_price', 'category_ids', diff --git a/Model/Translator/DeepL.php b/Model/Translator/DeepL.php index 3e1b470..efc6833 100644 --- a/Model/Translator/DeepL.php +++ b/Model/Translator/DeepL.php @@ -12,7 +12,7 @@ class DeepL implements TranslatorInterface { - const array REGIONAL_VARIANTS_LANGUAGES = [ + const REGIONAL_VARIANTS_LANGUAGES = [ 'en', 'pt', 'es', diff --git a/Plugin/AdminhtmlCategoryBeforeSavePlugin.php b/Plugin/AdminhtmlCategoryBeforeSavePlugin.php index 82e280d..c2a586d 100644 --- a/Plugin/AdminhtmlCategoryBeforeSavePlugin.php +++ b/Plugin/AdminhtmlCategoryBeforeSavePlugin.php @@ -14,7 +14,7 @@ class AdminhtmlCategoryBeforeSavePlugin { - const array CATEGORY_TRANSLATABLE_ATTRIBUTES = [ + const CATEGORY_TRANSLATABLE_ATTRIBUTES = [ 'name', 'description', 'url_key', diff --git a/Service/ProductTranslator.php b/Service/ProductTranslator.php index 812cbf1..7f60bb9 100644 --- a/Service/ProductTranslator.php +++ b/Service/ProductTranslator.php @@ -128,6 +128,7 @@ public function translateProduct( * @param string $targetLanguage * @param string $sourceLanguage * @throws LocalizedException + * @throws Exception */ protected function translateGalleryAlternativeTexts( ProductInterface $product, diff --git a/Service/TextChunker.php b/Service/TextChunker.php index 0db55fa..9c4fc7f 100644 --- a/Service/TextChunker.php +++ b/Service/TextChunker.php @@ -8,12 +8,12 @@ class TextChunker { - const int MAX_CHUNK_SIZE = 4500; - const int HALF_CHUNK_SIZE = 2250; + const MAX_CHUNK_SIZE = 4500; + const HALF_CHUNK_SIZE = 2250; - const string BLOCK_TAG_PATTERN = '#()#i'; + const BLOCK_TAG_PATTERN = '#()#i'; - const array PLAIN_TEXT_PATTERNS = [ + const PLAIN_TEXT_PATTERNS = [ '/(\n\n)/', '/(\n)/', '/((?<=[.!?])\s+)/', diff --git a/Service/TranslateParsedContent.php b/Service/TranslateParsedContent.php index 35077ed..4fba4bd 100644 --- a/Service/TranslateParsedContent.php +++ b/Service/TranslateParsedContent.php @@ -12,10 +12,10 @@ class TranslateParsedContent { - const string WIDGET_PATTERN = '/\{\{widget\s[^}]*\}\}/'; - const array TRANSLATABLE_WIDGET_PARAMS = ['anchor_text', 'title', 'description']; - const array TRANSLATABLE_REPEATABLE_PARAMS = ['title', 'content', 'button', 'image_alt']; - const int JSON_ENCODE_FLAGS = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES; + const WIDGET_PATTERN = '/\{\{widget\s[^}]*\}\}/'; + const TRANSLATABLE_WIDGET_PARAMS = ['anchor_text', 'title', 'description']; + const TRANSLATABLE_REPEATABLE_PARAMS = ['title', 'content', 'button', 'image_alt']; + const JSON_ENCODE_FLAGS = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES; /** * @param Service $serviceHelper @@ -102,7 +102,7 @@ function (array $matches) use (&$contentSettingsMap): string { } } - $result = strpos($requestPostValue, 'data-content-type="html"') !== false + $result = str_contains($requestPostValue, 'data-content-type="html"') ? $this->serviceHelper->encodePageBuilderHtmlBox($requestPostValue) : $requestPostValue; diff --git a/Setup/Patch/Data/MigrateConfigPaths.php b/Setup/Patch/Data/MigrateConfigPaths.php index 1cda32c..d34dc66 100644 --- a/Setup/Patch/Data/MigrateConfigPaths.php +++ b/Setup/Patch/Data/MigrateConfigPaths.php @@ -13,13 +13,13 @@ class MigrateConfigPaths implements DataPatchInterface { - const array ENCRYPTED_OLD_PATHS = [ + const ENCRYPTED_OLD_PATHS = [ 'automatic_translation/translations_engine/deepl_auth_key', 'automatic_translation/translations_engine/openai_api_key', 'automatic_translation/translations_engine/gemini_api_key', ]; - const array MAPPINGS = [ + const MAPPINGS = [ 'automatic_translation/general/enable' => 'ai_integration/automatic_translation/general/enable', 'automatic_translation/general/source_language' => 'ai_integration/automatic_translation/general/source_language', 'automatic_translation/general/destination_language' => 'general/locale/code', diff --git a/Ui/DataProvider/Category/Form/Modifier/TranslationStores.php b/Ui/DataProvider/Category/Form/Modifier/TranslationStores.php index 4a8e630..f9dd144 100644 --- a/Ui/DataProvider/Category/Form/Modifier/TranslationStores.php +++ b/Ui/DataProvider/Category/Form/Modifier/TranslationStores.php @@ -17,7 +17,7 @@ class TranslationStores extends AbstractModifier { - const string GROUP_CODE = 'translation-stores'; + const GROUP_CODE = 'translation-stores'; /** * @param StoreSwitcher $storeSwitcher @@ -55,9 +55,7 @@ public function modifyMeta(array $meta): array } $meta = $this->customizeSwitchStoreModal($meta); - $meta = $this->customizeTranslationStoresList($meta); - - return $meta; + return $this->customizeTranslationStoresList($meta); } /** @@ -132,7 +130,6 @@ protected function getTranslationStores(): array ); $categoryStoreIds = $currentCategory->getStoreIds(); - /** @var Website $website */ foreach ($this->storeSwitcher->getWebsites() as $website) { $stores = $website->getStores(); /** @var Store $store */ diff --git a/Ui/DataProvider/Product/Form/Modifier/TranslationStores.php b/Ui/DataProvider/Product/Form/Modifier/TranslationStores.php index 7195abd..9934d45 100644 --- a/Ui/DataProvider/Product/Form/Modifier/TranslationStores.php +++ b/Ui/DataProvider/Product/Form/Modifier/TranslationStores.php @@ -17,7 +17,7 @@ class TranslationStores extends AbstractModifier { - const string GROUP_CODE = 'translation-stores'; + const GROUP_CODE = 'translation-stores'; /** * @param StoreSwitcher $storeSwitcher @@ -132,7 +132,6 @@ protected function getTranslationStores(): array ); $productStoreIds = $currentProduct->getStoreIds(); - /** @var Website $website */ foreach ($this->storeSwitcher->getWebsites() as $website) { $stores = $website->getStores(); /** @var Store $store */ diff --git a/composer.json b/composer.json index c277eac..cfc33f0 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "MIT" ], "require": { - "php": ">=8.3", + "php": ">=8.2", "magento/framework": "*", "magento/module-catalog": "^104.0.0", "deeplcom/deepl-php": "^1",