Skip to content

Commit

Permalink
Merge pull request #26 from ben182/develop
Browse files Browse the repository at this point in the history
0.5.0
  • Loading branch information
ben182 committed May 13, 2019
2 parents 21ba0cc + 512198b commit a4807eb
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 30 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
@@ -1,7 +1,6 @@
language: php

php:
- 7.1
- 7.2
- 7.3

Expand All @@ -18,9 +17,6 @@ env:

matrix:
fast_finish: true
exclude:
- php: 7.1
env: ILLUMINATE_VERSION=5.8.* PHPUNIT_VERSION=~8.0 COVERAGE=true

before_install:
- travis_retry composer self-update
Expand Down
26 changes: 22 additions & 4 deletions README.md
Expand Up @@ -4,16 +4,15 @@

<p align="center"><a href="https://github.com/ben182/laravel-auto-translate/releases"><img src="https://camo.githubusercontent.com/7aeaaffdab372bb7f1a7bc771400d9e18295916b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f62656e3138322f6c61726176656c2d6175746f2d7472616e736c6174652e7376673f7374796c653d666c61742d737175617265" alt="Latest Version" data-canonical-src="https://img.shields.io/github/release/ben182/laravel-auto-translate.svg?style=flat-square" style="max-width:100%;"></a>
<a href="https://travis-ci.org/ben182/laravel-auto-translate" rel="nofollow"><img src="https://camo.githubusercontent.com/8c01aa130a16fabf6a8e313719f4f274c7c401b4/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f62656e3138322f6c61726176656c2d6175746f2d7472616e736c6174652f6d61737465722e7376673f7374796c653d666c61742d737175617265" alt="Build Status" data-canonical-src="https://img.shields.io/travis/ben182/laravel-auto-translate/master.svg?style=flat-square" style="max-width:100%;"></a>
<a href="https://scrutinizer-ci.com/g/ben182/laravel-auto-translate" rel="nofollow"><img src="https://camo.githubusercontent.com/a2132ab348aaaeae4e0cfee432965a86b8d6b7af/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f62656e3138322f6c61726176656c2d6175746f2d7472616e736c6174652e7376673f7374796c653d666c61742d737175617265" alt="Quality Score" data-canonical-src="https://img.shields.io/scrutinizer/g/ben182/laravel-auto-translate.svg?style=flat-square" style="max-width:100%;"></a>
<a href="https://scrutinizer-ci.com/g/ben182/laravel-auto-translate/?branch=master" rel="nofollow"><img src="https://camo.githubusercontent.com/24eb67f423309ba600507b578cc04a925e6d4698/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f62656e3138322f6c61726176656c2d6175746f2d7472616e736c6174652f6261646765732f636f7665726167652e706e673f623d6d6173746572" alt="Code Coverage" data-canonical-src="https://scrutinizer-ci.com/g/ben182/laravel-auto-translate/badges/coverage.png?b=master" style="max-width:100%;"></a></p>
<a href="https://scrutinizer-ci.com/g/ben182/laravel-auto-translate" rel="nofollow"><img src="https://camo.githubusercontent.com/a2132ab348aaaeae4e0cfee432965a86b8d6b7af/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f62656e3138322f6c61726176656c2d6175746f2d7472616e736c6174652e7376673f7374796c653d666c61742d737175617265" alt="Quality Score" data-canonical-src="https://img.shields.io/scrutinizer/g/ben182/laravel-auto-translate.svg?style=flat-square" style="max-width:100%;"></a></p>

With this package you can translate your language files using a translator service. Currently the package ships only with Google Translate.
With this package you can translate your language files using a translator service. The package ships with a free Google Translate version and Deepl.

Specify a source language and a target language and it will automatically translate your files. This is useful if you want to prototype something quickly or just a first idea of the translation for later editing. The package ships with two artisan commands. One for translating all the missing translations that are set in the source language but not in the target language. The other one for translating all source language files and overwriting everything in the target language.

## Installation

This package can be used in Laravel 5.6 or higher.
This package can be used in Laravel 5.6 or higher and needs PHP 7.2 or higher.

You can install the package via composer:

Expand All @@ -31,6 +30,15 @@ php artisan vendor:publish --provider="Ben182\AutoTranslate\AutoTranslateService

You can specify your source language, the target language(s), the translator and the path to your language files in there.

## Translators

