PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/qcodo/_core/framework/QI18n.class.php

http://github.com/qcodo/qcodo
PHP | 288 lines | 243 code | 42 blank | 3 comment | 66 complexity | 580021a998c38dc86687ca1a3b56e828 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. class QPoParserException extends QCallerException {}
  3. class QI18n extends QBaseClass {
  4. public static function Initialize() {
  5. if (QApplication::$LanguageCode) {
  6. if (QApplication::$CountryCode) {
  7. $strCode = sprintf('%s_%s', QApplication::$LanguageCode, QApplication::$CountryCode);
  8. $strLanguageFiles = array(
  9. __QCODO_CORE__ . '/i18n/' . QApplication::$LanguageCode . '.po',
  10. __QCODO_CORE__ . '/i18n/' . $strCode . '.po',
  11. __QCODO__ . '/i18n/' . QApplication::$LanguageCode . '.po',
  12. __QCODO__ . '/i18n/' . $strCode . '.po'
  13. );
  14. } else {
  15. $strCode = QApplication::$LanguageCode;
  16. $strLanguageFiles = array(
  17. __QCODO_CORE__ . '/i18n/' . QApplication::$LanguageCode . '.po',
  18. __QCODO__ . '/i18n/' . QApplication::$LanguageCode . '.po'
  19. );
  20. }
  21. // Setup the LanguageFileObject cache mechanism
  22. $objCache = new QCache('i18n', $strCode, 'i18n', $strLanguageFiles);
  23. // If cached data exists and is valid, use it
  24. $strData = $objCache->GetData();
  25. if ($strData)
  26. QApplication::$LanguageObject = unserialize($strData);
  27. // Otherwise, reload all langauge files and update the cache
  28. else {
  29. $objLanguage = new QI18n();
  30. foreach ($strLanguageFiles as $strLanguageFile)
  31. if (file_exists($strLanguageFile)) {
  32. try {
  33. $objLanguage->ParsePoData(file_get_contents($strLanguageFile));
  34. } catch (QPoParserException $objExc) {
  35. $objExc->setMessage('Invalid Language File: ' . $strLanguageFile . ': ' . $objExc->getMessage());
  36. $objExc->IncrementOffset();
  37. throw $objExc;
  38. }
  39. }
  40. QApplication::$LanguageObject = $objLanguage;
  41. $objCache->SaveData(serialize($objLanguage));
  42. }
  43. }
  44. }
  45. const PoParseStateNone = 0;
  46. const PoParseStateMessageIdStart = 1;
  47. const PoParseStateMessageId = 2;
  48. const PoParseStateMessageStringStart = 3;
  49. const PoParseStateMessageString = 4;
  50. protected static function UnescapeContent($strContent) {
  51. $intLength = strlen($strContent);
  52. $strToReturn = '';
  53. $blnEscape = false;
  54. for ($intIndex = 0; $intIndex < $intLength; $intIndex++) {
  55. if ($blnEscape) {
  56. switch ($strContent[$intIndex]) {
  57. case 'n':
  58. $blnEscape = false;
  59. $strToReturn .= "\n";
  60. break;
  61. case 'r':
  62. $blnEscape = false;
  63. $strToReturn .= "\r";
  64. break;
  65. case 't':
  66. $blnEscape = false;
  67. $strToReturn .= " ";
  68. break;
  69. case '\\':
  70. $blnEscape = false;
  71. $strToReturn .= '\\';
  72. break;
  73. case '"':
  74. $blnEscape = false;
  75. $strToReturn .= '"';
  76. break;
  77. case "'":
  78. $blnEscape = false;
  79. $strToReturn .= "'";
  80. break;
  81. default:
  82. $blnEscape = false;
  83. $strToReturn .= '\\' . $strContent[$intIndex];
  84. break;
  85. }
  86. } else {
  87. if ($strContent[$intIndex] == '\\')
  88. $blnEscape = true;
  89. else
  90. $strToReturn .= $strContent[$intIndex];
  91. }
  92. }
  93. if ($blnEscape)
  94. return false;
  95. $strToReturn = str_replace("\r", '', $strToReturn);
  96. return $strToReturn;
  97. }
  98. protected function ParsePoData($strPoData) {
  99. $strPoData = str_replace("\r", '', trim($strPoData));
  100. $strPoLines = explode("\n", $strPoData);
  101. $strMatches = array();
  102. $intState = QI18n::PoParseStateNone;
  103. $intLineCount = count($strPoLines);
  104. if (strlen($strPoLines[0]) == 0)
  105. return;
  106. for ($intLineNumber = 0; $intLineNumber < $intLineCount; $intLineNumber++) {
  107. $strPoLine = $strPoLines[$intLineNumber] = trim($strPoLines[$intLineNumber]);
  108. if (strlen($strPoLine) && (QString::FirstCharacter($strPoLine) != '#')) {
  109. switch ($intState) {
  110. case QI18n::PoParseStateNone:
  111. $intCount = preg_match_all('/msgid(_[a-z0-9]+)?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  112. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  113. $intLineNumber--;
  114. $intState = QI18n::PoParseStateMessageIdStart;
  115. } else
  116. throw new QPoParserException('Invalid content for PoParseStateNone on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  117. break;
  118. case QI18n::PoParseStateMessageIdStart:
  119. $intCount = preg_match_all('/msgid(_[a-z0-9]+)?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  120. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  121. $strMessageId = array('', '', '', '', '', '', '');
  122. $strMessageString = array('', '', '', '', '', '', '');
  123. $intArrayIndex = 0;
  124. $strContent = QI18n::UnescapeContent($strMatches[2][0]);
  125. if ($strContent === false)
  126. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  127. $strMessageId[$intArrayIndex] = $strContent;
  128. $intState = QI18n::PoParseStateMessageId;
  129. } else
  130. throw new QPoParserException('Invalid content for PoParseStateMessageIdStart on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  131. break;
  132. case QI18n::PoParseStateMessageId:
  133. $intCount = preg_match_all('/msgid(_[a-z0-9]+)[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  134. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  135. if (strlen(trim($strMessageId[$intArrayIndex])) == 0)
  136. throw new QPoParserException('No MsgId content for current MsgId on Line ' . ($intLineNumber) . ': ' . $strPoLine);
  137. $intArrayIndex++;
  138. $strContent = QI18n::UnescapeContent($strMatches[2][0]);
  139. if ($strContent === false)
  140. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  141. $strMessageId[$intArrayIndex] = $strContent;
  142. break;
  143. }
  144. $intCount = preg_match_all('/"([\S ]*)"/', $strPoLine, $strMatches);
  145. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  146. $strContent = QI18n::UnescapeContent($strMatches[1][0]);
  147. if ($strContent === false)
  148. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  149. $strMessageId[$intArrayIndex] .= $strContent;
  150. break;
  151. }
  152. $intCount = preg_match_all('/msgstr(\[[0-9]+\])?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  153. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  154. if (strlen(trim($strMessageId[$intArrayIndex])) == 0)
  155. throw new QPoParserException('No MsgId content for current MsgId on Line ' . ($intLineNumber) . ': ' . $strPoLine);
  156. $intLineNumber--;
  157. $intState = QI18n::PoParseStateMessageStringStart;
  158. break;
  159. }
  160. throw new QPoParserException('Invalid content for PoParseStateMessageId on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  161. case QI18n::PoParseStateMessageStringStart:
  162. $intCount = preg_match_all('/msgstr(\[[0-9]+\])?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  163. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  164. $intArrayIndex = 0;
  165. if (strlen($strMatches[1][0]))
  166. $intArrayIndex = intval(substr($strMatches[1][0], 1, strlen($strMatches[1][0]) - 2));
  167. $strContent = QI18n::UnescapeContent($strMatches[2][0]);
  168. if ($strContent === false)
  169. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  170. $strMessageString[$intArrayIndex] = $strContent;
  171. $intState = QI18n::PoParseStateMessageString;
  172. } else
  173. throw new QPoParserException('Invalid content for PoParseStateMessageStringStart on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  174. break;
  175. case QI18n::PoParseStateMessageString:
  176. $intCount = preg_match_all('/msgid(_[a-z0-9]+)?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  177. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  178. for ($intIndex = 0; $intIndex < count($strMessageId); $intIndex++)
  179. if (strlen(trim($strMessageId[$intIndex]))) {
  180. if (!strlen(trim($strMessageString[$intIndex]))) {
  181. throw new QPoParserException('No MsgStr defined for MsgId at index ' . $intIndex . ' prior to Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  182. }
  183. $this->SetTranslation($strMessageId[$intIndex], $strMessageString[$intIndex]);
  184. }
  185. $intLineNumber--;
  186. $intState = QI18n::PoParseStateMessageIdStart;
  187. break;
  188. }
  189. $intCount = preg_match_all('/"([\S ]*)"/', $strPoLine, $strMatches);
  190. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  191. $strContent = QI18n::UnescapeContent($strMatches[1][0]);
  192. if ($strContent === false)
  193. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  194. $strMessageString[$intArrayIndex] .= $strContent;
  195. break;
  196. }
  197. $intCount = preg_match_all('/msgstr(\[[0-9]+\])?[\s]+"([\S ]*)"/i', $strPoLine, $strMatches);
  198. if ($intCount && ($strMatches[0][0] == $strPoLine)) {
  199. if (strlen($strMatches[1][0]))
  200. $intArrayIndex = intval(substr($strMatches[1][0], 1, strlen($strMatches[1][0]) - 2));
  201. else
  202. throw new QPoParserException('No index specified for alternate MsgStr for PoParseStateMessageString on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  203. if (strlen(trim($strMessageId[$intArrayIndex])) == 0)
  204. throw new QPoParserException('No MsgId for MsgStr' . $strMatches[1][0] . ' for PoParseStateMessageString on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  205. $strContent = QI18n::UnescapeContent($strMatches[2][0]);
  206. if ($strContent === false)
  207. throw new QPoParserException('Invalid content on Line ' . ($intLineNumber + 1));
  208. $strMessageString[$intArrayIndex] = $strContent;
  209. break;
  210. }
  211. throw new QPoParserException('Invalid content for PoParseStateMessageString on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  212. default:
  213. throw new QPoParserException('Invalid PoParseState on Line ' . ($intLineNumber + 1) . ': ' . $strPoLine);
  214. }
  215. }
  216. }
  217. for ($intIndex = 0; $intIndex < count($strMessageId); $intIndex++)
  218. if (strlen(trim($strMessageId[$intIndex]))) {
  219. if (!strlen(trim($strMessageString[$intIndex]))) {
  220. throw new QPoParserException('No MsgStr defined for MsgId at index ' . $intIndex . ' at the End of the File');
  221. }
  222. $this->SetTranslation($strMessageId[$intIndex], $strMessageString[$intIndex]);
  223. }
  224. }
  225. protected $strTranslationArray = array();
  226. protected function SetTranslation($strToken, $strTranslatedText) {
  227. $this->strTranslationArray[$strToken] = $strTranslatedText;
  228. }
  229. public function TranslateToken($strToken) {
  230. $strCleanToken = str_replace("\r", '', $strToken);
  231. if (array_key_exists($strCleanToken, $this->strTranslationArray))
  232. return $this->strTranslationArray[$strCleanToken];
  233. else
  234. return $strToken;
  235. }
  236. public function VarDump() {
  237. $strToReturn = '';
  238. foreach ($this->strTranslationArray as $strKey=>$strValue) {
  239. $strKey = str_replace("\n", '\\n', addslashes(QApplication::HtmlEntities($strKey)));
  240. $strValue = str_replace("\n", '\\n', addslashes(QApplication::HtmlEntities($strValue)));
  241. $strToReturn .= sprintf("\"%s\"\n\"%s\"\n\n", $strKey, $strValue);
  242. }
  243. return $strToReturn;
  244. }
  245. }
  246. ?>