PHPackages                             ali-translator/translator - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. ali-translator/translator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ali-translator/translator
=========================

Translator

v0.8.10(11mo ago)41.6k3MITPHPPHP &gt;=7.4 &lt;8.5

Since Mar 5Pushed 10mo ago2 watchersCompare

[ Source](https://github.com/ali-translator/translator)[ Packagist](https://packagist.org/packages/ali-translator/translator)[ Docs](https://sli.su/)[ RSS](/packages/ali-translator-translator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (2)Versions (28)Used By (3)

Translator
==========

[](#translator)

The Translation component provides tools to internationalize your application.

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

[](#installation)

Supports PHP 7.4 through 8.4.

```
$ composer require ali-translator/translator
```

### Simplified translator

[](#simplified-translator)

Example of init one direction translator (one original and one translation languages):

```
use \ALI\Translator\Source\Sources\MySqlSource\MySqlSource;
use \ALI\Translator\PlainTranslator\PlainTranslatorFactory;

$originalLanguageAlias = 'en';
$translationLanguageAlias = 'ru';

$connection = new PDO(SOURCE_MYSQL_DNS, SOURCE_MYSQL_USER, SOURCE_MYSQL_PASSWORD);
$source = new MySqlSource($connection, $originalLanguageAlias);

// Install source
$installer = $source->generateInstaller();
if (!$installer->isInstalled()) {
    $installer->install();
    // $installer->destroy();
}

$plainTranslator = (new PlainTranslatorFactory())->createPlainTranslator($source, $translationLanguageAlias);

$plainTranslator->saveTranslate('Hello','Привет');
$plainTranslator->translate('Hello', true); // -> 'Привет'
$plainTranslator->translateAll(['Hello']); // -> ['Привет']

// Try translate not exist phrase
$plainTranslator->translate('Goodbye', false); // -> null
$plainTranslator->translate('Goodbye', true); // With fallback -> 'Goodbye'

$plainTranslator->delete('Hello');
```

### Complex translator

[](#complex-translator)

If you need few original and translation languages, this way for you:

```
use \ALI\Translator\Translator;
use \ALI\Translator\Source\SourceInterface;
use \ALI\Translator\Source\SourcesCollection;
use \ALI\Translator\PlainTranslator\PlainTranslator;

/** @var SourceInterface $firsSource */
/** @var SourceInterface $secondSource */

$sourceCollection = new SourcesCollection();
$sourceCollection->addSource($firsSource,['ua', 'ru']);
$sourceCollection->addSource($secondSource); // Second source for all another translation languages
$translator = new Translator($sourceCollection);

$translator->saveTranslate('en', 'ru', 'Hello', 'Привет');
$translator->translate('en', 'ru', 'Hello');

// Also, if you need, you always can transform translator to plainTranslator to work simplification
$plainTranslator = new PlainTranslator('en', 'ru', $translator);
```

### Parameters resolving

[](#parameters-resolving)

```
/** @var \ALI\Translator\PlainTranslator\PlainTranslatorInterface $plainTranslator */

// Simple parameter
$translatedPhrase = $plainTranslator->translate('Осталось {number}', true);
echo MessageFormatter::formatMessage('ru_RU', $translatedPhrase, ['number' => 25]);
// -> 'Осталось 25'

// Plural forms
$translatedPhrase = $plainTranslator->translate('Осталось {placeLeft, plural, =0{# мест} one{# место} few{# места} other{# мест}}', true);
echo MessageFormatter::formatMessage('ru_RU', $translatedPhrase, [
    'placeLeft' => 1,
]);
// -> 'Осталось 1 место'
```

### Events

[](#events)

- Catchers of missing translations Packet allow set catchers of phrases without translation, which will run after `translate` method failing

```
use ALI\Translator\TranslatorInterface;
use ALI\Translator\MissingTranslateCatchers\CollectorMissingTranslatesCatcher;

/** @var TranslatorInterface $translator */
$translator->addMissingTranslationCatchers(function (string $searchPhrase, TranslatorInterface $translator){
    ...
});

// Or use existed CollectorMissingTranslatesCatcher
$collectorMissingTranslatesCatcher = new CollectorMissingTranslatesCatcher();
$translator->addMissingTranslationCatchers($collectorMissingTranslatesCatcher);
$translator->translate('Hello 123');
$collectorMissingTranslatesCatcher->getOriginalPhraseCollectionsByLanguageAlias('ru')->getAll();
 // -> ['Hello 123']
```

- [SourceWriter events](./src/Source/Sources/EventDriven/README.md)

### Phrase decorators

[](#phrase-decorators)

If you need decorate original-phrase or translated-phrase before output - this section for you.
Example, of existed decorator, which replaces numbers to "0" before saving originals, and restoring correct number after translate.

```
use ALI\Translator\Decorators\PhraseDecorators\OriginalDecorators\ReplaceNumbersOriginalDecorator;
use ALI\Translator\Decorators\PhraseDecorators\OriginalPhraseDecoratorManager;
use ALI\Translator\Decorators\PhraseDecorators\TranslateDecorators\RestoreNumbersTranslateDecorator;
use ALI\Translator\Decorators\PhraseDecorators\TranslatePhraseDecoratorManager;
use ALI\Translator\Decorators\PhraseTranslatorDecorator;
use ALI\Translator\TranslatorInterface;
use ALI\Translator\PlainTranslator\PlainTranslator;

/** @var TranslatorInterface $translator */

$originalDecoratorManger = new OriginalPhraseDecoratorManager([
    new ReplaceNumbersOriginalDecorator(),
]);
$translateDecoratorManager = new TranslatePhraseDecoratorManager([
    new RestoreNumbersTranslateDecorator(),
]);

$phraseTranslatorDecorator = new PhraseTranslatorDecorator($translator, $originalDecoratorManger, $translateDecoratorManager);
// For simplifying
$plainPhraseTranslatorDecorator = new PlainTranslator('en', 'ua', $phraseTranslatorDecorator);

$plainPhraseTranslatorDecorator->saveTranslate('Hello 123 Hi 000', 'Привіт 123 Хай 000');
// and when translate text with another numbers, you get previous saved translation
$plainPhraseTranslatorDecorator->translate('Hello 555 Hi 8676', true);
// -> 'Привіт 555 Хай 8676'
```

### Originals grouping

[](#originals-grouping)

Optionality, you can add group to the originals. This can be useful for cases, when many different processes adding originals, and then when one of these processes removes its dependencies form them, to deciding whether to remove the original from the translator - use the groups. If original now does not have any group - remove them.

```
use ALI\Translator\OriginalGroups\Repository\Mysql\MysqlOriginalGroupRepository;
use ALI\Translator\OriginalGroups\Repository\Mysql\MySqlRepositoryConfig;
use ALI\Translator\Source\SourceInterface;
use \PDO;

/** @var SourceInterface $translatorSource */
/** @var PDO $pdo */

$mysqlConfig = new MySqlRepositoryConfig($pdo);
$groupRepositories = new MysqlOriginalGroupRepository($mysqlConfig, $translatorSource);

// Installing
$installer = $groupRepositories->generateInstaller();
if(!$installer->isInstalled()){
    $installer->install();
    // $installer->destroy();
}

// Use cases
$groupRepositories->addGroups(['Hello world','test'],['default','models']);
$groupRepositories->getGroups(['Hello world','test']);
$groupRepositories->getOriginalsByGroup('default', 0 , 20);

$groupRepositories->removeGroups(['Hello world','test'],['default']);
$groupRepositories->removeAllGroups(['Hello world','test']);
```

#### Available sources

[](#available-sources)

- **MySqlSource** - recommended for using with [ali-translator/buffered-translation](https://github.com/ali-translator/buffered-translation) to reduce the number of requests to Source
- **CsvFileSource** - csv source. Files will be look like as `en-ua.csv`

### Languages

[](#languages)

For convenience, a couple of classes are integrated into this package to help with languages.
`LanguageInterface` - Has `getTitle()`, `getIsoCode()` and `getAlias()`methods
`LanguageRepositoryInterface` - Has `save(LanguageInterface $language, $isActive)`, `find($alias)`, `findByIsoCode($isoCode)`, `getAll($onlyActive)` methods.
And realizations for repository interface: `ArrayLanguageRepository`(`ArrayLanguageRepositoryFactory`) and `MySqlLanguageRepository`

### Suggest packets

[](#suggest-packets)

- **[ali-translator/buffered-translation](https://github.com/ali-translator/buffered-translation)** - Manually pasted text on document for translation, by means of buffering is translated by one approach (helpful for DB sources)
- **[ali-translator/translator-js-integrate](https://github.com/ali-translator/translator-js-integrate)** - Integrate this packet to frontend js
- **[ali-translator/auto-html-translation](https://github.com/ali-translator/auto-html-translation)** - Parses html document, and translate included texts
- **[ali-translator/url-template](https://github.com/ali-translator/url-template)** - Helps on url language resolving

### Tests

[](#tests)

In packet exist docker-compose file, with environment for testing.

```
docker-compose up -d
docker-compose exec php bash
docker-compose run php composer install
docker-compose run php vendor/bin/phpunit
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance54

Moderate activity, may be stable

Popularity22

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 92.7% 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.

###  Release Activity

Cadence

Every ~65 days

Recently: every ~218 days

Total

25

Last Release

337d ago

PHP version history (4 changes)v0.1PHP &gt;=5.6.0

v0.4PHP &gt;=7.0

v0.8.3PHP &gt;=7.4

v0.8.10PHP &gt;=7.4 &lt;8.5

### Community

Maintainers

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

---

Top Contributors

[![Slayer911](https://avatars.githubusercontent.com/u/9704032?v=4)](https://github.com/Slayer911 "Slayer911 (38 commits)")[![Web-bbb](https://avatars.githubusercontent.com/u/216318048?v=4)](https://github.com/Web-bbb "Web-bbb (3 commits)")

---

Tags

sli

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ali-translator-translator/health.svg)

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

PHPackages © 2026

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