| Name | Free | File | Documentation | Available languages |
|-----------------------|------|---------------------------------------------------------|-------------------------------------|----------|
| Google Translate HTTP | Yes | Ben182\AutoTranslate\Translators\SimpleGoogleTranslator | / | Over 100 |
| Deepl API v2 | No | Ben182\AutoTranslate\Translators\DeeplTranslator | [Documentation](https://www.deepl.com/docs-api.html) | EN, DE, FR, ES, PT, IT, NL, PL, RU |

If you have lots of translations to make I recommend Deepl. It is fast, reliable and you will not encounter any rate limiting.

## Usage

### Missing translations
Expand Down Expand Up @@ -74,6 +82,16 @@ php artisan autotrans:all

This will overwrite every single key with a translation of the equivalent source language key.

### Parameters

Sometimes you have translations like these:

```php
'welcome' => 'Welcome, :name',
```

They can be replaced with variables. When we pass these placeholders to a translator service, weird things can happen. Sometimes the placeholder comes back in upper-case letters or it has been translated. Thankfully the package will respect your variable placeholders, so they will be the same after the translation.

## Extending

You can create your own translator by creating a class that implements `\Ben182\AutoTranslate\Translators\TranslatorInterface`. Simply reference it in your config file.
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -16,8 +16,9 @@
}
],
"require": {
"php": "^7.1",
"php": "^7.2",
"illuminate/support": "5.6.* || 5.7.* || 5.8.*",
"scn/deepl-api-connector": "^1.3",
"stichoza/google-translate-php": "^4.0",
"themsaid/laravel-langman": "^1.3"
},
Expand Down
6 changes: 6 additions & 0 deletions config/config.php
Expand Up @@ -29,4 +29,10 @@
// If you want to proxy the requests, you can specify a proxy server here.
'proxy' => '',
],

