Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9cc80ec

Browse files
committed
feature#28070 [Translator] Use ICU parent locales as fallback locales (thewilkybarkid)
This PR was squashed before being merged into the 4.2-dev branch (closes#28070).Discussion----------[Translator] Use ICU parent locales as fallback locales| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#12319| License | MIT| Doc PR |symfony/symfony-docs#10122Currently the `Translator` fall backs based on the locale separator (eg `es_AR` to `es`), but the ICU data contains parent locales (eg `es_AR` is a child of `es_419`, as is `es_BO`, `es_EC` etc).This makes use of the ICU data to add add in these fallbacks. This means the specific locales can be used, but the translations can stored in these groupings (eg `es_419` for Latin American Spanish), as well as adding other sensible fallbacks (eg Cape Verdean Portuguese to `pt_PT`).Commits-------e0f402f [Translator] Use ICU parent locales as fallback locales
2 parentsa1aee05 +e0f402f commit9cc80ec

File tree

7 files changed

+241
-3
lines changed

7 files changed

+241
-3
lines changed

‎src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public function generateData(GeneratorConfig $config)
5757

5858
$locales =$localeScanner->scanLocales($config->getSourceDir().'/locales');
5959
$aliases =$localeScanner->scanAliases($config->getSourceDir().'/locales');
60+
$parents =$localeScanner->scanParents($config->getSourceDir().'/locales');
6061

6162
// Flip to facilitate lookup
6263
$flippedLocales =array_flip($locales);
@@ -134,6 +135,12 @@ public function generateData(GeneratorConfig $config)
134135
'Aliases' =>$aliases,
135136
));
136137
}
138+
139+
// Write parents locale file for the Translation component
140+
\file_put_contents(
141+
__DIR__.'/../../../Translation/Resources/data/parents.json',
142+
\json_encode($parents, \JSON_PRETTY_PRINT).\PHP_EOL
143+
);
137144
}
138145

139146
privatefunctiongenerateLocaleName($locale,$displayLocale)

‎src/Symfony/Component/Intl/Data/Util/LocaleScanner.php‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,24 @@ public function scanAliases($sourceDir)
8282

8383
return$aliases;
8484
}
85+
86+
/**
87+
* Returns all locale parents found in the given directory.
88+
*/
89+
publicfunctionscanParents(string$sourceDir):array
90+
{
91+
$locales =$this->scanLocales($sourceDir);
92+
$fallbacks =array();
93+
94+
foreach ($localesas$locale) {
95+
$content =\file_get_contents($sourceDir.'/'.$locale.'.txt');
96+
97+
// Aliases contain the text "%%PARENT" followed by the aliased locale
98+
if (\preg_match('/%%Parent{"([^"]+)"}/',$content,$matches)) {
99+
$fallbacks[$locale] =$matches[1];
100+
}
101+
}
102+
103+
return$fallbacks;
104+
}
85105
}

‎src/Symfony/Component/Intl/Tests/Data/Util/LocaleScannerTest.php‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ protected function setUp()
4242

4343
$this->filesystem->touch($this->directory.'/en.txt');
4444
$this->filesystem->touch($this->directory.'/en_alias.txt');
45+
$this->filesystem->touch($this->directory.'/en_child.txt');
4546
$this->filesystem->touch($this->directory.'/de.txt');
4647
$this->filesystem->touch($this->directory.'/de_alias.txt');
48+
$this->filesystem->touch($this->directory.'/de_child.txt');
4749
$this->filesystem->touch($this->directory.'/fr.txt');
4850
$this->filesystem->touch($this->directory.'/fr_alias.txt');
51+
$this->filesystem->touch($this->directory.'/fr_child.txt');
4952
$this->filesystem->touch($this->directory.'/root.txt');
5053
$this->filesystem->touch($this->directory.'/supplementalData.txt');
5154
$this->filesystem->touch($this->directory.'/supplementaldata.txt');
@@ -54,6 +57,9 @@ protected function setUp()
5457
file_put_contents($this->directory.'/en_alias.txt','en_alias{"%%ALIAS"{"en"}}');
5558
file_put_contents($this->directory.'/de_alias.txt','de_alias{"%%ALIAS"{"de"}}');
5659
file_put_contents($this->directory.'/fr_alias.txt','fr_alias{"%%ALIAS"{"fr"}}');
60+
file_put_contents($this->directory.'/en_child.txt','en_GB{%%Parent{"en"}}');
61+
file_put_contents($this->directory.'/de_child.txt','en_GB{%%Parent{"de"}}');
62+
file_put_contents($this->directory.'/fr_child.txt','en_GB{%%Parent{"fr"}}');
5763
}
5864

5965
protectedfunctiontearDown()
@@ -63,7 +69,7 @@ protected function tearDown()
6369

6470
publicfunctiontestScanLocales()
6571
{
66-
$sortedLocales =array('de','de_alias','en','en_alias','fr','fr_alias');
72+
$sortedLocales =array('de','de_alias','de_child','en','en_alias','en_child','fr','fr_alias','fr_child');
6773

6874
$this->assertSame($sortedLocales,$this->scanner->scanLocales($this->directory));
6975
}
@@ -74,4 +80,11 @@ public function testScanAliases()
7480

