Skip to content

Commit 6488d79

Browse files
committed
support json translations
1 parent 2c0f08b commit 6488d79

19 files changed

+523
-313
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
Manage all your laravel translations easily:
99

10-
- Sort tranlations array in natural order
11-
- Find missing translations strings
1210
- Translate strings to other languages (DeepL, OpenAI or any custom service)
13-
- Fix Grammar and syntax in your translations (OpenAI, or any custome service)
14-
- Format your translations files
11+
- Proofread your translations strings and automatically fix grammar and syntax (OpenAI, or any custome service)
12+
- Find missing translations strings in all your locales
1513
- Find dead translations keys (keys not used anywhere in your codebase)
14+
- Sort your tranlations in natural order
15+
- Format your translations files
1616

1717
## Installation
1818

config/translator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
],
2525
],
2626

27-
'grammar' => [
27+
'proofread' => [
2828
'service' => 'openai',
2929
'services' => [
3030
'openai' => [
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Elegantly\Translator\Collections;
4+
5+
use Illuminate\Support\Collection;
6+
7+
/**
8+
* @extends Collection<string, string|int|float|null>
9+
*/
10+
final class JsonTranslations extends Collection implements TranslationsInterface
11+
{
12+
public function set(string|int|null $key, mixed $value): static
13+
{
14+
return $this->put($key, $value);
15+
}
16+
17+
public function sortNatural(): static
18+
{
19+
return $this->sortKeys(SORT_NATURAL);
20+
}
21+
22+
public function toDotTranslations(): Collection
23+
{
24+
return $this->toBase();
25+
}
26+
27+
public function toTranslationsKeys(): Collection
28+
{
29+
return $this->toDotTranslations()->keys();
30+
}
31+
32+
public function toTranslationsValues(): Collection
33+
{
34+
return $this->toDotTranslations()->values();
35+
}
36+
37+
public function diffTranslationsKeys(Collection $translations): Collection
38+
{
39+
$translationsKeys = $translations
40+
->dot()
41+
->filter(fn ($item) => ! blank($item))
42+
->keys()
43+
->toBase();
44+
45+
return $this
46+
->toTranslationsKeys()
47+
->diff($translationsKeys)
48+
->values();
49+
}
50+
51+
public function toFile(): string
52+
{
53+
return $this->toJson();
54+
}
55+
}
Lines changed: 78 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
11
<?php
22

3-
namespace Elegantly\Translator;
3+
namespace Elegantly\Translator\Collections;
44

55
use Illuminate\Support\Arr;
66
use Illuminate\Support\Collection;
77

88
/**
99
* @extends Collection<string|int, array|string|int|float|null>
1010
*/
11-
final class Translations extends Collection
11+
final class PhpTranslations extends Collection implements TranslationsInterface
1212
{
13-
//
14-
15-
/**
16-
* Set a value with dot notation
17-
*/
18-
public function set(string|int $key, array|string|int|float|null $value): static
13+
public function set(string|int|null $key, mixed $value): static
1914
{
2015
Arr::set($this->items, $key, $value);
2116

2217
return $this;
2318
}
2419

25-
public function get($key, $default = null): array|string|int|float|null
20+
public function get($key, $default = null)
2621
{
2722
return Arr::get($this->items, $key);
2823
}
@@ -36,38 +31,18 @@ public function forget($keys): static
3631
return $this;
3732
}
3833

39-
/**
40-
* Write the lines of the inner array of the language file.
41-
*/
42-
public function toFile(
43-
?array $items = null,
44-
string $prefix = '',
45-
): string {
46-
$items = $items ?? $this->items;
47-
48-
$output = '';
49-
50-
foreach ($items as $key => $value) {
51-
if (is_array($value)) {
52-
$value = $this->toFile($value, $prefix.' ');
53-
54-
if (is_string($key)) {
55-
$output .= "\n{$prefix} '{$key}' => [{$value}\n {$prefix}],";
56-
} else {
57-
$output .= "\n{$prefix} [{$value}\n {$prefix}],";
58-
}
59-
} else {
60-
$value = str_replace('\"', '"', addslashes($value));
61-
62-
if (is_string($key)) {
63-
$output .= "\n{$prefix} '{$key}' => '{$value}',";
64-
} else {
65-
$output .= "\n{$prefix} '{$value}',";
66-
}
67-
}
68-
}
34+
public function only($keys): static
35+
{
36+
return new static(
37+
$this->toBase()->dot()->only($keys)->undot()
38+
);
39+
}
6940

70-
return $output;
41+
public function except($keys): static
42+
{
43+
return new static(
44+
$this->toBase()->dot()->except($keys)->undot()
45+
);
7146
}
7247

7348
public function sortNatural(): static
@@ -90,28 +65,76 @@ protected function recursiveSortNatural(array $items): array
9065
return $items;
9166
}
9267

93-
public function getMissingTranslationsIn(Translations $translations): array
68+
public function toDotTranslations(): Collection
9469
{
95-
$dotted = $this->dot()->toBase();
96-
$translationsDotted = $translations->dot()->filter(fn ($item) => ! blank($item))->toBase();
70+
return $this->dot()->toBase();
71+
}
9772

98-
return $dotted
99-
->diffKeys($translationsDotted)
100-
->keys()
101-
->toArray();
73+
public function toTranslationsKeys(): Collection
74+
{
75+
return $this->toDotTranslations()->keys();
10276
}
10377

104-
public function only($keys): static
78+
public function toTranslationsValues(): Collection
10579
{
106-
return new static(
107-
$this->toBase()->dot()->only($keys)->undot()
108-
);
80+
return $this->toDotTranslations()->values();
10981
}
11082

111-
public function except($keys): static
83+
public function diffTranslationsKeys(Collection $translations): Collection
11284
{
113-
return new static(
114-
$this->toBase()->dot()->except($keys)->undot()
115-
);
85+
$translationsKeys = $translations
86+
->dot()
87+
->filter(fn ($item) => ! blank($item))
88+
->keys()
89+
->toBase();
90+
91+
return $this
92+
->toTranslationsKeys()
93+
->diff($translationsKeys)
94+
->values();
95+
}
96+
97+
/**
98+
* Write the lines of the inner array of the language file.
99+
*/
100+
public function toFile(): string
101+
{
102+
$content = "<?php\n\nreturn [";
103+
104+
$content .= $this->recursiveToFile($this->items);
105+
106+
$content .= "\n];\n";
107+
108+
return $content;
109+
}
110+
111+
public function recursiveToFile(
112+
array $items,
113+
string $prefix = '',
114+
): string {
115+
116+
$output = '';
117+
118+
foreach ($items as $key => $value) {
119+
if (is_array($value)) {
120+
$value = $this->recursiveToFile($value, $prefix.' ');
121+
122+
if (is_string($key)) {
123+
$output .= "\n{$prefix} '{$key}' => [{$value}\n {$prefix}],";
124+
} else {
125+
$output .= "\n{$prefix} [{$value}\n {$prefix}],";
126+
}
127+
} else {
128+
$value = str_replace('\"', '"', addslashes($value));
129+
130+
if (is_string($key)) {
131+
$output .= "\n{$prefix} '{$key}' => '{$value}',";
132+
} else {
133+
$output .= "\n{$prefix} '{$value}',";
134+
}
135+
}
136+
}
137+
138+
return $output;
116139
}
117140
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Elegantly\Translator\Collections;
4+
5+
use Illuminate\Support\Collection;
6+
7+
interface TranslationsInterface
8+
{
9+
public function set(string|int|null $key, mixed $value): static;
10+
11+
public function get($key, $default = null);
12+
13+
public function forget($keys);
14+
15+
public function only($keys);
16+
17+
public function except($keys);
18+
19+
public function sortNatural(): static;
20+
21+
public function toDotTranslations(): Collection;
22+
23+
public function toTranslationsKeys(): Collection;
24+
25+
public function toTranslationsValues(): Collection;
26+
27+
public function diffTranslationsKeys(Collection $translations): Collection;
28+
29+
public function toFile(): string;
30+
}

src/Commands/FixGrammarTranslationsCommand.php renamed to src/Commands/ProofreadTranslationsCommand.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
use function Laravel\Prompts\progress;
1515
use function Laravel\Prompts\select;
1616

17-
class FixGrammarTranslationsCommand extends Command implements PromptsForMissingInput
17+
class ProofreadTranslationsCommand extends Command implements PromptsForMissingInput
1818
{
19-
public $signature = 'translator:grammar
19+
public $signature = 'translator:proofread
2020
{locale : The locale to fix}
2121
{--namespaces=* : The namespaces to fix}
2222
{--service= : The service to use}';
2323

24-
public $description = 'Fix grammar in the given locale translations.';
24+
public $description = 'Proofread the translations in the given locale.';
2525

2626
public function handle(): int
2727
{
@@ -32,21 +32,21 @@ public function handle(): int
3232
$namespaces = $this->option('namespaces');
3333

3434
progress(
35-
label: 'Fixing grammar',
35+
label: 'Proofreading',
3636
steps: $namespaces,
3737
callback: function (string $namespace, Progress $progress) use ($locale, $service) {
38-
$progress->label("Fixing {$namespace}");
38+
$progress->label("Proofreading {$namespace}");
3939

4040
$keys = Translator::getTranslations($locale, $namespace)
4141
->dot()
4242
->keys()
4343
->toArray();
4444

45-
Translator::fixGrammarTranslations(
45+
Translator::proofreadTranslations(
4646
locale: $locale,
4747
namespace: $namespace,
4848
keys: $keys,
49-
service: TranslatorServiceProvider::getGrammarServiceFromConfig($service)
49+
service: TranslatorServiceProvider::getproofreadServiceFromConfig($service)
5050
);
5151
},
5252
);
@@ -59,7 +59,7 @@ public function promptForMissingArgumentsUsing()
5959
return [
6060
'locale' => function () {
6161
return select(
62-
label: 'What locale would you like to fix?',
62+
label: 'What locale would you like to proofread?',
6363
options: Translator::getLocales(),
6464
default: config('app.locale'),
6565
required: true,
@@ -79,7 +79,7 @@ public function afterPromptingForMissingArguments(InputInterface $input, OutputI
7979
$options = Translator::getNamespaces($this->argument('locale'));
8080

8181
$input->setOption('namespaces', multiselect(
82-
label: 'What namespaces would you like to fix?',
82+
label: 'What namespaces would you like to proofread?',
8383
options: $options,
8484
default: $options,
8585
required: true,
@@ -89,8 +89,8 @@ public function afterPromptingForMissingArguments(InputInterface $input, OutputI
8989
if ($input->getOption('service') === null) {
9090
$input->setOption('service', select(
9191
label: 'What service would you like to use?',
92-
options: array_keys(config('translator.grammar.services')),
93-
default: config('translator.grammar.service'),
92+
options: array_keys(config('translator.proofread.services')),
93+
default: config('translator.proofread.service'),
9494
required: true,
9595
));
9696
}

src/Commands/TranslateTranslationsCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public function handle(): int
5252
}
5353

5454
return Translator::translateTranslations(
55-
referenceLocale: $from,
56-
targetLocale: $to,
55+
source: $from,
56+
target: $to,
5757
namespace: $namespace,
5858
keys: $keys,
5959
service: TranslatorServiceProvider::getTranslateServiceFromConfig($service)

src/Exceptions/TranslatorServiceException.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public static function missingTranslateService(): self
1111
return new self('The translate service is missing. Please define a translate service in configs.');
1212
}
1313

14-
public static function missingGrammarService(): self
14+
public static function missingProofreadService(): self
1515
{
16-
return new self('The grammar service is missing. Please define a grammar service in configs.');
16+
return new self('The proofread service is missing. Please define a proofread service in configs.');
1717
}
1818

1919
public static function missingSearchcodeService(): self

0 commit comments

Comments
 (0)