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 1999-2020 The SquirrelMail Project Team
  13.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  14.  * @version $Id: i18n.php 14840 2020-01-07 07:42:38Z pdontthink $
  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.  * Wrapper for textdomain(), bindtextdomain() and
  27.  * bind_textdomain_codeset() primarily intended for
  28.  * plugins when changing into their own text domain
  29.  * and back again.
  30.  *
  31.  * Note that if plugins using this function have
  32.  * their translation files located in the SquirrelMail
  33.  * locale directory, the second argument is optional.
  34.  *
  35.  * @param string $domain_name The name of the text domain
  36.  *                             (usually the plugin name, or
  37.  *                             "squirrelmail") being switched to.
  38.  * @param string $directory   The directory that contains
  39.  *                             all translations for the domain
  40.  *                             (OPTIONAL; default is SquirrelMail
  41.  *                             locale directory).
  42.  *
  43.  * @return string The name of the text domain that was set
  44.  *                 *BEFORE* it is changed herein - NOTE that
  45.  *                 this differs from PHP's textdomain()
  46.  *
  47.  * @since 1.4.10 and 1.5.2
  48.  */
  49. function sq_change_text_domain($domain_name$directory=''{
  50.     global $use_gettext;
  51.     static $domains_already_seen array();
  52.  
  53.     $return_value textdomain(NULL);
  54.  
  55.     // empty domain defaults to "squirrelmail"
  56.     //
  57.     if (empty($domain_name)) $domain_name 'squirrelmail';
  58.  
  59.     // only need to call bindtextdomain() once unless
  60.     // $use_gettext is turned on
  61.     //
  62.     if (!$use_gettext && in_array($domain_name$domains_already_seen)) {
  63.         textdomain($domain_name);
  64.         return $return_value;
  65.     }
  66.  
  67.     $domains_already_seen[$domain_name;
  68.  
  69.     if (empty($directory)) $directory SM_PATH 'locale/';
  70.  
  71.     sq_bindtextdomain($domain_name$directory);
  72.     textdomain($domain_name);
  73.  
  74.     return $return_value;
  75. }
  76.  
  77. /**
  78.  * Gettext bindtextdomain wrapper.
  79.  *
  80.  * Wrapper solves differences between php versions in order to provide
  81.  * ngettext support. Should be used if translation uses ngettext
  82.  * functions.
  83.  *
  84.  * This also provides a bind_textdomain_codeset call to make sure the
  85.  * domain's encoding will not be overridden.
  86.  *
  87.  * @since 1.4.10 and 1.5.1
  88.  * @param string $domain gettext domain name
  89.  * @param string $dir directory that contains all translations (OPTIONAL;
  90.  *                     if not specified, defaults to SquirrelMail locale
  91.  *                     directory)
  92.  * @return string path to translation directory
  93.  */
  94. function sq_bindtextdomain($domain,$dir=''{
  95.     global $languages$sm_notAlias;
  96.  
  97.     if (empty($dir)) $dir SM_PATH 'locale/';
  98.  
  99.     $dir bindtextdomain($domain$dir);
  100.  
  101.     // set codeset in order to avoid gettext charset conversions
  102.     if (function_exists('bind_textdomain_codeset')
  103.      && isset($languages[$sm_notAlias]['CHARSET'])) {
  104.  
  105.         // Japanese translation uses different internal charset
  106.         if ($sm_notAlias == 'ja_JP'{
  107.             bind_textdomain_codeset ($domain'EUC-JP');
  108.         else {
  109.             bind_textdomain_codeset ($domain$languages[$sm_notAlias]['CHARSET']);
  110.         }
  111.  
  112.     }
  113.  
  114.     return $dir;
  115. }
  116.  
  117. /**
  118.  * php setlocale function wrapper
  119.  *
  120.  * From php 4.3.0 it is possible to use arrays in order to set locale.
  121.  * php gettext extension works only when locale is set. This wrapper
  122.  * function allows to use more than one locale name.
  123.  *
  124.  * @param int $category locale category name. Use php named constants
  125.  *      (LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME)
  126.  * @param mixed $locale option contains array with possible locales or string with one locale
  127.  * @return string name of set locale or false, if all locales fail.
  128.  * @since 1.4.5 and 1.5.1
  129.  * @see http://php.net/setlocale
  130.  */
  131. function sq_setlocale($category,$locale{
  132.     if (is_string($locale)) {
  133.         // string with only one locale
  134.         $ret setlocale($category,$locale);
  135.     elseif (check_php_version(4,3)) {
  136.         // older php version (second setlocale argument must be string)
  137.         $ret=false;
  138.         $index=0;
  139.         while $ret && $index<count($locale)) {
  140.             $ret=setlocale($category,$locale[$index]);
  141.             $index++;
  142.         }
  143.     else {
  144.         // php 4.3.0 or better, use entire array
  145.         $ret=setlocale($category,$locale);
  146.     }
  147.  
  148.     /* safety checks */
  149.     if (preg_match("/^.*\/.*\/.*\/.*\/.*\/.*$/",$ret)) {
  150.         /**
  151.          * Welcome to We-Don't-Follow-Own-Fine-Manual department
  152.          * OpenBSD 3.8, 3.9-current and maybe later versions
  153.          * return invalid response to setlocale command.
  154.          * SM bug report #1427512.
  155.          */
  156.         $ret false;
  157.     }
  158.     return $ret;
  159. }
  160.  
  161. /**
  162.  * Converts string from given charset to charset, that can be displayed by user translation.
  163.  *
  164.  * Function by default returns html encoded strings, if translation uses different encoding.
  165.  * If Japanese translation is used - function returns string converted to euc-jp
  166.  * If $charset is not supported - function returns unconverted string.
  167.  *
  168.  * sanitizing of html tags is also done by this function.
  169.  *
  170.  * @param string $charset 
  171.  * @param string $string Text to be decoded
  172.  * @param boolean $force_decode converts string to html without $charset!=$default_charset check.
  173.  *  Argument is available since 1.4.5 and 1.5.1.
  174.  * @param boolean $save_html disables sm_encode_html_special_chars() in order to preserve
  175.  *   html formating. Use with care. Available since 1.4.6 and 1.5.1
  176.  * @return string decoded string
  177.  */
  178. function charset_decode ($charset$string$force_decode=false$save_html=false{
  179.     global $languages$squirrelmail_language$default_charset;
  180.  
  181.     if (isset($languages[$squirrelmail_language]['XTRA_CODE']&&
  182.         function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
  183.         $string $languages[$squirrelmail_language]['XTRA_CODE']('decode'$string);
  184.     }
  185.  
  186.     /* All HTML special characters are 7 bit and can be replaced first */
  187.     if ($save_html$string sm_encode_html_special_chars ($string);
  188.     $charset strtolower($charset);
  189.  
  190.     set_my_charset();
  191.  
  192.     // Don't do conversion if charset is the same.
  193.     if $force_decode && $charset == strtolower($default_charset) )
  194.         return $string;
  195.  
  196.     /* controls cpu and memory intensive decoding cycles */
  197.     global $aggressive_decoding;
  198.     $aggressive_decoding false;
  199.  
  200.     $decode=fixcharset($charset);
  201.     $decodefile=SM_PATH 'functions/decode/' $decode '.php';
  202.     if ($decode != 'index' && file_exists($decodefile)) {
  203.       include_once($decodefile);
  204.       $ret call_user_func('charset_decode_'.$decode$string$save_html);
  205.     else {
  206.       $ret $string;
  207.     }
  208.  
  209.     return$ret );
  210. }
  211.  
  212. /**
  213.  * Converts html string to given charset
  214.  * @since 1.4.4 and 1.5.1
  215.  * @param string $string 
  216.  * @param string $charset 
  217.  * @param boolean $htmlencode keep sm_encode_html_special_chars encoding
  218.  * @return string 
  219.  */
  220. function charset_encode($string,$charset,$htmlencode=true{
  221.     global $default_charset;
  222.  
  223.     $encode=fixcharset($charset);
  224.     $encodefile=SM_PATH 'functions/encode/' $encode '.php';
  225.     if ($encode != 'index' && file_exists($encodefile)) {
  226.         include_once($encodefile);
  227.         $ret call_user_func('charset_encode_'.$encode$string);
  228.     elseif(file_exists(SM_PATH 'functions/encode/us_ascii.php')) {
  229.         // function replaces all 8bit html entities with question marks.
  230.         // it is used when other encoding functions are unavailable
  231.         include_once(SM_PATH 'functions/encode/us_ascii.php');
  232.         $ret charset_encode_us_ascii($string);
  233.     else {
  234.         /**
  235.          * fix for yahoo users that remove all us-ascii related things
  236.          */
  237.         $ret $string;
  238.     }
  239.  
  240.     /**
  241.      * Undo html special chars, some places (like compose form) have
  242.      * own sanitizing functions and don't need html symbols.
  243.      * Undo chars only after encoding in order to prevent conversion of
  244.      * html entities in plain text emails.
  245.      */
  246.     if ($htmlencode {
  247.         $ret str_replace(array('&amp;','&gt;','&lt;','&quot;'),array('&','>','<','"'),$ret);
  248.     }
  249.     return$ret );
  250. }
  251.  
  252. /**
  253.  * Combined decoding and encoding functions
  254.  *
  255.  * If conversion is done to charset different that utf-8, unsupported symbols
  256.  * will be replaced with question marks.
  257.  * @since 1.4.4 and 1.5.1
  258.  * @param string $in_charset initial charset
  259.  * @param string $string string that has to be converted
  260.  * @param string $out_charset final charset
  261.  * @param boolean $htmlencode keep sm_encode_html_special_chars encoding
  262.  * @return string converted string
  263.  */
  264. function charset_convert($in_charset,$string,$out_charset,$htmlencode=true{
  265.     $string=charset_decode($in_charset,$string,true);
  266.     $string=charset_encode($string,$out_charset,$htmlencode);
  267.     return $string;
  268. }
  269.  
  270. /**
  271.  * Makes charset name suitable for decoding cycles
  272.  *
  273.  * ks_c_5601_1987, x-euc-* and x-windows-* charsets are supported
  274.  * since 1.4.6 and 1.5.1.
  275.  *
  276.  * @since 1.4.4 and 1.5.0
  277.  * @param string $charset Name of charset
  278.  * @return string $charset Adjusted name of charset
  279.  */
  280. function fixcharset($charset{
  281.  
  282.     /* Remove minus and characters that might be used in paths from charset
  283.      * name in order to be able to use it in function names and include calls.
  284.      * Also make sure it's in lower case (ala "UTF" --> "utf")
  285.      */
  286.     $charset=preg_replace("/[-:.\/\\\]/",'_'strtolower($charset));
  287.  
  288.     // OE ks_c_5601_1987 > cp949
  289.     $charset=str_replace('ks_c_5601_1987','cp949',$charset);
  290.     // Moz x-euc-tw > euc-tw
  291.     $charset=str_replace('x_euc','euc',$charset);
  292.     // Moz x-windows-949 > cp949
  293.     $charset=str_replace('x_windows_','cp',$charset);
  294.  
  295.     // windows-125x and cp125x charsets
  296.     $charset=str_replace('windows_','cp',$charset);
  297.  
  298.     // ibm > cp
  299.     $charset=str_replace('ibm','cp',$charset);
  300.  
  301.     // iso-8859-8-i -> iso-8859-8
  302.     // use same cycle until I'll find differences
  303.     $charset=str_replace('iso_8859_8_i','iso_8859_8',$charset);
  304.  
  305.     return $charset;
  306. }
  307.  
  308. /**
  309.  * Set up the language to be output
  310.  * if $do_search is true, then scan the browser information
  311.  * for a possible language that we know
  312.  *
  313.  * Function sets system locale environment (LC_ALL, LANG, LANGUAGE),
  314.  * gettext translation bindings and html header information.
  315.  *
  316.  * Function returns error codes, if there is some fatal error.
  317.  *  0 = no error,
  318.  *  1 = mbstring support is not present,
  319.  *  2 = mbstring support is not present, user's translation reverted to en_US.
  320.  *
  321.  * @param string $sm_language  Translation used by user's interface
  322.  * @param bool   $do_search    Use browser's preferred language detection functions.
  323.  *                              Defaults to false.
  324.  * @param bool   $default      Set $sm_language to $squirrelmail_default_language if
  325.  *                              language detection fails or language is not set.
  326.  *                              Defaults to false.
  327.  * @return int function execution error codes.
  328.  *
  329.  */
  330. function set_up_language($sm_language$do_search false$default false{
  331.  
  332.     static $SetupAlready 0;
  333.     global $use_gettext$languages$squirrelmail_language,
  334.            $squirrelmail_default_language$default_charset$sm_notAlias;
  335.  
  336.     if ($SetupAlready{
  337.         return;
  338.     }
  339.  
  340.     $SetupAlready TRUE;
  341.     sqgetGlobalVar('HTTP_ACCEPT_LANGUAGE',  $accept_langSQ_SERVER);
  342.  
  343.     /**
  344.      * If function is asked to detect preferred language
  345.      *  OR SquirrelMail default language is set to empty string
  346.      *    AND
  347.      * SquirrelMail language ($sm_language) is empty string
  348.      * (not set in user's prefs and no cookie with language info)
  349.      *    AND
  350.      * browser provides list of preferred languages
  351.      *  THEN
  352.      * get preferred language from HTTP_ACCEPT_LANGUAGE header
  353.      */
  354.     if (($do_search || empty($squirrelmail_default_language)) &&
  355.         $sm_language &&
  356.         isset($accept_lang)) {
  357.         // TODO: use more than one language, if first language is not available
  358.         // FIXME: function assumes that string contains two or more characters.
  359.         // FIXME: some languages use 5 chars
  360.         $sm_language substr($accept_lang02);
  361.     }
  362.  
  363.     /**
  364.      * If language preference is not set OR script asks to use default language
  365.      *  AND
  366.      * default SquirrelMail language is not set to empty string
  367.      *  THEN
  368.      * use default SquirrelMail language value from configuration.
  369.      */
  370.     if ((!$sm_language||$default&&
  371.         empty($squirrelmail_default_language)) {
  372.         $squirrelmail_language $squirrelmail_default_language;
  373.         $sm_language $squirrelmail_default_language;
  374.     }
  375.  
  376.     /** provide failsafe language when detection fails */
  377.     if ($sm_language$sm_language='en_US';
  378.  
  379.     $sm_notAlias $sm_language;
  380.  
  381.     // Catching removed translation
  382.     // System reverts to English translation if user prefs contain translation
  383.     // that is not available in $languages array
  384.     if (!isset($languages[$sm_notAlias])) {
  385.         $sm_notAlias="en_US";
  386.     }
  387.  
  388.     while (isset($languages[$sm_notAlias]['ALIAS'])) {
  389.         $sm_notAlias $languages[$sm_notAlias]['ALIAS'];
  390.     }
  391.  
  392.     if isset($sm_language&&
  393.          $use_gettext &&
  394.          $sm_language != '' &&
  395.          isset($languages[$sm_notAlias]['CHARSET']) ) {
  396.         bindtextdomain'squirrelmail'SM_PATH 'locale/' );
  397.         textdomain'squirrelmail' );
  398.         if (function_exists('bind_textdomain_codeset')) {
  399.             if ($sm_notAlias == 'ja_JP'{
  400.                 bind_textdomain_codeset ("squirrelmail"'EUC-JP');
  401.             else {
  402.                 bind_textdomain_codeset ("squirrelmail"$languages[$sm_notAlias]['CHARSET');
  403.             }
  404.         }
  405.  
  406.         // Use LOCALE key, if it is set.
  407.         if (isset($languages[$sm_notAlias]['LOCALE'])){
  408.             $longlocale=$languages[$sm_notAlias]['LOCALE'];
  409.         else {
  410.             $longlocale=$sm_notAlias;
  411.         }
  412.  
  413.         // try setting locale
  414.         $retlocale=sq_setlocale(LC_ALL$longlocale);
  415.  
  416.         // check if locale is set and assign that locale to $longlocale
  417.         // in order to use it in putenv calls.
  418.         if (is_bool($retlocale)) {
  419.             $longlocale=$retlocale;
  420.         elseif (is_array($longlocale)) {
  421.             // setting of all locales failed.
  422.             // we need string instead of array used in LOCALE key.
  423.             $longlocale=$sm_notAlias;
  424.         }
  425.  
  426.         if !((bool)ini_get('safe_mode')) &&
  427.              getenv'LC_ALL' != $longlocale {
  428.             putenv"LC_ALL=$longlocale);
  429.             putenv"LANG=$longlocale);
  430.             putenv"LANGUAGE=$longlocale);
  431.             putenv"LC_NUMERIC=C" );
  432.             if ($sm_notAlias=='tr_TR'putenv"LC_CTYPE=C" );
  433.         }
  434.         // Workaround for plugins that use numbers with floating point
  435.         // It might be removed if plugins use correct decimal delimiters
  436.         // according to locale settings.
  437.         setlocale(LC_NUMERIC'C');
  438.         // Workaround for specific Turkish strtolower/strtoupper rules.
  439.         // Many functions expect English conversion rules.
  440.         if ($sm_notAlias=='tr_TR'setlocale(LC_CTYPE,'C');
  441.  
  442.         $squirrelmail_language $sm_notAlias;
  443.         if ($squirrelmail_language == 'ja_JP'{
  444.             header ('Content-Type: text/html; charset=EUC-JP');
  445.             if (!function_exists('mb_internal_encoding')) {
  446.  
  447.                 // don't display mbstring warning when user isn't logged
  448.                 // in because the user may not be using SM for Japanese;
  449.                 // also don't display on webmail page so user has the
  450.                 // chance to go back and revert their language setting
  451.                 // until admin can get their act together
  452.                 if (sqGetGlobalVar('user_is_logged_in'$user_is_logged_inSQ_SESSION)
  453.                  && $user_is_logged_in && PAGE_NAME != 'webmail'{
  454.                     echo _("You need to have PHP installed with the multibyte string function enabled (using configure option --enable-mbstring).");
  455.                     // Revert to English link has to be added.
  456.                     // stop further execution in order not to get php errors on mb_internal_encoding().
  457.                 }
  458.                 return;
  459.             }
  460.             if (function_exists('mb_language')) {
  461.                 mb_language('Japanese');
  462.             }
  463.             mb_internal_encoding('EUC-JP');
  464.             mb_http_output('pass');
  465.         elseif ($squirrelmail_language == 'en_US'{
  466.             header'Content-Type: text/html; charset=' $default_charset );
  467.         else {
  468.             header'Content-Type: text/html; charset=' $languages[$sm_notAlias]['CHARSET');
  469.         }
  470.         /**
  471.          * mbstring.func_overload fix (#929644).
  472.          *
  473.          * php mbstring extension can replace standard string functions with their multibyte
  474.          * equivalents. See http://php.net/ref.mbstring#mbstring.overload. This feature
  475.          * was added in php v.4.2.0
  476.          *
  477.          * Some SquirrelMail functions work with 8bit strings in bytes. If interface is forced
  478.          * to use mbstring functions and mbstring internal encoding is set to multibyte charset,
  479.          * interface can't trust regular string functions. Due to mbstring overloading design
  480.          * limits php scripts can't control this setting.
  481.          *
  482.          * This hack should fix some issues related to 8bit strings in passwords. Correct fix is
  483.          * to disable mbstring overloading. Japanese translation uses different internal encoding.
  484.          */
  485.         if ($squirrelmail_language != 'ja_JP' &&
  486.             function_exists('mb_internal_encoding'&&
  487.             check_php_version(4,2,0&&
  488.             (int)ini_get('mbstring.func_overload')!=0{
  489.             mb_internal_encoding('pass');
  490.         }
  491.     }
  492. }
  493.  
  494. /**
  495.  * Sets default_charset variable according to the one that is used by user's
  496.  * translations.
  497.  *
  498.  * Function changes global $default_charset variable in order to be sure, that
  499.  * it contains charset used by user's translation. Sanity of
  500.  * $squirrelmail_language and $default_charset combination provided in the
  501.  * SquirrelMail configuration is also tested.
  502.  *
  503.  * There can be a $default_charset setting in the
  504.  * config.php file, but the user may have a different language
  505.  * selected for a user interface. This function checks the
  506.  * language selected by the user and tags the outgoing messages
  507.  * with the appropriate charset corresponding to the language
  508.  * selection. This is "more right" (tm), than just stamping the
  509.  * message blindly with the system-wide $default_charset.
  510.  */
  511. function set_my_charset(){
  512.     global $data_dir$username$default_charset$languages$squirrelmail_language;
  513.  
  514.     $my_language getPref($data_dir$username'language');
  515.     if (!$my_language{
  516.         $my_language $squirrelmail_language ;
  517.     }
  518.     // Catch removed translation
  519.     if (!isset($languages[$my_language])) {
  520.         $my_language="en_US";
  521.     }
  522.     while (isset($languages[$my_language]['ALIAS'])) {
  523.         $my_language $languages[$my_language]['ALIAS'];
  524.     }
  525.     $my_charset $languages[$my_language]['CHARSET'];
  526.     if ($my_language!='en_US'{
  527.         $default_charset $my_charset;
  528.     }
  529. }
  530.  
  531. /**
  532.  * Function informs if it is safe to convert given charset to the one that is used by user.
  533.  *
  534.  * It is safe to use conversion only if user uses utf-8 encoding and when
  535.  * converted charset is similar to the one that is used by user.
  536.  *
  537.  * @param string $input_charset Charset of text that needs to be converted
  538.  * @return bool is it possible to convert to user's charset
  539.  */
  540. function is_conversion_safe($input_charset{
  541.     global $languages$sm_notAlias$default_charset$lossy_encoding;
  542.  
  543.     if (isset($lossy_encoding&& $lossy_encoding )
  544.         return true;
  545.  
  546.     // convert to lower case
  547.     $input_charset strtolower($input_charset);
  548.  
  549.     // Is user's locale Unicode based ?
  550.     if $default_charset == "utf-8" {
  551.         return true;
  552.     }
  553.  
  554.     // Charsets that are similar
  555.     switch ($default_charset{
  556.     case "windows-1251":
  557.         if $input_charset == "iso-8859-5" ||
  558.                 $input_charset == "koi8-r" ||
  559.                 $input_charset == "koi8-u" {
  560.             return true;
  561.         else {
  562.             return false;
  563.         }
  564.     case "windows-1257":
  565.         if $input_charset == "iso-8859-13" ||
  566.              $input_charset == "iso-8859-4" {
  567.             return true;
  568.         else {
  569.             return false;
  570.         }
  571.     case "iso-8859-4":
  572.         if $input_charset == "iso-8859-13" ||
  573.              $input_charset == "windows-1257" {
  574.             return true;
  575.         else {
  576.             return false;
  577.         }
  578.     case "iso-8859-5":
  579.         if $input_charset == "windows-1251" ||
  580.              $input_charset == "koi8-r" ||
  581.              $input_charset == "koi8-u" {
  582.             return true;
  583.         else {
  584.             return false;
  585.         }
  586.     case "iso-8859-13":
  587.         if $input_charset == "iso-8859-4" ||
  588.              $input_charset == "windows-1257" {
  589.             return true;
  590.         else {
  591.             return false;
  592.         }
  593.     case "koi8-r":
  594.         if $input_charset == "windows-1251" ||
  595.              $input_charset == "iso-8859-5" ||
  596.              $input_charset == "koi8-u" {
  597.             return true;
  598.         else {
  599.             return false;
  600.         }
  601.     case "koi8-u":
  602.         if $input_charset == "windows-1251" ||
  603.              $input_charset == "iso-8859-5" ||
  604.              $input_charset == "koi8-r" {
  605.             return true;
  606.         else {
  607.             return false;
  608.         }
  609.     default:
  610.         return false;
  611.     }
  612. }
  613.  
  614. /* ---- extra code functions ----*/
  615. /**
  616.  * Japanese charset extra function
  617.  */
  618. function japanese_charset_xtra({
  619.     $ret func_get_arg(1);  /* default return value */
  620.     if (function_exists('mb_detect_encoding')) {
  621.         switch (func_get_arg(0)) /* action */
  622.         case 'decode':
  623.             $detect_encoding @mb_detect_encoding($ret);
  624.             if ($detect_encoding == 'JIS' ||
  625.                 $detect_encoding == 'EUC-JP' ||
  626.                 $detect_encoding == 'SJIS' ||
  627.                 $detect_encoding == 'UTF-8'{
  628.  
  629.                 $ret mb_convert_kana(mb_convert_encoding($ret'EUC-JP''AUTO')"KV");
  630.             }
  631.             break;
  632.         case 'encode':
  633.             $detect_encoding @mb_detect_encoding($ret);
  634.             if ($detect_encoding == 'JIS' ||
  635.                 $detect_encoding == 'EUC-JP' ||
  636.                 $detect_encoding == 'SJIS' ||
  637.                 $detect_encoding == 'UTF-8'{
  638.  
  639.                 $ret mb_convert_encoding(mb_convert_kana($ret"KV")'JIS''AUTO');
  640.             }
  641.             break;
  642.         case 'strimwidth':
  643.             $width func_get_arg(2);
  644.             $ret mb_strimwidth($ret0$width'...');
  645.             break;
  646.         case 'encodeheader':
  647.             /**
  648.              * First argument ($ret) contains header string.
  649.              * SquirrelMail ja_JP translation uses euc-jp as internal encoding.
  650.              * euc-jp stores Japanese letters in 0xA1-0xFE block (source:
  651.              * JIS X 0208 unicode.org mapping. see euc_jp.php in extra decoding
  652.              * library). Standard SquirrelMail 8bit test should detect if text
  653.              * is in euc or in ascii.
  654.              */
  655.             if (sq_is8bit($ret)) {
  656.                 /**
  657.                  * Minimize dependency on mb_mime_encodeheader(). PHP 4.4.1 bug
  658.                  * and maybe other bugs.
  659.                  *
  660.                  * Convert text from euc-jp (internal encoding) to iso-2022-jp
  661.                  * (commonly used Japanese encoding) with mbstring functions.
  662.                  *
  663.                  * Use SquirrelMail internal B encoding function. 'encodeheader'
  664.                  * XTRA_CODE is executed in encodeHeader() function, so
  665.                  * functions/mime.php (encodeHeaderBase64) and functions/strings.php
  666.                  * (sq_is8bit) are already loaded.
  667.                  */
  668.                 $ret encodeHeaderBase64(mb_convert_encoding($ret,'ISO-2022-JP','EUC-JP'),
  669.                                           'iso-2022-jp');
  670.             }
  671.             /**
  672.              * if text is in ascii, we leave it unchanged. If some ASCII
  673.              * chars must be encoded, add code here in else statement.
  674.              */
  675.             break;
  676.         case 'decodeheader':
  677.             $ret str_replace("\t"""$ret);
  678.             if (preg_match('/=\?([^?]+)\?(q|b)\?([^?]+)\?=/i'$ret))
  679.                 $ret @mb_decode_mimeheader($ret);
  680.             $ret @mb_convert_encoding($ret'EUC-JP''AUTO');
  681.             break;
  682.         case 'downloadfilename':
  683.             $useragent func_get_arg(2);
  684.             if (strstr($useragent'Windows'!== false ||
  685.                 strstr($useragent'Mac_'!== false{
  686.                 $ret mb_convert_encoding($ret'SJIS''AUTO');
  687.             else {
  688.                 $ret mb_convert_encoding($ret'EUC-JP''AUTO');
  689. }
  690.             break;
  691.         case 'wordwrap':
  692.             $no_begin "\x21\x25\x29\x2c\x2e\x3a\x3b\x3f\x5d\x7d\xa1\xf1\xa1\xeb\xa1" .
  693.                 "\xc7\xa1\xc9\xa2\xf3\xa1\xec\xa1\xed\xa1\xee\xa1\xa2\xa1\xa3\xa1\xb9" .
  694.                 "\xa1\xd3\xa1\xd5\xa1\xd7\xa1\xd9\xa1\xdb\xa1\xcd\xa4\xa1\xa4\xa3\xa4" .
  695.                 "\xa5\xa4\xa7\xa4\xa9\xa4\xc3\xa4\xe3\xa4\xe5\xa4\xe7\xa4\xee\xa1\xab" .
  696.                 "\xa1\xac\xa1\xb5\xa1\xb6\xa5\xa1\xa5\xa3\xa5\xa5\xa5\xa7\xa5\xa9\xa5" .
  697.                 "\xc3\xa5\xe3\xa5\xe5\xa5\xe7\xa5\xee\xa5\xf5\xa5\xf6\xa1\xa6\xa1\xbc" .
  698.                 "\xa1\xb3\xa1\xb4\xa1\xaa\xa1\xf3\xa1\xcb\xa1\xa4\xa1\xa5\xa1\xa7\xa1" .
  699.                 "\xa8\xa1\xa9\xa1\xcf\xa1\xd1";
  700.             $no_end "\x5c\x24\x28\x5b\x7b\xa1\xf2\x5c\xa1\xc6\xa1\xc8\xa1\xd2\xa1" .
  701.                 "\xd4\xa1\xd6\xa1\xd8\xa1\xda\xa1\xcc\xa1\xf0\xa1\xca\xa1\xce\xa1\xd0\xa1\xef";
  702.             $wrap func_get_arg(2);
  703.  
  704.             if (strlen($ret>= $wrap &&
  705.                 substr($ret01!= '>' &&
  706.                 strpos($ret'http://'=== FALSE &&
  707.                 strpos($ret'https://'=== FALSE &&
  708.                 strpos($ret'ftp://'=== FALSE{
  709.  
  710.                 $ret mb_convert_kana($ret"KV");
  711.  
  712.                 $line_new '';
  713.                 $ptr 0;
  714.  
  715.                 while ($ptr strlen($ret1{
  716.                     $l mb_strcut($ret$ptr$wrap);
  717.                     $ptr += strlen($l);
  718.                     $tmp $l;
  719.  
  720.                     $l mb_strcut($ret$ptr2);
  721.                     while (strlen($l!= && mb_strpos($no_begin$l!== FALSE {
  722.                         $tmp .= $l;
  723.                         $ptr += strlen($l);
  724.                         $l mb_strcut($ret$ptr1);
  725.                     }
  726.                     $line_new .= $tmp;
  727.                     if ($ptr strlen($ret1)
  728.                         $line_new .= "\n";
  729.                 }
  730.                 $ret $line_new;
  731.             }
  732.             break;
  733.         case 'utf7-imap_encode':
  734.             $ret mb_convert_encoding($ret'UTF7-IMAP''EUC-JP');
  735.             break;
  736.         case 'utf7-imap_decode':
  737.             $ret mb_convert_encoding($ret'EUC-JP''UTF7-IMAP');
  738.             break;
  739.         }
  740.     }
  741.     return $ret;
  742. }
  743.  
  744.  
  745. /*
  746.  * Korean charset extra function
  747.  * Hangul(Korean Character) Attached File Name Fix.
  748.  */
  749. function korean_charset_xtra({
  750.  
  751.     $ret func_get_arg(1);  /* default return value */
  752.     if (func_get_arg(0== 'downloadfilename'/* action */
  753.         $ret str_replace("\x0D\x0A"''$ret);  /* Hanmail's CR/LF Clear */
  754.         for ($i=0;$i<strlen($ret);$i++{
  755.             if ($ret[$i>= "\xA1" && $ret[$i<= "\xFE"{   /* 0xA1 - 0XFE are Valid */
  756.                 $i++;
  757.                 continue;
  758.             else if (($ret[$i>= 'a' && $ret[$i<= 'z'|| /* From Original ereg_replace in download.php */
  759.                        ($ret[$i>= 'A' && $ret[$i<= 'Z'||
  760.                        ($ret[$i== '.'|| ($ret[$i== '-')) {
  761.                 continue;
  762.             else {
  763.                 $ret[$i'_';
  764.             }
  765.         }
  766.  
  767.     }
  768.  
  769.     return $ret;
  770. }
  771.  
  772. /* ------------------------------ main --------------------------- */
  773.  
  774. global $squirrelmail_language$languages$use_gettext;
  775.  
  776. if (sqgetGlobalVar('squirrelmail_language',$squirrelmail_language,SQ_COOKIE)) {
  777.     $squirrelmail_language '';
  778. }
  779.  
  780. /**
  781.  * This array specifies the available translations.
  782.  *
  783.  * Structure of array:
  784.  * $languages['language']['variable'] = 'value'
  785.  *
  786.  * Possible 'variable' names:
  787.  *  NAME      - Translation name in English
  788.  *  CHARSET   - Encoding used by translation
  789.  *  ALIAS     - used when 'language' is only short name and 'value' should provide long language name
  790.  *  ALTNAME   - Native translation name. Any 8bit symbols must be html encoded.
  791.  *  LOCALE    - Full locale name (in xx_XX.charset format). It can use array with more than one locale name since 1.4.5 and 1.5.1
  792.  *  DIR       - Text direction. Used to define Right-to-Left languages. Possible values 'rtl' or 'ltr'. If undefined - defaults to 'ltr'
  793.  *  XTRA_CODE - translation uses special functions. See http://squirrelmail.org/docs/devel/devel-3.html
  794.  *
  795.  * Each 'language' definition requires NAME+CHARSET or ALIAS variables.
  796.  *
  797.  * @name $languages
  798.  * @global array $languages 
  799.  */
  800. $languages['bg_BG']['NAME']    'Bulgarian';
  801. $languages['bg_BG']['CHARSET''windows-1251';
  802. $languages['bg_BG']['LOCALE']  'bg_BG.CP1251';
  803. $languages['bg']['ALIAS']      'bg_BG';
  804.  
  805. $languages['bn_BD']['NAME']    'Bengali (Bangladesh)';
  806. //$languages['bn_BD']['ALTNAME'] = 'Bangla';
  807. $languages['bn_BD']['ALTNAME''&#x09AC;&#x09BE;&#x0982;&#x09B2;&#x09BE;';
  808. $languages['bn_BD']['CHARSET''utf-8';
  809. $languages['bn_BD']['LOCALE']  array('bn_BD.UTF-8''bn_BD.UTF8''bn_BD''bn.UTF-8''bn.UTF8''bn');
  810. $languages['bn']['ALIAS''bn_BD';
  811.  
  812. $languages['bn_IN']['NAME']    'Bengali (India)';
  813. $languages['bn_IN']['CHARSET''utf-8';
  814. $languages['bn_IN']['LOCALE']  array('bn_IN.UTF-8''bn_IN.UTF8');
  815.  
  816. $languages['ca_ES']['NAME']    'Catalan';
  817. $languages['ca_ES']['CHARSET''iso-8859-1';
  818. $languages['ca_ES']['LOCALE']  array('ca_ES.ISO8859-1','ca_ES.ISO-8859-1','ca_ES');
  819. $languages['ca']['ALIAS']      'ca_ES';
  820.  
  821. $languages['cs_CZ']['NAME']    'Czech';
  822. $languages['cs_CZ']['ALTNAME''&#268;e&scaron;tina';
  823. $languages['cs_CZ']['CHARSET''utf-8';
  824. $languages['cs_CZ']['LOCALE']  array('cs_CZ.UTF-8''cs_CZ.UTF8''cs_CZ');
  825. $languages['cs']['ALIAS']      'cs_CZ';
  826.  
  827. $languages['cy_GB']['NAME']    'Welsh';
  828. $languages['cy_GB']['CHARSET''iso-8859-1';
  829. $languages['cy_GB']['LOCALE']  array('cy_GB.ISO8859-1','cy_GB.ISO-8859-1','cy_GB');
  830. $languages['cy']['ALIAS''cy_GB';
  831.  
  832. $languages['da_DK']['NAME']    'Danish';
  833. $languages['da_DK']['CHARSET''iso-8859-1';
  834. $languages['da_DK']['LOCALE']  array('da_DK.ISO8859-1','da_DK.ISO-8859-1','da_DK');
  835. $languages['da']['ALIAS']      'da_DK';
  836.  
  837. $languages['de_DE']['NAME']    'German';
  838. $languages['de_DE']['ALTNAME''Deutsch';
  839. $languages['de_DE']['CHARSET''iso-8859-1';
  840. $languages['de_DE']['LOCALE']  array('de_DE.ISO8859-1','de_DE.ISO-8859-1','de_DE');
  841. $languages['de']['ALIAS']      'de_DE';
  842.  
  843. $languages['el_GR']['NAME']    'Greek';
  844. $languages['el_GR']['CHARSET''iso-8859-7';
  845. $languages['el_GR']['LOCALE']  array('el_GR.ISO8859-7','el_GR.ISO-8859-7','el_GR');
  846. $languages['el']['ALIAS']      'el_GR';
  847.  
  848. /* This translation is disabled because it contains less than 50%
  849.  * translated strings. In those cases where British and American English are
  850.  * spelled the same, the translation should indicate that by copy the "msgid" to
  851.  * the "msgstr" instead of leaving the "msgstr" blank.
  852. $languages['en_GB']['NAME']    = 'British';
  853. $languages['en_GB']['CHARSET'] = 'iso-8859-15';
  854. $languages['en_GB']['LOCALE']  = array('en_GB.ISO8859-15','en_GB.ISO-8859-15','en_GB');
  855. */
  856.  
  857. $languages['en_US']['NAME']    'English';
  858. $languages['en_US']['CHARSET''iso-8859-1';
  859. $languages['en_US']['LOCALE']  'en_US.ISO8859-1';
  860. $languages['en']['ALIAS']      'en_US';
  861.  
  862. $languages['es_ES']['NAME']    'Spanish';
  863. $languages['es_ES']['CHARSET''iso-8859-1';
  864. $languages['es_ES']['LOCALE']  array('es_ES.ISO8859-1','es_ES.ISO-8859-1','es_ES');
  865. $languages['es']['ALIAS']      'es_ES';
  866.  
  867. $languages['et_EE']['NAME']    'Estonian';
  868. $languages['et_EE']['CHARSET''iso-8859-15';
  869. $languages['et_EE']['LOCALE']  array('et_EE.ISO8859-15','et_EE.ISO-8859-15','et_EE');
  870. $languages['et']['ALIAS']      'et_EE';
  871.  
  872. $languages['eu_ES']['NAME']    'Basque';
  873. $languages['eu_ES']['CHARSET''iso-8859-1';
  874. $languages['eu_ES']['LOCALE']  array('eu_ES.ISO8859-1','eu_ES.ISO-8859-1','eu_ES');
  875. $languages['eu']['ALIAS']      'eu_ES';
  876.  
  877. $languages['fi_FI']['NAME']    'Finnish';
  878. $languages['fi_FI']['CHARSET''iso-8859-1';
  879. $languages['fi_FI']['LOCALE']  array('fi_FI.ISO8859-1','fi_FI.ISO-8859-1','fi_FI');
  880. $languages['fi']['ALIAS']      'fi_FI';
  881.  
  882. $languages['fo_FO']['NAME']    'Faroese';
  883. $languages['fo_FO']['CHARSET''iso-8859-1';
  884. $languages['fo_FO']['LOCALE']  array('fo_FO.ISO8859-1','fo_FO.ISO-8859-1','fo_FO');
  885. $languages['fo']['ALIAS']      'fo_FO';
  886.  
  887. $languages['fr_FR']['NAME']    'French';
  888. $languages['fr_FR']['CHARSET''iso-8859-1';
  889. $languages['fr_FR']['LOCALE']  array('fr_FR.ISO8859-1','fr_FR.ISO-8859-1','fr_FR');
  890. $languages['fr']['ALIAS']      'fr_FR';
  891.  
  892. $languages['fy']['NAME']       'Frisian';
  893. $languages['fy']['CHARSET']    'utf-8';
  894. $languages['fy']['LOCALE']     array('fy.UTF-8''fy.UTF8''fy_NL.UTF-8''fy_NL.UTF8');
  895.  
  896. $languages['hr_HR']['NAME']    'Croatian';
  897. $languages['hr_HR']['CHARSET''iso-8859-2';
  898. $languages['hr_HR']['LOCALE']  array('hr_HR.ISO8859-2','hr_HR.ISO-8859-2','hr_HR');
  899. $languages['hr']['ALIAS']      'hr_HR';
  900.  
  901. $languages['hu_HU']['NAME']    'Hungarian';
  902. $languages['hu_HU']['ALTNAME''Magyar';
  903. $languages['hu_HU']['CHARSET''utf-8';
  904. $languages['hu_HU']['LOCALE']  array('hu_HU.UTF-8''hu_HU.UTF8''hu_HU');
  905. $languages['hu']['ALIAS']      'hu_HU';
  906.  
  907. $languages['id_ID']['NAME']    'Bahasa Indonesia';
  908. $languages['id_ID']['CHARSET''iso-8859-1';
  909. $languages['id_ID']['LOCALE']  array('id_ID.ISO8859-1','id_ID.ISO-8859-1','id_ID');
  910. $languages['id']['ALIAS']      'id_ID';
  911.  
  912. $languages['is_IS']['NAME']    'Icelandic';
  913. $languages['is_IS']['CHARSET''iso-8859-1';
  914. $languages['is_IS']['LOCALE']  array('is_IS.ISO8859-1','is_IS.ISO-8859-1','is_IS');
  915. $languages['is']['ALIAS']      'is_IS';
  916.  
  917. $languages['it_IT']['NAME']    'Italian';
  918. $languages['it_IT']['ALTNAME''Italiano';
  919. $languages['it_IT']['CHARSET''utf-8';
  920. $languages['it_IT']['LOCALE']  array('it_IT.UTF-8','it_IT-UTF8','it_IT');
  921. $languages['it']['ALIAS']      'it_IT';
  922.  
  923. $languages['ja_JP']['NAME']    'Japanese';
  924. $languages['ja_JP']['CHARSET''iso-2022-jp';
  925. $languages['ja_JP']['XTRA_CODE''japanese_charset_xtra';
  926. $languages['ja']['ALIAS']      'ja_JP';
  927.  
  928. $languages['ka']['NAME']       'Georgian';
  929. $languages['ka']['CHARSET']    'utf-8';
  930. $languages['ka']['LOCALE']     array('ka_GE.UTF-8''ka_GE.UTF8''ka_GE''ka');
  931. $languages['ka_GE']['ALIAS']   'ka';
  932.  
  933. $languages['km']['NAME']       'Khmer';
  934. $languages['km']['ALTNAME']    '&#6017;&#6098;&#6040;&#6082;&#6042;';
  935. $languages['km']['CHARSET']    'utf-8';
  936. $languages['km']['LOCALE']     array('km.UTF-8''km.UTF8''km_KH.UTF-8''km_KH.UTF8''km''km_KH');
  937. $languages['km_KH']['ALIAS']   'km';
  938.  
  939. $languages['ko_KR']['NAME']    'Korean';
  940. $languages['ko_KR']['CHARSET''euc-KR';
  941. // Function does not provide all needed options
  942. // $languages['ko_KR']['XTRA_CODE'] = 'korean_charset_xtra';
  943. $languages['ko']['ALIAS']      'ko_KR';
  944.  
  945. $languages['lv_LV']['NAME']    'Latvian';
  946. $languages['lv_LV']['ALTNAME''Latvi&#371;';
  947. $languages['lv_LV']['CHARSET''utf-8';
  948. $languages['lv_LV']['LOCALE'array('lv_LV.UTF-8''lv_LV.UTF8');
  949. $languages['lv']['ALIAS''lv_LV';
  950.  
  951. $languages['lt_LT']['NAME']    'Lithuanian';
  952. $languages['lt_LT']['CHARSET''utf-8';
  953. $languages['lt_LT']['LOCALE']  array('lt_LT.UTF-8''lt_LT.UTF8');
  954. $languages['lt']['ALIAS']      'lt_LT';
  955.  
  956. $languages['mk']['NAME']       'Macedonian';
  957. $languages['mk']['CHARSET']    'utf-8';
  958. $languages['mk']['LOCALE']     array('mk.UTF-8''mk.UTF8''mk_MK.UTF-8''mk_MK.UTF8');
  959.  
  960. $languages['ms_MY']['NAME']    'Bahasa Melayu';
  961. $languages['ms_MY']['CHARSET''iso-8859-1';
  962. $languages['ms_MY']['LOCALE']  array('ms_MY.ISO8859-1','ms_MY.ISO-8859-1','ms_MY');
  963. $languages['my']['ALIAS']      'ms_MY';
  964.  
  965. $languages['nl_NL']['NAME']    'Dutch';
  966. $languages['nl_NL']['CHARSET''iso-8859-1';
  967. $languages['nl_NL']['LOCALE']  array('nl_NL.ISO8859-1','nl_NL.ISO-8859-1','nl_NL');
  968. $languages['nl']['ALIAS']      'nl_NL';
  969.  
  970. $languages['nb_NO']['NAME']    'Norwegian (Bokm&aring;l)';
  971. $languages['nb_NO']['CHARSET''utf-8';
  972. $languages['nb_NO']['LOCALE']  array('nb_NO.UTF-8''nb_NO.UTF8''nb_NO');
  973. $languages['nb']['ALIAS']      'nb_NO';
  974.  
  975. $languages['nn_NO']['NAME']    'Norwegian (Nynorsk)';
  976. $languages['nn_NO']['CHARSET''iso-8859-1';
  977. $languages['nn_NO']['LOCALE']  array('nn_NO.ISO8859-1','nn_NO.ISO-8859-1','nn_NO');
  978.  
  979. $languages['pl_PL']['NAME']    'Polish';
  980. $languages['pl_PL']['CHARSET''iso-8859-2';
  981. $languages['pl_PL']['LOCALE']  array('pl_PL.ISO8859-2','pl_PL.ISO-8859-2','pl_PL');
  982. $languages['pl']['ALIAS']      'pl_PL';
  983.  
  984. $languages['pt_PT']['NAME']    'Portuguese (Portugal)';
  985. $languages['pt_PT']['CHARSET''iso-8859-1';
  986. $languages['pt_PT']['LOCALE']  array('pt_PT.ISO8859-1','pt_PT.ISO-8859-1','pt_PT');
  987. $languages['pt']['ALIAS']      'pt_PT';
  988.  
  989. $languages['pt_BR']['NAME']    'Portuguese (Brazil)';
  990. $languages['pt_BR']['CHARSET''iso-8859-1';
  991. $languages['pt_BR']['LOCALE']  array('pt_BR.ISO8859-1','pt_BR.ISO-8859-1','pt_BR');
  992.  
  993. $languages['ro_RO']['NAME']    'Romanian';
  994. $languages['ro_RO']['CHARSET''utf-8';
  995. $languages['ro_RO']['LOCALE']  array('ro_RO.UTF-8''ro_RO.UTF8''ro_RO');
  996. $languages['ro']['ALIAS']      'ro_RO';
  997.  
  998. $languages['ru_RU']['NAME']    'Russian';
  999. $languages['ru_RU']['CHARSET''utf-8';
  1000. $languages['ru_RU']['LOCALE']  array('ru_RU.UTF-8''ru_RU.UTF8');
  1001. $languages['ru']['ALIAS']      'ru_RU';
  1002.  
  1003. /* This translation is disabled because it is supposedly
  1004.  * Russian slang and is in need of updating.
  1005. $languages['ru_UA']['NAME']    = 'Russian (Ukrainian)';
  1006. $languages['ru_UA']['CHARSET'] = 'koi8-r';
  1007. $languages['ru_UA']['LOCALE']  = 'ru_UA.KOI8-R';
  1008. */
  1009.  
  1010. /* This translation is disabled because it contains less than 50%
  1011.  * translated strings
  1012. $languages['si_LK']['NAME']    = 'Sinhala';
  1013. $languages['si_LK']['ALTNAME'] = '&#3523;&#3538;&#3458;&#3524;&#3517;';
  1014. $languages['si_LK']['CHARSET'] = 'utf-8';
  1015. $languages['si_LK']['LOCALE']  = array('si_LK.UTF-8', 'si_LK.UTF8');
  1016. $languages['si']['ALIAS'] = 'si_LK';
  1017. */
  1018.  
  1019. $languages['sk_SK']['NAME']    'Slovak';
  1020. $languages['sk_SK']['CHARSET''utf-8';
  1021. $languages['sk_SK']['LOCALE']  array('sk_SK.UTF-8''sk_SK.UTF8''sk_SK');
  1022. $languages['sk']['ALIAS']      'sk_SK';
  1023.  
  1024. $languages['sl_SI']['NAME']    'Slovenian';
  1025. $languages['sl_SI']['CHARSET''iso-8859-2';
  1026. $languages['sl_SI']['LOCALE']  array('sl_SI.ISO8859-2','sl_SI.ISO-8859-2','sl_SI');
  1027. $languages['sl']['ALIAS']      'sl_SI';
  1028.  
  1029. $languages['sr_YU']['NAME']    'Serbian';
  1030. $languages['sr_YU']['CHARSET''iso-8859-2';
  1031. $languages['sr_YU']['LOCALE']  array('sr_YU.ISO8859-2','sr_YU.ISO-8859-2','sr_YU');
  1032. $languages['sr']['ALIAS']      'sr_YU';
  1033.  
  1034. $languages['sv_SE']['NAME']    'Swedish';
  1035. $languages['sv_SE']['CHARSET''utf-8';
  1036. $languages['sv_SE']['LOCALE']  array('sv_SE.UTF-8''sv_SE.UTF8''sv_SE');
  1037. $languages['sv']['ALIAS']      'sv_SE';
  1038.  
  1039. $languages['ta_LK']['NAME']    'Tamil';
  1040. $languages['ta_LK']['ALTNAME''&#2980;&#2990;&#3007;&#2996;&#3021;';
  1041. $languages['ta_LK']['CHARSET''utf-8';
  1042. $languages['ta_LK']['LOCALE']  array('ta_LK.UTF-8''ta_LK.UTF8''ta_LK''ta.UTF-8''ta.UTF8''ta');
  1043. $languages['ta']['ALIAS''ta_LK';
  1044.  
  1045. /* This translation is disabled because it contains less than 50%
  1046.  * translated strings
  1047. $languages['th_TH']['NAME']    = 'Thai';
  1048. $languages['th_TH']['CHARSET'] = 'tis-620';
  1049. $languages['th_TH']['LOCALE']  = 'th_TH.TIS-620';
  1050. $languages['th']['ALIAS'] = 'th_TH';
  1051. */
  1052.  
  1053. /* This translation is disabled because it contains less than 50%
  1054.  * translated strings
  1055. $languages['tl_PH']['NAME']    = 'Tagalog';
  1056. $languages['tl_PH']['CHARSET'] = 'iso-8859-1';
  1057. $languages['tl_PH']['LOCALE']  = array('tl_PH.ISO8859-1','tl_PH.ISO-8859-1','tl_PH');
  1058. $languages['tl']['ALIAS'] = 'tl_PH';
  1059. */
  1060.  
  1061. $languages['tr_TR']['NAME']    'Turkish';
  1062. $languages['tr_TR']['CHARSET''iso-8859-9';
  1063. $languages['tr_TR']['LOCALE']  array('tr_TR.ISO8859-9','tr_TR.ISO-8859-9','tr_TR');
  1064. $languages['tr']['ALIAS']      'tr_TR';
  1065.  
  1066. $languages['zh_TW']['NAME']    'Chinese Trad';
  1067. $languages['zh_TW']['CHARSET''utf-8';
  1068. $languages['zh_TW']['LOCALE']  array('zh_TW.UTF-8''zh_TW.UTF8');
  1069. $languages['tw']['ALIAS']      'zh_TW';
  1070.  
  1071. $languages['zh_CN']['NAME']    'Chinese Simp';
  1072. $languages['zh_CN']['CHARSET''gb2312';
  1073. $languages['zh_CN']['LOCALE']  'zh_CN.GB2312';
  1074. $languages['cn']['ALIAS']      'zh_CN';
  1075.  
  1076. $languages['uk_UA']['NAME']    'Ukrainian';
  1077. $languages['uk_UA']['CHARSET''utf-8';
  1078. $languages['uk_UA']['LOCALE']  array('uk_UA.UTF-8''uk_UA.UTF8''uk_UA''uk');
  1079. $languages['uk']['ALIAS''uk_UA';
  1080.  
  1081. $languages['vi_VN']['NAME']    'Vietnamese';
  1082. $languages['vi_VN']['CHARSET''utf-8';
  1083. $languages['vi']['ALIAS''vi_VN';
  1084.  
  1085. // Right to left languages
  1086.  
  1087. $languages['ar']['NAME']    'Arabic';
  1088. $languages['ar']['CHARSET''windows-1256';
  1089. $languages['ar']['DIR']     'rtl';
  1090.  
  1091. $languages['fa_IR']['NAME']    'Persian';
  1092. $languages['fa_IR']['CHARSET''utf-8';
  1093. $languages['fa_IR']['DIR']     'rtl';
  1094. $languages['fa_IR']['LOCALE']  array('fa_IR.UTF-8''fa_IR.UTF8');
  1095. $languages['fa']['ALIAS']      'fa_IR';
  1096.  
  1097. $languages['he_IL']['NAME']    'Hebrew';
  1098. $languages['he_IL']['CHARSET''windows-1255';
  1099. $languages['he_IL']['DIR']     'rtl';
  1100. $languages['he']['ALIAS']      'he_IL';
  1101.  
  1102. $languages['ug']['NAME']    'Uighur';
  1103. $languages['ug']['CHARSET''utf-8';
  1104. $languages['ug']['DIR']     'rtl';
  1105.  
  1106. /* Detect whether gettext is installed. */
  1107. $gettext_flags 0;
  1108. if (function_exists('_')) {
  1109.     $gettext_flags += 1;
  1110. }
  1111. if (function_exists('bindtextdomain')) {
  1112.     $gettext_flags += 2;
  1113. }
  1114. if (function_exists('textdomain')) {
  1115.     $gettext_flags += 4;
  1116. }
  1117.  
  1118. /* If gettext is fully loaded, cool */
  1119. if ($gettext_flags == 7{
  1120.     $use_gettext true;
  1121. }
  1122. /* If we can fake gettext, try that */
  1123. elseif ($gettext_flags == 0{
  1124.     $use_gettext true;
  1125.     include_once(SM_PATH 'functions/gettext.php');
  1126. else {
  1127.     /* Uh-ho.  A weird install */
  1128.     if ($gettext_flags 1{
  1129.       /**
  1130.        * Function is used as replacement in broken installs
  1131.        * @ignore
  1132.        */
  1133.         function _($str{
  1134.             return $str;
  1135.         }
  1136.     }
  1137.     if ($gettext_flags 2{
  1138.       /**
  1139.        * Function is used as replacement in broken installs
  1140.        * @ignore
  1141.        */
  1142.         function bindtextdomain({
  1143.             return;
  1144.         }
  1145.     }
  1146.     if ($gettext_flags 4{
  1147.       /**
  1148.        * Function is used as replacemet in broken installs
  1149.        * @ignore
  1150.        */
  1151.         function textdomain({
  1152.             return;
  1153.         }
  1154.     }
  1155. }

Documentation generated on Mon, 13 Jan 2020 04:24:42 +0100 by phpDocumentor 1.4.3