0) { foreach($plugins as $plugin) { $plugin = $plugin['directory']; $path2catalogue = $config['base_path'] . '/plugins/' . $plugin . '/locales/LC_MESSAGES/' . $lang2locale[$cacti_locale]['filename'] . '.mo'; if (file_exists($path2catalogue)) { $cacti_textdomains[$plugin]['path2locales'] = $config['base_path'] . '/plugins/' . $plugin . '/locales'; $cacti_textdomains[$plugin]['path2catalogue'] = $path2catalogue; } } /* if i18n support is set to strict mode then check if all plugins support the requested language */ if (read_config_option('i18n_language_support') == 2) { if(sizeof($plugins) != (sizeof($cacti_textdomains) - 1)) { load_fallback_procedure(); return; } } } /* load php-gettext class */ require($config['include_path'] . '/phpgettext/streams.php'); require($config['include_path'] . '/phpgettext/gettext.php'); /* prefetch all language files to work in memory only, die if one of the language files is corrupted */ $l10n = array(); foreach($cacti_textdomains as $domain => $paths) { $input = new FileReader($cacti_textdomains[$domain]['path2catalogue']); if($input == false) { die('Unable to read file: ' . $cacti_textdomains[$domain]['path2catalogue']); } $l10n[$domain] = new gettext_reader($input); if($l10n[$domain] == false) { die('Invalid language file: ' . $cacti_textdomains[$domain]['path2catalogue']); } } unset($input); /* load standard wrappers */ load_i18n_gettext_wrappers(); define('CACTI_LOCALE', $cacti_locale); define('CACTI_COUNTRY', $cacti_country); define('CACTI_LANGUAGE', $lang2locale[CACTI_LOCALE]['language']); define('CACTI_LANGUAGE_FILE', $lang2locale[CACTI_LOCALE]['filename']); /** * Universal escaping wrappers */ function __esc() { return htmlspecialchars( call_user_func_array('__', func_get_args()), ENT_QUOTES); } function __esc_n() { return htmlspecialchars( call_user_func_array('__n', func_get_args()), ENT_QUOTES); } function __esc_x() { return htmlspecialchars( call_user_func_array('__x', func_get_args()), ENT_QUOTES); } function __esc_xn() { return htmlspecialchars( call_user_func_array('__xn', func_get_args()), ENT_QUOTES); } /** * load_fallback_procedure - loads wrapper package if native language (English) has to be used * * @return */ function load_fallback_procedure(){ global $cacti_textdomains, $cacti_locale, $cacti_country, $lang2locale; /* load wrappers if native gettext is not available */ load_i18n_fallback_wrappers(); /* reset variables */ $_SESSION['sess_user_language'] = ''; $cacti_textdomains = array(); define('CACTI_LOCALE', 'en'); define('CACTI_COUNTRY', 'us'); define('CACTI_LANGUAGE', 'English'); define('CACTI_LANGUAGE_FILE', 'english_usa'); } /** * load_i18n_gettext_wrappers - creates all wrappers to translate strings by using php-gettext * * @return */ function load_i18n_gettext_wrappers(){ function __gettext($text, $domain = 'cacti') { global $l10n; if (isset($l10n[$domain])) { return $l10n[$domain]->translate($text); }else { return $text; } } function __n($singular, $plural, $number, $domain = 'cacti'){ global $l10n; if (isset($l10n[$domain])) { return $l10n[$domain]->ngettext($singular, $plural, $number); }else { return ($number == 1) ? $singular : $plural; } } function __() { global $l10n; $args = func_get_args(); $num = func_num_args(); /* this should not happen */ if ($num < 1) { return false; /* convert pure text strings */ } elseif ($num == 1) { return __gettext($args[0]); /* convert pure text strings by using a different textdomain */ } elseif ($num == 2 && isset($l10n[$args[1]])) { return __gettext($args[0], $args[1]); /* convert stings including one or more placeholders */ }else { /* only the last argument is allowed to initiate the use of a different textdomain */ /* get gettext string */ $args[0] = isset($l10n[$args[$num-1]]) ? __gettext($args[0], $args[$num-1]) : __gettext($args[0]); /* process return string against input arguments */ return call_user_func_array('sprintf', $args); } } function __xn($context, $singular, $plural, $number, $domain = 'cacti'){ $xsingular = $context . chr(4) . $singular; $xplural = $context . chr(4) . $plural; $msgstr = __n($xsingular, $xplural, $number, $domain); if($number == 1 ) { return ( $msgstr == $xsingular ) ? $singular : $msgstr; }else { return ( $msgstr == $xplural ) ? $plural : $msgstr; } } function __x(){ global $l10n; $args = func_get_args(); $num = func_num_args(); /* this should never happen */ if ($num < 2) { return false; }else { $context = array_shift($args); $num--; $msgid = reset($args); $xmsgid = $context . chr(4) . $msgid; $args[0] = $xmsgid; if($num == 1) { /* pure text string without placeholders and a change of the default textdomain */ $msgstr = __gettext($args[0]); }else { /* get gettext string */ $msgstr = isset($l10n[$args[$num-1]]) ? __gettext($args[0], $args[$num-1]) : __gettext($args[0]); } /* use the raw message id if language catalogue does not contain a context specific message string */ $args[0] = ( $msgstr == $xmsgid ) ? $msgid : $msgstr; /* process return string against input arguments */ return call_user_func_array('sprintf', $args); } } function __date($format, $timestamp = false, $domain = 'cacti') { global $i18n_date_placeholders; if (!$timestamp) { $timestamp = time(); } /* placeholders will allow to fill in the translated weekdays, month and so on.. */ $i18n_date_placeholders = array( '#1' => __(date('D', $timestamp), $domain), '#2' => __(date('M', $timestamp), $domain), '#3' => __(date('F', $timestamp), $domain), '#4' => __(date('l', $timestamp), $domain) ); /* if defined exchange the format string for the configured locale */ $format = __gettext($format, $domain); /* replace special date chars by placeholders */ $format = str_replace(array('D', 'M', 'F', 'l'), array('#1', '#2', '#3', '#4'), $format); /* get date string included placeholders */ $date = date($format, $timestamp); /* fill in specific translations */ $date = str_replace(array_keys($i18n_date_placeholders), array_values($i18n_date_placeholders), $date); return $date; } } /** * load_i18n_fallback_wrappers - creates special wrappers to leave the native language untouched * * @return */ function load_i18n_fallback_wrappers(){ function __gettext($text, $domain = 'cacti') { return $text; } function __n($singular, $plural, $number, $domain = 'cacti') { return ($number == 1) ? $singular : $plural; } function __() { $args = func_get_args(); $num = func_num_args(); /* this should not happen */ if ($num < 1) { return false; /* convert pure text strings */ } elseif ($num == 1) { return $args[0]; /* convert pure text strings by using a different textdomain */ } elseif ($num == 2 && isset($l10n[$args[1]])) { return $args[0]; /* convert stings including one or more placeholders */ }else { /* only the last argument is allowed to initiate the use of a different textdomain */ /* process return string against input arguments */ return call_user_func_array('sprintf', $args); } } function __xn($context, $singular, $plural, $number, $domain = 'cacti'){ return __n($singular, $plural, $number, $domain); } function __x(){ $args = func_get_args(); $num = func_num_args(); /* this should never happen */ if ($num < 2) { return false; }else { $context = array_shift($args); return call_user_func_array('__', $args); } } function __date($format, $timestamp = false, $domain = 'cacti') { if (!$timestamp) {$timestamp = time();} return date($format, $timestamp); } } /** * get_list_of_locales - returns the default settings being used for l10n * * @return - a multi-dimensional array with the locale code as main key */ function get_list_of_locales () { $lang2locale = array( 'sq' => array('language' => 'Albanian', 'country' => 'al', 'filename' => 'albanian_albania'), 'ar' => array('language' => 'Arabic', 'country' => 'sa', 'filename' => 'arabic_saudi_arabia'), 'hy' => array('language' => 'Armenian', 'country' => 'am', 'filename' => 'armenian_armenia'), 'be' => array('language' => 'Belarusian', 'country' => 'by', 'filename' => 'belarusian_belarus'), 'bg' => array('language' => 'Bulgarian', 'country' => 'bg', 'filename' => 'bulgarian_bulgaria'), 'zh' => array('language' => 'Chinese', 'country' => 'cn', 'filename' => 'chinese_china'), 'zh-cn' => array('language' => 'Chinese (China)', 'country' => 'cn', 'filename' => 'chinese_china_simplified'), 'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'country' => 'hk', 'filename' => 'chinese_hong_kong'), 'zh-sg' => array('language' => 'Chinese (Singapore)', 'country' => 'sg', 'filename' => 'chinese_singapore'), 'zh-tw' => array('language' => 'Chinese (Taiwan)', 'country' => 'tw', 'filename' => 'chinese_taiwan'), 'hr' => array('language' => 'Croatian', 'country' => 'hr', 'filename' => 'croatian_croatia'), 'cs' => array('language' => 'Czech', 'country' => 'cz', 'filename' => 'czech_czech_republic'), 'da' => array('language' => 'Danish', 'country' => 'dk', 'filename' => 'danish_denmark'), 'nl' => array('language' => 'Dutch', 'country' => 'nl', 'filename' => 'dutch_netherlands'), 'en' => array('language' => 'English', 'country' => 'us', 'filename' => 'english_usa'), 'et' => array('language' => 'Estonian', 'country' => 'ee', 'filename' => 'estonian_estonia'), 'fi' => array('language' => 'Finnish', 'country' => 'fi', 'filename' => 'finnish_finland'), 'fr' => array('language' => 'French', 'country' => 'fr', 'filename' => 'french_france'), 'de' => array('language' => 'German', 'country' => 'de', 'filename' => 'german_germany'), 'el' => array('language' => 'Greek', 'country' => 'gr', 'filename' => 'greek_greece'), 'iw' => array('language' => 'Hebrew', 'country' => 'il', 'filename' => 'hebrew_israel'), 'hi' => array('language' => 'Hindi', 'country' => 'in', 'filename' => 'hindi_india'), 'hu' => array('language' => 'Hungarian', 'country' => 'hu', 'filename' => 'hungarian_hungary'), 'is' => array('language' => 'Icelandic', 'country' => 'is', 'filename' => 'icelandic_iceland'), 'id' => array('language' => 'Indonesian', 'country' => 'id', 'filename' => 'indonesian_indonesia'), 'ga' => array('language' => 'Irish', 'country' => 'ie', 'filename' => 'irish_ireland'), 'it' => array('language' => 'Italian', 'country' => 'it', 'filename' => 'italian_italy'), 'ja' => array('language' => 'Japanese', 'country' => 'jp', 'filename' => 'japanese_japan'), 'ko' => array('language' => 'Korean', 'country' => 'kr', 'filename' => 'korean_korea'), 'lv' => array('language' => 'Lativan', 'country' => 'lv', 'filename' => 'latvian_latvia'), 'lt' => array('language' => 'Lithuanian', 'country' => 'lt', 'filename' => 'lithuanian_lithuania'), 'mk' => array('language' => 'Macedonian', 'country' => 'mk', 'filename' => 'macedonian_macedonia'), 'ms' => array('language' => 'Malay', 'country' => 'my', 'filename' => 'malay_malaysia'), 'mt' => array('language' => 'Maltese', 'country' => 'lt', 'filename' => 'maltese_malta'), 'no' => array('language' => 'Norwegian', 'country' => 'no', 'filename' => 'norwegian_norway'), 'pl' => array('language' => 'Polish', 'country' => 'pl', 'filename' => 'polish_poland'), 'pt' => array('language' => 'Portuguese', 'country' => 'pt', 'filename' => 'portuguese_portugal'), 'pt-br' => array('language' => 'Portuguese (Brazil)', 'country' => 'br', 'filename' => 'portuguese_brazil'), 'ro' => array('language' => 'Romanian', 'country' => 'ro', 'filename' => 'romanian_romania'), 'ru' => array('language' => 'Russian', 'country' => 'ru', 'filename' => 'russian_russia'), 'sr' => array('language' => 'Serbian', 'country' => 'rs', 'filename' => 'serbian_serbia'), 'sk' => array('language' => 'Slovak', 'country' => 'sk', 'filename' => 'slovak_slovakia'), 'sl' => array('language' => 'Slovenian', 'country' => 'si', 'filename' => 'slovenian_slovenia'), 'es' => array('language' => 'Spanish', 'country' => 'es', 'filename' => 'spanish_spain'), 'sv' => array('language' => 'Swedish', 'country' => 'se', 'filename' => 'swedish_sweden'), 'th' => array('language' => 'Thai', 'country' => 'th', 'filename' => 'thai_thailand'), 'tr' => array('language' => 'Turkish', 'country' => 'tr', 'filename' => 'turkish_turkey'), 'vi' => array('language' => 'Vietnamese', 'country' => 'vn', 'filename' => 'vietnamese_vietnam') ); return $lang2locale; } /** * get_installed_locales - finds all installed locales * * @return - an associative array of all installed locales (e.g. 'en' => 'English') */ function get_installed_locales(){ global $config, $lang2locale; $locations = array(); $supported_languages['en'] = $lang2locale['en']['language']; foreach($lang2locale as $locale => $properties) { $locations[$properties['filename'] . '.mo'] = array('locale' => $locale, 'language' => $properties['language']); } /* create a list of all languages this Cacti system supports ... */ $dhandle = opendir($config['base_path'] . '/locales/LC_MESSAGES'); if(is_resource($dhandle)) { while (false !== ($filename = readdir($dhandle))) { /* check if language file for DHTML calendar is also available */ $path2calendar = $config['include_path'] . '/js/LC_MESSAGES/jquery.ui.datepicker-' . str_replace('.mo', '.js', $filename); if(isset($locations[$filename]) & file_exists($path2calendar)) { $supported_languages[$locations[$filename]['locale']] = $locations[$filename]['language']; } } } asort($supported_languages); return $supported_languages; } /* read_user_i18n_setting - finds the current value of a i18n configuration setting @arg $config_name - the name of the configuration setting as specified $settings_user array in 'include/global_settings.php' @returns - the current value of the i18n configuration option or the system default value */ function read_user_i18n_setting($config_name) { global $config; /* users must have cacti user auth turned on to use this, or the guest account must be active */ if (isset($_SESSION['sess_user_id'])) { $effective_uid = $_SESSION['sess_user_id']; }else if ((read_config_option('auth_method') == 0)) { if (isset($_SESSION['sess_config_array'])) { $config_array = $_SESSION['sess_config_array']; }else if (isset($config['config_options_array'])) { $config_array = $config['config_options_array']; } if (!isset($config_array[$config_name])) { $effective_uid = db_fetch_cell("SELECT user_auth.id FROM settings INNER JOIN user_auth ON user_auth.username = settings.value WHERE settings.name = 'guest_user'"); } if ($effective_uid == '') { $effective_uid = 0; } } else { $effective_uid = 0; } if (db_table_exists('settings_user')) { $db_setting = db_fetch_row_prepared('SELECT value FROM settings_user WHERE name = ? AND user_id = ?', array($config_name, $effective_uid)); } if (isset($db_setting['value'])) { return $db_setting['value']; } else { return false; } } /** * number_format_i18n - local specific number format wrapper * * @return - formatted numer in the correct locale */ function number_format_i18n($number, $decimals = 0, $baseu = 1024) { global $cacti_locale, $cacti_country; $country = strtoupper($cacti_country); if (function_exists('numfmt_create')) { $fmt = numfmt_create($cacti_locale . '_' . $country, NumberFormatter::DECIMAL); numfmt_set_attribute($fmt, NumberFormatter::MAX_FRACTION_DIGITS, $decimals); return numfmt_format($fmt, $number); } else { $origlocales = explode(';', setlocale(LC_ALL, 0)); setlocale(LC_ALL, $cacti_locale . '_' . $country); $locale = localeconv(); if ($decimals == -1) { $number = number_format($number, $decimals, $locale['decimal_point'], $locale['thousands_sep']); } elseif ($number>=pow($baseu, 4)) { $number = number_format($number/pow($baseu, 4), $decimals, $locale['decimal_point'], $locale['thousands_sep']) . __(' T'); } elseif($number>=pow($baseu, 3)) { $number = number_format($number/pow($baseu, 3), $decimals, $locale['decimal_point'], $locale['thousands_sep']) . __(' G'); } elseif($number>=pow($baseu, 2)) { $number = number_format($number/pow($baseu, 2), $decimals, $locale['decimal_point'], $locale['thousands_sep']) . __(' M'); } elseif($number>=$baseu) { $number = number_format($number/$baseu, $decimals, $locale['decimal_point'], $locale['thousands_sep']) . __(' K'); } else { $number = number_format($number, $decimals, $locale['decimal_point'], $locale['thousands_sep']); } foreach ($origlocales as $locale_setting) { if (strpos($locale_setting, '=') !== false) { list($category, $locale) = explode('=', $locale_setting); } else { $category = LC_ALL; $locale = $locale_setting; } switch($category) { case 'LC_ALL': case 'LC_COLLATE': case 'LC_CTYPE': case 'LC_MONETARY': case 'LC_NUMERIC': case 'LC_TIME': if (defined($category)) { setlocale(constant($category), $locale); } } } return $number; } }