Skip to content

Commit f1ad42d

Browse files
committed
add grammar support
1 parent 6537a12 commit f1ad42d

File tree

5 files changed

+169
-6
lines changed

5 files changed

+169
-6
lines changed

README.md

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ return [
5151

5252
## Usage
5353

54-
You can use the package like a CLI tool with the following command:
54+
This package can be used:
55+
56+
- Like a CLI tool, using commands.
57+
- In a programmatic way using `\Elegantly\Translator\Facades\Translator::class` facade class.
5558

5659
### Sort all translations in natural order
5760

@@ -61,14 +64,80 @@ You can format and sort all your php translations files using:
6164
php artisan translator:sort
6265
```
6366

64-
### Finnd the missing translations
67+
```php
68+
use Elegantly\Translator\Facades\Translator;
69+
70+
Translator::sortAllTranslations();
71+
```
72+
73+
### Find the missing translations
6574

6675
You can display all the missing translations present in a given locale but not in the other ones using:
6776

6877
```bash
6978
php artisan translator:missing fr
7079
```
7180

81+
```php
82+
use Elegantly\Translator\Facades\Translator;
83+
84+
Translator::getAllMissingTranslations('fr');
85+
```
86+
87+
### Auto translate strings
88+
89+
This package can automatically translate your files for you.
90+
It includes 2 services right now:
91+
92+
- DeepL
93+
- OpenAI
94+
95+
You can also define your own service.
96+
97+
### Auto-translate using DeepL
98+
99+
First, you need to edit the config file to add your DeepL api key and select deepl as your service:
100+
101+
```php
102+
return [
103+
'translate' => [
104+
'service' => 'deepl', // select the default service here
105+
106+
'services' => [
107+
'deepl' => [
108+
'key' => env('DEEPL_KEY'), // add you api key here
109+
],
110+
111+
],
112+
],
113+
]
114+
```
115+
116+
To translate all the missing translations use:
117+
118+
```bash
119+
php artisan translator:translate --from=fr --to=en
120+
```
121+
122+
To translate all translations use:
123+
124+
```bash
125+
php artisan translator:translate --from=fr --to=en --all
126+
```
127+
128+
Ommitting the `--to` option will translate to every available languages in your project.
129+
130+
```php
131+
use Elegantly\Translator\Facades\Translator;
132+
133+
Translator::translateTranslations(
134+
referenceLocale: 'fr',
135+
targetLocale: 'en',
136+
namespace: 'namespace-file',
137+
keys: ['title', ...]
138+
);
139+
```
140+
72141
## Testing
73142

74143
```bash
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Elegantly\Translator\Commands;
4+
5+
use Elegantly\Translator\Facades\Translator;
6+
use Elegantly\Translator\TranslatorServiceProvider;
7+
use Illuminate\Console\Command;
8+
use Illuminate\Support\Collection;
9+
10+
class FixGrammarTranslationsCommand extends Command
11+
{
12+
public $signature = 'translator:grammar {--locales=} {--service=} ';
13+
14+
public $description = 'Translate translations from the given locale to the target one.';
15+
16+
public function handle(): int
17+
{
18+
$serviceArg = $this->option('service');
19+
$localesArg = explode(",", (string) $this->option('locales'));
20+
21+
$service = TranslatorServiceProvider::getGrammarServiceFromConfig($serviceArg);
22+
23+
$locales = collect(Translator::getLanguages())
24+
->when($localesArg, fn (Collection $items) => $items->intersect($localesArg));
25+
26+
27+
foreach ($locales as $locale) {
28+
29+
$this->info("Fixing grammar in '{$locale}' locale:");
30+
$this->line('Using service ' . get_class($service));
31+
32+
$namespaces = Translator::getNamespaces($locale);
33+
34+
foreach ($namespaces as $namespace) {
35+
36+
$keys = Translator::getTranslations($locale, $namespace)
37+
->dot()
38+
->keys()
39+
->toArray();
40+
41+
$this->line(count($keys) . " keys to fix found in {$locale}/{$namespace}.php");
42+
if (!$this->confirm("Would you like to continue?", true)) {
43+
continue;
44+
}
45+
46+
$translations = Translator::fixGrammarTranslations(
47+
$locale,
48+
$namespace,
49+
$keys,
50+
$service
51+
);
52+
53+
$this->table(
54+
headers: ['key', 'Translation'],
55+
rows: $translations->dot()->map(fn ($value, $key) => ["{$namespace}.{$key}", $value])
56+
);
57+
}
58+
}
59+
60+
return self::SUCCESS;
61+
}
62+
}

src/Commands/TranslateTranslationsCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function handle(): int
3131

3232
$this->info("Translating from '{$from}' to '{$target}':");
3333
if ($service) {
34-
$this->line('Using custom service '.get_class($service));
34+
$this->line('Using custom service ' . get_class($service));
3535
}
3636

3737
foreach ($namespaces as $namespace) {
@@ -42,7 +42,7 @@ public function handle(): int
4242
$keys = Translator::getMissingTranslations($from, $target, $namespace);
4343
}
4444

45-
if (! $this->confirm(count($keys)." keys to translate found in {$target}.{$namespace}.php, would you like to continue?", true)) {
45+
if (!$this->confirm(count($keys) . " keys to translate found in {$target}/{$namespace}.php, would you like to continue?", true)) {
4646
continue;
4747
}
4848

src/Facades/Translator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Elegantly\Translator\Facades;
44

5+
use Elegantly\Translator\Services\Grammar\GrammarServiceInterface;
56
use Elegantly\Translator\Services\Translate\TranslateServiceInterface;
67
use Elegantly\Translator\Translations;
78
use Illuminate\Support\Facades\Facade;
@@ -12,6 +13,7 @@
1213
* @method static Translations getTranslations(string $locale, string $namespace)
1314
* @method static Translations sortTranslations(string $locale, string $namespace)
1415
* @method static Translations translateTranslations(string $referenceLocale, string $targetLocale, string $namespace, array $keys, ?TranslateServiceInterface $service)
16+
* @method static Translations fixGrammarTranslations(string $locale, string $namespace, array $keys, ?GrammarServiceInterface $service)
1517
* @method static array<int, string> getMissingTranslations(string $referenceLocale, string $targetLocale, string $namespace)
1618
* @method static array getAllMissingTranslations(string $referenceLocale)
1719
* @method static void sortAllTranslations()

src/Translator.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ function (Translations $translations) use ($referenceLocale, $targetLocale, $nam
142142

143143
$referenceTranslations = $this->getTranslations($referenceLocale, $namespace);
144144

145-
$referenceValues = collect($keys)
146-
->mapWithKeys(fn (string $key) => [$key => $referenceTranslations->get($key)])
145+
$referenceValues = $referenceTranslations
146+
->dot()
147+
->only($keys)
147148
->filter(fn ($value) => ! blank($value))
148149
->toArray();
149150

@@ -161,6 +162,35 @@ function (Translations $translations) use ($referenceLocale, $targetLocale, $nam
161162
)->only($keys);
162163
}
163164

165+
public function fixGrammarTranslations(
166+
string $locale,
167+
string $namespace,
168+
array $keys,
169+
?GrammarServiceInterface $service = null,
170+
): Translations {
171+
$service = $service ?? $this->grammarService;
172+
173+
if (! $service) {
174+
throw TranslatorServiceException::missingGrammarService();
175+
}
176+
177+
return $this->transformTranslations($locale, $namespace, function (Translations $translations) use ($service, $keys) {
178+
179+
$fixedTranslations = $service->fixAll(
180+
texts: $translations->dot()
181+
->only($keys)
182+
->filter(fn ($value) => ! blank($value))
183+
->toArray()
184+
);
185+
186+
foreach ($fixedTranslations as $key => $value) {
187+
$translations->set($key, $value);
188+
}
189+
190+
return $translations;
191+
});
192+
}
193+
164194
public function translateTranslation(
165195
string $referenceLocale,
166196
string $targetLocale,

0 commit comments

Comments
 (0)