PageRenderTime 65ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/phpmyfaq/inc/Language.php

https://github.com/cyrke/phpMyFAQ
PHP | 377 lines | 208 code | 31 blank | 138 comment | 42 complexity | 706d13eee7920f061cb997d3f330728b MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Manages all language stuff
  4. *
  5. * PHP Version 5.3
  6. *
  7. * This Source Code Form is subject to the terms of the Mozilla Public License,
  8. * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  9. * obtain one at http://mozilla.org/MPL/2.0/.
  10. *
  11. * @category phpMyFAQ
  12. * @package Language
  13. * @author Thorsten Rinne <thorsten@phpmyfaq.de>
  14. * @author Matteo scaramuccia <matteo@phpmyfaq.de>
  15. * @author Aurimas Fišeras <aurimas@gmail.com>
  16. * @copyright 2009-2012 phpMyFAQ Team
  17. * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
  18. * @link http://www.phpmyfaq.de
  19. * @since 2009-05-14
  20. */
  21. if (!defined('IS_VALID_PHPMYFAQ')) {
  22. exit();
  23. }
  24. /**
  25. * Language
  26. *
  27. * @category phpMyFAQ
  28. * @package Language
  29. * @author Thorsten Rinne <thorsten@phpmyfaq.de>
  30. * @author Matteo scaramuccia <matteo@phpmyfaq.de>
  31. * @author Aurimas Fišeras <aurimas@gmail.com>
  32. * @copyright 2009-2012 phpMyFAQ Team
  33. * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
  34. * @link http://www.phpmyfaq.de
  35. * @since 2009-05-14
  36. */
  37. class PMF_Language
  38. {
  39. /**
  40. * The accepted language of the user agend
  41. *
  42. * @var string
  43. */
  44. public $acceptedLanguage = '';
  45. /**
  46. * The current language
  47. *
  48. * @var string
  49. */
  50. public static $language = '';
  51. /**
  52. * @var PMF_Configuration
  53. */
  54. private $config;
  55. /**
  56. * Constructor
  57. *
  58. * @param PMF_Configuration $config
  59. *
  60. * @return PMF_Language
  61. */
  62. public function __construct(PMF_Configuration $config)
  63. {
  64. $this->config = $config;
  65. }
  66. /**
  67. * Returns an array of country codes for a specific FAQ record ID,
  68. * specific category ID or all languages used by FAQ records , categories
  69. *
  70. * @param integer $id ID
  71. * @param string $table Specifies table
  72. *
  73. * @return array
  74. */
  75. public function languageAvailable($id, $table = 'faqdata')
  76. {
  77. $output = array();
  78. if (isset($id)) {
  79. if ($id == 0) {
  80. // get languages for all ids
  81. $distinct = ' DISTINCT ';
  82. $where = '';
  83. } else {
  84. // get languages for specified id
  85. $distinct = '';
  86. $where = " WHERE id = ".$id;
  87. }
  88. $query = sprintf("
  89. SELECT %s
  90. lang
  91. FROM
  92. %s%s
  93. %s",
  94. $distinct,
  95. PMF_Db::getTablePrefix(),
  96. $table,
  97. $where
  98. );
  99. $result = $this->config->getDb()->query($query);
  100. if ($this->config->getDb()->numRows($result) > 0) {
  101. while ($row = $this->config->getDb()->fetchObject($result)) {
  102. $output[] = $row->lang;
  103. }
  104. }
  105. }
  106. return $output;
  107. }
  108. /**
  109. * Sets the current language for phpMyFAQ user session
  110. *
  111. * @param bool $configDetection Configuration detection
  112. * @param string $configLanguage Language from configuration
  113. *
  114. * @return string
  115. */
  116. public function setLanguage($configDetection, $configLanguage)
  117. {
  118. $_lang = array();
  119. self::_getUserAgentLanguage();
  120. // Get language from: _POST, _GET, _COOKIE, phpMyFAQ configuration and the automatic language detection
  121. $_lang['post'] = PMF_Filter::filterInput(INPUT_POST, 'language', FILTER_SANITIZE_STRING);
  122. if (!is_null($_lang['post']) && !self::isASupportedLanguage($_lang['post']) ) {
  123. $_lang['post'] = null;
  124. }
  125. // Get the user language
  126. $_lang['get'] = PMF_Filter::filterInput(INPUT_GET, 'lang', FILTER_SANITIZE_STRING);
  127. if (!is_null($_lang['get']) && !self::isASupportedLanguage($_lang['get']) ) {
  128. $_lang['get'] = null;
  129. }
  130. // Get the faq record language
  131. $_lang['artget'] = PMF_Filter::filterInput(INPUT_GET, 'artlang', FILTER_SANITIZE_STRING);
  132. if (!is_null($_lang['artget']) && !self::isASupportedLanguage($_lang['artget']) ) {
  133. $_lang['get'] = null;
  134. }
  135. // Get the language from the session
  136. if (isset($_SESSION['pmf_lang']) && self::isASupportedLanguage($_SESSION['pmf_lang']) ) {
  137. $_lang['session'] = trim($_SESSION['pmf_lang']);
  138. }
  139. // Get the language from the config
  140. if (isset($configLanguage)) {
  141. $confLangCode = str_replace(array("language_", ".php"), "", $configLanguage);
  142. if (self::isASupportedLanguage($confLangCode) ) {
  143. $_lang['config'] = $confLangCode;
  144. }
  145. }
  146. // Detect the browser's language
  147. if ((true === $configDetection) && self::isASupportedLanguage($this->acceptedLanguage) ) {
  148. $_lang['detection'] = strtolower($this->acceptedLanguage);
  149. }
  150. // Select the language
  151. if (isset($_lang['post'])) {
  152. self::$language = $_lang['post'];
  153. $_lang = null;
  154. unset($_lang);
  155. } elseif (isset($_lang['get'])) {
  156. self::$language = $_lang['get'];
  157. } elseif (isset($_lang['session'])) {
  158. self::$language = $_lang['session'];
  159. $_lang = null;
  160. unset($_lang);
  161. } elseif (isset($_lang['detection'])) {
  162. self::$language = $_lang['detection'];
  163. $_lang = null;
  164. unset($_lang);
  165. } elseif (isset($_lang['config'])) {
  166. self::$language = $_lang['config'];
  167. $_lang = null;
  168. unset($_lang);
  169. } else {
  170. self::$language = 'en'; // just a fallback
  171. }
  172. return $_SESSION['pmf_lang'] = self::$language;
  173. }
  174. /**
  175. * Returns the current language
  176. *
  177. * @return string
  178. */
  179. public function getLanguage()
  180. {
  181. return self::$language;
  182. }
  183. /**
  184. * This function returns the available languages
  185. *
  186. * @return array
  187. */
  188. public static function getAvailableLanguages()
  189. {
  190. global $languageCodes;
  191. $search = array("language_" , ".php");
  192. $languages = $languageFiles = array();
  193. $dir = new DirectoryIterator(__DIR__ . '/../lang');
  194. foreach ($dir as $fileinfo) {
  195. if (! $fileinfo->isDot()) {
  196. $languageFiles[] = strtoupper(
  197. str_replace($search, '', trim($fileinfo->getFilename()))
  198. );
  199. }
  200. }
  201. foreach ($languageFiles as $lang) {
  202. // Check if the file is related to a (real) language before using it
  203. if (array_key_exists($lang, $languageCodes)) {
  204. $languages[strtolower($lang)] = $languageCodes[$lang];
  205. }
  206. }
  207. // Sort the languages list
  208. asort($languages);
  209. reset($languages);
  210. return $languages;
  211. }
  212. /**
  213. * This function displays the <select> box for the available languages
  214. * optionally filtered by excluding some provided languages
  215. *
  216. * @param string $default
  217. * @param boolean $submitOnChange
  218. * @param array $excludedLanguages
  219. * @param string $id
  220. * @return string
  221. */
  222. public static function selectLanguages($default, $submitOnChange = false, Array $excludedLanguages = array(), $id = 'language')
  223. {
  224. global $languageCodes;
  225. $onChange = ($submitOnChange ? ' onchange="this.form.submit();"' : '');
  226. $output = '<select class="language" name="' . $id . '" id="' . $id . '" size="1"' . $onChange . ">\n";
  227. $languages = self::getAvailableLanguages();
  228. if (count($languages) > 0) {
  229. foreach ($languages as $lang => $value) {
  230. if (! in_array($lang, $excludedLanguages)) {
  231. $output .= "\t" . '<option value="' . $lang . '"';
  232. if ($lang == $default) {
  233. $output .= ' selected="selected"';
  234. }
  235. $output .= '>' . $value . "</option>\n";
  236. }
  237. }
  238. } else {
  239. $output .= "\t<option value=\"en\">" . $languageCodes["EN"] . "</option>";
  240. }
  241. $output .= "</select>\n";
  242. return $output;
  243. }
  244. /**
  245. * Function for displaying all languages in <option>
  246. *
  247. * @param string $lang the languange to be selected
  248. * @param bool $onlyThisLang print only the passed language?
  249. * @param bool $fileLanguageValue print the <language file> instead of the <language code> as value?
  250. * @return string
  251. */
  252. public static function languageOptions($lang = '', $onlyThisLang = false, $fileLanguageValue = false)
  253. {
  254. $output = "";
  255. foreach (self::getAvailableLanguages() as $key => $value) {
  256. if ($onlyThisLang) {
  257. if (strtolower($key) == $lang) {
  258. if ($fileLanguageValue) {
  259. $output .= "\t<option value=\"language_" . strtolower($lang) . ".php\"";
  260. } else {
  261. $output .= "\t<option value=\"" . strtolower($lang) . "\"";
  262. }
  263. $output .= " selected=\"selected\"";
  264. $output .= ">" . $value . "</option>\n";
  265. break;
  266. }
  267. } else {
  268. if ($fileLanguageValue) {
  269. $output .= "\t<option value=\"language_" . strtolower($key) . ".php\"";
  270. } else {
  271. $output .= "\t<option value=\"" . strtolower($key) . "\"";
  272. }
  273. if (strtolower($key) == $lang) {
  274. $output .= " selected=\"selected\"";
  275. }
  276. $output .= ">" . $value . "</option>\n";
  277. }
  278. }
  279. return $output;
  280. }
  281. /**
  282. * True if the language is supported by the current phpMyFAQ installation
  283. *
  284. * @param string $langcode Language code
  285. * @return boolean
  286. */
  287. public static function isASupportedLanguage($langcode)
  288. {
  289. global $languageCodes;
  290. return isset($languageCodes[strtoupper($langcode)]);
  291. }
  292. /**
  293. * True if the language is supported by the bundled TinyMCE editor
  294. *
  295. * TinyMCE Language is supported if there is a language file present in
  296. * PMF_ROOT/admin/editor/langs/$langcode.js
  297. *
  298. * TinyMCE language packs can be downloaded from
  299. * http://tinymce.moxiecode.com/download_i18n.php
  300. * and extracted to PMF_ROOT/admin/editor
  301. *
  302. * @param string $langcode Language code
  303. *
  304. * @return boolean
  305. */
  306. public static function isASupportedTinyMCELanguage($langcode)
  307. {
  308. return file_exists(
  309. dirname(__DIR__) . '/admin/editor/langs/' . $langcode . '.js'
  310. );
  311. }
  312. /**
  313. * Gets the accepted language from the user agent
  314. *
  315. * $_SERVER['HTTP_ACCEPT_LANGUAGE'] could be like the text below:
  316. * it,pt-br;q=0.8,en-us;q=0.5,en;q=0.3
  317. *
  318. * @return void
  319. */
  320. private function _getUserAgentLanguage()
  321. {
  322. $matches = $languages = array();
  323. if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  324. // ISO Language Codes, 2-letters: ISO 639-1, <Country tag>[-<Country subtag>]
  325. // Simplified language syntax detection: xx[-yy]
  326. preg_match_all(
  327. '/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
  328. $_SERVER['HTTP_ACCEPT_LANGUAGE'],
  329. $matches
  330. );
  331. if (count($matches[1])) {
  332. $languages = array_combine($matches[1], $matches[4]);
  333. foreach ($languages as $lang => $val) {
  334. if ($val === '') $languages[$lang] = 1;
  335. }
  336. arsort($languages, SORT_NUMERIC);
  337. }
  338. foreach ($languages as $lang => $val) {
  339. if (self::isASupportedLanguage(strtoupper($lang))) {
  340. $this->acceptedLanguage = $lang;
  341. break;
  342. }
  343. }
  344. }
  345. }
  346. }