8000 [Intl] Add FallbackTrait for data generation by ro0NL · Pull Request #31432 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Intl] Add FallbackTrait for data generation #31432

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

Merged
merged 1 commit into from
May 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/Symfony/Component/Intl/Data/Generator/FallbackTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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\Intl\Data\Generator;

use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
use Symfony\Component\Intl\Locale;

/**
* @author Roland Franssen <franssen.roland@gmail.com>
*
* @internal
*/
trait FallbackTrait
{
private $fallbackCache = [];
private $generatingFallback = false;

/**
* @param string $tempDir
* @param string $displayLocale
*
* @return array|null
*
* @see AbstractDataGenerator::generateDataForLocale()
*/
abstract protected function generateDataForLocale(BundleEntryReaderInterface $reader, $tempDir, $displayLocale);

/**
* @param string $tempDir
*
* @return array|null
*
* @see AbstractDataGenerator::generateDataForRoot()
*/
abstract protected function generateDataForRoot(BundleEntryReaderInterface $reader, $tempDir);

/**
* @param string $tempDir
* @param string $displayLocale
*
* @return array
*/
private function generateFallbackData(BundleEntryReaderInterface $reader, $tempDir, $displayLocale)
{
if (null === $fallback = Locale::getFallback($displayLocale)) {
return [];
}

if (isset($this->fallbackCache[$fallback])) {
return $this->fallbackCache[$fallback];
}

$prevGeneratingFallback = $this->generatingFallback;
$this->generatingFallback = true;

try {
$data = 'root' === $fallback ? $this->generateDataForRoot($reader, $tempDir) : $this->generateDataForLocale($reader, $tempDir, $fallback);
} finally {
$this->generatingFallback = $prevGeneratingFallback;
}

return $this->fallbackCache[$fallback] = $data ?: [];
}
}
82 changes: 29 additions & 53 deletions src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
use Symfony\Component\Intl\Data\Util\LocaleScanner;
use Symfony\Component\Intl\Exception\MissingResourceException;
use Symfony\Component\Intl\Locale;

/**
* The rule for compiling the locale bundle.
Expand All @@ -28,10 +27,10 @@
*/
class LocaleDataGenerator extends AbstractDataGenerator
{
private $locales;
private $localeAliases;
private $fallbackMapping;
private $fallbackCache = [];
use FallbackTrait;

private $locales = [];
private $localeAliases = [];

/**
* {@inheritdoc}
Expand All @@ -40,7 +39,6 @@ protected function scanLocales(LocaleScanner $scanner, $sourceDir)
{
$this->locales = $scanner->scanLocales($sourceDir.'/locales');
$this->localeAliases = $scanner->scanAliases($sourceDir.'/locales');
$this->fallbackMapping = $this->generateFallbackMapping(array_diff($this->locales, array_keys($this->localeAliases)), $this->localeAliases);

return $this->locales;
}
Expand All @@ -64,7 +62,6 @@ protected function compileTemporaryBundles(BundleCompilerInterface $compiler, $s
*/
protected function preGenerate()
{
$this->fallbackCache = [];
}

/**
Expand All @@ -73,7 +70,8 @@ protected function preGenerate()
protected function generateDataForLocale(BundleEntryReaderInterface $reader, $tempDir, $displayLocale)
{
// Don't generate aliases, as they are resolved during runtime
if (isset($this->localeAliases[$displayLocale])) {
// Unless an alias is needed as fallback for de-duplication purposes
if (isset($this->localeAliases[$displayLocale]) && !$this->generatingFallback) {
return;
}

Expand All @@ -85,7 +83,7 @@ protected function generateDataForLocale(BundleEntryReaderInterface $reader, $te
$localeNames = [];
foreach ($this->locales as $locale) {
// Ensure a normalized list of pure locales
if (isset($this->localeAliases[$displayLocale]) || \Locale::getAllVariants($locale)) {
if (\Locale::getAllVariants($locale)) {
continue;
}

Expand All @@ -102,21 +100,27 @@ protected function generateDataForLocale(BundleEntryReaderInterface $reader, $te
}
}

// Process again to de-duplicate locales and their fallback locales
// Only keep the differences
$fallback = $displayLocale;
while (isset($this->fallbackMapping[$fallback])) {
if (!isset($this->fallbackCache[$fallback = $this->fallbackMapping[$fallback]])) {
$this->fallbackCache[$fallback] = $this->generateDataForLocale($reader, $tempDir, $fallback) ?: [];
}
if (isset($this->fallbackCache[$fallback]['Names'])) {
$localeNames = array_diff($localeNames, $this->fallbackCache[$fallback]['Names']);
}
$data = [
'Names' => $localeNames,
];

// Don't de-duplicate a fallback locale
// Ensures the display locale can be de-duplicated on itself
if ($this->generatingFallback) {
return $data;
}

if ($localeNames) {
return ['Names' => $localeNames];
// Process again to de-duplicate locale and its fallback locales
// Only keep the differences
$fallbackData = $this->generateFallbackData($reader, $tempDir, $displayLocale);
if (isset($fallbackData['Names'])) {
$data['Names'] = array_diff($data['Names'], $fallbackData['Names']);
}
if (!$data['Names']) {
return;
}

return $data;
}

/**
Expand All @@ -131,12 +135,10 @@ protected function generateDataForRoot(BundleEntryReaderInterface $reader, $temp
*/
protected function generateDataForMeta(BundleEntryReaderInterface $reader, $tempDir)
{
if ($this->locales || $this->localeAliases) {
return [
'Locales' => $this->locales,
'Aliases' => $this->localeAliases,
];
}
return [
'Locales' => $this->locales,
'Aliases' => $this->localeAliases,
];
}

/**
Expand Down Expand Up @@ -175,30 +177,4 @@ private function generateLocaleName(BundleEntryReaderInterface $reader, $tempDir

return $name;
}

private function generateFallbackMapping(array $displayLocales, array $aliases)
{
$displayLocales = array_flip($displayLocales);
$mapping = [];

foreach ($displayLocales as $displayLocale => $_) {
$mapping[$displayLocale] = null;
$fallback = $displayLocale;

// Recursively search for a fallback locale until one is found
while (null !== ($fallback = Locale::getFallback($fallback))) {
// Currently, no locale has an alias as fallback locale.
// If this starts to be the case, we need to add code here.
\assert(!isset($aliases[$fallback]));

// Check whether the fallback exists
if (isset($displayLocales[$fallback])) {
$mapping[$displayLocale] = $fallback;
break;
}
}
}

return $mapping;
}
}
0