# mage-os/module-automatic-translation

> Automatic AI content translation for Mage-OS.

`composer require mage-os/module-automatic-translation`

Canonical URL: https://packagento.com/mage-os/module-automatic-translation

## At a glance

- **Vendor**: mage-os (https://packagento.com/mage-os.md)
- **Latest version**: 2.2.0 — released 2026-06-23
- **Pricing**: Free
- **Package type**: Magento 2 module
- **Status**: active, accepting new buyers

## Installation

Packagento is licence-gated, so even free packages need a licence on a project before Composer can resolve them.

1. **Sign in or create an account** at https://packagento.com/customer/account/.

2. **Add the package to your account.** Open https://packagento.com/mage-os/module-automatic-translation and complete the free checkout. A licence is minted automatically.

3. **Create or pick a project, then activate the licence on it.**
   - Projects represent the Magento installs you deploy to. Manage them at https://packagento.com/projects/.
   - Activate the new licence on the project you'll deploy this package to. Activation is what generates the Composer credentials scoped to that project.

4. **Add the project credentials to your Magento codebase.**

   Grab the project's public + private key from https://packagento.com/projects/ (open the project, then its Credentials tab), and add them to `auth.json`:

   ```json
   {
     "http-basic": {
       "packagento.com": {
         "username": "ppk_live_...",
         "password": "psk_live_..."
       }
     }
   }
   ```

   Add the Packagento Composer repository to `composer.json`:

   ```json
   {
     "repositories": [
       { "type": "composer", "url": "https://packagento.com" }
     ]
   }
   ```

5. **Install and apply.**

   ```bash
   composer require mage-os/module-automatic-translation:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

Automatic AI content translation for Mage-OS.

## README

### Overview

The **MageOS Automatic Translation** module allows you to automatically translate content in your Magento store, such as products, categories, pages, and static blocks, using AI-based translation engines. The module is natively integrated with DeepL, OpenAI and Google Gemini, but it can be easily extended to support other translation engines.

### Installation

1. Install the module via Composer:
   ```bash
   composer require mage-os/module-automatic-translation
   ```

2. Enable the module:
   ```bash
   bin/magento module:enable MageOS_AutomaticTranslation
   ```

3. Run the setup upgrade command:
   ```bash
   bin/magento setup:upgrade
   ```

### Features

#### Product Translation
The product translation process is divided into two parts:
1. **Textual attributes** – The translated value is directly set in the product entity.
2. **Select and Multiselect attributes** – The translation of these attributes involves translating the labels of the options, not the option IDs, as option IDs remain consistent across languages.

The module automatically translates products via scheduled cron jobs for both textual and select/multiselect attributes. You can also manually translate products through a backoffice button available in the product editing page.

**Cron Jobs for Product Translation**:
- The product translation process runs according to a cron schedule, which can be configured via the `Product translation cron expression` in the configuration.
- For select/multiselect attribute options, another cron job is scheduled, configurable via the `Select attributes translation cron expression`.

#### Category Translation
Categories are translated only manually via a backoffice button. This is because the number of categories is usually much smaller than the number of products, and thus the manual translation process is more efficient.

For categories, only the following fields are translated:
- Name
- Description
- URL Key
- Meta information

**Note**: If you add custom attributes to categories programmatically, it is the developer’s responsibility to decide whether to translate these attributes and add them to the translation list programmatically.

#### Pages and Static Blocks Translation
Similar to categories, pages and static blocks can only be translated manually via a backoffice button. However, because Magento does not support multiple language versions for pages and static blocks, translation will overwrite the original content when saving. To prevent losing the original content, it is recommended to use the "Save & Duplicate" feature in the backoffice to create a copy of the page or block before translating it.

#### Retranslation of Products
When the module translates a product for a storeview, it values two attributes specific to that product and that storeview: "skip translation" set to "yes" and "last translation date" with the date of the translation. These attributes are automatically created by the module during installation and are updated each time the product is translated.

This process is used to "flag" the product as "already translated" preventing it from being translated again in future executions, thus improving performance.

However, if the merchant changes the basic content of the product after translation, it may need to be retranslated. The merchant can do this manually by using the button in the backoffice or by setting the "skip translation" attribute to "no" and saving the product. These operations are feasible if there are few products to be edited.

If, however, there are many products to be retranslated or the underlying content changes frequently, it may be useful to enable automatic retranslation. When enabled, this feature also includes products with the "skip translation" attribute set to "yes" in the translation process if the date in the "last translation date" attribute is older than a specified number of days, which can be configured in the settings.

#### Translation Engines
- **DeepL**, **OpenAI** and **Google Gemini** are the supported engines by default. You can easily extend the module to support additional translation engines by creating a class that implements the `MageOS\AutomaticTranslation\Api\TranslatorInterface`.
- The engine is selected under **Stores > Configuration > MageOS > Automatic translation with AI > Translation engine**.

#### Configuration Options

The module provides several configuration options under **Stores > Configuration > Services > AI Integration > Automatic translation with AI**:

##### General Configuration
- **Enable**: Enables or disables the module. This setting is configurable per store view, allowing you to translate only certain languages.
- **Source Language**: Defines the source language of your content. This is typically set to the language in which your products were initially created.
- **Destination Language**: This is the target language for translation, which corresponds to the store view's language.

##### Catalog Translation Options
- **Product Text Attributes to Translate**: Select the textual attributes you want to translate (e.g., name, description).
- **Product Select/Multiselect Attributes to Translate**: Select which select/multiselect attributes to translate.
- **Translate Disabled Products**: Skips disabled products during translation to improve performance.
- **Product Translation Cron Expression**: Schedules the product translation process.
- **Select Attributes Translation Cron Expression**: Schedules the translation of select/multiselect attributes.
- **Enable Periodic Retranslation & Retranslation Period (in days)**: Enables automatic retranslation for products if their translation is outdated (older than a set number of days).

_(README truncated for .md surface. Full README on https://packagento.com/mage-os/module-automatic-translation.)_

## Changelog

### [2.2.0] - 23/06/2026
#### Fixed
- Fix cron expression
#### Changed
- Paginate per 100 to prevent failure on large catalogs
- Use v2/languages endpoint for Deepl target language normalization

### [2.1.2] - 21/04/2026
#### Fixed
- PHP 8.4 and 8.5 compatibility
- Hardened `preg_replace` return value handling in admin before-save plugins (`strtolower(null)` becomes a TypeError in PHP 8.5)
- Cast `DOMDocument::saveHTML()` results to string before passing to `html_entity_decode()` (PHP 8.5 stricter scalar type enforcement)
- Cast retranslation period to int before building `DateTime::modify()` string to avoid `DateMalformedStringException` in PHP 8.5 when the config value is empty
- Cast legacy scope value to string before re-encryption in `MigrateConfigPaths` data patch
- Cast nullable values to string/int before using as array index (PHP 8.5 null array key deprecation)
#### Changed
- Allowed PHP range widened to `>=8.2 <8.6` in composer.json

### [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
- Constructor promotion across all classes
- Typed constants (const string, const array, const int) across all classes
- Modern PHP 8.0+ functions: str_contains, str_starts_with, str_ends_with replacing legacy equivalents
- Non-capturing catch blocks where exception variable is unused
- Explicit return types on all methods
- Union types and mixed type hints where appropriate
- First-class callable syntax replacing array-style callables
- Replaced empty() checks on typed nullable properties with explicit null comparisons
- Changed private methods/properties to protected for Magento interceptor compatibility
- Replaced inline FQCNs with use imports for exceptions
- General code cleanup and refactoring

### [1.11.2] - 12/03/2026
#### Fixed
- Fixed widget content_settings translation using JSON decode/encode instead of unreliable regex on raw encoded string
- Added translation of repeatable items (title, content, button, image_alt) inside content_settings
- Added translation of widget preview HTML inside content_settings for Page Builder editor consistency

### [1.11.1] - 12/03/2026
#### Fixed
- Fixed encodePageBuilderHtmlBox corrupting text/heading content types (double HTML-encoding, style block encoding, spurious newlines)
- Expanded parsePageBuilderHtmlBox XPath to extract text from text and heading content types, not just html
- Fixed is_string branch sending entire structural HTML to translator — now only translates widget parameters
- Fixed log message not showing exception details (sprintf instead of __())

### [1.11.0] - 11/03/2026
#### Fixed
- Fixed chunking fallback for segments without block-level HTML tags (hard split on sentence/word boundaries)

#### Added
- Widget directives are now excluded from translation payload and their translatable parameters are translated individually

### [1.10.1] - 10/03/2026
#### Fixed
- Fixed translation failing on long texts by adding chunking plugin for translation API limits
- Fixed double-encoding of HTML entities in PageBuilder HTML Code blocks
- Fixed greedy string replacement corrupting content when identical text appeared multiple times
- Fixed DOMDocument corrupting Widget content_settings JSON attributes during translation

_(Changelog truncated for .md surface. Full history on https://packagento.com/mage-os/module-automatic-translation.)_

## Recent Versions

| Version | Released |
|---|---|
| 2.2.0 | 2026-06-23 |
| 2.1.2 | 2026-04-30 |
| 2.1.1 | 2026-04-15 |
| 2.1.0 | 2026-03-20 |
| 2.0.2 | 2026-03-19 |
| 2.0.1 | 2026-03-13 |
| 2.0.0 | 2026-03-12 |
| 1.11.2 | 2026-03-12 |
| 1.11.1 | 2026-03-12 |
| 1.11.0 | 2026-03-12 |

Showing 10 of 31 versions. Full release history on https://packagento.com/mage-os/module-automatic-translation.

## Dependencies

### Require

| Package | Constraint |
|---|---|
| deeplcom/deepl-php | ^1 |
| google-gemini-php/client | ^1 |
| guzzlehttp/guzzle | ^7.9 |
| magento/framework | * |
| magento/module-catalog | ^104.0.0 |
| openai-php/client | ^0 |
| php | >=8.2 <8.6 |

## Quality

Latest release (2.2.0) fails the Packagento QA pipeline. Verdicts below are per-cell (Magento line × PHP version) for the matrixed tools, and run-once for the static / security tiers.


### Compatibility

Each Magento line is installed on its supported PHP versions, then the module is built (DI compile + static-content deploy). Cells show passed / failed / untested; staircase gaps render as `–`.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | Pass | Pass | – | – |
| 2.4.8 | – | Pass | Pass | – |
| 2.4.9 | – | – | Pass | Pass |


### Code Quality

Advisory checks against the module's source. Never affect the Compatibility verdict — a phpcs finding can't make a module incompatible.

#### Static Analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Warning | 89 | 89 warnings (ruleset: Magento2) — 6 auto-fixable with phpcbf |
| PHPMD | Warning | 13 | 13 rule violations (UnusedFormalParameter:6, IfStatementAssignment:2, CyclomaticComplexity:2, NPathComplexity:1, MissingImport:1) |
| Cpd | Pass | 0 |  |
| Composer validate | Info | 1 | valid; 1 advisory note (composer validate --strict) |

#### PHPStan

Type-checks the module against a real Magento install. Re-runs per Magento + PHP version because resolvable symbols differ between releases.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | 33 | 33 | – | – |
| 2.4.8 | – | 33 | 33 | – |
| 2.4.9 | – | – | 33 | 33 |


### Tests

Unit and integration suites run per Magento + PHP cell. Test failures speak to the module's behaviour, not its compatibility with a line, so they're reported here separately.

#### Unit Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |

#### Integration Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |


### Security

Dependency-advisory audit (composer audit) plus a source malware scan. A malware detection fails the version outright.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| Composer audit | Pass | 0 |  |
| Malware scan | Pass | 0 |  |

## Licence and pricing

Free. A licence is still minted on checkout and bound to your project for Composer access — no payment step.

Refundable within 14 days of first purchase via https://packagento.com/account/refunds/.

## Install via Claude Code or any MCP client

The Packagento MCP server can run the licence + project + Composer steps above in one tool call:

```
purchase_and_install_packages(
  composer_names=["mage-os/module-automatic-translation"],
  project_id="proj_xxx"
)
```

This handles cart, checkout, licence minting, project activation, and writes auth.json credentials. Connect a client with `claude mcp add packagento https://mcp.packagento.com`. Full setup at https://packagento.com/docs/mcp-setup.

## Vendor

mage-os is a Magento 2 vendor on Packagento. See https://packagento.com/mage-os.md for their full catalogue.