'deepl' => [

// Your DeepL API Key. See https://www.deepl.com/pro.html#developer
'api_key' => '',
],
];
34 changes: 32 additions & 2 deletions src/AutoTranslate.php
Expand Up @@ -9,7 +9,7 @@
class AutoTranslate
{
protected $manager;
protected $translator;
public $translator;

public function __construct(Langman $manager, TranslatorInterface $translator)
{
Expand Down Expand Up @@ -55,19 +55,49 @@ public function getMissingTranslations(string $lang)
return collect($dottedSource)->only($diff);
}

public function translate(string $targetLanguage, $data)
public function translate(string $targetLanguage, $data, $callbackAfterEachTranslation = null)
{
$this->translator->setTarget($targetLanguage);

$dottedSource = Arr::dot($data);

foreach ($dottedSource as $key => $value) {
$variables = $this->findVariables($value);

$dottedSource[$key] = is_string($value) ? $this->translator->translate($value) : $value;

$dottedSource[$key] = $this->replaceTranslatedVariablesWithOld($variables, $dottedSource[$key]);

if ($callbackAfterEachTranslation) {
$callbackAfterEachTranslation();
}
}

return $this->array_undot($dottedSource);
}

public function findVariables($string)
{
$m = null;

if (is_string($string)) {
preg_match_all('/:\S+/', $string, $m);
}

return $m;
}

public function replaceTranslatedVariablesWithOld($variables, $string)
{
if (isset($variables[0])) {
$replacements = $variables[0];

return preg_replace_callback('/:\S+/', function ($matches) use (&$replacements) {
return array_shift($replacements);
}, $string);
}
}

public function fillLanguageFiles(string $language, array $data)
{
foreach ($data as $languageFileKey => $translations) {
Expand Down
4 changes: 1 addition & 3 deletions src/AutoTranslateServiceProvider.php
Expand Up @@ -36,9 +36,7 @@ public function register()
// Automatically apply the package configuration
$this->mergeConfigFrom(__DIR__.'/../config/config.php', 'auto-translate');

$translator = config('auto-translate.translator');

$this->app->bind(TranslatorInterface::class, $translator);
$this->app->bind(TranslatorInterface::class, config('auto-translate.translator'));

// Register the main class to use with the facade
$this->app->singleton('auto-translate', function () {
Expand Down
20 changes: 13 additions & 7 deletions src/Commands/AllCommand.php
Expand Up @@ -3,6 +3,7 @@
namespace Ben182\AutoTranslate\Commands;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Ben182\AutoTranslate\AutoTranslate;

Expand Down Expand Up @@ -44,23 +45,28 @@ public function handle()
{
$targetLanguages = Arr::wrap(config('auto-translate.target_language'));

$this->line('Found '.count($targetLanguages).' languages to translate');
$foundLanguages = count($targetLanguages);
$this->line('Found '.$foundLanguages.' '.Str::plural('language', $foundLanguages).' to translate');

$bar = $this->output->createProgressBar(count($targetLanguages));
$availableTranslations = 0;
$sourceTranslations = $this->autoTranslator->getSourceTranslations();
$availableTranslations = count(Arr::dot($sourceTranslations)) * count($targetLanguages);

$bar = $this->output->createProgressBar($availableTranslations);
$bar->start();

foreach ($targetLanguages as $targetLanguage) {
$sourceTranslations = $this->autoTranslator->getSourceTranslations();
$dottedSource = Arr::dot($sourceTranslations);

$translated = $this->autoTranslator->translate($targetLanguage, $sourceTranslations);
$translated = $this->autoTranslator->translate($targetLanguage, $dottedSource, function () use ($bar) {
$bar->advance();
});

$this->autoTranslator->fillLanguageFiles($targetLanguage, $translated);

$bar->advance();
}

$bar->finish();

$this->info('Translated '.count(Arr::dot($sourceTranslations)).' language keys.');
$this->info("\nTranslated ".$availableTranslations.' language keys.');
}
}
24 changes: 15 additions & 9 deletions src/Commands/MissingCommand.php
Expand Up @@ -3,6 +3,7 @@
namespace Ben182\AutoTranslate\Commands;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Console\Command;
use Ben182\AutoTranslate\AutoTranslate;

Expand Down Expand Up @@ -44,26 +45,31 @@ public function handle()
{
$targetLanguages = Arr::wrap(config('auto-translate.target_language'));

$this->line('Found '.count($targetLanguages).' languages to translate');

$bar = $this->output->createProgressBar(count($targetLanguages));
$bar->start();
$foundLanguages = count($targetLanguages);
$this->line('Found '.$foundLanguages.' '.Str::plural('language', $foundLanguages).' to translate');

$missingCount = 0;

foreach ($targetLanguages as $targetLanguage) {
$missing = $this->autoTranslator->getMissingTranslations($targetLanguage);
$missingCount += $missing->count();
$this->line('Found '.$missing->count().' missing keys in '.$targetLanguage);
}

$bar = $this->output->createProgressBar($missingCount);
$bar->start();

$translated = $this->autoTranslator->translate($targetLanguage, $missing);
foreach ($targetLanguages as $targetLanguage) {
$missing = $this->autoTranslator->getMissingTranslations($targetLanguage);

$this->autoTranslator->fillLanguageFiles($targetLanguage, $translated);
$translated = $this->autoTranslator->translate($targetLanguage, $missing, function () use ($bar) {
$bar->advance();
});

$bar->advance();
$this->autoTranslator->fillLanguageFiles($targetLanguage, $translated);
}

$bar->finish();

$this->info('Translated '.$missingCount.' missing language keys.');
$this->info("\nTranslated ".$missingCount.' missing language keys.');
}
}
53 changes: 53 additions & 0 deletions src/Translators/DeeplTranslator.php
@@ -0,0 +1,53 @@
<?php

namespace Ben182\AutoTranslate\Translators;

use Scn\DeeplApiConnector\DeeplClient;
use Scn\DeeplApiConnector\Model\TranslationConfig;
use Scn\DeeplApiConnector\Exception\RequestException;
use Ben182\AutoTranslate\Exceptions\LanguageCodeNotExist;

class DeeplTranslator implements TranslatorInterface
{
protected $translator;
protected $source;
protected $target;

public function __construct()
{
$this->translator = DeeplClient::create(config('auto-translate.deepl.api_key'));
}

public function setSource(string $source)
{
$this->source = strtoupper($source);

return $this;
}

public function setTarget(string $target)
{
$this->target = strtoupper($target);

return $this;
}

public function translate(string $string) : string
{
$translation = new TranslationConfig(
$string,
$this->target,
$this->source
);

try {
return $this->translator->getTranslation($translation)->getText();
} catch (RequestException $th) {
if ($th->getMessage() === '400 {"message":"Value for \'target_lang\' is not supported."}') {
throw LanguageCodeNotExist::throw($this->source, $this->target);
}

throw $th;
}
}
}
2 changes: 2 additions & 0 deletions src/Translators/SimpleGoogleTranslator.php
Expand Up @@ -50,6 +50,8 @@ public function translate(string $string) : string
if ($th->getMessage() === 'Return value of Stichoza\GoogleTranslate\GoogleTranslate::translate() must be of the type string, null returned') {
throw LanguageCodeNotExist::throw($this->source, $this->target);
}

throw $th;
}
}
}

0 comments on commit a4807eb

Please sign in to comment.