PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/symfony/symfony/src/Symfony/Component/Intl/ResourceBundle/Transformer/Rule/LocaleBundleTransformationRule.php

https://bitbucket.org/gruenwaldt/loquitur-web
PHP | 251 lines | 127 code | 48 blank | 76 comment | 15 complexity | b36898f104b6fab51ac1b3d43688a445 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Intl\ResourceBundle\Transformer\Rule;
  11. use Symfony\Component\Intl\Exception\RuntimeException;
  12. use Symfony\Component\Intl\Intl;
  13. use Symfony\Component\Intl\ResourceBundle\Transformer\CompilationContextInterface;
  14. use Symfony\Component\Intl\ResourceBundle\Transformer\StubbingContextInterface;
  15. use Symfony\Component\Intl\ResourceBundle\Writer\TextBundleWriter;
  16. /**
  17. * The rule for compiling the locale bundle.
  18. *
  19. * @author Bernhard Schussek <bschussek@gmail.com>
  20. */
  21. class LocaleBundleTransformationRule implements TransformationRuleInterface
  22. {
  23. /**
  24. * @var \Symfony\Component\Intl\ResourceBundle\LanguageBundleInterface
  25. */
  26. private $languageBundle;
  27. /**
  28. * @var \Symfony\Component\Intl\ResourceBundle\RegionBundleInterface
  29. */
  30. private $regionBundle;
  31. public function __construct()
  32. {
  33. $this->languageBundle = Intl::getLanguageBundle();
  34. $this->regionBundle = Intl::getRegionBundle();
  35. }
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public function getBundleName()
  40. {
  41. return 'locales';
  42. }
  43. /**
  44. * {@inheritdoc}
  45. */
  46. public function beforeCompile(CompilationContextInterface $context)
  47. {
  48. $tempDir = sys_get_temp_dir() . '/icu-data-locales';
  49. $context->getFilesystem()->remove($tempDir);
  50. $context->getFilesystem()->mkdir($tempDir);
  51. $this->generateTextFiles($tempDir, $this->scanLocales($context));
  52. return $tempDir;
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. public function afterCompile(CompilationContextInterface $context)
  58. {
  59. $context->getFilesystem()->remove(sys_get_temp_dir() . '/icu-data-locales');
  60. }
  61. /**
  62. * {@inheritdoc}
  63. */
  64. public function beforeCreateStub(StubbingContextInterface $context)
  65. {
  66. return array(
  67. 'Locales' => Intl::getLocaleBundle()->getLocaleNames('en'),
  68. );
  69. }
  70. /**
  71. * {@inheritdoc}
  72. */
  73. public function afterCreateStub(StubbingContextInterface $context)
  74. {
  75. }
  76. private function scanLocales(CompilationContextInterface $context)
  77. {
  78. $tempDir = sys_get_temp_dir() . '/icu-data-locales-source';
  79. $context->getFilesystem()->remove($tempDir);
  80. $context->getFilesystem()->mkdir($tempDir);
  81. // Temporarily generate the resource bundles
  82. $context->getCompiler()->compile($context->getSourceDir() . '/locales', $tempDir);
  83. // Discover the list of supported locales, which are the names of the resource
  84. // bundles in the "locales" directory
  85. $locales = glob($tempDir . '/*.res');
  86. // Remove file extension and sort
  87. array_walk($locales, function (&$locale) { $locale = basename($locale, '.res'); });
  88. sort($locales);
  89. // Delete unneeded locales
  90. foreach ($locales as $key => $locale) {
  91. // Delete all aliases from the list
  92. // i.e., "az_AZ" is an alias for "az_Latn_AZ"
  93. $content = file_get_contents($context->getSourceDir() . '/locales/' . $locale . '.txt');
  94. // The key "%%ALIAS" is not accessible through the \ResourceBundle class,
  95. // so look in the original .txt file instead
  96. if (strpos($content, '%%ALIAS') !== false) {
  97. unset($locales[$key]);
  98. }
  99. // Delete locales that have no content (i.e. only "Version" key)
  100. $bundle = new \ResourceBundle($locale, $tempDir);
  101. if (null === $bundle) {
  102. throw new RuntimeException('The resource bundle for locale ' . $locale . ' could not be loaded from directory ' . $tempDir);
  103. }
  104. // There seems to be no other way for identifying all keys in this specific
  105. // resource bundle
  106. if (array_keys(iterator_to_array($bundle)) === array('Version')) {
  107. unset($locales[$key]);
  108. }
  109. }
  110. $context->getFilesystem()->remove($tempDir);
  111. return $locales;
  112. }
  113. private function generateTextFiles($targetDirectory, array $locales)
  114. {
  115. $displayLocales = array_unique(array_merge(
  116. $this->languageBundle->getLocales(),
  117. $this->regionBundle->getLocales()
  118. ));
  119. $txtWriter = new TextBundleWriter();
  120. // Generate a list of locale names in the language of each display locale
  121. // Each locale name has the form: "Language (Script, Region, Variant1, ...)
  122. // Script, Region and Variants are optional. If none of them is available,
  123. // the braces are not printed.
  124. foreach ($displayLocales as $displayLocale) {
  125. // Don't include ICU's root resource bundle
  126. if ('root' === $displayLocale) {
  127. continue;
  128. }
  129. $names = array();
  130. foreach ($locales as $locale) {
  131. // Don't include ICU's root resource bundle
  132. if ($locale === 'root') {
  133. continue;
  134. }
  135. if (null !== ($name = $this->generateLocaleName($locale, $displayLocale))) {
  136. $names[$locale] = $name;
  137. }
  138. }
  139. // If no names could be generated for the current locale, skip it
  140. if (0 === count($names)) {
  141. continue;
  142. }
  143. $txtWriter->write($targetDirectory, $displayLocale, array('Locales' => $names));
  144. }
  145. }
  146. private function generateLocaleName($locale, $displayLocale)
  147. {
  148. $name = null;
  149. $lang = \Locale::getPrimaryLanguage($locale);
  150. $script = \Locale::getScript($locale);
  151. $region = \Locale::getRegion($locale);
  152. $variants = \Locale::getAllVariants($locale);
  153. // Currently the only available variant is POSIX, which we don't want
  154. // to include in the list
  155. if (count($variants) > 0) {
  156. return null;
  157. }
  158. // Some languages are translated together with their region,
  159. // i.e. "en_GB" is translated as "British English"
  160. // we don't include these languages though because they mess up
  161. // the name sorting
  162. // $name = $this->langBundle->getLanguageName($displayLocale, $lang, $region);
  163. // Some languages are simply not translated
  164. // Example: "az" (Azerbaijani) has no translation in "af" (Afrikaans)
  165. if (null === ($name = $this->languageBundle->getLanguageName($lang, null, $displayLocale))) {
  166. return null;
  167. }
  168. // "as" (Assamese) has no "Variants" block
  169. //if (!$langBundle->get('Variants')) {
  170. // continue;
  171. //}
  172. $extras = array();
  173. // Discover the name of the script part of the locale
  174. // i.e. in zh_Hans_MO, "Hans" is the script
  175. if ($script) {
  176. // Some scripts are not translated into every language
  177. if (null === ($scriptName = $this->languageBundle->getScriptName($script, $lang, $displayLocale))) {
  178. return null;
  179. }
  180. $extras[] = $scriptName;
  181. }
  182. // Discover the name of the region part of the locale
  183. // i.e. in de_AT, "AT" is the region
  184. if ($region) {
  185. // Some regions are not translated into every language
  186. if (null === ($regionName = $this->regionBundle->getCountryName($region, $displayLocale))) {
  187. return null;
  188. }
  189. $extras[] = $regionName;
  190. }
  191. if (count($extras) > 0) {
  192. // Remove any existing extras
  193. // For example, in German, zh_Hans is "Chinesisch (vereinfacht)".
  194. // The latter is the script part which is already included in the
  195. // extras and will be appended again with the other extras.
  196. if (preg_match('/^(.+)\s+\([^\)]+\)$/', $name, $matches)) {
  197. $name = $matches[1];
  198. }
  199. $name .= ' ('.implode(', ', $extras).')';
  200. }
  201. return $name;
  202. }
  203. }