diff options
Diffstat (limited to 'langs.inc.php')
-rw-r--r-- | langs.inc.php | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/langs.inc.php b/langs.inc.php new file mode 100644 index 000000000..5e9dceab5 --- /dev/null +++ b/langs.inc.php @@ -0,0 +1,509 @@ +<?php +/** +*/ + +$g_app_root = realpath(dirname(__FILE__)); +define('G_APP_ROOT', $g_app_root); +define('G_VHOST', $_SERVER['SERVER_NAME']); + +// languages for home +// $langs = array() is now in /_nav/lib.php + +// TODO (rda) define fallback languages for each language +// for instance, pt-br could fallback on pt and pt on pt-br (but without +// a cycle) then on es, etc. +$i18n_fallback_rules = array( + 'pt-br' => 'pt', + 'pt' => 'pt-br' +); + +$domains_lang = array( + 'mageia.fr' => 'fr', + 'mageia.it' => 'it', + 'mageia.ro' => 'ro', +); + +require_once ('_nav/lib.php'); + +/** + * Redirect to a localized path, depending on incoming TLD. + * Only manages redirections to main home path. + * + * @param string $tld + * @param array $domains_lang + * @param string $vhost + * + * @return void +*/ +function tld_redirect($tld, $domains_lang, $vhost) +{ + domain_redirect('mageia.' . $tld, $domains_lang, $vhost); +} + +/** + * Redirect to a localized path, depending on incoming full domain. + * Only manages redirections to main home path. + * + * @param string $host + * @param array $domains_lang + * @param string $vhost + * + * @return void +*/ +function domain_redirect($host, $domains_lang, $vhost) +{ + $host = str_replace('www.', '', $host); + + if (array_key_exists($host, $domains_lang)) { + $path = $domains_lang[$host] . '/'; + header ('HTTP/1.1 301 Moved Permanently'); + } else { + $path = '?langs'; + } + header(sprintf('Location: %s://%s/%s', 'http', $vhost, $path)); + die; +} + + +/** + * Redirect to a localized path, after browser Accept-Language prefs. + * Return the path. + * Do not exit the process. + * + * @param array $langs list of languages + * @param string $page optional path to which we want to redirect + * @param string $default_locale + * @param string $force_accept_language replace remote browser HTTP_ACCEPT_LANGUAGE request header + * @param boolean $do_redirect + * + * @return string +*/ +function relocate($langs, $page = '', $default_locale = 'en', $force_accept_language = null, $do_redirect = true) +{ + require_once 'localeDetection.class.php'; + + $locale = new ChooseLocale(array_keys($langs), $force_accept_language); + $locale->setDefaultLocale($default_locale); + + $relocate = sprintf('/%s/%s', $locale->getCompatibleLocale(), $page); + $relocate = str_replace('//', '/', $relocate); + + if ('cli' != PHP_SAPI && $do_redirect) { + header('Location: ' . $relocate); + } + + return $relocate; +} + + +/** + * Create string pt_br from string pt-br and alike but leave the rest as is + * Return string. + * Do not exit the process. + * + * @param string $locale which we want to change + * @param boolean $version_of_locale_uppercase optional, true if we want second part in uppercase (pt_BR) + * + * @return string +*/ +function locale_hyphen_underscore($locale, $version_of_locale_uppercase = false) +{ + preg_match("/(..)(-)(..)/", $locale, $parsed_locale); + if(isset($parsed_locale[3])) { + return $parsed_locale[1] . '_' . ($version_of_locale_uppercase ? strtoupper($parsed_locale[3]) : $parsed_locale[3]); + } else { + return $locale; + } +} + + +/** +*/ +function show_langs($langs) +{ + header('Content-Type: text/html; charset=utf-8'); + $count = count($langs); + $s = <<<S +<!DOCTYPE html> +<html lang="en"> +<head> + <charset="utf-8"> + <meta name="robots" content="noindex,nosnippet"> + <title>Mageia</title> +</head> +<body> +<p><a href="/">Mageia.org</a> is currently available in {$count} languages:</p> +<ul> +S; + foreach ($langs as $k => $v) { + $s .= sprintf('<li><a href="/%s/" hreflang="%s">%s</a></li>', + $k, $k, $v); + } + echo $s, '</ul><hr />', + '<p>If you would like to help improving this Web site or its translations, ', + 'check out our <a href="/langs/report.php">translation report page</a> ', + '<a href="https://wiki.mageia.org/en/Web_team">Web</a> and ', + '<a href="https://wiki.mageia.org/en/Internationalisation_Team_(i18n)">localization</a> teams!</p>', + '<p>Your browser Accept-Language is: ', $_SERVER['HTTP_ACCEPT_LANGUAGE'], '.</p>', + '<hr /></body></html>'; +} + + +/** + * Class regrouping basic methods for i18n strings in their current forms. + * +*/ +class i18n +{ + /** + * @param string $request_uri + * + * @return string + */ + public static function get_language_from_url($request_uri) + { + $l = explode('/', $request_uri); + return $l[1]; + } + + /** + * Return language strings in $strings that match $lang, + * and merge with pre-loaded strings matching $fallback_lang. + * + * @param array $strings array('fr' => array(strings...), 'en' => array(...)) + * @param string $lang + * @param string $fallback_lang + * + * @return array + */ + public static function get_strings($strings, $lang, $fallback_rules = null) + { + $use_lang = self::get_fallback_language($lang, array_keys($strings), $fallback_rules); + + return array_merge($strings['en'], $strings[$use_lang]); + } + + /** + * Return a language we know we have support for, or a fallback language. + * + * Important note: this is supposed to be used only once in a row; do not + * chain this method over itself as you may end up with an infinite loop + * (depends on $fallback_rules contents). + * + * TODO (rda) implement this into an object, so we can check several langs + * in a row for a same document, with several fallback hops, without a cycle. + * + * @param string $lang language we wish to use + * @param array $known_langs list of languages we support + * @param mixed $fallback_rules + * + * @return string + */ + public static function get_fallback_language($lang, $known_langs, $fallback_rules = null) + { + $ret = 'en'; + + if (in_array($lang, $known_langs)) { + $ret = $lang; + } + else { + if (is_string($fallback_rules)) { + $ret = $fallback_rules; + } + elseif (is_array($fallback_rules) + && array_key_exists($lang, $fallback_rules)) { + + $ret = $fallback_rules[$lang]; + } + + if (!in_array($ret, $known_langs)) + $ret = 'en'; + } + + return $ret; + } + + /** + * Get a translated string to output. + * + * Use it when you need to capture the string to output. + * + * Examples: + * + * echo _t("Hello."), _t("How are you?"); + * + * + * @param string $s string to localize + * @param array $opt translated strings list + * @param string $post string suffix. Useful to prevent non-breaking lines. + * + * @return null|string + */ + public static function _t($s = null, $opt = null, $post = ' ') + { + return self::_d($s, $opt) . $post; + } + + /** + * Lookup for translated string for $s + * in global array $_t (yes, ugly) + * OR in $opt param. + * + * $_t or $opt is the list of string for the current locale. + * + * Use it when you need to get the exact, char-specific translation text. + * + * Examples: + * + * _d('http://mageia.org/en/'); + * _d('http://blog.mageia.org/en/feed'); + * + * @param string $s + * @param array $opt + * + * @return string + * + * FIXME Yes, it's terribly wrong/evil to rely on an unknown global $_t. + * Solution? rethink the whole i18n thing in an integrated one. + */ + public static function _d($s = null, $opt = null) + { + if ($s == '') + return null; + + if (!is_null($opt)) { + $_t = $opt; + } else { + global $_t; + } + + $ret = array_key_exists($s, $_t) ? $_t[$s] : $s; + + return trim(str_replace(array('{ok}', '{OK}', '{Ok}', '{oK}'), '', $ret)); + } + + /** + * Output a localized string $s, with optional $args. + * + * Use it when you need to just output a string. + * + * Examples: + * + * _e("Hello"); + * _e("Hello %d %d", array(1, 2)); + * + * @param string $s + * @param array $args + * + * @return null + */ + public static function _e($s = null, $args = null) + { + if (is_array($args)) + echo vsprintf(_t($s), $args); + else + echo self::_t($s); + } + + /** + * Output a localized string $s, sprintf'ed with $args, HTML-wrapped in $tag. + * + * Use it when you need to wrap your text is HTML, and this is faster. + * + * Examples: + * + * _h("Hello"); + * _h("Hello %s", array("Alice")); + * _h("Title", null, "h1"); + * + * @param string $s string to echo + * @param array $args optional params to $s + * @param string $tag optional tag to wrap $s into + * + * @return null + */ + public static function _h($s, $args = null, $tag = 'p') + { + $s = self::_t($s); + $s = is_array($args) ? vsprintf($s, $args) : $s; + + $close_tag = explode(' ', $tag); + $close_tag = array_shift($close_tag); + + echo sprintf('<%s>%s</%s>', $tag, $s, $close_tag); + } + + /** + * Get all locales from given file. + * + * @param string $file + * @param string $return_duplicates optional switch + * + * @return array + */ + public static function _lang_return($file, $return_duplicates = false) + { + $strings = array(); + + if (file_exists($file)) { + $f = file($file); + + foreach ($f as $k => $v) { + + $C = substr($v, 0, 1); + if ($C === '#') continue; + + if ($C === ';' && !empty($f[$k+1])) { + $j = trim(substr($v, 1)); + $j = str_replace(array("\'", "\""), array("'", '"'), $j); + if ($return_duplicates && !empty($strings[$j])) { + $duplicates[] = $j; + } + $strings[$j] = trim($f[$k+1]); + } + } + if (!empty($duplicates)) { + $strings['duplicates'] = $duplicates; + } + } + + return $strings; + } + + /** + * Load requested $locale, from $domain lang file, into global $_t array. + * + * @param string $locale + * @param string $domain + * + * @return boolean + * + * @todo use i18n::get_fallback_language() or eq. + */ + public static function _lang_load($locale, $domain) + { + if ($locale == 'en') + return true; + + $lang_file = sprintf('%s/langs/%s/%s.%s.lang', G_APP_ROOT, $locale, $domain, $locale); + + if (file_exists($lang_file)) { + + global $_t; + if (!isset($_t) || !is_array($_t)) + $_t = array(); + + $_t = array_merge($_t, self::_lang_return($lang_file)); + + return true; + } + + return false; + } + +} + +// shorthand helpers, to make legacy calls work. +function _t($s = null, $opt = null, $post = ' ') { return i18n::_t($s, $opt, $post); } +function _d($s = null, $opt = null) { return i18n::_d($s, $opt); } +function _e($s = null, $args = null) { return i18n::_e($s, $args); } +function _h($s = null, $args = null, $tag = 'p') { return i18n::_h($s, $args, $tag); } + +function _lang_load($locale, $domain) { return i18n::_lang_load($locale, $domain); } + +/** + * Create dictionary from gettext file + * Return array. + * Do not exit the process. + * + * @param string $locale from which we want to create dictionary + * @param string $name_of_translation gettext filename + * + * @return array +*/ +function read_translation_file($locale, $name_of_translation) +{ + if($name_of_translation == '../_nav/langs/en') { + $path_filename = '/_nav/langs/' . $locale . '.po'; + } else { + $path_filename = '/langs/' . $locale . '/' . $name_of_translation . '.po'; + } + if($locale == 'en') { + $path_filename .= 't'; + } + return phpmo_parse_po_file(G_APP_ROOT . $path_filename); +} + +/** + * Returns a translated string from global $dictionary + * it can append space if needed + * + * Note that it trims {ok} for translations equal to original too. + * + * Use it when you need to capture the string to output. + * + * Examples: + * echo _r("Hello!", ' ') . _r("How are you?") + * which should return translated: Hello! How are you? + * + * @param string $string_for_translation which we want to translate + * @param string $sufix append (usually space) + * + * @return string translated to current locale +*/ +function _r($string_for_translation, $sufix = '') +{ + global $dictionary; + $escapeded_string = str_replace(array('"'), array('\\"'), $string_for_translation); + if(!empty($dictionary[$escapeded_string]["msgstr"][0])) { + $find = array('\\"', '\n', ' ', '{ok}', '{OK}', '{Ok}', '{oK}'); + $replace = array('"','<br>', ' '); + $prepared_string = trim(str_replace($find, $replace, $dictionary[$escapeded_string]["msgstr"][0])); + } + if(empty($prepared_string)) { + $prepared_string = $string_for_translation; + } + if(!empty($sufix)) { + $prepared_string .= $sufix; + } + return $prepared_string; +} + +/** + * Higher level function for _r() to echo a translated string from global $dictionary + * used also to wrap the translation with HTML tags + * it can also append space if needed + * + * Examples: + *_g("How are you?") + * will just echo translation + * + * _g('Download Mageia %d!', array(5), 'a href="" style="color: blue;"') + * will echo blue link + * + * _g("Hey there.", null, ' '); _g("How are you?") + * will just echo translation: Hey there. How are you? + * + * Return boolean. + * Do not exit the process. + * + * @param string $string_for_translation which we want to translate + * @param array $args for vsprintf + * @param string $tag_or_space HTML tag or space to append + * + * @return null +*/ +function _g($string_for_translation, $args = null, $tag_or_space = '') +{ + $translated_string = _r($string_for_translation); + if(is_array($args)) { + $translated_string = vsprintf($translated_string, $args); + } + if(!empty($tag_or_space) && $tag_or_space != ' ') { + $tag_or_space_w_args = explode(' ', $tag_or_space); + $close_tag = array_shift($tag_or_space_w_args); + echo sprintf('<%s>%s</%s>', $tag_or_space, $translated_string, $close_tag); + } else { + echo $translated_string . $tag_or_space; + } +} |