8000 [Translation] Extract locale fallback computation into a dedicated class by mpdude · Pull Request #45553 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Translation] Extract locale fallback computation into a dedicated class #45553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: 7.4
Choose a base branch
from
Open
Next Next commit
Extract locale fallback computation into a dedicated class
  • Loading branch information
mpdude committed Feb 28, 2022
commit aa6a43327d69f57df319560283afa0fba144c199
82 changes: 82 additions & 0 deletions src/Symfony/Component/Translation/FallbackLocaleProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation;

/**
* Contains a configured list of fallback locales and provides the fallback
* chain for a given locale.
*
* @author Matthias Pigulla <mp@webfactory.de>
*/
class FallbackLocaleProvider
{
/**
* @var string[]
*/
private array $fallbackLocales = [];

private array $parentLocales;

public function setFallbackLocales(array $locales)
{
$this->fallbackLocales = $locales;
}

/**
* @internal
*/
public function getFallbackLocales(): array
{
return $this->fallbackLocales;
}

public function computeFallbackLocales(string $locale)
{
$this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);

$originLocale = $locale;
$locales = [];

while ($locale) {
$parent = $this->parentLocales[$locale] ?? null;

if ($parent) {
$locale = 'root' !== $parent ? $parent : null;
} elseif (\function_exists('locale_parse')) {
$localeSubTags = locale_parse($locale);
$locale = null;
if (1 < \count($localeSubTags)) {
array_pop($localeSubTags);
$locale = locale_compose($localeSubTags) ?: null;
}
} elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
$locale = substr($locale, 0, $i);
} else {
$locale = null;
}

if (null !== $locale) {
$locales[] = $locale;
}
}

foreach ($this->fallbackLocales as $fallback) {
if ($fallback === $originLocale) {
continue;
}

$locales[] = $fallback;
}

return array_unique($locales);
}
}
62 changes: 12 additions & 50 deletions src/Symfony/Component/Translation/Translator.php
8B28
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA

private string $locale;

/**
* @var string[]
*/
private array $fallbackLocales = [];

/**
* @var LoaderInterface[]
*/
Expand All @@ -62,14 +57,17 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA

private ?ConfigCacheFactoryInterface $configCacheFactory;

private array $parentLocales;

private bool $hasIntlFormatter;

/**
* @var FallbackLocaleProvider
*/
private $fallbackLocaleProvider;

/**
* @throws InvalidArgumentException If a locale contains invalid characters
*/
public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [], FallbackLocaleProvider $fallbackLocaleProvider = null)
{
$this->setLocale($locale);

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

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

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

if (\in_array($locale, $this->fallbackLocales)) {
if (\in_array($locale, $this->fallbackLocaleProvider->getFallbackLocales())) {
$this->catalogues = [];
} else {
unset($this->catalogues[$locale]);
Expand Down Expand Up @@ -158,17 +157,16 @@ public function setFallbackLocales(array $locales)
$this->assertValidLocale($locale);
}

$this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
$this->fallbackLocaleProvider->setFallbackLocales($locales);
$this->cacheVary['fallback_locales'] = $locales;
}

/**
* Gets the fallback locales.
*
* @internal
*/
public function getFallbackLocales(): array
{
return $this->fallbackLocales;
return $this->fallbackLocaleProvider->getFallbackLocales();
}

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

protected function computeFallbackLocales(string $locale)
{
$this->parentLocales ??= json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);

$originLocale = $locale;
$locales = [];

while ($locale) {
$parent = $this->parentLocales[$locale] ?? null;

if ($parent) {
$locale = 'root' !== $parent ? $parent : null;
} elseif (\function_exists('locale_parse')) {
$localeSubTags = locale_parse($locale);
$locale = null;
if (1 < \count($localeSubTags)) {
array_pop($localeSubTags);
$locale = locale_compose($localeSubTags) ?: null;
}
} elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
$locale = substr($locale, 0, $i);
} else {
$locale = null;
}

if (null !== $locale) {
$locales[] = $locale;
}
}

foreach ($this->fallbackLocales as $fallback) {
if ($fallback === $originLocale) {
continue;
}

$locales[] = $fallback;
}

return array_unique($locales);
return $this->fallbackLocaleProvider->computeFallbackLocales($locale);
}

/**
Expand Down
0