mirror of
https://github.com/cytopia/devilbox.git
synced 2024-12-24 23:16:41 +00:00
873 lines
21 KiB
PHP
873 lines
21 KiB
PHP
<?php
|
|
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
|
/**
|
|
* Hold the PMA\libraries\LanguageManager class
|
|
*
|
|
* @package PhpMyAdmin
|
|
*/
|
|
namespace PMA\libraries;
|
|
|
|
use PMA\libraries\Language;
|
|
|
|
/**
|
|
* Language selection manager
|
|
*
|
|
* @package PhpMyAdmin
|
|
*/
|
|
class LanguageManager
|
|
{
|
|
/**
|
|
* @var array Definition data for languages
|
|
*
|
|
* Each member contains:
|
|
* - Language code
|
|
* - English language name
|
|
* - Native language name
|
|
* - Match regullar expression
|
|
* - MySQL locale
|
|
*/
|
|
private static $_language_data = array(
|
|
'af' => array(
|
|
'af',
|
|
'Afrikaans',
|
|
'',
|
|
'af|afrikaans',
|
|
'',
|
|
),
|
|
'ar' => array(
|
|
'ar',
|
|
'Arabic',
|
|
'العربية',
|
|
'ar|arabic',
|
|
'ar_AE',
|
|
),
|
|
'az' => array(
|
|
'az',
|
|
'Azerbaijani',
|
|
'Azərbaycanca',
|
|
'az|azerbaijani',
|
|
'',
|
|
),
|
|
'bn' => array(
|
|
'bn',
|
|
'Bangla',
|
|
'বাংলা',
|
|
'bn|bangla',
|
|
'',
|
|
),
|
|
'be' => array(
|
|
'be',
|
|
'Belarusian',
|
|
'Беларуская',
|
|
'be|belarusian',
|
|
'be_BY',
|
|
),
|
|
'be@latin' => array(
|
|
'be@latin',
|
|
'Belarusian (latin)',
|
|
'Biełaruskaja',
|
|
'be[-_]lat|be@latin|belarusian latin',
|
|
'',
|
|
),
|
|
'bg' => array(
|
|
'bg',
|
|
'Bulgarian',
|
|
'Български',
|
|
'bg|bulgarian',
|
|
'bg_BG',
|
|
),
|
|
'bs' => array(
|
|
'bs',
|
|
'Bosnian',
|
|
'Bosanski',
|
|
'bs|bosnian',
|
|
'',
|
|
),
|
|
'br' => array(
|
|
'br',
|
|
'Breton',
|
|
'Brezhoneg',
|
|
'br|breton',
|
|
'',
|
|
),
|
|
'brx' => array(
|
|
'brx',
|
|
'Bodo',
|
|
'बड़ो',
|
|
'brx|bodo',
|
|
'',
|
|
),
|
|
'ca' => array(
|
|
'ca',
|
|
'Catalan',
|
|
'Català',
|
|
'ca|catalan',
|
|
'ca_ES',
|
|
),
|
|
'ckb' => array(
|
|
'ckb',
|
|
'Sorani',
|
|
'سۆرانی',
|
|
'ckb|sorani',
|
|
'',
|
|
),
|
|
'cs' => array(
|
|
'cs',
|
|
'Czech',
|
|
'Čeština',
|
|
'cs|czech',
|
|
'cs_CZ',
|
|
),
|
|
'cy' => array(
|
|
'cy',
|
|
'Welsh',
|
|
'Cymraeg',
|
|
'cy|welsh',
|
|
'',
|
|
),
|
|
'da' => array(
|
|
'da',
|
|
'Danish',
|
|
'Dansk',
|
|
'da|danish',
|
|
'da_DK',
|
|
),
|
|
'de' => array(
|
|
'de',
|
|
'German',
|
|
'Deutsch',
|
|
'de|german',
|
|
'de_DE',
|
|
),
|
|
'el' => array(
|
|
'el',
|
|
'Greek',
|
|
'Ελληνικά',
|
|
'el|greek',
|
|
'',
|
|
),
|
|
'en' => array(
|
|
'en',
|
|
'English',
|
|
'',
|
|
'en|english',
|
|
'en_US',
|
|
),
|
|
'en_gb' => array(
|
|
'en_GB',
|
|
'English (United Kingdom)',
|
|
'',
|
|
'en[_-]gb|english (United Kingdom)',
|
|
'en_GB',
|
|
),
|
|
'eo' => array(
|
|
'eo',
|
|
'Esperanto',
|
|
'Esperanto',
|
|
'eo|esperanto',
|
|
'',
|
|
),
|
|
'es' => array(
|
|
'es',
|
|
'Spanish',
|
|
'Español',
|
|
'es|spanish',
|
|
'es_ES',
|
|
),
|
|
'et' => array(
|
|
'et',
|
|
'Estonian',
|
|
'Eesti',
|
|
'et|estonian',
|
|
'et_EE',
|
|
),
|
|
'eu' => array(
|
|
'eu',
|
|
'Basque',
|
|
'Euskara',
|
|
'eu|basque',
|
|
'eu_ES',
|
|
),
|
|
'fa' => array(
|
|
'fa',
|
|
'Persian',
|
|
'فارسی',
|
|
'fa|persian',
|
|
'',
|
|
),
|
|
'fi' => array(
|
|
'fi',
|
|
'Finnish',
|
|
'Suomi',
|
|
'fi|finnish',
|
|
'fi_FI',
|
|
),
|
|
'fr' => array(
|
|
'fr',
|
|
'French',
|
|
'Français',
|
|
'fr|french',
|
|
'fr_FR',
|
|
),
|
|
'fy' => array(
|
|
'fy',
|
|
'Frisian',
|
|
'Frysk',
|
|
'fy|frisian',
|
|
'',
|
|
),
|
|
'gl' => array(
|
|
'gl',
|
|
'Galician',
|
|
'Galego',
|
|
'gl|galician',
|
|
'gl_ES',
|
|
),
|
|
'gu' => array(
|
|
'gu',
|
|
'Gujarati',
|
|
'ગુજરાતી',
|
|
'gu|gujarati',
|
|
'gu_IN',
|
|
),
|
|
'he' => array(
|
|
'he',
|
|
'Hebrew',
|
|
'עברית',
|
|
'he|hebrew',
|
|
'he_IL',
|
|
),
|
|
'hi' => array(
|
|
'hi',
|
|
'Hindi',
|
|
'हिन्दी',
|
|
'hi|hindi',
|
|
'hi_IN',
|
|
),
|
|
'hr' => array(
|
|
'hr',
|
|
'Croatian',
|
|
'Hrvatski',
|
|
'hr|croatian',
|
|
'hr_HR',
|
|
),
|
|
'hu' => array(
|
|
'hu',
|
|
'Hungarian',
|
|
'Magyar',
|
|
'hu|hungarian',
|
|
'hu_HU',
|
|
),
|
|
'hy' => array(
|
|
'hy',
|
|
'Armenian',
|
|
'Հայերէն',
|
|
'hy|armenian',
|
|
'',
|
|
),
|
|
'ia' => array(
|
|
'ia',
|
|
'Interlingua',
|
|
'',
|
|
'ia|interlingua',
|
|
'',
|
|
),
|
|
'id' => array(
|
|
'id',
|
|
'Indonesian',
|
|
'Bahasa Indonesia',
|
|
'id|indonesian',
|
|
'id_ID',
|
|
),
|
|
'it' => array(
|
|
'it',
|
|
'Italian',
|
|
'Italiano',
|
|
'it|italian',
|
|
'it_IT',
|
|
),
|
|
'ja' => array(
|
|
'ja',
|
|
'Japanese',
|
|
'日本語',
|
|
'ja|japanese',
|
|
'ja_JP',
|
|
),
|
|
'ko' => array(
|
|
'ko',
|
|
'Korean',
|
|
'한국어',
|
|
'ko|korean',
|
|
'ko_KR',
|
|
),
|
|
'ka' => array(
|
|
'ka',
|
|
'Georgian',
|
|
'ქართული',
|
|
'ka|georgian',
|
|
'',
|
|
),
|
|
'kk' => array(
|
|
'kk',
|
|
'Kazakh',
|
|
'Қазақ',
|
|
'kk|kazakh',
|
|
'',
|
|
),
|
|
'km' => array(
|
|
'km',
|
|
'Khmer',
|
|
'ខ្មែរ',
|
|
'km|khmer',
|
|
'',
|
|
),
|
|
'kn' => array(
|
|
'kn',
|
|
'Kannada',
|
|
'ಕನ್ನಡ',
|
|
'kn|kannada',
|
|
'',
|
|
),
|
|
'ksh' => array(
|
|
'ksh',
|
|
'Colognian',
|
|
'Kölsch',
|
|
'ksh|colognian',
|
|
'',
|
|
),
|
|
'ky' => array(
|
|
'ky',
|
|
'Kyrgyz',
|
|
'Кыргызча',
|
|
'ky|kyrgyz',
|
|
'',
|
|
),
|
|
'li' => array(
|
|
'li',
|
|
'Limburgish',
|
|
'Lèmbörgs',
|
|
'li|limburgish',
|
|
'',
|
|
),
|
|
'lt' => array(
|
|
'lt',
|
|
'Lithuanian',
|
|
'Lietuvių',
|
|
'lt|lithuanian',
|
|
'lt_LT',
|
|
),
|
|
'lv' => array(
|
|
'lv',
|
|
'Latvian',
|
|
'Latviešu',
|
|
'lv|latvian',
|
|
'lv_LV',
|
|
),
|
|
'mk' => array(
|
|
'mk',
|
|
'Macedonian',
|
|
'Macedonian',
|
|
'mk|macedonian',
|
|
'mk_MK',
|
|
),
|
|
'ml' => array(
|
|
'ml',
|
|
'Malayalam',
|
|
'Malayalam',
|
|
'ml|malayalam',
|
|
'',
|
|
),
|
|
'mn' => array(
|
|
'mn',
|
|
'Mongolian',
|
|
'Монгол',
|
|
'mn|mongolian',
|
|
'mn_MN',
|
|
),
|
|
'ms' => array(
|
|
'ms',
|
|
'Malay',
|
|
'Bahasa Melayu',
|
|
'ms|malay',
|
|
'ms_MY',
|
|
),
|
|
'ne' => array(
|
|
'ne',
|
|
'Nepali',
|
|
'नेपाली',
|
|
'ne|nepali',
|
|
'',
|
|
),
|
|
'nb' => array(
|
|
'nb',
|
|
'Norwegian',
|
|
'Norsk',
|
|
'nb|norwegian',
|
|
'nb_NO',
|
|
),
|
|
'nl' => array(
|
|
'nl',
|
|
'Dutch',
|
|
'Nederlands',
|
|
'nl|dutch',
|
|
'nl_NL',
|
|
),
|
|
'pa' => array(
|
|
'pa',
|
|
'Punjabi',
|
|
'ਪੰਜਾਬੀ',
|
|
'pa|punjabi',
|
|
'',
|
|
),
|
|
'pl' => array(
|
|
'pl',
|
|
'Polish',
|
|
'Polski',
|
|
'pl|polish',
|
|
'pl_PL',
|
|
),
|
|
'pt_br' => array(
|
|
'pt_BR',
|
|
'Brazilian Portuguese',
|
|
'Português',
|
|
'pt[-_]br|brazilian portuguese',
|
|
'pt_BR',
|
|
),
|
|
'pt' => array(
|
|
'pt',
|
|
'Portuguese',
|
|
'Português',
|
|
'pt|portuguese',
|
|
'pt_PT',
|
|
),
|
|
'ro' => array(
|
|
'ro',
|
|
'Romanian',
|
|
'Română',
|
|
'ro|romanian',
|
|
'ro_RO',
|
|
),
|
|
'ru' => array(
|
|
'ru',
|
|
'Russian',
|
|
'Русский',
|
|
'ru|russian',
|
|
'ru_RU',
|
|
),
|
|
'si' => array(
|
|
'si',
|
|
'Sinhala',
|
|
'සිංහල',
|
|
'si|sinhala',
|
|
'',
|
|
),
|
|
'sk' => array(
|
|
'sk',
|
|
'Slovak',
|
|
'Slovenčina',
|
|
'sk|slovak',
|
|
'sk_SK',
|
|
),
|
|
'sl' => array(
|
|
'sl',
|
|
'Slovenian',
|
|
'Slovenščina',
|
|
'sl|slovenian',
|
|
'sl_SI',
|
|
),
|
|
'sq' => array(
|
|
'sq',
|
|
'Slbanian',
|
|
'Shqip',
|
|
'sq|albanian',
|
|
'sq_AL',
|
|
),
|
|
'sr@latin' => array(
|
|
'sr@latin',
|
|
'Serbian (latin)',
|
|
'Srpski',
|
|
'sr[-_]lat|sr@latin|serbian latin',
|
|
'sr_YU',
|
|
),
|
|
'sr' => array(
|
|
'sr',
|
|
'Serbian',
|
|
'Српски',
|
|
'sr|serbian',
|
|
'sr_YU',
|
|
),
|
|
'sv' => array(
|
|
'sv',
|
|
'Swedish',
|
|
'Svenska',
|
|
'sv|swedish',
|
|
'sv_SE',
|
|
),
|
|
'ta' => array(
|
|
'ta',
|
|
'Tamil',
|
|
'தமிழ்',
|
|
'ta|tamil',
|
|
'ta_IN',
|
|
),
|
|
'te' => array(
|
|
'te',
|
|
'Telugu',
|
|
'తెలుగు',
|
|
'te|telugu',
|
|
'te_IN',
|
|
),
|
|
'th' => array(
|
|
'th',
|
|
'Thai',
|
|
'ภาษาไทย',
|
|
'th|thai',
|
|
'th_TH',
|
|
),
|
|
'tk' => array(
|
|
'tk',
|
|
'Turkmen',
|
|
'Türkmençe',
|
|
'tk|turkmen',
|
|
'',
|
|
),
|
|
'tr' => array(
|
|
'tr',
|
|
'Turkish',
|
|
'Türkçe',
|
|
'tr|turkish',
|
|
'tr_TR',
|
|
),
|
|
'tt' => array(
|
|
'tt',
|
|
'Tatarish',
|
|
'Tatarça',
|
|
'tt|tatarish',
|
|
'',
|
|
),
|
|
'ug' => array(
|
|
'ug',
|
|
'Uyghur',
|
|
'ئۇيغۇرچە',
|
|
'ug|uyghur',
|
|
'',
|
|
),
|
|
'uk' => array(
|
|
'uk',
|
|
'Ukrainian',
|
|
'Українська',
|
|
'uk|ukrainian',
|
|
'uk_UA',
|
|
),
|
|
'ur' => array(
|
|
'ur',
|
|
'Urdu',
|
|
'اُردوُ',
|
|
'ur|urdu',
|
|
'ur_PK',
|
|
),
|
|
'uz@latin' => array(
|
|
'uz@latin',
|
|
'Uzbek (latin)',
|
|
'O‘zbekcha',
|
|
'uz[-_]lat|uz@latin|uzbek-latin',
|
|
'',
|
|
),
|
|
'uz' => array(
|
|
'uz',
|
|
'Uzbek (cyrillic)',
|
|
'Ўзбекча',
|
|
'uz[-_]cyr|uz@cyrillic|uzbek-cyrillic',
|
|
'',
|
|
),
|
|
'vi' => array(
|
|
'vi',
|
|
'Vietnamese',
|
|
'Tiếng Việt',
|
|
'vi|vietnamese',
|
|
'vi_VN',
|
|
),
|
|
'vls' => array(
|
|
'vls',
|
|
'Flemish',
|
|
'West-Vlams',
|
|
'vls|flemish',
|
|
'',
|
|
),
|
|
'zh_tw' => array(
|
|
'zh_TW',
|
|
'Chinese traditional',
|
|
'中文',
|
|
'zh[-_](tw|hk)|chinese traditional',
|
|
'zh_TW',
|
|
),
|
|
// only TW and HK use traditional Chinese while others (CN, SG, MY)
|
|
// use simplified Chinese
|
|
'zh_cn' => array(
|
|
'zh_CN',
|
|
'Chinese simplified',
|
|
'中文',
|
|
'zh(?![-_](tw|hk))([-_][[:alpha:]]{2,3})?|chinese simplified',
|
|
'zh_CN',
|
|
),
|
|
);
|
|
|
|
private $_available_locales;
|
|
private $_available_languages;
|
|
private $_lang_failed_cfg;
|
|
private $_lang_failed_cookie;
|
|
private $_lang_failed_request;
|
|
private static $instance;
|
|
|
|
/**
|
|
* Returns LanguageManager singleton
|
|
*
|
|
* @return LanguageManager
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
if (self::$instance === NULL) {
|
|
self::$instance = new LanguageManager;
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Returns list of available locales
|
|
*
|
|
* @return array
|
|
*/
|
|
public function listLocaleDir()
|
|
{
|
|
$result = array('en');
|
|
|
|
/* Check for existing directory */
|
|
if (!is_dir(LOCALE_PATH)) {
|
|
return $result;
|
|
}
|
|
|
|
/* Open the directory */
|
|
$handle = @opendir(LOCALE_PATH);
|
|
/* This can happen if the kit is English-only */
|
|
if ($handle === false) {
|
|
return $result;
|
|
}
|
|
|
|
/* Process all files */
|
|
while (false !== ($file = readdir($handle))) {
|
|
$path = LOCALE_PATH
|
|
. '/' . $file
|
|
. '/LC_MESSAGES/phpmyadmin.mo';
|
|
if ($file != "."
|
|
&& $file != ".."
|
|
&& @file_exists($path)
|
|
) {
|
|
$result[] = $file;
|
|
}
|
|
}
|
|
/* Close the handle */
|
|
closedir($handle);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Returns (cached) list of all available locales
|
|
*
|
|
* @return array of strings
|
|
*/
|
|
public function availableLocales()
|
|
{
|
|
if (! $this->_available_locales) {
|
|
|
|
if (empty($GLOBALS['cfg']['FilterLanguages'])) {
|
|
$this->_available_locales = $this->listLocaleDir();
|
|
} else {
|
|
$this->_available_locales = preg_grep(
|
|
'@' . $GLOBALS['cfg']['FilterLanguages'] . '@',
|
|
$this->listLocaleDir()
|
|
);
|
|
}
|
|
}
|
|
return $this->_available_locales;
|
|
}
|
|
|
|
/**
|
|
* Returns (cached) list of all available languages
|
|
*
|
|
* @return array of Language objects
|
|
*/
|
|
public function availableLanguages()
|
|
{
|
|
if (! $this->_available_languages) {
|
|
$this->_available_languages = array();
|
|
|
|
foreach($this->availableLocales() as $lang) {
|
|
$lang = strtolower($lang);
|
|
if (isset($this::$_language_data[$lang])) {
|
|
$data = $this::$_language_data[$lang];
|
|
$this->_available_languages[$lang] = new Language(
|
|
$data[0],
|
|
$data[1],
|
|
$data[2],
|
|
$data[3],
|
|
$data[4]
|
|
);
|
|
} else {
|
|
$this->_available_languages[$lang] = new Language(
|
|
$lang,
|
|
ucfirst($lang),
|
|
ucfirst($lang),
|
|
$lang,
|
|
''
|
|
);
|
|
}
|
|
}
|
|
}
|
|
return $this->_available_languages;
|
|
}
|
|
|
|
/**
|
|
* Returns (cached) list of all available languages sorted
|
|
* by name
|
|
*
|
|
* @return array of Language objects
|
|
*/
|
|
public function sortedLanguages()
|
|
{
|
|
$this->availableLanguages();
|
|
uasort($this->_available_languages, function($a, $b)
|
|
{
|
|
return $a->cmp($b);
|
|
}
|
|
);
|
|
return $this->_available_languages;
|
|
}
|
|
|
|
/**
|
|
* Return Language object for given code
|
|
*
|
|
* @param string $code Language code
|
|
*
|
|
* @return object|false Language object or false on failure
|
|
*/
|
|
public function getLanguage($code)
|
|
{
|
|
$code = strtolower($code);
|
|
$langs = $this->availableLanguages();
|
|
if (isset($langs[$code])) {
|
|
return $langs[$code];
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return currently active Language object
|
|
*
|
|
* @return object Language object
|
|
*/
|
|
public function getCurrentLanguage()
|
|
{
|
|
return $this->_available_languages[strtolower($GLOBALS['lang'])];
|
|
}
|
|
|
|
/**
|
|
* Activates language based on configuration, user preferences or
|
|
* browser
|
|
*
|
|
* @return Language
|
|
*/
|
|
public function selectLanguage()
|
|
{
|
|
// check forced language
|
|
if (! empty($GLOBALS['cfg']['Lang'])) {
|
|
$lang = $this->getLanguage($GLOBALS['cfg']['Lang']);
|
|
if ($lang !== false) {
|
|
return $lang;
|
|
}
|
|
$this->_lang_failed_cfg = true;
|
|
}
|
|
|
|
// Don't use REQUEST in following code as it might be confused by cookies
|
|
// with same name. Check user requested language (POST)
|
|
if (! empty($_POST['lang'])) {
|
|
$lang = $this->getLanguage($_POST['lang']);
|
|
if ($lang !== false) {
|
|
return $lang;
|
|
}
|
|
$this->_lang_failed_request = true;
|
|
}
|
|
|
|
// check user requested language (GET)
|
|
if (! empty($_GET['lang'])) {
|
|
$lang = $this->getLanguage($_GET['lang']);
|
|
if ($lang !== false) {
|
|
return $lang;
|
|
}
|
|
$this->_lang_failed_request = true;
|
|
}
|
|
|
|
// check previous set language
|
|
if (! empty($_COOKIE['pma_lang'])) {
|
|
$lang = $this->getLanguage($_COOKIE['pma_lang']);
|
|
if ($lang !== false) {
|
|
return $lang;
|
|
}
|
|
$this->_lang_failed_cookie = true;
|
|
}
|
|
|
|
$langs = $this->availableLanguages();
|
|
|
|
// try to find out user's language by checking its HTTP_ACCEPT_LANGUAGE variable;
|
|
// prevent XSS
|
|
$accepted_languages = PMA_getenv('HTTP_ACCEPT_LANGUAGE');
|
|
if ($accepted_languages && false === mb_strpos($accepted_languages, '<')) {
|
|
foreach (explode(',', $accepted_languages) as $header) {
|
|
foreach ($langs as $language) {
|
|
if ($language->matchesAcceptLanguage($header)) {
|
|
return $language;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// try to find out user's language by checking its HTTP_USER_AGENT variable
|
|
$user_agent = PMA_getenv('HTTP_USER_AGENT');
|
|
if (! empty($user_agent)) {
|
|
foreach ($langs as $language) {
|
|
if ($language->matchesUserAgent($user_agent)) {
|
|
return $language;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Didn't catch any valid lang : we use the default settings
|
|
if (isset($langs[$GLOBALS['cfg']['DefaultLang']])) {
|
|
return $langs[$GLOBALS['cfg']['DefaultLang']];
|
|
}
|
|
|
|
// Fallback to English
|
|
return $langs['en'];
|
|
}
|
|
|
|
/**
|
|
* Displays warnings about invalid languages. This needs to be postponed
|
|
* to show messages at time when language is initialized.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function showWarnings()
|
|
{
|
|
// now, that we have loaded the language strings we can send the errors
|
|
if ($this->_lang_failed_cfg
|
|
|| $this->_lang_failed_cookie
|
|
|| $this->_lang_failed_request
|
|
) {
|
|
trigger_error(
|
|
__('Ignoring unsupported language code.'),
|
|
E_USER_ERROR
|
|
);
|
|
}
|
|
}
|
|
}
|