7581
$this->assertSame($sortedAliases,$this->scanner->scanAliases($this->directory));
7682
}
83+
84+
publicfunctiontestScanParents()
85+
{
86+
$sortedParents =array('de_child' =>'de','en_child' =>'en','fr_child' =>'fr');
87+
88+
$this->assertSame($sortedParents,$this->scanner->scanParents($this->directory));
89+
}
7790
}

‎src/Symfony/Component/Translation/CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.2.0
5+
-----
6+
7+
* Started using ICU parent locales as fallback locales.
8+
49
4.1.0
510
-----
611

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
{
2+
"az_Cyrl":"root",
3+
"bs_Cyrl":"root",
4+
"en_150":"en_001",
5+
"en_AG":"en_001",
6+
"en_AI":"en_001",
7+
"en_AT":"en_150",
8+
"en_AU":"en_001",
9+
"en_BB":"en_001",
10+
"en_BE":"en_001",
11+
"en_BM":"en_001",
12+
"en_BS":"en_001",
13+
"en_BW":"en_001",
14+
"en_BZ":"en_001",
15+
"en_CA":"en_001",
16+
"en_CC":"en_001",
17+
"en_CH":"en_150",
18+
"en_CK":"en_001",
19+
"en_CM":"en_001",
20+
"en_CX":"en_001",
21+
"en_CY":"en_001",
22+
"en_DE":"en_150",
23+
"en_DG":"en_001",
24+
"en_DK":"en_150",
25+
"en_DM":"en_001",
26+
"en_ER":"en_001",
27+
"en_FI":"en_150",
28+
"en_FJ":"en_001",
29+
"en_FK":"en_001",
30+
"en_FM":"en_001",
31+
"en_GB":"en_001",
32+
"en_GD":"en_001",
33+
"en_GG":"en_001",
34+
"en_GH":"en_001",
35+
"en_GI":"en_001",
36+
"en_GM":"en_001",
37+
"en_GY":"en_001",
38+
"en_HK":"en_001",
39+
"en_IE":"en_001",
40+
"en_IL":"en_001",
41+
"en_IM":"en_001",
42+
"en_IN":"en_001",
43+
"en_IO":"en_001",
44+
"en_JE":"en_001",
45+
"en_JM":"en_001",
46+
"en_KE":"en_001",
47+
"en_KI":"en_001",
48+
"en_KN":"en_001",
49+
"en_KY":"en_001",
50+
"en_LC":"en_001",
51+
"en_LR":"en_001",
52+
"en_LS":"en_001",
53+
"en_MG":"en_001",
54+
"en_MO":"en_001",
55+
"en_MS":"en_001",
56+
"en_MT":"en_001",
57+
"en_MU":"en_001",
58+
"en_MW":"en_001",
59+
"en_MY":"en_001",
60+
"en_NA":"en_001",
61+
"en_NF":"en_001",
62+
"en_NG":"en_001",
63+
"en_NL":"en_150",
64+
"en_NR":"en_001",
65+
"en_NU":"en_001",
66+
"en_NZ":"en_001",
67+
"en_PG":"en_001",
68+
"en_PH":"en_001",
69+
"en_PK":"en_001",
70+
"en_PN":"en_001",
71+
"en_PW":"en_001",
72+
"en_RW":"en_001",
73+
"en_SB":"en_001",
74+
"en_SC":"en_001",
75+
"en_SD":"en_001",
76+
"en_SE":"en_150",
77+
"en_SG":"en_001",
78+
"en_SH":"en_001",
79+
"en_SI":"en_150",
80+
"en_SL":"en_001",
81+
"en_SS":"en_001",
82+
"en_SX":"en_001",
83+
"en_SZ":"en_001",
84+
"en_TC":"en_001",
85+
"en_TK":"en_001",
86+
"en_TO":"en_001",
87+
"en_TT":"en_001",
88+
"en_TV":"en_001",
89+
"en_TZ":"en_001",
90+
"en_UG":"en_001",
91+
"en_VC":"en_001",
92+
"en_VG":"en_001",
93+
"en_VU":"en_001",
94+
"en_WS":"en_001",
95+
"en_ZA":"en_001",
96+
"en_ZM":"en_001",
97+
"en_ZW":"en_001",
98+
"es_AR":"es_419",
99+
"es_BO":"es_419",
100+
"es_BR":"es_419",
101+
"es_BZ":"es_419",
102+
"es_CL":"es_419",
103+
"es_CO":"es_419",
104+
"es_CR":"es_419",
105+
"es_CU":"es_419",
106+
"es_DO":"es_419",
107+
"es_EC":"es_419",
108+
"es_GT":"es_419",
109+
"es_HN":"es_419",
110+
"es_MX":"es_419",
111+
"es_NI":"es_419",
112+
"es_PA":"es_419",
113+
"es_PE":"es_419",
114+
"es_PR":"es_419",
115+
"es_PY":"es_419",
116+
"es_SV":"es_419",
117+
"es_US":"es_419",
118+
"es_UY":"es_419",
119+
"es_VE":"es_419",
120+
"pa_Arab":"root",
121+
"pt_AO":"pt_PT",
122+
"pt_CH":"pt_PT",
123+
"pt_CV":"pt_PT",
124+
"pt_GQ":"pt_PT",
125+
"pt_GW":"pt_PT",
126+
"pt_LU":"pt_PT",
127+
"pt_MO":"pt_PT",
128+
"pt_MZ":"pt_PT",
129+
"pt_ST":"pt_PT",
130+
"pt_TL":"pt_PT",
131+
"sr_Latn":"root",
132+
"uz_Arab":"root",
133+
"uz_Cyrl":"root",
134+
"zh_Hant":"root",
135+
"zh_Hant_MO":"zh_Hant_HK"
136+
}

