Вход Регистрация
Файл: symfony-2.7/src/Symfony/Component/Intl/Data/Generator/LocaleDataGenerator.php
Строк: 284
<?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 SymfonyComponentIntlDataGenerator;

use 
SymfonyComponentFilesystemFilesystem;
use 
SymfonyComponentIntlDataProviderLanguageDataProvider;
use 
SymfonyComponentIntlDataProviderRegionDataProvider;
use 
SymfonyComponentIntlDataProviderScriptDataProvider;
use 
SymfonyComponentIntlDataUtilLocaleScanner;
use 
SymfonyComponentIntlExceptionMissingResourceException;
use 
SymfonyComponentIntlExceptionResourceBundleNotFoundException;
use 
SymfonyComponentIntlLocale;

/**
 * The rule for compiling the locale bundle.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 *
 * @internal
 */
class LocaleDataGenerator
{
    
/**
     * @var string
     */
    
private $dirName;

    
/**
     * @var LanguageDataProvider
     */
    
private $languageDataProvider;

    
/**
     * @var ScriptDataProvider
     */
    
private $scriptDataProvider;

    
/**
     * @var RegionDataProvider
     */
    
private $regionDataProvider;

    public function 
__construct($dirNameLanguageDataProvider $languageDataProviderScriptDataProvider $scriptDataProviderRegionDataProvider $regionDataProvider)
    {
        
$this->dirName $dirName;
        
$this->languageDataProvider $languageDataProvider;
        
$this->scriptDataProvider $scriptDataProvider;
        
$this->regionDataProvider $regionDataProvider;
    }

    
/**
     * {@inheritdoc}
     */
    
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 (=== 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;
    }
}
Онлайн: 2
Реклама