Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

136 lines
4.4KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\i18n;
  8. use Yii;
  9. /**
  10. * GettextMessageSource represents a message source that is based on GNU Gettext.
  11. *
  12. * Each GettextMessageSource instance represents the message translations
  13. * for a single domain. And each message category represents a message context
  14. * in Gettext. Translated messages are stored as either a MO or PO file,
  15. * depending on the [[useMoFile]] property value.
  16. *
  17. * All translations are saved under the [[basePath]] directory.
  18. *
  19. * Translations in one language are kept as MO or PO files under an individual
  20. * subdirectory whose name is the language ID. The file name is specified via
  21. * [[catalog]] property, which defaults to 'messages'.
  22. *
  23. * @author Qiang Xue <qiang.xue@gmail.com>
  24. * @since 2.0
  25. */
  26. class GettextMessageSource extends MessageSource
  27. {
  28. const MO_FILE_EXT = '.mo';
  29. const PO_FILE_EXT = '.po';
  30. /**
  31. * @var string
  32. */
  33. public $basePath = '@app/messages';
  34. /**
  35. * @var string
  36. */
  37. public $catalog = 'messages';
  38. /**
  39. * @var boolean
  40. */
  41. public $useMoFile = true;
  42. /**
  43. * @var boolean
  44. */
  45. public $useBigEndian = false;
  46. /**
  47. * Loads the message translation for the specified language and category.
  48. * If translation for specific locale code such as `en-US` isn't found it
  49. * tries more generic `en`.
  50. *
  51. * @param string $category the message category
  52. * @param string $language the target language
  53. * @return array the loaded messages. The keys are original messages, and the values
  54. * are translated messages.
  55. */
  56. protected function loadMessages($category, $language)
  57. {
  58. $messageFile = $this->getMessageFilePath($language);
  59. $messages = $this->loadMessagesFromFile($messageFile, $category);
  60. $fallbackLanguage = substr($language, 0, 2);
  61. if ($fallbackLanguage != $language) {
  62. $fallbackMessageFile = $this->getMessageFilePath($fallbackLanguage);
  63. $fallbackMessages = $this->loadMessagesFromFile($fallbackMessageFile, $category);
  64. if ($messages === null && $fallbackMessages === null && $fallbackLanguage != $this->sourceLanguage) {
  65. Yii::error("The message file for category '$category' does not exist: $messageFile Fallback file does not exist as well: $fallbackMessageFile", __METHOD__);
  66. } elseif (empty($messages)) {
  67. return $fallbackMessages;
  68. } elseif (!empty($fallbackMessages)) {
  69. foreach ($fallbackMessages as $key => $value) {
  70. if (!empty($value) && empty($messages[$key])) {
  71. $messages[$key] = $fallbackMessages[$key];
  72. }
  73. }
  74. }
  75. } else {
  76. if ($messages === null) {
  77. Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__);
  78. }
  79. }
  80. return (array) $messages;
  81. }
  82. /**
  83. * Returns message file path for the specified language and category.
  84. *
  85. * @param string $language the target language
  86. * @return string path to message file
  87. */
  88. protected function getMessageFilePath($language)
  89. {
  90. $messageFile = Yii::getAlias($this->basePath) . '/' . $language . '/' . $this->catalog;
  91. if ($this->useMoFile) {
  92. $messageFile .= self::MO_FILE_EXT;
  93. } else {
  94. $messageFile .= self::PO_FILE_EXT;
  95. }
  96. return $messageFile;
  97. }
  98. /**
  99. * Loads the message translation for the specified language and category or returns null if file doesn't exist.
  100. *
  101. * @param string $messageFile path to message file
  102. * @param string $category the message category
  103. * @return array|null array of messages or null if file not found
  104. */
  105. protected function loadMessagesFromFile($messageFile, $category)
  106. {
  107. if (is_file($messageFile)) {
  108. if ($this->useMoFile) {
  109. $gettextFile = new GettextMoFile(['useBigEndian' => $this->useBigEndian]);
  110. } else {
  111. $gettextFile = new GettextPoFile();
  112. }
  113. $messages = $gettextFile->load($messageFile, $category);
  114. if (!is_array($messages)) {
  115. $messages = [];
  116. }
  117. return $messages;
  118. } else {
  119. return null;
  120. }
  121. }
  122. }