The Translation component provides tools to internationalize your application.
$ composer require ali-translator/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');
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);
/** @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 место'
Packet allow set catchers of phrases without translation, which will run after tranlsate
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']
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'
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']);
- MySqlSource - recommended for using with ali-translator/buffered-translation to reduce the number of requests to Source
- CsvFileSource - csv source. Files will be look like as
en-ua.csv
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
- 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 - Integrate this packet to frontend js
- ali-translator/auto-html-translation - Parses html document, and translate included texts
- ali-translator/url-template - Helps on url language resolving
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