‎src/Symfony/Component/Translation/Tests/TranslatorTest.php‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,42 @@ public function testTransWithFallbackLocaleFile($format, $loader)
234234
$this->assertEquals('bar',$translator->trans('foo',array(),'resources'));
235235
}
236236

237+
publicfunctiontestTransWithIcuFallbackLocale()
238+
{
239+
$translator =newTranslator('en_GB');
240+
$translator->addLoader('array',newArrayLoader());
241+
$translator->addResource('array',array('foo' =>'foofoo'),'en_GB');
242+
$translator->addResource('array',array('bar' =>'foobar'),'en_001');
243+
$translator->addResource('array',array('baz' =>'foobaz'),'en');
244+
$this->assertSame('foofoo',$translator->trans('foo'));
245+
$this->assertSame('foobar',$translator->trans('bar'));
246+
$this->assertSame('foobaz',$translator->trans('baz'));
247+
}
248+
249+
publicfunctiontestTransWithIcuVariantFallbackLocale()
250+
{
251+
$translator =newTranslator('en_GB_scouse');
252+
$translator->addLoader('array',newArrayLoader());
253+
$translator->addResource('array',array('foo' =>'foofoo'),'en_GB_scouse');
254+
$translator->addResource('array',array('bar' =>'foobar'),'en_GB');
255+
$translator->addResource('array',array('baz' =>'foobaz'),'en_001');
256+
$translator->addResource('array',array('qux' =>'fooqux'),'en');
257+
$this->assertSame('foofoo',$translator->trans('foo'));
258+
$this->assertSame('foobar',$translator->trans('bar'));
259+
$this->assertSame('foobaz',$translator->trans('baz'));
260+
$this->assertSame('fooqux',$translator->trans('qux'));
261+
}
262+
263+
publicfunctiontestTransWithIcuRootFallbackLocale()
264+
{
265+
$translator =newTranslator('az_Cyrl');
266+
$translator->addLoader('array',newArrayLoader());
267+
$translator->addResource('array',array('foo' =>'foofoo'),'az_Cyrl');
268+
$translator->addResource('array',array('bar' =>'foobar'),'az');
269+
$this->assertSame('foofoo',$translator->trans('foo'));
270+
$this->assertSame('bar',$translator->trans('bar'));
271+
}
272+
237273
publicfunctiontestTransWithFallbackLocaleBis()
238274
{
239275
$translator =newTranslator('en_US');

‎src/Symfony/Component/Translation/Translator.php‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class Translator implements TranslatorInterface, TranslatorBagInterface
7373
*/
7474
private$configCacheFactory;
7575

76+
/**
77+
* @var array|null
78+
*/
79+
private$parentLocales;
80+
7681
/**
7782
* @throws InvalidArgumentException If a locale contains invalid characters
7883
*/
@@ -392,6 +397,10 @@ private function loadFallbackCatalogues($locale): void
392397

393398
protectedfunctioncomputeFallbackLocales($locale)
394399
{
400+
if (null ===$this->parentLocales) {
401+
$parentLocales =\json_decode(\file_get_contents(__DIR__.'/Resources/data/parents.json'),true);
402+
}
403+
395404
$locales =array();
396405
foreach ($this->fallbackLocalesas$fallback) {
397406
if ($fallback ===$locale) {
@@ -401,8 +410,20 @@ protected function computeFallbackLocales($locale)
401410
$locales[] =$fallback;
402411
}
403412

404-
if (false !==strrchr($locale,'_')) {
405-
array_unshift($locales,substr($locale,0, -\strlen(strrchr($locale,'_'))));
413+
while ($locale) {
414+
$parent =$parentLocales[$locale] ??null;
415+
416+
if (!$parent &&false !==strrchr($locale,'_')) {
417+
$locale =substr($locale,0, -\strlen(strrchr($locale,'_')));
418+
}elseif ('root' !==$parent) {
419+
$locale =$parent;
420+
}else {
421+
$locale =null;
422+
}
423+
424+
if (null !==$locale) {
425+
array_unshift($locales,$locale);
426+
}
406427
}
407428

408429
returnarray_unique($locales);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp