PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/core/Translate.php

https://github.com/CodeYellowBV/piwik
PHP | 215 lines | 113 code | 24 blank | 78 comment | 10 complexity | 66aeaeb9ff382ec194ef60c6db5d4881 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik;
  10. use Exception;
  11. /**
  12. */
  13. class Translate
  14. {
  15. private static $languageToLoad = null;
  16. private static $loadedLanguage = false;
  17. /**
  18. * Clean a string that may contain HTML special chars, single/double quotes, HTML entities, leading/trailing whitespace
  19. *
  20. * @param string $s
  21. * @return string
  22. */
  23. public static function clean($s)
  24. {
  25. return html_entity_decode(trim($s), ENT_QUOTES, 'UTF-8');
  26. }
  27. public static function loadEnglishTranslation()
  28. {
  29. self::loadCoreTranslationFile('en');
  30. }
  31. public static function unloadEnglishTranslation()
  32. {
  33. $GLOBALS['Piwik_translations'] = array();
  34. }
  35. public static function reloadLanguage($language = false)
  36. {
  37. if (empty($language)) {
  38. $language = self::getLanguageToLoad();
  39. }
  40. self::unloadEnglishTranslation();
  41. self::loadEnglishTranslation();
  42. self::loadCoreTranslation($language);
  43. \Piwik\Plugin\Manager::getInstance()->loadPluginTranslations($language);
  44. }
  45. /**
  46. * Reads the specified code translation file in memory.
  47. *
  48. * @param bool|string $language 2 letter language code. If not specified, will detect current user translation, or load default translation.
  49. * @return void
  50. */
  51. public static function loadCoreTranslation($language = false)
  52. {
  53. if (empty($language)) {
  54. $language = self::getLanguageToLoad();
  55. }
  56. if (self::$loadedLanguage == $language) {
  57. return;
  58. }
  59. self::loadCoreTranslationFile($language);
  60. }
  61. private static function loadCoreTranslationFile($language)
  62. {
  63. if(empty($language)) {
  64. return;
  65. }
  66. $path = PIWIK_INCLUDE_PATH . '/lang/' . $language . '.json';
  67. if (!Filesystem::isValidFilename($language) || !is_readable($path)) {
  68. throw new Exception(Piwik::translate('General_ExceptionLanguageFileNotFound', array($language)));
  69. }
  70. $data = file_get_contents($path);
  71. $translations = json_decode($data, true);
  72. self::mergeTranslationArray($translations);
  73. self::setLocale();
  74. self::$loadedLanguage = $language;
  75. }
  76. public static function mergeTranslationArray($translation)
  77. {
  78. if (!isset($GLOBALS['Piwik_translations'])) {
  79. $GLOBALS['Piwik_translations'] = array();
  80. }
  81. if (empty($translation)) {
  82. return;
  83. }
  84. // we could check that no string overlap here
  85. $GLOBALS['Piwik_translations'] = array_replace_recursive($GLOBALS['Piwik_translations'], $translation);
  86. }
  87. /**
  88. * @return string the language filename prefix, eg 'en' for english
  89. * @throws exception if the language set is not a valid filename
  90. */
  91. public static function getLanguageToLoad()
  92. {
  93. if (is_null(self::$languageToLoad)) {
  94. $lang = Common::getRequestVar('language', '', 'string');
  95. /**
  96. * Triggered when the current user's language is requested.
  97. *
  98. * By default the current language is determined by the **language** query
  99. * parameter. Plugins can override this logic by subscribing to this event.
  100. *
  101. * **Example**
  102. *
  103. * public function getLanguage(&$lang)
  104. * {
  105. * $client = new My3rdPartyAPIClient();
  106. * $thirdPartyLang = $client->getLanguageForUser(Piwik::getCurrentUserLogin());
  107. *
  108. * if (!empty($thirdPartyLang)) {
  109. * $lang = $thirdPartyLang;
  110. * }
  111. * }
  112. *
  113. * @param string &$lang The language that should be used for the current user. Will be
  114. * initialized to the value of the **language** query parameter.
  115. */
  116. Piwik::postEvent('User.getLanguage', array(&$lang));
  117. self::$languageToLoad = $lang;
  118. }
  119. return self::$languageToLoad;
  120. }
  121. /** Reset the cached language to load. Used in tests. */
  122. public static function reset()
  123. {
  124. self::$languageToLoad = null;
  125. }
  126. public static function getLanguageLoaded()
  127. {
  128. return self::$loadedLanguage;
  129. }
  130. public static function getLanguageDefault()
  131. {
  132. return Config::getInstance()->General['default_language'];
  133. }
  134. /**
  135. * Generate javascript translations array
  136. */
  137. public static function getJavascriptTranslations()
  138. {
  139. $translations = & $GLOBALS['Piwik_translations'];
  140. $clientSideTranslations = array();
  141. foreach (self::getClientSideTranslationKeys() as $key) {
  142. list($plugin, $stringName) = explode("_", $key, 2);
  143. $clientSideTranslations[$key] = $translations[$plugin][$stringName];
  144. }
  145. $js = 'var translations = ' . Common::json_encode($clientSideTranslations) . ';';
  146. $js .= "\n" . 'if(typeof(piwik_translations) == \'undefined\') { var piwik_translations = new Object; }' .
  147. 'for(var i in translations) { piwik_translations[i] = translations[i];} ';
  148. return $js;
  149. }
  150. /**
  151. * Returns the list of client side translations by key. These translations will be outputted
  152. * to the translation JavaScript.
  153. */
  154. private static function getClientSideTranslationKeys()
  155. {
  156. $result = array();
  157. /**
  158. * Triggered before generating the JavaScript code that allows i18n strings to be used
  159. * in the browser.
  160. *
  161. * Plugins should subscribe to this event to specify which translations
  162. * should be available to JavaScript.
  163. *
  164. * Event handlers should add whole translation keys, ie, keys that include the plugin name.
  165. *
  166. * **Example**
  167. *
  168. * public function getClientSideTranslationKeys(&$result)
  169. * {
  170. * $result[] = "MyPlugin_MyTranslation";
  171. * }
  172. *
  173. * @param array &$result The whole list of client side translation keys.
  174. */
  175. Piwik::postEvent('Translate.getClientSideTranslationKeys', array(&$result));
  176. $result = array_unique($result);
  177. return $result;
  178. }
  179. /**
  180. * Set locale
  181. *
  182. * @see http://php.net/setlocale
  183. */
  184. private static function setLocale()
  185. {
  186. $locale = $GLOBALS['Piwik_translations']['General']['Locale'];
  187. $locale_variant = str_replace('UTF-8', 'UTF8', $locale);
  188. setlocale(LC_ALL, $locale, $locale_variant);
  189. setlocale(LC_CTYPE, '');
  190. }
  191. }