Source for file i18n.php

Documentation is available at i18n.php

  1. <?php
  2.  
  3. /**
  4.  * SquirrelMail internationalization functions
  5.  *
  6.  * This file contains variuos functions that are needed to do
  7.  * internationalization of SquirrelMail.
  8.  *
  9.  * Internally the output character set is used. Other characters are
  10.  * encoded using Unicode entities according to HTML 4.0.
  11.  *
  12.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  13.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  14.  * @version $Id: i18n.php,v 1.129.2.49 2006/04/30 04:49:34 tokul Exp $
  15.  * @package squirrelmail
  16.  * @subpackage i18n
  17.  */
  18.  
  19. /** @ignore */
  20. if (!defined('SM_PATH')) define('SM_PATH','../');
  21.  
  22. /** Everything uses global.php... */
  23. require_once(SM_PATH 'functions/global.php');
  24.  
  25. /**
  26.  * php setlocale function wrapper
  27.  *
  28.  * From php 4.3.0 it is possible to use arrays in order to set locale.
  29.  * php gettext extension works only when locale is set. This wrapper
  30.  * function allows to use more than one locale name.
  31.  *
  32.  * @param int $category locale category name. Use php named constants
  33.  *      (LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME)
  34.  * @param mixed $locale option contains array with possible locales or string with one locale
  35.  * @return string name of set locale or false, if all locales fail.
  36.  * @since 1.5.1 and 1.4.5
  37.  * @see http://www.php.net/setlocale
  38.  */
  39. function sq_setlocale($category,$locale{
  40.     if (is_string($locale)) {
  41.         // string with only one locale
  42.         $ret setlocale($category,$locale);
  43.     elseif (check_php_version(4,3)) {
  44.         // older php version (second setlocale argument must be string)
  45.         $ret=false;
  46.         $index=0;
  47.         while $ret && $index<count($locale)) {
  48.             $ret=setlocale($category,$locale[$index]);
  49.             $index++;
  50.         }
  51.     else {
  52.         // php 4.3.0 or better, use entire array
  53.         $ret=setlocale($category,$locale);
  54.     }
  55.  
  56.     /* safety checks */
  57.     if (preg_match("/^.*\/.*\/.*\/.*\/.*\/.*$/",$ret)) {
  58.         /**
  59.          * Welcome to We-Don't-Follow-Own-Fine-Manual department
  60.          * OpenBSD 3.8, 3.9-current and maybe later versions 
  61.          * return invalid response to setlocale command.
  62.          * SM bug report #1427512.
  63.          */
  64.         $ret false;
  65.     }
  66.     return $ret;
  67. }
  68.  
  69. /**
  70.  * Converts string from given charset to charset, that can be displayed by user translation.
  71.  *
  72.  * Function by default returns html encoded strings, if translation uses different encoding.
  73.  * If Japanese translation is used - function returns string converted to euc-jp
  74.  * If $charset is not supported - function returns unconverted string.
  75.  *
  76.  * sanitizing of html tags is also done by this function.
  77.  *
  78.  * @param string $charset 
  79.  * @param string $string Text to be decoded
  80.  * @param boolean $force_decode converts string to html without $charset!=$default_charset check.
  81.  *  Argument is available since 1.5.1 and 1.4.5.
  82.  * @param boolean $save_html disables htmlspecialchars() in order to preserve
  83.  *   html formating. Use with care. Available since 1.5.1 and 1.4.6
  84.  * @return string decoded string
  85.  */
  86. function charset_decode ($charset$string$force_decode=false$save_html=false{
  87.     global $languages$squirrelmail_language$default_charset;
  88.  
  89.     if (isset($languages[$squirrelmail_language]['XTRA_CODE']&&
  90.         function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
  91.         $string $languages[$squirrelmail_language]['XTRA_CODE']('decode'$string);
  92.     }
  93.  
  94.     /* All HTML special characters are 7 bit and can be replaced first */
  95.     if ($save_html$string htmlspecialchars ($string);
  96.     $charset strtolower($charset);
  97.  
  98.     set_my_charset(;
  99.  
  100.     // Don't do conversion if charset is the same.
  101.     if $force_decode && $charset == strtolower($default_charset) )
  102.         return $string;
  103.  
  104.     /* controls cpu and memory intensive decoding cycles */
  105.     global $aggressive_decoding;
  106.     $aggressive_decoding false;
  107.  
  108.     $decode=fixcharset($charset);
  109.     $decodefile=SM_PATH 'functions/decode/' $decode '.php';
  110.     if (file_exists($decodefile)) {
  111.       include_once($decodefile);
  112.       $ret call_user_func('charset_decode_'.$decode$string$save_html);
  113.     else {
  114.       $ret $string;
  115.     }
  116.  
  117.     return$ret );
  118. }
  119.  
  120. /**
  121.  * Converts html string to given charset
  122.  * @since 1.4.4 and 1.5.1
  123.  * @param string $string 
  124.  * @param string $charset 
  125.  * @param boolean $htmlencode keep htmlspecialchars encoding
  126.  * @param string 
  127.  */
  128. function charset_encode($string,$charset,$htmlencode=true{
  129.     global $default_charset;
  130.  
  131.     $encode=fixcharset($charset);
  132.     $encodefile=SM_PATH 'functions/encode/' $encode '.php';
  133.     if (file_exists($encodefile)) {
  134.         include_once($encodefile);
  135.         $ret call_user_func('charset_encode_'.$encode$string);
  136.     elseif(file_exists(SM_PATH 'functions/encode/us_ascii.php')) {
  137.         // function replaces all 8bit html entities with question marks.
  138.         // it is used when other encoding functions are unavailable
  139.         include_once(SM_PATH 'functions/encode/us_ascii.php');
  140.         $ret charset_encode_us_ascii($string);
  141.     else {
  142.         /**
  143.          * fix for yahoo users that remove all us-ascii related things
  144.          */
  145.         $ret $string;
  146.     }
  147.  
  148.     /**
  149.      * Undo html special chars, some places (like compose form) have
  150.      * own sanitizing functions and don't need html symbols.
  151.      * Undo chars only after encoding in order to prevent conversion of 
  152.      * html entities in plain text emails.
  153.      */
  154.     if ($htmlencode {
  155.         $ret str_replace(array('&amp;','&gt;','&lt;','&quot;'),array('&','>','<','"'),$ret);
  156.     }
  157.  
  158.     return$ret );
  159. }
  160.  
  161. /**
  162.  * Combined decoding and encoding functions
  163.  *
  164.  * If conversion is done to charset different that utf-8, unsupported symbols
  165.  * will be replaced with question marks.
  166.  * @since 1.4.4 and 1.5.1
  167.  * @param string $in_charset initial charset
  168.  * @param string $string string that has to be converted
  169.  * @param string $out_charset final charset
  170.  * @param boolean $htmlencode keep htmlspecialchars encoding
  171.  * @return string converted string
  172.  */
  173. function charset_convert($in_charset,$string,$out_charset,$htmlencode=true{
  174.     $string=charset_decode($in_charset,$string,true);
  175.     $string=charset_encode($string,$out_charset,$htmlencode);
  176.     return $string;
  177. }
  178.  
  179. /**
  180.  * Makes charset name suitable for decoding cycles
  181.  *
  182.  * ks_c_5601_1987, x-euc-* and x-windows-* charsets are supported
  183.  * since 1.5.1/1.4.6
  184.  * @param string $charset Name of charset
  185.  * @return string $charset Adjusted name of charset
  186.  * @since 1.5.1 and 1.4.4
  187.  */
  188. function fixcharset($charset{
  189.     /* remove minus and characters that might be used in paths from charset
  190.      * name in order to be able to use it in function names and include calls.
  191.      */
  192.     $charset=preg_replace("/[-:.\/\\\]/",'_',$charset);
  193.  
  194.     // OE ks_c_5601_1987 > cp949 
  195.     $charset=str_replace('ks_c_5601_1987','cp949',$charset);
  196.     // Moz x-euc-tw > euc-tw
  197.     $charset=str_replace('x_euc','euc',$charset);
  198.     // Moz x-windows-949 > cp949
  199.     $charset=str_replace('x_windows_','cp',$charset);
  200.     // windows-125x and cp125x charsets
  201.     $charset=str_replace('windows_','cp',$charset);
  202.  
  203.     // ibm > cp
  204.     $charset=str_replace('ibm','cp',$charset);
  205.  
  206.     // iso-8859-8-i -> iso-8859-8
  207.     // use same cycle until I'll find differences
  208.     $charset=str_replace('iso_8859_8_i','iso_8859_8',$charset);
  209.  
  210.     return $charset;
  211. }
  212.  
  213. /*
  214.  * Set up the language to be output
  215.  * if $do_search is true, then scan the browser information
  216.  * for a possible language that we know
  217.  */
  218. function set_up_language($sm_language$do_search false$default false{
  219.  
  220.     static $SetupAlready 0;
  221.     global $use_gettext$languages,
  222.            $squirrelmail_language$squirrelmail_default_language
  223.            $default_charset$sm_notAlias;
  224.  
  225.     if ($SetupAlready{
  226.         return;
  227.     }
  228.  
  229.     $SetupAlready TRUE;
  230.     sqgetGlobalVar('HTTP_ACCEPT_LANGUAGE',  $accept_langSQ_SERVER);
  231.  
  232.     /**
  233.      * detect preferred language from header when SquirrelMail asks for
  234.      * it or when default language is set to empty string.
  235.      */
  236.     if (($do_search || empty($squirrelmail_default_language)) &&
  237.         $sm_language &&
  238.         isset($accept_lang)) {
  239.         $sm_language substr($accept_lang02);
  240.     }
  241.  
  242.     /**
  243.      * Use default language when it is not detected or when script
  244.      * asks to use default language.
  245.      */
  246.     if ((!$sm_language||$default&& 
  247.         empty($squirrelmail_default_language)) {
  248.         $squirrelmail_language $squirrelmail_default_language;
  249.         $sm_language $squirrelmail_default_language;
  250.     }
  251.  
  252.     /** provide failsafe language when detection fails */
  253.     if ($sm_language$sm_language='en_US';
  254.  
  255.     $sm_notAlias $sm_language;
  256.  
  257.     /**
  258.      * Catch removed translation
  259.      * System reverts to English translation if user prefs contain translation
  260.      * that is not available in $languages array
  261.      */
  262.     if (!isset($languages[$sm_notAlias])) {
  263.         $sm_notAlias="en_US";
  264.     }
  265.  
  266.     while (isset($languages[$sm_notAlias]['ALIAS'])) {
  267.         $sm_notAlias $languages[$sm_notAlias]['ALIAS'];
  268.     }
  269.  
  270.     if isset($sm_language&&
  271.          $use_gettext &&
  272.          $sm_language != '' &&
  273.          isset($languages[$sm_notAlias]['CHARSET']) ) {
  274.         bindtextdomain'squirrelmail'SM_PATH 'locale/' );
  275.         textdomain'squirrelmail' );
  276.         if (function_exists('bind_textdomain_codeset')) {
  277.             if ($sm_notAlias == 'ja_JP'{
  278.                 bind_textdomain_codeset ("squirrelmail"'EUC-JP');
  279.             else {
  280.                 bind_textdomain_codeset ("squirrelmail"$languages[$sm_notAlias]['CHARSET');
  281.             }
  282.         }
  283.  
  284.         // Use LOCALE key, if it is set.
  285.         if (isset($languages[$sm_notAlias]['LOCALE'])){
  286.             $longlocale=$languages[$sm_notAlias]['LOCALE'];
  287.         else {
  288.             $longlocale=$sm_notAlias;
  289.         }
  290.  
  291.         // try setting locale
  292.         $retlocale=sq_setlocale(LC_ALL$longlocale);
  293.  
  294.         // check if locale is set and assign that locale to $longlocale
  295.         // in order to use it in putenv calls.
  296.         if (is_bool($retlocale)) {
  297.             $longlocale=$retlocale;
  298.         elseif (is_array($longlocale)) {
  299.             // setting of all locales failed.
  300.             // we need string instead of array used in LOCALE key.
  301.             $longlocale=$sm_notAlias;
  302.         }
  303.  
  304.         if !((bool)ini_get('safe_mode')) &&
  305.              getenv'LC_ALL' != $longlocale {
  306.             putenv"LC_ALL=$longlocale);
  307.             putenv"LANG=$longlocale);
  308.             putenv"LANGUAGE=$longlocale);
  309.             putenv"LC_NUMERIC=C" );
  310.             if ($sm_notAlias=='tr_TR'putenv"LC_CTYPE=C" );
  311.         }
  312.         // Workaround for plugins that use numbers with floating point
  313.         // It might be removed if plugins use correct decimal delimiters
  314.         // according to locale settings.
  315.         setlocale(LC_NUMERIC'C');
  316.         // Workaround for specific Turkish strtolower/strtoupper rules.
  317.         // Many functions expect English conversion rules.
  318.         if ($sm_notAlias=='tr_TR'setlocale(LC_CTYPE,'C');
  319.  
  320.         $squirrelmail_language $sm_notAlias;
  321.         if ($squirrelmail_language == 'ja_JP'{
  322.             header ('Content-Type: text/html; charset=EUC-JP');
  323.             if (!function_exists('mb_internal_encoding')) {
  324.                 echo _("You need to have PHP installed with the multibyte string function enabled (using configure option --enable-mbstring).");
  325.                 // Revert to English link has to be added.
  326.                 // stop further execution in order not to get php errors on mb_internal_encoding().
  327.                 return;
  328.             }
  329.             if (function_exists('mb_language')) {
  330.                 mb_language('Japanese');
  331.             }
  332.             mb_internal_encoding('EUC-JP');
  333.             mb_http_output('pass');
  334.         elseif ($squirrelmail_language == 'en_US'{
  335.             header'Content-Type: text/html; charset=' $default_charset );
  336.         else {
  337.             header'Content-Type: text/html; charset=' $languages[$sm_notAlias]['CHARSET');
  338.         }
  339.         // mbstring.func_overload<>0 fix. See cvs HEAD comments.
  340.         if ($squirrelmail_language != 'ja_JP' && 
  341.             function_exists('mb_internal_encoding'&&
  342.             check_php_version(4,2,0&&
  343.             (int)ini_get('mbstring.func_overload')!=0{
  344.             mb_internal_encoding('pass');
  345.         }
  346.     }
  347. }
  348.  
  349. /**
  350.  * Sets default_charset variable according to the one that is used by user's translations.
  351.  *
  352.  * Function changes global $default_charset variable in order to be sure, that it
  353.  * contains charset used by user's translation. Sanity of $squirrelmail_language
  354.  * and $default_charset combination provided in SquirrelMail config is also tested.
  355.  *
  356.  * There can be a $default_charset setting in the
  357.  * config.php file, but the user may have a different language
  358.  * selected for a user interface. This function checks the
  359.  * language selected by the user and tags the outgoing messages
  360.  * with the appropriate charset corresponding to the language
  361.  * selection. This is "more right" (tm), than just stamping the
  362.  * message blindly with the system-wide $default_charset.
  363.  */
  364. function set_my_charset(){
  365.     global $data_dir$username$default_charset$languages$squirrelmail_language;
  366.  
  367.     $my_language getPref($data_dir$username'language');
  368.     if (!$my_language{
  369.         $my_language $squirrelmail_language ;
  370.     }
  371.     // Catch removed translation
  372.     if (!isset($languages[$my_language])) {
  373.         $my_language="en_US";
  374.     }
  375.     while (isset($languages[$my_language]['ALIAS'])) {
  376.         $my_language $languages[$my_language]['ALIAS'];
  377.     }
  378.     $my_charset $languages[$my_language]['CHARSET'];
  379.     if ($my_language!='en_US'{
  380.         $default_charset $my_charset;
  381.     }
  382. }
  383.  
  384. /**
  385.  * Function informs if it is safe to convert given charset to the one that is used by user.
  386.  *
  387.  * It is safe to use conversion only if user uses utf-8 encoding and when
  388.  * converted charset is similar to the one that is used by user.
  389.  *
  390.  * @param string $input_charset Charset of text that needs to be converted
  391.  * @return bool is it possible to convert to user's charset
  392.  */
  393. function is_conversion_safe($input_charset{
  394.     global $languages$sm_notAlias$default_charset$lossy_encoding;
  395.  
  396.     if (isset($lossy_encoding&& $lossy_encoding )
  397.         return true;
  398.  
  399.     // convert to lower case
  400.     $input_charset strtolower($input_charset);
  401.  
  402.     // Is user's locale Unicode based ?
  403.     if $default_charset == "utf-8" {
  404.         return true;
  405.     }
  406.  
  407.     // Charsets that are similar
  408.     switch ($default_charset{
  409.     case "windows-1251":
  410.         if $input_charset == "iso-8859-5" ||
  411.            $input_charset == "koi8-r" ||
  412.            $input_charset == "koi8-u" {
  413.         return true;
  414.         else {
  415.             return false;
  416.         }
  417.     case "windows-1257":
  418.         if $input_charset == "iso-8859-13" ||
  419.              $input_charset == "iso-8859-4" {
  420.             return true;
  421.         else {
  422.             return false;
  423.         }
  424.     case "iso-8859-4":
  425.         if $input_charset == "iso-8859-13" ||
  426.              $input_charset == "windows-1257" {
  427.             return true;
  428.         else {
  429.             return false;
  430.         }
  431.     case "iso-8859-5":
  432.         if $input_charset == "windows-1251" ||
  433.              $input_charset == "koi8-r" ||
  434.              $input_charset == "koi8-u" {
  435.             return true;
  436.         else {
  437.             return false;
  438.         }
  439.     case "iso-8859-13":
  440.         if $input_charset == "iso-8859-4" ||
  441.              $input_charset == "windows-1257" {
  442.             return true;
  443.         else {
  444.             return false;
  445.         }
  446.     case "koi8-r":
  447.         if $input_charset == "windows-1251" ||
  448.              $input_charset == "iso-8859-5" ||
  449.              $input_charset == "koi8-u" {
  450.             return true;
  451.         else {
  452.             return false;
  453.         }
  454.     case "koi8-u":
  455.         if $input_charset == "windows-1251" ||
  456.              $input_charset == "iso-8859-5" ||
  457.              $input_charset == "koi8-r" {
  458.             return true;
  459.         else {
  460.             return false;
  461.         }
  462.     default:
  463.         return false;
  464.     }
  465. }
  466.  
  467. /* ---- extra code functions ----*/
  468. /**
  469.  * Japanese charset extra function
  470.  */
  471. function japanese_charset_xtra({
  472.     $ret func_get_arg(1);  /* default return value */
  473.     if (function_exists('mb_detect_encoding')) {
  474.         switch (func_get_arg(0)) /* action */
  475.         case 'decode':
  476.             $detect_encoding @mb_detect_encoding($ret);
  477.             if ($detect_encoding == 'JIS' ||
  478.                 $detect_encoding == 'EUC-JP' ||
  479.                 $detect_encoding == 'SJIS' ||
  480.                 $detect_encoding == 'UTF-8'{
  481.  
  482.                 $ret mb_convert_kana(mb_convert_encoding($ret'EUC-JP''AUTO')"KV");
  483.             }
  484.             break;
  485.         case 'encode':
  486.             $detect_encoding @mb_detect_encoding($ret);
  487.             if ($detect_encoding == 'JIS' ||
  488.                 $detect_encoding == 'EUC-JP' ||
  489.                 $detect_encoding == 'SJIS' ||
  490.                 $detect_encoding == 'UTF-8'{
  491.  
  492.                 $ret mb_convert_encoding(mb_convert_kana($ret"KV")'JIS''AUTO');
  493.             }
  494.             break;
  495.         case 'strimwidth':
  496.             $width func_get_arg(2);
  497.             $ret mb_strimwidth($ret0$width'...');
  498.             break;
  499.         case 'encodeheader':
  500.             $result '';
  501.             if (strlen($ret0{
  502.                 $tmpstr mb_substr($ret01);
  503.                 $prevcsize strlen($tmpstr);
  504.                 for ($i 1$i mb_strlen($ret)$i++{
  505.                     $tmp mb_substr($ret$i1);
  506.                     if (strlen($tmp== $prevcsize{
  507.                         $tmpstr .= $tmp;
  508.                     else {
  509.                         if ($prevcsize == 1{
  510.                             $result .= $tmpstr;
  511.                         else {
  512.                             $result .= str_replace(' ''',
  513.                                                    mb_encode_mimeheader($tmpstr,'iso-2022-jp','B',''));
  514.                         }
  515.                         $tmpstr $tmp;
  516.                         $prevcsize strlen($tmp);
  517.                     }
  518.                 }
  519.                 if (strlen($tmpstr)) {
  520.                     if (strlen(mb_substr($tmpstr01)) == 1)
  521.                         $result .= $tmpstr;
  522.                     else
  523.                         $result .= str_replace(' ''',
  524.                                                mb_encode_mimeheader($tmpstr,'iso-2022-jp','B',''));
  525.                 }
  526.             }
  527.             $ret $result;
  528.             break;
  529.         case 'decodeheader':
  530.             $ret str_replace("\t"""$ret);
  531.             if (eregi('=\\?([^?]+)\\?(q|b)\\?([^?]+)\\?='$ret))
  532.                 $ret @mb_decode_mimeheader($ret);
  533.             $ret @mb_convert_encoding($ret'EUC-JP''AUTO');
  534.             break;
  535.         case 'downloadfilename':
  536.             $useragent func_get_arg(2);
  537.             if (strstr($useragent'Windows'!== false ||
  538.                 strstr($useragent'Mac_'!== false{
  539.                 $ret mb_convert_encoding($ret'SJIS''AUTO');
  540.             else {
  541.                 $ret mb_convert_encoding($ret'EUC-JP''AUTO');
  542. }
  543.             break;
  544.         case 'wordwrap':
  545.             $no_begin "\x21\x25\x29\x2c\x2e\x3a\x3b\x3f\x5d\x7d\xa1\xf1\xa1\xeb\xa1" .
  546.                 "\xc7\xa1\xc9\xa2\xf3\xa1\xec\xa1\xed\xa1\xee\xa1\xa2\xa1\xa3\xa1\xb9" .
  547.                 "\xa1\xd3\xa1\xd5\xa1\xd7\xa1\xd9\xa1\xdb\xa1\xcd\xa4\xa1\xa4\xa3\xa4" .
  548.                 "\xa5\xa4\xa7\xa4\xa9\xa4\xc3\xa4\xe3\xa4\xe5\xa4\xe7\xa4\xee\xa1\xab" .
  549.                 "\xa1\xac\xa1\xb5\xa1\xb6\xa5\xa1\xa5\xa3\xa5\xa5\xa5\xa7\xa5\xa9\xa5" .
  550.                 "\xc3\xa5\xe3\xa5\xe5\xa5\xe7\xa5\xee\xa5\xf5\xa5\xf6\xa1\xa6\xa1\xbc" .
  551.                 "\xa1\xb3\xa1\xb4\xa1\xaa\xa1\xf3\xa1\xcb\xa1\xa4\xa1\xa5\xa1\xa7\xa1" .
  552.                 "\xa8\xa1\xa9\xa1\xcf\xa1\xd1";
  553.             $no_end "\x5c\x24\x28\x5b\x7b\xa1\xf2\x5c\xa1\xc6\xa1\xc8\xa1\xd2\xa1" .
  554.                 "\xd4\xa1\xd6\xa1\xd8\xa1\xda\xa1\xcc\xa1\xf0\xa1\xca\xa1\xce\xa1\xd0\xa1\xef";
  555.             $wrap func_get_arg(2);
  556.  
  557.             if (strlen($ret>= $wrap &&
  558.                 substr($ret01!= '>' &&
  559.                 strpos($ret'http://'=== FALSE &&
  560.                 strpos($ret'https://'=== FALSE &&
  561.                 strpos($ret'ftp://'=== FALSE{
  562.  
  563.                 $ret mb_convert_kana($ret"KV");
  564.  
  565.                 $line_new '';
  566.                 $ptr 0;
  567.  
  568.                 while ($ptr strlen($ret1{
  569.                     $l mb_strcut($ret$ptr$wrap);
  570.                     $ptr += strlen($l);
  571.                     $tmp $l;
  572.  
  573.                     $l mb_strcut($ret$ptr2);
  574.                     while (strlen($l!= && mb_strpos($no_begin$l!== FALSE {
  575.                         $tmp .= $l;
  576.                         $ptr += strlen($l);
  577.                         $l mb_strcut($ret$ptr1);
  578.                     }
  579.                     $line_new .= $tmp;
  580.                     if ($ptr strlen($ret1)
  581.                         $line_new .= "\n";
  582.                 }
  583.                 $ret $line_new;
  584.             }
  585.             break;
  586.         case 'utf7-imap_encode':
  587.             $ret mb_convert_encoding($ret'UTF7-IMAP''EUC-JP');
  588.             break;
  589.         case 'utf7-imap_decode':
  590.             $ret mb_convert_encoding($ret'EUC-JP''UTF7-IMAP');
  591.             break;
  592.         }
  593.     }
  594.     return $ret;
  595. }
  596.  
  597.  
  598. /*
  599.  * Korean charset extra function
  600.  * Hangul(Korean Character) Attached File Name Fix.
  601.  */
  602. function korean_charset_xtra({
  603.  
  604.     $ret func_get_arg(1);  /* default return value */
  605.     if (func_get_arg(0== 'downloadfilename'/* action */
  606.         $ret str_replace("\x0D\x0A"''$ret);  /* Hanmail's CR/LF Clear */
  607.         for ($i=0;$i<strlen($ret);$i++{
  608.             if ($ret[$i>= "\xA1" && $ret[$i<= "\xFE"{   /* 0xA1 - 0XFE are Valid */
  609.                 $i++;
  610.                 continue;
  611.             else if (($ret[$i>= 'a' && $ret[$i<= 'z'|| /* From Original ereg_replace in download.php */
  612.                        ($ret[$i>= 'A' && $ret[$i<= 'Z'||
  613.                        ($ret[$i== '.'|| ($ret[$i== '-')) {
  614.                 continue;
  615.             else {
  616.                 $ret[$i'_';
  617.             }
  618.         }
  619.  
  620.     }
  621.  
  622.     return $ret;
  623. }
  624.  
  625.  
  626. /* ------------------------------ main --------------------------- */
  627.  
  628. global $squirrelmail_language$languages$use_gettext;
  629.  
  630. if (sqgetGlobalVar('squirrelmail_language',$squirrelmail_language,SQ_COOKIE)) {
  631.     $squirrelmail_language '';
  632. }
  633.  
  634. /* This array specifies the available languages. */
  635.  
  636. $languages['bg_BG']['NAME']    'Bulgarian';
  637. $languages['bg_BG']['CHARSET''windows-1251';
  638. $languages['bg_BG']['LOCALE']  'bg_BG.CP1251';
  639. $languages['bg']['ALIAS']      'bg_BG';
  640.  
  641. $languages['bn_IN']['NAME']    'Bengali';
  642. $languages['bn_IN']['CHARSET''utf-8';
  643. $languages['bn_IN']['LOCALE']  'bn_IN.UTF-8';
  644. $languages['bn_BD']['ALIAS''bn_IN';
  645. $languages['bn']['ALIAS''bn_IN';
  646.  
  647. $languages['ca_ES']['NAME']    'Catalan';
  648. $languages['ca_ES']['CHARSET''iso-8859-1';
  649. $languages['ca_ES']['LOCALE']  array('ca_ES.ISO8859-1','ca_ES.ISO-8859-1','ca_ES');
  650. $languages['ca']['ALIAS']      'ca_ES';
  651.  
  652. $languages['cs_CZ']['NAME']    'Czech';
  653. $languages['cs_CZ']['CHARSET''iso-8859-2';
  654. $languages['cs_CZ']['LOCALE']  array('cs_CZ.ISO8859-2','cs_CZ.ISO-8859-2','cs_CZ');
  655. $languages['cs']['ALIAS']      'cs_CZ';
  656.  
  657. $languages['cy_GB']['NAME']    'Welsh';
  658. $languages['cy_GB']['CHARSET''iso-8859-1';
  659. $languages['cy_GB']['LOCALE']  array('cy_GB.ISO8859-1','cy_GB.ISO-8859-1','cy_GB');
  660. $languages['cy']['ALIAS''cy_GB';
  661.  
  662. $languages['da_DK']['NAME']    'Danish';
  663. $languages['da_DK']['CHARSET''iso-8859-1';
  664. $languages['da_DK']['LOCALE']  array('da_DK.ISO8859-1','da_DK.ISO-8859-1','da_DK');
  665. $languages['da']['ALIAS']      'da_DK';
  666.  
  667. $languages['de_DE']['NAME']    'Deutsch';
  668. $languages['de_DE']['CHARSET''iso-8859-1';
  669. $languages['de_DE']['LOCALE']  array('de_DE.ISO8859-1','de_DE.ISO-8859-1','de_DE');
  670. $languages['de']['ALIAS']      'de_DE';
  671.  
  672. $languages['el_GR']['NAME']    'Greek';
  673. $languages['el_GR']['CHARSET''iso-8859-7';
  674. $languages['el_GR']['LOCALE']  array('el_GR.ISO8859-7','el_GR.ISO-8859-7','el_GR');
  675. $languages['el']['ALIAS']      'el_GR';
  676.  
  677. $languages['en_GB']['NAME']    'British';
  678. $languages['en_GB']['CHARSET''iso-8859-15';
  679. $languages['en_GB']['LOCALE']  array('en_GB.ISO8859-15','en_GB.ISO-8859-15','en_GB');
  680.  
  681. $languages['en_US']['NAME']    'English';
  682. $languages['en_US']['CHARSET''iso-8859-1';
  683. $languages['en_US']['LOCALE']  'en_US.ISO8859-1';
  684. $languages['en']['ALIAS']      'en_US';
  685.  
  686. $languages['es_ES']['NAME']    'Spanish';
  687. $languages['es_ES']['CHARSET''iso-8859-1';
  688. $languages['es_ES']['LOCALE']  array('es_ES.ISO8859-1','es_ES.ISO-8859-1','es_ES');
  689. $languages['es']['ALIAS']      'es_ES';
  690.  
  691. $languages['et_EE']['NAME']    'Estonian';
  692. $languages['et_EE']['CHARSET''iso-8859-15';
  693. $languages['et_EE']['LOCALE']  array('et_EE.ISO8859-15','et_EE.ISO-8859-15','et_EE');
  694. $languages['et']['ALIAS']      'et_EE';
  695.  
  696. $languages['eu_ES']['NAME']    'Basque';
  697. $languages['eu_ES']['CHARSET''iso-8859-1';
  698. $languages['eu_ES']['LOCALE']  array('eu_ES.ISO8859-1','eu_ES.ISO-8859-1','eu_ES');
  699. $languages['eu']['ALIAS']      'eu_ES';
  700.  
  701. $languages['fi_FI']['NAME']    'Finnish';
  702. $languages['fi_FI']['CHARSET''iso-8859-1';
  703. $languages['fi_FI']['LOCALE']  array('fi_FI.ISO8859-1','fi_FI.ISO-8859-1','fi_FI');
  704. $languages['fi']['ALIAS']      'fi_FI';
  705.  
  706. $languages['fo_FO']['NAME']    'Faroese';
  707. $languages['fo_FO']['CHARSET''iso-8859-1';
  708. $languages['fo_FO']['LOCALE']  array('fo_FO.ISO8859-1','fo_FO.ISO-8859-1','fo_FO');
  709. $languages['fo']['ALIAS']      'fo_FO';
  710.  
  711. $languages['fr_FR']['NAME']    'French';
  712. $languages['fr_FR']['CHARSET''iso-8859-1';
  713. $languages['fr_FR']['LOCALE']  array('fr_FR.ISO8859-1','fr_FR.ISO-8859-1','fr_FR');
  714. $languages['fr']['ALIAS']      'fr_FR';
  715.  
  716. $languages['hr_HR']['NAME']    'Croatian';
  717. $languages['hr_HR']['CHARSET''iso-8859-2';
  718. $languages['hr_HR']['LOCALE']  array('hr_HR.ISO8859-2','hr_HR.ISO-8859-2','hr_HR');
  719. $languages['hr']['ALIAS']      'hr_HR';
  720.  
  721. $languages['hu_HU']['NAME']    'Hungarian';
  722. $languages['hu_HU']['CHARSET''iso-8859-2';
  723. $languages['hu_HU']['LOCALE']  array('hu_HU.ISO8859-2','hu_HU.ISO-8859-2','hu_HU');
  724. $languages['hu']['ALIAS']      'hu_HU';
  725.  
  726. $languages['id_ID']['NAME']    'Bahasa Indonesia';
  727. $languages['id_ID']['CHARSET''iso-8859-1';
  728. $languages['id_ID']['LOCALE']  array('id_ID.ISO8859-1','id_ID.ISO-8859-1','id_ID');
  729. $languages['id']['ALIAS']      'id_ID';
  730.  
  731. $languages['is_IS']['NAME']    'Icelandic';
  732. $languages['is_IS']['CHARSET''iso-8859-1';
  733. $languages['is_IS']['LOCALE']  array('is_IS.ISO8859-1','is_IS.ISO-8859-1','is_IS');
  734. $languages['is']['ALIAS']      'is_IS';
  735.  
  736. $languages['it_IT']['NAME']    'Italian';
  737. $languages['it_IT']['CHARSET''iso-8859-1';
  738. $languages['it_IT']['LOCALE']  array('it_IT.ISO8859-1','it_IT.ISO-8859-1','it_IT');
  739. $languages['it']['ALIAS']      'it_IT';
  740.  
  741. $languages['ja_JP']['NAME']    'Japanese';
  742. $languages['ja_JP']['CHARSET''iso-2022-jp';
  743. $languages['ja_JP']['XTRA_CODE''japanese_charset_xtra';
  744. $languages['ja']['ALIAS']      'ja_JP';
  745.  
  746. $languages['ka']['NAME']       'Georgian';
  747. $languages['ka']['CHARSET']    'utf-8';
  748. $languages['ka']['LOCALE']     array('ka_GE.UTF-8','ka_GE','ka');
  749. $languages['ka_GE']['ALIAS']   'ka';
  750.  
  751. $languages['ko_KR']['NAME']    'Korean';
  752. $languages['ko_KR']['CHARSET''euc-KR';
  753. // Function does not provide all needed options
  754. // $languages['ko_KR']['XTRA_CODE'] = 'korean_charset_xtra';
  755. $languages['ko']['ALIAS']      'ko_KR';
  756.  
  757. $languages['lt_LT']['NAME']    'Lithuanian';
  758. $languages['lt_LT']['CHARSET''utf-8';
  759. $languages['lt_LT']['LOCALE']  'lt_LT.UTF-8';
  760. $languages['lt']['ALIAS']      'lt_LT';
  761.  
  762. $languages['ms_MY']['NAME']    'Bahasa Melayu';
  763. $languages['ms_MY']['CHARSET''iso-8859-1';
  764. $languages['ms_MY']['LOCALE']  array('ms_MY.ISO8859-1','ms_MY.ISO-8859-1','ms_MY');
  765. $languages['my']['ALIAS''ms_MY';
  766.  
  767. $languages['nl_NL']['NAME']    'Dutch';
  768. $languages['nl_NL']['CHARSET''iso-8859-1';
  769. $languages['nl_NL']['LOCALE']  array('nl_NL.ISO8859-1','nl_NL.ISO-8859-1','nl_NL');
  770. $languages['nl']['ALIAS']      'nl_NL';
  771.  
  772. $languages['nb_NO']['NAME']    'Norwegian (Bokm&aring;l)';
  773. $languages['nb_NO']['CHARSET''iso-8859-1';
  774. $languages['nb_NO']['LOCALE']  array('nb_NO.ISO8859-1','nb_NO.ISO-8859-1','nb_NO');
  775. $languages['nb']['ALIAS']      'nb_NO';
  776.  
  777. $languages['nn_NO']['NAME']    'Norwegian (Nynorsk)';
  778. $languages['nn_NO']['CHARSET''iso-8859-1';
  779. $languages['nn_NO']['LOCALE']  array('nn_NO.ISO8859-1','nn_NO.ISO-8859-1','nn_NO');
  780.  
  781. $languages['pl_PL']['NAME']    'Polish';
  782. $languages['pl_PL']['CHARSET''iso-8859-2';
  783. $languages['pl_PL']['LOCALE']  array('pl_PL.ISO8859-2','pl_PL.ISO-8859-2','pl_PL');
  784. $languages['pl']['ALIAS']      'pl_PL';
  785.  
  786. $languages['pt_PT']['NAME''Portuguese (Portugal)';
  787. $languages['pt_PT']['CHARSET''iso-8859-1';
  788. $languages['pt_PT']['LOCALE']  array('pt_PT.ISO8859-1','pt_PT.ISO-8859-1','pt_PT');
  789. $languages['pt']['ALIAS']      'pt_PT';
  790.  
  791. $languages['pt_BR']['NAME']    'Portuguese (Brazil)';
  792. $languages['pt_BR']['CHARSET''iso-8859-1';
  793. $languages['pt_BR']['LOCALE']  array('pt_BR.ISO8859-1','pt_BR.ISO-8859-1','pt_BR');
  794.  
  795. $languages['ro_RO']['NAME']    'Romanian';
  796. $languages['ro_RO']['CHARSET''iso-8859-2';
  797. $languages['ro_RO']['LOCALE']  array('ro_RO.ISO8859-2','ro_RO.ISO-8859-2','ro_RO');
  798. $languages['ro']['ALIAS']      'ro_RO';
  799.  
  800. $languages['ru_RU']['NAME']    'Russian';
  801. $languages['ru_RU']['CHARSET''utf-8';
  802. $languages['ru_RU']['LOCALE']  'ru_RU.UTF-8';
  803. $languages['ru']['ALIAS']      'ru_RU';
  804.  
  805. $languages['sk_SK']['NAME']     'Slovak';
  806. $languages['sk_SK']['CHARSET']  'iso-8859-2';
  807. $languages['sk_SK']['LOCALE']   array('sk_SK.ISO8859-2','sk_SK.ISO-8859-2','sk_SK');
  808. $languages['sk']['ALIAS']       'sk_SK';
  809.  
  810. $languages['sl_SI']['NAME']    'Slovenian';
  811. $languages['sl_SI']['CHARSET''iso-8859-2';
  812. $languages['sl_SI']['LOCALE']  array('sl_SI.ISO8859-2','sl_SI.ISO-8859-2','sl_SI');
  813. $languages['sl']['ALIAS']      'sl_SI';
  814.  
  815. $languages['sr_YU']['NAME']    'Serbian';
  816. $languages['sr_YU']['CHARSET''iso-8859-2';
  817. $languages['sr_YU']['LOCALE']  array('sr_YU.ISO8859-2','sr_YU.ISO-8859-2','sr_YU');
  818. $languages['sr']['ALIAS']      'sr_YU';
  819.  
  820. $languages['sv_SE']['NAME']    'Swedish';
  821. $languages['sv_SE']['CHARSET''iso-8859-1';
  822. $languages['sv_SE']['LOCALE']  array('sv_SE.ISO8859-1','sv_SE.ISO-8859-1','sv_SE');
  823. $languages['sv']['ALIAS']      'sv_SE';
  824.  
  825. /* translation is disabled because it contains less than 50%
  826.  * translated strings
  827. $languages['th_TH']['NAME']    = 'Thai';
  828. $languages['th_TH']['CHARSET'] = 'tis-620';
  829. $languages['th_TH']['LOCALE']  = 'th_TH.TIS-620';
  830. $languages['th']['ALIAS'] = 'th_TH';
  831. */
  832.  
  833. $languages['tr_TR']['NAME']    'Turkish';
  834. $languages['tr_TR']['CHARSET''iso-8859-9';
  835. $languages['tr_TR']['LOCALE']  array('tr_TR.ISO8859-9','tr_TR.ISO-8859-9','tr_TR');
  836. $languages['tr']['ALIAS']      'tr_TR';
  837.  
  838. $languages['zh_TW']['NAME']    'Chinese Trad';
  839. $languages['zh_TW']['CHARSET''big5';
  840. $languages['zh_TW']['LOCALE']  'zh_TW.BIG5';
  841. $languages['tw']['ALIAS']      'zh_TW';
  842.  
  843. $languages['zh_CN']['NAME']    'Chinese Simp';
  844. $languages['zh_CN']['CHARSET''gb2312';
  845. $languages['zh_CN']['LOCALE']  'zh_CN.GB2312';
  846. $languages['cn']['ALIAS']      'zh_CN';
  847.  
  848. $languages['uk_UA']['NAME']    'Ukrainian';
  849. $languages['uk_UA']['CHARSET''utf-8';
  850. $languages['uk_UA']['LOCALE']  array('uk_UA.UTF-8','uk_UA','uk');
  851. $languages['uk']['ALIAS''uk_UA';
  852.  
  853. /*
  854. $languages['vi_VN']['NAME']    = 'Vietnamese';
  855. $languages['vi_VN']['CHARSET'] = 'utf-8';
  856. $languages['vi']['ALIAS'] = 'vi_VN';
  857. */
  858.  
  859. // Right to left languages
  860.  
  861. $languages['ar']['NAME']    'Arabic';
  862. $languages['ar']['CHARSET''windows-1256';
  863. $languages['ar']['DIR']     'rtl';
  864.  
  865. $languages['fa_IR']['NAME']    'Farsi';
  866. $languages['fa_IR']['CHARSET''utf-8';
  867. $languages['fa_IR']['DIR']     'rtl';
  868. $languages['fa_IR']['LOCALE']  'fa_IR.UTF-8';
  869. $languages['fa']['ALIAS']      'fa_IR';
  870.  
  871. $languages['he_IL']['NAME']    'Hebrew';
  872. $languages['he_IL']['CHARSET''windows-1255';
  873. $languages['he_IL']['DIR']     'rtl';
  874. $languages['he']['ALIAS']      'he_IL';
  875.  
  876. $languages['ug']['NAME']    'Uighur';
  877. $languages['ug']['CHARSET''utf-8';
  878. $languages['ug']['DIR']     'rtl';
  879.  
  880. /* Detect whether gettext is installed. */
  881. $gettext_flags 0;
  882. if (function_exists('_')) {
  883.     $gettext_flags += 1;
  884. }
  885. if (function_exists('bindtextdomain')) {
  886.     $gettext_flags += 2;
  887. }
  888. if (function_exists('textdomain')) {
  889.     $gettext_flags += 4;
  890. }
  891.  
  892. /* If gettext is fully loaded, cool */
  893. if ($gettext_flags == 7{
  894.     $use_gettext true;
  895. }
  896. /* If we can fake gettext, try that */
  897. elseif ($gettext_flags == 0{
  898.     $use_gettext true;
  899.     include_once(SM_PATH 'functions/gettext.php');
  900. else {
  901.     /* Uh-ho.  A weird install */
  902.     if ($gettext_flags 1{
  903.         function _($str{
  904.             return $str;
  905.         }
  906.     }
  907.     if ($gettext_flags 2{
  908.         function bindtextdomain({
  909.             return;
  910.         }
  911.     }
  912.     if ($gettext_flags 4{
  913.         function textdomain({
  914.             return;
  915.         }
  916.     }
  917. }
  918. ?>

Documentation generated on Sat, 07 Oct 2006 16:31:33 +0300 by phpDocumentor 1.3.0RC6