diff options
author | momo-i <momo-i@ampache> | 2008-08-26 22:08:13 +0000 |
---|---|---|
committer | momo-i <momo-i@ampache> | 2008-08-26 22:08:13 +0000 |
commit | c3a0f470271cae98883d137c8d1ed10a9ed9d7f6 (patch) | |
tree | 96fbc29e03c25e49836824684f80942dfa7fc0a9 /modules | |
parent | f54f17453d160932781295632587ef7490136e77 (diff) | |
download | ampache-c3a0f470271cae98883d137c8d1ed10a9ed9d7f6.tar.gz ampache-c3a0f470271cae98883d137c8d1ed10a9ed9d7f6.tar.bz2 ampache-c3a0f470271cae98883d137c8d1ed10a9ed9d7f6.zip |
if can't use gettext, emulate gettext(). update some templates.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/emulater/gettext.php | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/modules/emulater/gettext.php b/modules/emulater/gettext.php new file mode 100644 index 00000000..dcf23eb7 --- /dev/null +++ b/modules/emulater/gettext.php @@ -0,0 +1,391 @@ +<?php +/* + api: PHP + type: functions + title: gettext() + description: emulates PHP gettext extension functionality + priority: auto + category: library + + This include script simulates gettext() functionality. + - It could read translation data from .mo and .po files. + - Lookup of plural forms mostly work (but not 100% compliant, + no real interpreter for Plural-Forms: expression). + - Categories/codesets are ignored. + + Besides using setlocale() you should change the $_ENV["LANG"] var + to the desired language manually. Additionally all your scripts + could contain following (may also work with standard gettext): + $_ENV["LANGUAGE"] = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; + That's often more user-friendly than hardwired server-side values. +*/ + + +#-- emulate only if not present in current PHP interpreter +if (!function_exists("gettext")) { + + #-- all-in-one combined implementation + # (in original API only the first parameter is present) + function gettext($msg, $msg2=NULL, $domain=NULL, $category=NULL, $plural=NULL) { + global $_GETTEXT; + + #-- get default params if corresponding args are empty + if (!isset($domain)) { + $domain = $_GETTEXT['%domain']; + } + if (empty($_GETTEXT[$domain])) { + bindtextdomain($domain); // auto load from system dirs + } + + #-- plural array position + if (!isset($plural)) { + $pli = 0; + } + elseif ($ph = $_GETTEXT[$domain]['%plural-c']) { + $pli = gettext___plural_guess($ph, $plural); + } + else { + $pli = ($plural != 1) ? 1 : 0; // English + } + + #-- look up string + if (isset($_GETTEXT[$domain][$msg]) && ($trans = $_GETTEXT[$domain][$msg]) + or ($pli) and ($trans = $_GETTEXT[$domain][$msg2])) + { + // handle plural entries + if (is_array($trans)) { + if (!isset($trans[$pli])) { + $pli = 0; // missing translation + } + $trans = $trans[$pli]; + } + // only return, if something found + if (strlen($trans)) { + $msg = $trans; + } + } + + #-- handle $category (???) + // recode() ... + + #-- give out whatever we have + return($msg); + } + + + #-- return plural form array index for algorithm type + # (compacted from C expression string beforehand) + function gettext___plural_guess(&$type, $n) { + + #-- guess from string with C expression and set integer shorthand + if (is_string($type)) { + if (($type == "nplurals=1;plural=0;") || !strlen($type)) { + $type = -1; // no plurals + } + elseif ($type == "nplurals=2;plural=n!=1;") { + $type = 1; // English + } + elseif ($type == "nplurals=2;plural=n>1;") { + $type = 2; // French + } + // special cases + elseif (strpos($type, "n%100!=11")) { + if (strpos($type, "n!=0")) { + $type == 21; // Latvian + } + if (strpos($type, "n%10<=4")) { + $type = 22; // a few Slavic langs (code similar to Polish below) + } + if (strpos($type, "n%10>=2")) { // Lithuanian + $type = 23; + } + $type = 0; + } + // specials, group 2 + elseif (strpos($type, "n<=4")) { // Slovak + $type = 25; + } + elseif (strpos($type, "n==2")) { // Irish + $type = 31; + } + elseif (strpos($type, "n%10>=2")) { // Polish + $type = 26; + } + elseif (strpos($type, "n%100==3")) { // Slovenian + $type = 28; + } + // fallbacks + elseif (strpos($type, ";plural=n;")) { + $type = 7; // unused + } + // first at this point a tokenizer/parser/interpreter would have made sense + else { + $type = 0; // no plurals + } + } + + #-- return plural index value from pre-set formulas + switch ($type) { + case -1: // no plural forms + return(0); + case 1: // English, and lots of others... + return($n != 1 ? 1 : 0); + case 2: // French, Brazilian Protuguese + return($n > 1 ? 1 : 0); + case 7: // unused + return($n); + + case 21: // Latvian + return (($n%10==1) && ($n%100!=11)) ? (0) : ($n!=0 ? 1 : 2) ; + case 22: // Slavic langs + return ($n%10==1) && ($n%100!=11) ? 0 : + ( ($n%10>=2) && ($n%10<=4) && ($n%100<10 || $n%100>=20) ? 1 : 2 ) ; + case 23: // Lithuanian + return ($n%10==1) && ($n%100!=11) ? 0 : + ( ($n%10>=2) && ($n%100<10 || $n%100>=20) ? 1 : 2 ) ; + case 25: // Slovak + return $n==1 ? 0 : ($n>=2 && $n<=4 ? 1 : 2) ; + case 26: // Polish + return $n==1 ? 0 : ( $n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2 ) ; + case 28: // Slovenian + return $n%100==1 ? 0 : ($n%100==2 || $n%100==3 || $n%100==4 ? 2 : 3) ; + case 31: // Irish + return ($n == 1) ? (0) : (($n == 2) ? 1 : 2) ; + + default: + $type = -1; + } // unsupported, always return non-plural index [0] + return(0); + } + + + #-- wrappers around monster function above + function ngettext($msg1, $msg2, $plural) { + return gettext($msg1, $msg2, NULL, NULL, $plural); + } + function dngettext($domain, $msg1, $msg2, $plural) { + return gettext($msg1, $msg2, $domain, NULL, $plural); + } + function dcngettext($domain, $msg1, $msg2, $plural, $category) { + return gettext($msg1, $msg2, $domain, $category, $plural); + } + function dcgettext($domain, $msg, $category) { + return gettext($msg, NULL, $domain, $category); + } + function dgettext($domain, $msg) { + return gettext($msg, NULL, $domain); + } + + + #-- sets current translation data source + # (must have been loaded beforehand) + function textdomain($default="NULL") { + global $_GETTEXT; + $prev = isset($_GETTEXT['%domain']) ? $_GETTEXT['%domain'] : NULL; + if (isset($default)) { + $_GETTEXT['%domain'] = $default; + } + return $prev; + } + + + #-- loads data files + function bindtextdomain($domain, $directory="/usr/share/locale:/usr/local/share/locale:./locale") { + global $_GETTEXT; + if (isset($_GETTEXT[$domain]) && (count($_GETTEXT[$domain]) > 3)) { + return; // don't load twice + } + $_GETTEXT[$domain]['%dir'] = $directory; + $_GETTEXT['%locale'] = setlocale(LC_CTYPE, 0); + + #-- allowed languages + $langs = @$_ENV['LANGUAGE'] . ',' . @$_ENV['LC_ALL'] . ',' + . @$_ENV['LC_MESSAGE'] .',' . @$_ENV['LANG'] . ',' + . @$_GETTEXT['%locale'] . ',' . @$_SERVER['HTTP_ACCEPT_LANGUAGE'] + . ',C,en'; + + #-- add shortened language codes (en_UK.UTF-8 -> + en_UK, en) + foreach (explode(',', $langs) as $d) { + $d = trim($d); + // $dir2[] = $d; + $d = strtok($d, "@.-+=%:; "); + if (strlen($d)) { + $dir2[] = $d; + } + if (strpos($d, '_')) { + $dir2[] = strtok($d, '_'); + } + } + + #-- search for matching directory and load data file + foreach (explode(':', $directory) as $directory) { + foreach ($dir2 as $lang) { + $base_fn = "$directory/$lang/LC_MESSAGES/$domain"; + +#echo "GETTEXT:$lang:$base_fn\n"; + + #-- binary format + if (file_exists($fn = "$base_fn.mo") && ($f = fopen($fn, "rb"))) + { + gettext___load_mo($f, $domain); + break 2; + } + + #-- text file + elseif (function_exists("gettext___load_po") + and file_exists($fn = "$base_fn.po") && ($f = fopen($fn, "r"))) + { + gettext___load_po($f, $domain); + break 2; + } + } + }//foreach + + #-- extract headers + if ($head = $_GETTEXT[$domain][""]) { + foreach (explode("\n", $head) as $line) { + $header = strtok(':', $line); + $line = trim(strtok("\n")); + $_GETTEXT[$domain]['%po-header'][strtolower($header)] = $line; + } + + #-- plural-forms header + if (function_exists("gettext___plural_guess") + and ($h = @$_GETTEXT[$domain]['%po-header']["plural-forms"])) + { + $h = preg_replace("/[(){}\[\]^\s*\\]+/", "", $h); // rm whitespace + gettext___plural_guess($h, 0); // pre-decode into algorithm type integer + $_GETTEXT[$domain]['%plural-c'] = $h; + } + } + + #-- set as default textdomain + if (empty($_GETTEXT['%domain'])) { + textdomain($domain); + } + return($domain); + } + + + #-- load string data from binary .mo files (ign checksums) + function gettext___load_mo($f, $domain) { + global $_GETTEXT; + + #-- read in data file completely + $data = fread($f, 1<<20); + fclose($f); + + #-- extract header fields and check file magic + if ($data) { + $header = substr($data, 0, 20); + $header = unpack("L1magic/L1version/L1count/L1o_msg/L1o_trn", $header); + extract($header); + if ((dechex($magic) == "950412de") && ($version == 0)) { + + #-- fetch all entries + for ($n=0; $n<$count; $n++) { + + #-- msgid + $r = unpack("L1len/L1offs", substr($data, $o_msg + $n * 8, 8)); + $msgid = substr($data, $r["offs"], $r["len"]); + unset($msgid_plural); + if (strpos($msgid, "\000")) { + list($msgid, $msgid_plural) = explode("\000", $msgid); + } + + #-- translation(s) + $r = unpack("L1len/L1offs", substr($data, $o_trn + $n * 8, 8)); + $msgstr = substr($data, $r["offs"], $r["len"]); + if (strpos($msgstr, "\000")) { + $msgstr = explode("\000", $msgstr); + } + + #-- add + $_GETTEXT[$domain][$msgid] = $msgstr; + if (isset($msgid_plural)) { + $_GETTEXT[$domain][$msgid_plural] = &$_GETTEXT[$domain][$msgid]; + } + } + + } + } + } + + + #-- read from textual .po source file (not fully correct, and redundant + # because the original gettext/libintl doesn't support this at all) + function gettext___load_po($f, $domain) { + global $_GETTEXT; + $c_esc = array("\\n"=>"\n", "\\r"=>"\r", "\\\\"=>"\\", "\\f"=>"\f", "\\t"=>"\t", "\\"=>""); + + #-- read line-wise from text file + do { + $line = trim(fgets($f)); + + #-- check what's in the current line + $space = strpos($line, " "); + // comment + if ($line[0] == "#") { + //continue; + } + // msgid + elseif (strncmp($line, "msgid", 5)==0) { + $msgid[] = trim(substr($line, $space+1), '"'); + } + // translation + elseif (strncmp($line, "msgstr", 6)==0) { + $msgstr[] = trim(substr($line, $space+1), '"'); + } + // continued (could be _id or _str) + elseif ($line[0] == '"') { + $line = trim($line, '"'); + if (isset($msggstr)) { + $msgstr[count($msgstr)] .= $line; + } + else { + $msgid[count($msgid)] .= $line; + } + } + + #-- append to global $_GETTEXT hash as soon as we have a complete dataset + if (isset($msgid) && isset($msgstr) && (empty($line) || ($line[0]=="#") || feof($f)) ) + { + $msgid[0] = strtr($msgid[0], $c_esc); + foreach ($msgstr as $v) { + $_GETTEXT[$domain][$msgid[0]] = strtr($v, $c_esc); + } + if ($msgid[1]) { + $msgid[1] = strtr($msgid[1], $c_esc); + $_GETTEXT[$domain][$msgid[1]] = &$_GETTEXT[$domain][$msgid[0]]; + } + + $msgid = array(); + $msgstr = array(); + } + + } while (!feof($f)); + fclose($f); + } + + + #-- ignored setting (no idea what it really should do) + function bind_textdomain_codeset($domain, $codeset) { + global $_GETTEXT; + $_GETTEXT[$domain]["%codeset"] = $codeset; + return($domain); + } + + +} + + +#-- define gettexts preferred function name _ separately +if (!function_exists("_")) { + function _($str) { + return gettext($str); + } +} + + + +?>
\ No newline at end of file |