Source of file LocaleBundleTransformationRule.php
Size: 8,213 Bytes - Last Modified: 2013-07-17T08:22:21+02:00
/home/theseer/Downloads/Symfony/vendor/symfony/symfony/src/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 | <?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\ResourceBundle\Transformer\Rule; use Symfony\Component\Intl\Exception\RuntimeException; use Symfony\Component\Intl\Intl; use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface; use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface; use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter; /** * The rule for compiling the locale bundle. * * @author Bernhard Schussek <bschussek@gmail.com> */ class LocaleBundleTransformationRule implements TransformationRuleInterface { /** * @var \Symfony\Component\Intl\ResourceBundle\LanguageBundleInterface */ private $languageBundle; /** * @var \Symfony\Component\Intl\ResourceBundle\RegionBundleInterface */ private $regionBundle; public function __construct() { $this->languageBundle = Intl::getLanguageBundle(); $this->regionBundle = Intl::getRegionBundle(); } /** * {@inheritdoc} */ public function getBundleName() { return 'locales'; } /** * {@inheritdoc} */ public function beforeCompile(CompilationContextInterface $context) { $tempDir = sys_get_temp_dir() . '/icu-data-locales'; $context->getFilesystem()->remove($tempDir); $context->getFilesystem()->mkdir($tempDir); $this->generateTextFiles($tempDir, $this->scanLocales($context)); return $tempDir; } /** * {@inheritdoc} */ public function afterCompile(CompilationContextInterface $context) { $context->getFilesystem()->remove(sys_get_temp_dir() . '/icu-data-locales'); } /** * {@inheritdoc} */ public function beforeCreateStub(StubbingContextInterface $context) { return array( 'Locales' => Intl::getLocaleBundle()->getLocaleNames('en'), ); } /** * {@inheritdoc} */ public function afterCreateStub(StubbingContextInterface $context) { } private function scanLocales(CompilationContextInterface $context) { $tempDir = sys_get_temp_dir() . '/icu-data-locales-source'; $context->getFilesystem()->remove($tempDir); $context->getFilesystem()->mkdir($tempDir); // Temporarily generate the resource bundles $context->getCompiler()->compile($context->getSourceDir() . '/locales', $tempDir); // Discover the list of supported locales, which are the names of the resource // bundles in the "locales" directory $locales = glob($tempDir . '/*.res'); // Remove file extension and sort array_walk($locales, function (&$locale) { $locale = basename($locale, '.res'); }); sort($locales); // Delete unneeded locales foreach ($locales as $key => $locale) { // Delete all aliases from the list // i.e., "az_AZ" is an alias for "az_Latn_AZ" $content = file_get_contents($context->getSourceDir() . '/locales/' . $locale . '.txt'); // The key "%%ALIAS" is not accessible through the \ResourceBundle class, // so look in the original .txt file instead if (strpos($content, '%%ALIAS') !== false) { unset($locales[$key]); } // Delete locales that have no content (i.e. only "Version" key) $bundle = new \ResourceBundle($locale, $tempDir); if (null === $bundle) { throw new RuntimeException('The resource bundle for locale ' . $locale . ' could not be loaded from directory ' . $tempDir); } // There seems to be no other way for identifying all keys in this specific // resource bundle if (array_keys(iterator_to_array($bundle)) === array('Version')) { unset($locales[$key]); } } $context->getFilesystem()->remove($tempDir); return $locales; } private function generateTextFiles($targetDirectory, array $locales) { $displayLocales = array_unique(array_merge( $this->languageBundle->getLocales(), $this->regionBundle->getLocales() )); $txtWriter = new TextBundleWriter(); // Generate a list of locale names 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. foreach ($displayLocales as $displayLocale) { // Don't include ICU's root resource bundle if ('root' === $displayLocale) { continue; } $names = array(); foreach ($locales as $locale) { // Don't include ICU's root resource bundle if ($locale === 'root') { continue; } if (null !== ($name = $this->generateLocaleName($locale, $displayLocale))) { $names[$locale] = $name; } } // If no names could be generated for the current locale, skip it if (0 === count($names)) { continue; } $txtWriter->write($targetDirectory, $displayLocale, array('Locales' => $names)); } } 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 null; } // 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->languageBundle->getLanguageName($lang, null, $displayLocale))) { return null; } // "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->languageBundle->getScriptName($script, $lang, $displayLocale))) { return null; } $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->regionBundle->getCountryName($region, $displayLocale))) { return null; } $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; } } |