Skip to content

Commit c19cfb2

Browse files
committed
validate locales
1 parent e791433 commit c19cfb2

File tree

12 files changed

+155
-15
lines changed

12 files changed

+155
-15
lines changed

README.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,29 @@ Easily manage all your Laravel translation strings with powerful features:
2626
# Table of Contents
2727

2828
1. [Installation](#installation)
29-
2. [Configuring the Driver](#configuring-the-driver)
30-
3. [Sorting and Formatting](#sorting-and-formatting)
29+
1. [Configuring the Driver](#configuring-the-driver)
30+
1. [Configuring the Locales](#configuring-the-locales)
31+
1. [Sorting and Formatting](#sorting-and-formatting)
3132
- [CLI Commands](#cli-commands)
3233
- [Using Code](#using-code)
33-
4. [Automatic Translation](#automatic-translation)
34+
1. [Automatic Translation](#automatic-translation)
3435
- [Configuring OpenAI](#configuring-openai)
3536
- [Configuring DeepL](#configuring-deepl)
3637
- [CLI Translation](#cli-translation)
3738
- [Programmatic Translation](#programmatic-translation)
38-
5. [Proofreading Translations](#proofreading-translations)
39+
1. [Proofreading Translations](#proofreading-translations)
3940
- [CLI Proofreading](#cli-proofreading)
4041
- [Programmatic Proofreading](#programmatic-proofreading)
41-
6. [Identifying Untranslated Translations](#identifying-untranslated-translations)
42+
1. [Identifying Untranslated Translations](#identifying-untranslated-translations)
4243
- [CLI Usage](#cli-usage)
4344
- [Programmatic Usage](#programmatic-usage)
44-
7. [Detecting Missing Translations](#detecting-missing-translations)
45+
1. [Detecting Missing Translations](#detecting-missing-translations)
4546
- [CLI Usage](#cli-usage-1)
4647
- [Programmatic Usage](#programmatic-usage-1)
47-
8. [Detecting Dead Translations](#detecting-dead-translations)
48+
1. [Detecting Dead Translations](#detecting-dead-translations)
4849
- [CLI Usage](#cli-usage-2)
4950
- [Programmatic Usage](#programmatic-usage-2)
50-
9. [Code Scanner Configuration](#code-scanner-configuration)
51+
1. [Code Scanner Configuration](#code-scanner-configuration)
5152
- [Included Paths](#included-paths)
5253
- [Excluded Paths](#excluded-paths)
5354
- [Ignored Translation Keys](#ignored-translation-keys)
@@ -94,6 +95,22 @@ return [
9495
];
9596
```
9697

98+
## Configuring the Locales
99+
100+
By default, this package will attempt to determine the locales defined in your application by scanning your `lang` directory.
101+
102+
To set the locales manually, use the following configuration:
103+
104+
````php
105+
return [
106+
// ...
107+
108+
'locales' => ['en', 'fr', 'es'],
109+
110+
// ...
111+
];
112+
113+
97114
---
98115

99116
## Sorting and Formatting
@@ -104,7 +121,7 @@ Sort translations with the default driver:
104121

105122
```bash
106123
php artisan translator:sort
107-
```
124+
````
108125

109126
Specify a driver for sorting:
110127

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"nikic/php-parser": "^5.1",
2626
"openai-php/laravel": "^0.10.1",
2727
"spatie/laravel-package-tools": "^1.16",
28-
"symfony/finder": "^6.0||^7.0"
28+
"symfony/finder": "^6.0||^7.0",
29+
"symfony/intl": "^7.2"
2930
},
3031
"require-dev": {
3132
"laravel/pint": "^1.14",

config/translator.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Elegantly\Translator\Drivers\PhpDriver;
4+
use Elegantly\Translator\Support\LocaleValidator;
45

56
return [
67

@@ -29,6 +30,21 @@
2930
*/
3031
'sort_keys' => false,
3132

33+
/*
34+
|--------------------------------------------------------------------------
35+
| Locales
36+
|--------------------------------------------------------------------------
37+
|
38+
| If set to an array such as ['en', 'es', 'fr']:
39+
| -> Translator::getLocales() will return this array.
40+
| If set to a class implementing `\Elegantly\Translator\Contracts\ValidateLocales`:
41+
| -> The locales will be those found in the lang directory and filtered according to the class.
42+
| If set to `null`:
43+
| -> The locales will be those found in the lang directory.
44+
|
45+
*/
46+
'locales' => LocaleValidator::class,
47+
3248
/*
3349
|--------------------------------------------------------------------------
3450
| Third-Party Services

src/Contracts/ValidateLocales.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Elegantly\Translator\Contracts;
4+
5+
interface ValidateLocales
6+
{
7+
public static function make(): self;
8+
9+
public function isValid(string $locale): bool;
10+
}

src/Drivers/PhpDriver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function getFilePath(string $locale, string $namespace): string
3636
*/
3737
public function getLocales(): array
3838
{
39-
return collect($this->storage->allDirectories())
39+
return collect($this->storage->directories())
4040
->sort(SORT_NATURAL)
4141
->values()
4242
->toArray();

src/Support/LocaleValidator.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Elegantly\Translator\Support;
4+
5+
use Elegantly\Translator\Contracts\ValidateLocales;
6+
use Symfony\Component\Intl\Locales;
7+
8+
class LocaleValidator implements ValidateLocales
9+
{
10+
public static function make(): self
11+
{
12+
return new self;
13+
}
14+
15+
public function isValid(string $locale): bool
16+
{
17+
return Locales::exists($locale);
18+
}
19+
}

src/Translator.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ public function driver(?string $name): static
3636
*/
3737
public function getLocales(): array
3838
{
39+
if ($locales = TranslatorServiceProvider::getLocalesFromConfig()) {
40+
return $locales;
41+
}
42+
43+
if ($validator = TranslatorServiceProvider::getLocaleValidator()) {
44+
return array_values(array_filter(
45+
$this->driver->getLocales(),
46+
fn ($locale) => $validator::make()->isValid($locale),
47+
));
48+
}
49+
3950
return $this->driver->getLocales();
4051
}
4152

src/TranslatorServiceProvider.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Elegantly\Translator\Commands\ProofreadCommand;
1111
use Elegantly\Translator\Commands\SortCommand;
1212
use Elegantly\Translator\Commands\UntranslatedCommand;
13+
use Elegantly\Translator\Contracts\ValidateLocales;
1314
use Elegantly\Translator\Drivers\Driver;
1415
use Elegantly\Translator\Drivers\JsonDriver;
1516
use Elegantly\Translator\Drivers\PhpDriver;
@@ -53,7 +54,7 @@ public function registeringPackage(): void
5354
return new Translator(
5455
driver: static::getDriverFromConfig(),
5556
translateService: static::getTranslateServiceFromConfig(),
56-
proofreadService: static::getproofreadServiceFromConfig(),
57+
proofreadService: static::getProofreadServiceFromConfig(),
5758
searchcodeService: static::getSearchcodeServiceFromConfig(),
5859
);
5960
});
@@ -86,7 +87,7 @@ public static function getTranslateServiceFromConfig(?string $serviceName = null
8687
};
8788
}
8889

89-
public static function getproofreadServiceFromConfig(?string $serviceName = null): ?ProofreadServiceInterface
90+
public static function getProofreadServiceFromConfig(?string $serviceName = null): ?ProofreadServiceInterface
9091
{
9192
/** @var string|null $service */
9293
$service = $serviceName ?? config('translator.proofread.service');
@@ -115,4 +116,34 @@ public static function getSearchcodeServiceFromConfig(?string $serviceName = nul
115116
default => $service::make(),
116117
};
117118
}
119+
120+
/**
121+
* @return ?array<int, string>
122+
*/
123+
public static function getLocalesFromConfig(): ?array
124+
{
125+
/** @var array<int, string>|class-string<ValidateLocales> */
126+
$locales = config('translator.locales');
127+
128+
if (is_array($locales)) {
129+
return $locales;
130+
}
131+
132+
return null;
133+
}
134+
135+
/**
136+
* @return null|class-string<ValidateLocales>
137+
*/
138+
public static function getLocaleValidator(): ?string
139+
{
140+
/** @var array<int, string>|class-string<ValidateLocales> */
141+
$validator = config('translator.locales');
142+
143+
if (is_array($validator)) {
144+
return null;
145+
}
146+
147+
return $validator;
148+
}
118149
}

tests/Feature/PhpDriverTest.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,32 @@
22

33
use Elegantly\Translator\Translator;
44

5-
it('gets locales', function () {
5+
it('gets locales from the directory', function () {
66
$translator = new Translator(
77
driver: $this->getPhpDriver(),
88
);
99

10-
expect($translator->getLocales())->toBe(['en', 'fr']);
10+
expect($translator->getLocales())->toBe(['en', 'fr', 'pt_BR']);
11+
});
12+
13+
it('gets locales from the config', function () {
14+
config()->set('translator.locales', ['fr']);
15+
16+
$translator = new Translator(
17+
driver: $this->getPhpDriver(),
18+
);
19+
20+
expect($translator->getLocales())->toBe(['fr']);
21+
});
22+
23+
it('gets locales from the config when null', function () {
24+
config()->set('translator.locales', null);
25+
26+
$translator = new Translator(
27+
driver: $this->getPhpDriver(),
28+
);
29+
30+
expect($translator->getLocales())->toBe(['dummy', 'en', 'fr', 'pt_BR']);
1131
});
1232

1333
it('gets translations', function () {

tests/src/lang/dummy/de/foo.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
return [
4+
//
5+
];

0 commit comments

Comments
 (0)