PHPackages                             opencat/mt - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. opencat/mt

ActiveLibrary[Framework](/categories/framework)

opencat/mt
==========

Machine translation adapter framework for the OpenCAT Framework

00PHP

Since May 9Pushed 1mo agoCompare

[ Source](https://github.com/shaikhammar/opencat-mt)[ Packagist](https://packagist.org/packages/opencat/mt)[ RSS](/packages/opencat-mt/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

opencat/mt
==========

[](#opencatmt)

Machine translation adapters for the [OpenCAT Framework](https://github.com/shaikhammar/opencat-framework).

Provides `DeepLAdapter` and `GoogleTranslateAdapter`, both built on PSR-18 HTTP client injection. Inline codes (`InlineCode` objects) survive the MT round-trip as numbered XML placeholders.

Installation
------------

[](#installation)

```
composer require opencat/mt
```

You also need a PSR-18 HTTP client. [Guzzle](https://packagist.org/packages/guzzlehttp/guzzle) is the most common choice:

```
composer require guzzlehttp/guzzle
```

DeepL adapter
-------------

[](#deepl-adapter)

```
use CatFramework\Mt\DeepL\DeepLAdapter;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Psr7\HttpFactory;

$http    = new GuzzleClient();
$factory = new HttpFactory();

$adapter = new DeepLAdapter(
    httpClient: $http,
    requestFactory: $factory,
    streamFactory: $factory,
    apiKey: 'your-deepl-api-key',
    // Free tier keys end with ":fx" — the adapter selects the correct endpoint automatically
);

// Translate a single segment
$translated = $adapter->translate($sourceSegment, 'en-US', 'fr-FR');

// Translate many segments in one HTTP request
$translatedBatch = $adapter->translateBatch($segments, 'en-US', 'fr-FR');
```

DeepL free-tier keys (ending in `:fx`) are routed to `api-free.deepl.com` automatically. Pro keys go to `api.deepl.com`.

On `429 Too Many Requests` or `5xx` errors the adapter retries up to three times with 1-second delays (configurable via `$retryDelays`):

```
$adapter = new DeepLAdapter($http, $factory, $factory, $apiKey, retryDelays: [500_000, 1_000_000]);
// 0.5 s then 1 s before giving up
```

Google Translate adapter
------------------------

[](#google-translate-adapter)

```
use CatFramework\Mt\Google\GoogleTranslateAdapter;

$adapter = new GoogleTranslateAdapter(
    httpClient: $http,
    requestFactory: $factory,
    streamFactory: $factory,
    apiKey: 'your-google-api-key',
    projectId: 'your-gcp-project-id',
);

$translated = $adapter->translate($sourceSegment, 'en', 'fr');
```

Null adapter (testing)
----------------------

[](#null-adapter-testing)

`NullMtAdapter` implements `MachineTranslationInterface` and returns copies of the source segment unchanged. Use it in tests or dry-runs where you don't want to call a live API:

```
use CatFramework\Mt\NullMtAdapter;

$adapter = new NullMtAdapter();
$result  = $adapter->translate($segment, 'en', 'fr');
// $result->getPlainText() === $segment->getPlainText()
```

Inline code preservation
------------------------

[](#inline-code-preservation)

`InlineCode` elements are converted to `` placeholders before sending to the MT API (`tag_handling=xml` for DeepL). The MT engine treats them as opaque tokens and repositions them in the translated text. On the way back they are restored to the original `InlineCode` objects.

If the MT response is malformed XML, the adapter falls back to stripping all `` tags and returning a plain-text segment — degraded output is better than a crash.

Error codes
-----------

[](#error-codes)

`MtException` carries a typed error code:

Code constantMeaning`MtException::AUTH_FAILED`403 — invalid API key`MtException::RATE_LIMITED`429 — too many requests`MtException::QUOTA_EXCEEDED`456 — DeepL character quota exceeded`MtException::BAD_REQUEST`4xx other`MtException::SERVER_ERROR`5xxCustom adapter
--------------

[](#custom-adapter)

Extend `AbstractMtAdapter` and implement the `MachineTranslationInterface` contract. The base class provides `encodeSegment()`, `decodeXml()`, `sendRequest()`, and `retry()`:

```
use CatFramework\Mt\AbstractMtAdapter;
use CatFramework\Core\Model\Segment;

class MyMtAdapter extends AbstractMtAdapter
{
    public function translate(Segment $source, string $sourceLanguage, string $targetLanguage): Segment
    {
        ['text' => $text, 'map' => $map] = $this->encodeSegment($source);
        // send $text to your MT API ...
        $responseText = '...';
        return $this->decodeXml($responseText, $map, $source->id . '-mt');
    }

    public function translateBatch(array $sources, string $sourceLanguage, string $targetLanguage): array
    {
        return array_map(fn($s) => $this->translate($s, $sourceLanguage, $targetLanguage), $sources);
    }

    public function getProviderId(): string { return 'my-mt'; }
}
```

Related packages
----------------

[](#related-packages)

- [`opencat/core`](https://github.com/shaikhammar/opencat-framework/tree/main/packages/core) — `MachineTranslationInterface`, `Segment`, `InlineCode`, `MtException`
- [`opencat/workflow`](https://github.com/shaikhammar/opencat-framework/tree/main/packages/workflow) — uses `MachineTranslationInterface` to fill segments below the TM threshold

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance61

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/c6b9044413071860fd6199e56c661a24f449797b77a1b130f0df7e98be8481f4?d=identicon)[shaikhammar](/maintainers/shaikhammar)

---

Top Contributors

[![actions-user](https://avatars.githubusercontent.com/u/65916846?v=4)](https://github.com/actions-user "actions-user (3 commits)")

### Embed Badge

![Health badge](/badges/opencat-mt/health.svg)

```
[![Health](https://phpackages.com/badges/opencat-mt/health.svg)](https://phpackages.com/packages/opencat-mt)
```

###  Alternatives

[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k104.3M822](/packages/laravel-socialite)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k38.6M289](/packages/laravel-dusk)[pinguo/php-msf

Pinguo Micro Service Framework For PHP

1.7k4.2k](/packages/pinguo-php-msf)[nineinchnick/edatatables

Grid widget for the Yii Framework, wrapper for the DataTables jQuery plugin

173.2k](/packages/nineinchnick-edatatables)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
