Skip to content

Commit 3fabce5

Browse files
committed
Extract locale fallback computation into a dedicated class
1 parent ad628ef commit 3fabce5

File tree

2 files changed

+95
-50
lines changed

2 files changed

+95
-50
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation;
13+
14+
/**
15+
* Contains a configured list of fallback locales and provides the fallback
16+
* chain for a given locale.
17+
*
18+
* @author Matthias Pigulla <mp@webfactory.de>
19+
*/
20+
21+
class FallbackLocaleProvider
22+
{
23+
/**
24+
* @var string[]
25+
*/
26+
private array $fallbackLocales = [];
27+
28+
private array $parentLocales;
29+
30+
public function setFallbackLocales(array $locales)
31+
{
32+
$this->fallbackLocales = $locales;
33+
}
34+
35+
/**
36+
* @internal
37+
*/
38+
public function getFallbackLocales(): array
39+
{
40+
return $this->fallbackLocales;
41+
}
42+
43+
public function computeFallbackLocales(string $locale)
44+
{
45+
$this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
46+
47+
$originLocale = $locale;
48+
$locales = [];
49+
50+
while ($locale) {
51+
$parent = $this->parentLocales[$locale] ?? null;
52+
53+
if ($parent) {
54+
$locale = 'root' !== $parent ? $parent : null;
55+
} elseif (\function_exists('locale_parse')) {
56+
$localeSubTags = locale_parse($locale);
57+
$locale = null;
58+
if (1 < \count($localeSubTags)) {
59+
array_pop($localeSubTags);
60+
$locale = locale_compose($localeSubTags) ?: null;
61+
}
62+
} elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
63+
$locale = substr($locale, 0, $i);
64+
} else {
65+
$locale = null;
66+
}
67+
68+
if (null !== $locale) {
69+
$locales[] = $locale;
70+
}
71+
}
72+
73+
foreach ($this->fallbackLocales as $fallback) {
74+
if ($fallback === $originLocale) {
75+
continue;
76+
}
77+
78+
$locales[] = $fallback;
79+
}
80+
81+
return array_unique($locales);
82+
}
83+
}

src/Symfony/Component/Translation/Translator.php

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
4040

4141
private string $locale;
4242

43-
/**
44-
* @var string[]
45-
*/
46-
private array $fallbackLocales = [];
47-
4843
/**
4944
* @var LoaderInterface[]
5045
*/
@@ -62,14 +57,17 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
6257

6358
private ?ConfigCacheFactoryInterface $configCacheFactory;
6459

65-
private array $parentLocales;
66-
6760
private bool $hasIntlFormatter;
6861

62+
/**
63+
* @var FallbackLocaleProvider
64+
*/
65+
private $fallbackLocaleProvider;
66+
6967
/**
7068
* @throws InvalidArgumentException If a locale contains invalid characters
7169
*/
72-
public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
70+
public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [], FallbackLocaleProvider $fallbackLocaleProvider = null)
7371
{
7472
$this->setLocale($locale);
7573

@@ -82,6 +80,7 @@ public function __construct(string $locale, MessageFormatterInterface $formatter
8280
$this->debug = $debug;
8381
$this->cacheVary = $cacheVary;
8482
$this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
83+
$this->fallbackLocaleProvider = $fallbackLocaleProvider ?? new FallbackLocaleProvider();
8584
}
8685

8786
public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
@@ -118,7 +117,7 @@ public function addResource(string $format, mixed $resource, string $locale, str
118117

119118
$this->resources[$locale][] = [$format, $resource, $domain];
120119

121-
if (\in_array($locale, $this->fallbackLocales)) {
120+
if (\in_array($locale, $this->fallbackLocaleProvider->getFallbackLocales())) {
122121
$this->catalogues = [];
123122
} else {
124123
unset($this->catalogues[$locale]);
@@ -158,17 +157,16 @@ public function setFallbackLocales(array $locales)
158157
$this->assertValidLocale($locale);
159158
}
160159

161-
$this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
160+
$this->fallbackLocaleProvider->setFallbackLocales($locales);
161+
$this->cacheVary['fallback_locales'] = $locales;
162162
}
163163

164164
/**
165-
* Gets the fallback locales.
166-
*
167165
* @internal
168166
*/
169167
public function getFallbackLocales(): array
170168
{
171-
return $this->fallbackLocales;
169+
return $this->fallbackLocaleProvider->getFallbackLocales();
172170
}
173171

174172
/**
@@ -393,43 +391,7 @@ private function loadFallbackCatalogues(string $locale): void
393391

394392
protected function computeFallbackLocales(string $locale)
395393
{
396-
$this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
397-
398-
$originLocale = $locale;
399-
$locales = [];
400-
401-
while ($locale) {
402-
$parent = $this->parentLocales[$locale] ?? null;
403-
404-
if ($parent) {
405-
$locale = 'root' !== $parent ? $parent : null;
406-
} elseif (\function_exists('locale_parse')) {
407-
$localeSubTags = locale_parse($locale);
408-
$locale = null;
409-
if (1 < \count($localeSubTags)) {
410-
array_pop($localeSubTags);
411-
$locale = locale_compose($localeSubTags) ?: null;
412-
}
413-
} elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
414-
$locale = substr($locale, 0, $i);
415-
} else {
416-
$locale = null;
417-
}
418-
419-
if (null !== $locale) {
420-
$locales[] = $locale;
421-
}
422-
}
423-
424-
foreach ($this->fallbackLocales as $fallback) {
425-
if ($fallback === $originLocale) {
426-
continue;
427-
}
428-
429-
$locales[] = $fallback;
430-
}
431-
432-
return array_unique($locales);
394+
return $this->fallbackLocaleProvider->computeFallbackLocales($locale);
433395
}
434396

435397
/**

0 commit comments

Comments
 (0)