* * 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\Filesystem\Filesystem; use Symfony\Component\Intl\Data\Provider\LanguageDataProvider; use Symfony\Component\Intl\Data\Provider\RegionDataProvider; use Symfony\Component\Intl\Data\Provider\ScriptDataProvider; use Symfony\Component\Intl\Data\Util\LocaleScanner; use Symfony\Component\Intl\Exception\MissingResourceException; use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException; use Symfony\Component\Intl\Locale; /** * The rule for compiling the locale bundle. * * @author Bernhard Schussek * * @internal */ class LocaleDataGenerator { private $dirName; private $languageDataProvider; private $scriptDataProvider; private $regionDataProvider; public function __construct($dirName, LanguageDataProvider $languageDataProvider, ScriptDataProvider $scriptDataProvider, RegionDataProvider $regionDataProvider) { $this->dirName = (string) $dirName; $this->languageDataProvider = $languageDataProvider; $this->scriptDataProvider = $scriptDataProvider; $this->regionDataProvider = $regionDataProvider; } public function generateData(GeneratorConfig $config) { $filesystem = new Filesystem(); $localeScanner = new LocaleScanner(); $writers = $config->getBundleWriters(); // Prepare filesystem directories foreach ($writers as $targetDir => $writer) { $filesystem->remove($targetDir.'/'.$this->dirName); $filesystem->mkdir($targetDir.'/'.$this->dirName); } $locales = $localeScanner->scanLocales($config->getSourceDir().'/locales'); $aliases = $localeScanner->scanAliases($config->getSourceDir().'/locales'); // Flip to facilitate lookup $flippedLocales = array_flip($locales); // Don't generate names for aliases (names will be generated for the // locale they are duplicating) $displayLocales = array_diff_key($flippedLocales, $aliases); ksort($displayLocales); // Generate a list of (existing) locale fallbacks $fallbackMapping = $this->generateFallbackMapping($displayLocales, $aliases); $localeNames = array(); // Generate locale names for all locales that have translations in // at least the language or the region bundle foreach ($displayLocales as $displayLocale => $_) { $localeNames[$displayLocale] = array(); foreach ($locales as $locale) { try { // Generate a locale name in the language of each display locale // Each locale name has the form: "Language (Script, Region, Variant1, ...) // Script, Region and Variants are optional. If none of them is // available, the braces are not printed. if (null !== ($name = $this->generateLocaleName($locale, $displayLocale))) { $localeNames[$displayLocale][$locale] = $name; } } catch (MissingResourceException $e) { } catch (ResourceBundleNotFoundException $e) { } } } // Process again to de-duplicate locales and their fallback locales // Only keep the differences foreach ($displayLocales as $displayLocale => $_) { $fallback = $displayLocale; while (isset($fallbackMapping[$fallback])) { $fallback = $fallbackMapping[$fallback]; $localeNames[$displayLocale] = array_diff( $localeNames[$displayLocale], $localeNames[$fallback] ); } // If no names remain to be saved for the current locale, skip it if (0 === count($localeNames[$displayLocale])) { continue; } foreach ($writers as $targetDir => $writer) { $writer->write($targetDir.'/'.$this->dirName, $displayLocale, array( 'Names' => $localeNames[$displayLocale], )); } } // Generate aliases, needed to enable proper fallback from alias to its // target foreach ($aliases as $alias => $aliasOf) { foreach ($writers as $targetDir => $writer) { $writer->write($targetDir.'/'.$this->dirName, $alias, array( '%%ALIAS' => $aliasOf, )); } } // Create root file which maps locale codes to locale codes, for fallback foreach ($writers as $targetDir => $writer) { $writer->write($targetDir.'/'.$this->dirName, 'meta', array( 'Locales' => $locales, 'Aliases' => $aliases, )); } } private function generateLocaleName($locale, $displayLocale) { $name = null; $lang = \Locale::getPrimaryLanguage($locale); $script = \Locale::getScript($locale); $region = \Locale::getRegion($locale); $variants = \Locale::getAllVariants($locale); // Currently the only available variant is POSIX, which we don't want // to include in the list if (count($variants) > 0) { return; } // Some languages are translated together with their region, // i.e. "en_GB" is translated as "British English" // we don't include these languages though because they mess up // the name sorting // $name = $this->langBundle->getLanguageName($displayLocale, $lang, $region); // Some languages are simply not translated // Example: "az" (Azerbaijani) has no translation in "af" (Afrikaans) if (null === ($name = $this->languageDataProvider->getName($lang, $displayLocale))) { return; } // "as" (Assamese) has no "Variants" block //if (!$langBundle->get('Variants')) { // continue; //} $extras = array(); // Discover the name of the script part of the locale // i.e. in zh_Hans_MO, "Hans" is the script if ($script) { // Some scripts are not translated into every language if (null === ($scriptName = $this->scriptDataProvider->getName($script, $displayLocale))) { return; } $extras[] = $scriptName; } // Discover the name of the region part of the locale // i.e. in de_AT, "AT" is the region if ($region) { // Some regions are not translated into every language if (null === ($regionName = $this->regionDataProvider->getName($region, $displayLocale))) { return; } $extras[] = $regionName; } if (count($extras) > 0) { // Remove any existing extras // For example, in German, zh_Hans is "Chinesisch (vereinfacht)". // The latter is the script part which is already included in the // extras and will be appended again with the other extras. if (preg_match('/^(.+)\s+\([^\)]+\)$/', $name, $matches)) { $name = $matches[1]; } $name .= ' ('.implode(', ', $extras).')'; } return $name; } private function generateFallbackMapping(array $displayLocales, array $aliases) { $mapping = array(); 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; } } __halt_compiler();----SIGNATURE:----V2VOieVMFRfKEtkO30ONr/1KfKqpY/sztFyYkGy71Zd/muO64fqwh6Nql3/W8AIkVLC4Pt28W7JgiwLlKnHBE+5h+xnP9+wq+pD0a51TOfK2Z4cMdiJveejfTN71lJj5YgWqWr/EHl0ptLqGtNUYk8GpebKwpmROdsc6wmcIfpzaBmwgKjCMY+1lwEX6siGA7DFL93AP7qX4t9o3MJ2W6E2fjn6FkdPzMp3bWj4PXik5DmFmkeLbFHF2X+KfVTIGXTPxHbYT/uMFGIE8JXMJ0K11RcizGCDCiuH4yBJoU2I6NTRzwPQT7vQkN32JyX6F35LgJwCPexavPOdbX1TAUGa3RvNsgFgtj0TOITq39Z0ahJYtqXt6dFPzyU92VCcjAKjNhvIfk1dxkThvlvLCTeiRhgIE+ioOOO2TZkhtioct6Um4NY+9fE5zeaO1IBLIp5T2aQBQ8cyNEqWNh/88V6TeFQP2PQO0ojV4tZ/NKqlD6W4GbChnhidedukzHmks3A5OzXppYHc9GZ13jT1ZyDnWOJ9mHO//G1UU/5Up1uSUKTlENhoxRw7+0AOMlIKK/o6nhBDhNi+JspD5vpvizRDKSPSFwCwwMnu29pq8hYWSdA1/HFmbTJB+5UiVv4YAk6/IkEojkd9j6WM/tICtSrVMoq7i0Nc5xAP6tpuIbA0=----ATTACHMENT:----Nzk4NTk2MTg3MjIwMjQ1NiAzNzI0ODQ0NzM4MTUzMjgxIDU1NTc1Nzg5MTY1MjcwNjA=