Skip to content

Commit

Permalink
better missing keys algo
Browse files Browse the repository at this point in the history
  • Loading branch information
QuentinGab committed Jun 18, 2024
1 parent e76900e commit 05763dc
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 54 deletions.
2 changes: 1 addition & 1 deletion config/translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
],
'openai' => [
'model' => 'gpt-4o',
'prompt' => 'Translate the following json to the locale {targetLocale} while preserving the keys.',
'prompt' => "Translate the following json to the locale '{targetLocale}' while preserving the keys.",
],
],
];
38 changes: 21 additions & 17 deletions src/Services/OpenAiService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Elegantly\Translator\Services;

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use OpenAI\Laravel\Facades\OpenAI;

class OpenAiService implements TranslatorServiceInterface
Expand All @@ -16,25 +17,28 @@ public function __construct(

public function translateAll(array $texts, string $targetLocale): array
{
$response = OpenAI::chat()->create([
'model' => $this->model,
'messages' => [
[
'role' => 'system',
'content' => str_replace('{targetLocale}', $targetLocale, $this->prompt),
],
[
'role' => 'user',
'content' => json_encode($texts),
],
],
]);
return collect($texts)
->chunk(50)
->flatMap(function (Collection $chunk) use ($targetLocale) {
$response = OpenAI::chat()->create([
'model' => $this->model,
'messages' => [
[
'role' => 'system',
'content' => str_replace('{targetLocale}', $targetLocale, $this->prompt),
],
[
'role' => 'user',
'content' => json_encode($chunk),
],
],
]);

$translations = $response->choices[0]->message->content;
$translations = json_decode($response->choices[0]->message->content);

return array_map(function (?string $textResult) {
return $textResult;
}, Arr::wrap($translations));
return $translations;
})
->toArray();
}

public function translate(string $text, string $targetLocale): ?string
Expand Down
11 changes: 11 additions & 0 deletions src/Translations.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,15 @@ protected function recursiveSortNatural(array $items): array

return $items;
}

public function getMissingTranslationsIn(Translations $translations): array
{
$dotted = $this->dot()->toBase();
$translationsDotted = $translations->dot()->filter(fn ($item) => ! blank($item))->toBase();

return $dotted
->diffKeys($translationsDotted)
->keys()
->toArray();
}
}
37 changes: 1 addition & 36 deletions src/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,42 +71,7 @@ public function getMissingTranslations(
$referenceTranslations = $this->getTranslations($referenceLocale, $namespace);
$targetTranslations = $this->getTranslations($targetLocale, $namespace);

return $this->recursivelyGetMissingTranslation($referenceTranslations, $targetTranslations);
}

protected function recursivelyGetMissingTranslation(
Translations $referenceTranslations,
Translations $targetTranslations,
?string $path = null
): array {
$missingTranslations = [];

foreach ($referenceTranslations as $key => $referenceValue) {
$newPath = (string) ($path ? "{$path}.{$key}" : $key);

$targetValue = $targetTranslations->get($key);

if (
gettype($referenceValue) !== gettype($targetValue) ||
$targetValue === null ||
$targetValue === ''
) {
$missingTranslations[] = $newPath;
}

if (is_array($referenceValue)) {
$missingTranslations = [
...$missingTranslations,
...$this->recursivelyGetMissingTranslation(
new Translations($referenceValue),
new Translations(is_array($targetValue) ? $targetValue : []),
$newPath
),
];
}
}

return $missingTranslations;
return $referenceTranslations->getMissingTranslationsIn($targetTranslations);
}

/**
Expand Down
36 changes: 36 additions & 0 deletions tests/Unit/TranslationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,39 @@
'd' => null,
]);
});

it('finds missing (nested) translations in another collections', function () {
$translations = new Translations([
'a' => 'text',
'b' => 'text',
'c' => [
'a' => 'text',
'b' => 'text',
],
'd' => 'text',
'e' => 'text',
'f' => [
'a' => 'text',
],
]);

$missingTranslations = $translations->getMissingTranslationsIn(
new Translations([
'a' => 'text',
'c' => [
'b' => 'text',
],
'd' => '',
'e' => null,
'f' => [],
])
);

expect($missingTranslations)->toBe([
'b',
'c.a',
'd',
'e',
'f.a',
]);
});

0 comments on commit 05763dc

Please sign in to comment.