changing SM internal gettext functions to use php-gettext classes. Fix for
authortokul <tokul@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Mon, 4 Oct 2004 14:14:48 +0000 (14:14 +0000)
committertokul <tokul@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Mon, 4 Oct 2004 14:14:48 +0000 (14:14 +0000)
bug. 1019007.

git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@8138 7612ce4b-ef26-0410-bec9-ea0150e637f0

functions/gettext.php
functions/i18n.php
functions/ngettext.php [new file with mode: 0644]

index f11f13f426b0e3a90da56715b6fd2c8404e9d570..4295a68bcd48aca48ebc252118bbddfd40dd8b9e 100644 (file)
@@ -2,16 +2,11 @@
 /**
  * SquirrelMail internal gettext functions
  *
- * Copyright (c) 1999-2004 The SquirrelMail Project Team
- * Licensed under the GNU GPL. For full terms see the file COPYING.
- *
- * Alternate to the system's built-in gettext.
- * relies on .po files (can't read .mo easily).
- * Uses the session for caching (speed increase)
- * Possible use in other PHP scripts?  The only SM-specific thing is
- *   $sm_language, I think
- *
+ * Uses php-gettext classes
+ * @copyright (c) 1999-2004 The SquirrelMail Project Team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public Licens
  * @link http://www.php.net/gettext Original php gettext manual
+ * @link http://savannah.nongnu.org/projects/php-gettext php-gettext classes
  * @version $Id$
  * @package squirrelmail
  * @subpackage i18n
 /** Almost everything requires global.php... */
 require_once(SM_PATH . 'functions/global.php');
 
-global $gettext_php_domain, $gettext_php_dir, $gettext_php_loaded,
- $gettext_php_translateStrings, $gettext_php_loaded_language,
- $gettext_php_short_circuit;
-
-if (! isset($gettext_php_loaded)) {
-    $gettext_php_loaded = false;
-    sqsession_register($gettext_php_loaded, 'gettext_php_loaded');
-}
-if (! isset($gettext_php_domain)) {
-    $gettext_php_domain = '';
-    sqsession_register($gettext_php_domain, 'gettext_php_domain');
-}
-if (! isset($gettext_php_dir)) {
-    $gettext_php_dir = '';
-    sqsession_register($gettext_php_dir, 'gettext_php_dir');
-}
-if (! isset($gettext_php_translateStrings)) {
-    $gettext_php_translateStrings = array();
-    sqsession_register($gettext_php_translateStrings, 'gettext_php_translateStrings');
-}
-if (! isset($gettext_php_loaded_language)) {
-    $gettext_php_loaded_language = '';
-    sqsession_register($gettext_php_loaded_language, 'gettext_php_loaded_language');
-}
-if (! isset($gettext_php_short_circuit)) {
-    $gettext_php_short_circuit = false;
-    sqsession_register($gettext_php_short_circuit, 'gettext_php_short_circuit');
-}
-
-/**
- * Converts .po file into array and stores it in session.
- *
- * Used internally by _($str) function
- *
- * @internal function is used internally by functions/gettext.php code
- */
-function gettext_php_load_strings() {
-    global $squirrelmail_language, $gettext_php_translateStrings,
-        $gettext_php_domain, $gettext_php_dir, $gettext_php_loaded,
-        $gettext_php_loaded_language, $gettext_php_short_circuit;
-    
-    /*
-     * $squirrelmail_language gives 'en' for English, 'de' for German,
-     * etc.  I didn't wanna use getenv or similar, but you easily could
-     * change my code to do that. 
-     */
-    
-    $gettext_php_translateStrings = array();
-    
-    $gettext_php_short_circuit = false;  /* initialization */
-    
-    $filename = $gettext_php_dir;
-    if (substr($filename, -1) != '/')
-        $filename .= '/';
-    $filename .= $squirrelmail_language . '/LC_MESSAGES/' . 
-        $gettext_php_domain . '.po';
-    
-    $file = @fopen($filename, 'r');
-    if ($file == false) {
-        /* Uh-ho -- we can't load the file.  Just fake it.  :-)
-           This is also for English, which doesn't use translations */
-        $gettext_php_loaded = true;
-        $gettext_php_loaded_language = $squirrelmail_language;
-        /* Avoid fuzzy matching when we didn't load strings */
-        $gettext_php_short_circuit = true;  
-        return;
-    }
-    
-    $key = '';
-    $SkipRead = false;
-    while (! feof($file)) {
-        if (! $SkipRead) {
-            $line = trim(fgets($file, 4096));
-        } else {
-            $SkipRead = false;
-        }
-        
-        if (ereg('^msgid "(.*)"$', $line, $match)) {
-            if ($match[1] == '') {
-                /*
-                 * Potential multi-line
-                 * msgid ""
-                 * "string string "
-                 * "string string"
-                 */
-                $key = '';
-                $line = trim(fgets($file, 4096));
-                while (ereg('^[ ]*"(.*)"[ ]*$', $line, $match)) {
-                    $key .= $match[1];
-                    $line = trim(fgets($file, 4096));
-                }
-                $SkipRead = true;
-            } else {
-                /* msgid "string string" */
-                $key = $match[1];
-            }
-        } elseif (ereg('^msgstr "(.*)"$', $line, $match)) {
-            if ($match[1] == '') {
-                /*
-                 * Potential multi-line
-                 * msgstr ""
-                 * "string string "
-                 * "string string"
-                 */
-                $gettext_php_translateStrings[$key] = '';
-                $line = trim(fgets($file, 4096));
-                while (ereg('^[ ]*"(.*)"[ ]*$', $line, $match)) {
-                    $gettext_php_translateStrings[$key] .= $match[1];
-                    $line = trim(fgets($file, 4096));
-                }
-                $SkipRead = true;
-            } else {
-                /* msgstr "string string" */
-                $gettext_php_translateStrings[$key] = $match[1];
-            }
-            $gettext_php_translateStrings[$key] =
-                stripslashes($gettext_php_translateStrings[$key]);
-            /* If there is no translation, just use the untranslated string */
-            if ($gettext_php_translateStrings[$key] == '') {
-                $gettext_php_translateStrings[$key] = $key;
-            }
-            $key = '';
-        }
-    }
-    fclose($file);
-    
-    $gettext_php_loaded = true;
-    $gettext_php_loaded_language = $squirrelmail_language;
-}
+/** Load classes and other functions */
+include_once(SM_PATH . 'class/l10n.class.php');
+include_once(SM_PATH . 'functions/ngettext.php');
 
 /**
  * Alternative php gettext function (short form)
@@ -159,49 +28,9 @@ function gettext_php_load_strings() {
  * @return string translated string
  */
 function _($str) {
-    global $gettext_php_loaded, $gettext_php_translateStrings, 
-        $squirrelmail_language, $gettext_php_loaded_language,
-        $gettext_php_short_circuit;
-    
-    if (! $gettext_php_loaded || 
-        $gettext_php_loaded_language != $squirrelmail_language) {
-        gettext_php_load_strings();
-    }
-    
-    /* Try finding the exact string */
-    if (isset($gettext_php_translateStrings[$str])) {
-        return $gettext_php_translateStrings[$str];
-    }
-    
-    /* See if we should short-circuit */
-    if ($gettext_php_short_circuit) {
-        $gettext_php_translateStrings[$str] = $str;
-        return $str;
-    }
-    
-    /* Look for a string that is very close to the one we want
-       Very computationally expensive */
-    $oldPercent = 0;
-    $oldStr = '';
-    $newPercent = 0;
-    foreach ($gettext_php_translateStrings as $k => $v) {
-        similar_text($str, $k, $newPercent);
-        if ($newPercent > $oldPercent) {
-            $oldStr = $v;
-            $oldPercent = $newPercent;
-        }
-    }
-    /* Require 80% match or better
-       Adjust to suit your needs */
-    if ($oldPercent > 80) {
-        /* Remember this so we don't need to search again */
-        $gettext_php_translateStrings[$str] = $oldStr;
-        return $oldStr;
-    }
-    
-    /* Remember this so we don't need to search again */
-    $gettext_php_translateStrings[$str] = $str;
-    return $str;
+    global $l10n, $gettext_domain;
+    if ($l10n[$gettext_domain]->error==1) return $str;
+    return $l10n[$gettext_domain]->translate($str);
 }
 
 /**
@@ -210,22 +39,18 @@ function _($str) {
  * Sets path to directory containing domain translations
  *
  * @link http://www.php.net/function.bindtextdomain
- * @param string $name gettext domain name
+ * @param string $domain gettext domain name
  * @param string $dir directory that contains all translations
  * @return string path to translation directory
  */
-function bindtextdomain($name, $dir) {
-    global $gettext_php_domain, $gettext_php_dir, $gettext_php_loaded;
-    
-    if ($gettext_php_domain != $name) {
-        $gettext_php_domain = $name;
-        $gettext_php_loaded = false;
-    }
-    if ($gettext_php_dir != $dir) {
-        $gettext_php_dir = $dir;
-        $gettext_php_loaded = false;
-    }
-    
+function bindtextdomain($domain, $dir) {
+    global $l10n, $sm_notAlias;
+    if (substr($dir, -1) != '/') $dir .= '/';
+    $mofile=$dir . $sm_notAlias . '/LC_MESSAGES/' . $domain . '.mo';
+
+    $input = new FileReader($mofile);
+    $l10n[$domain] = new gettext_reader($input);
+
     return $dir;
 }
 
@@ -239,13 +64,8 @@ function bindtextdomain($name, $dir) {
  * @return string gettext domain name
  */
 function textdomain($name = false) {
-    global $gettext_php_domain, $gettext_php_loaded;
-    
-    if ($name != false && $gettext_php_domain != $name) {
-        $gettext_php_domain = $name;
-        $gettext_php_loaded = false;
-    }
-
-    return $gettext_php_domain;
+    global $gettext_domain;
+    if ($name) $gettext_domain=$name;
+    return $gettext_domain;
 }
 ?>
\ No newline at end of file
index 6f604a3f655eaf88f655f2cd1433cd5dba2f6d09..ef58e18f6ce430d193c4a9973ffce5e434bf564a 100644 (file)
 /** Everything uses global.php... */
 require_once(SM_PATH . 'functions/global.php');
 
+/**
+ * Gettext bindtextdomain wrapper.
+ *
+ * Wrapper solves differences between php versions in order to provide
+ * ngettext support. Should be used if translation uses ngettext
+ * functions.
+ * @param string $domain gettext domain name
+ * @param string $dir directory that contains all translations
+ * @return string path to translation directory
+ */
+function sq_bindtextdomain($domain,$dir) {
+    global $l10n, $gettext_flags, $sm_notAlias;
+
+    if ($gettext_flags==7) {
+        // gettext extension without ngettext
+        if (substr($dir, -1) != '/') $dir .= '/';
+        $mofile=$dir . $sm_notAlias . '/LC_MESSAGES/' . $domain . '.mo';
+        $input = new FileReader($mofile);
+        $l10n[$domain] = new gettext_reader($input);
+    }
+
+    $dir=bindtextdomain($domain,$dir);
+
+    return $dir;
+}
+
+/**
+ * Gettext textdomain wrapper.
+ * Makes sure that gettext_domain global is modified.
+ * @param string $name gettext domain name
+ * @return string gettext domain name
+ */
+function sq_textdomain($domain) {
+    global $gettext_domain;
+    $gettext_domain=textdomain($domain);
+    return $gettext_domain;
+}
+
 /**
  * Converts string from given charset to charset, that can be displayed by user translation.
  *
@@ -49,17 +87,17 @@ function charset_decode ($charset, $string) {
 
     // Variables that allow to use functions without function_exist() calls
     if (! isset($use_php_recode) || $use_php_recode=="" ) {
-      $use_php_recode=false; }
+        $use_php_recode=false; }
     if (! isset($use_php_iconv) || $use_php_iconv=="" ) {
-         $use_php_iconv=false; }
+        $use_php_iconv=false; }
 
     // Don't do conversion if charset is the same.
     if ( $charset == strtolower($default_charset) )
-          return htmlspecialchars($string);
+        return htmlspecialchars($string);
 
     // catch iso-8859-8-i thing
     if ( $charset == "iso-8859-8-i" )
-              $charset = "iso-8859-8";
+        $charset = "iso-8859-8";
 
     /*
      * Recode converts html special characters automatically if you use
@@ -67,23 +105,23 @@ function charset_decode ($charset, $string) {
      * into php recode function call.
      */
     if ( $use_php_recode ) {
-      if ( $default_charset == "utf-8" ) {
-        // other charsets can be converted to utf-8 without loss.
-        // and output string is smaller
-        $string = recode_string($charset . "..utf-8",$string);
-        return htmlspecialchars($string);
-      } else {
-        $string = recode_string($charset . "..html",$string);
-        // recode does not convert single quote, htmlspecialchars does.
-        $string = str_replace("'", '&#039;', $string);
-        return $string;
-      }
+        if ( $default_charset == "utf-8" ) {
+            // other charsets can be converted to utf-8 without loss.
+            // and output string is smaller
+            $string = recode_string($charset . "..utf-8",$string);
+            return htmlspecialchars($string);
+        } else {
+            $string = recode_string($charset . "..html",$string);
+            // recode does not convert single quote, htmlspecialchars does.
+            $string = str_replace("'", '&#039;', $string);
+            return $string;
+        }
     }
 
     // iconv functions does not have html target and can be used only with utf-8
     if ( $use_php_iconv && $default_charset=='utf-8') {
-      $string = iconv($charset,$default_charset,$string);
-      return htmlspecialchars($string);
+        $string = iconv($charset,$default_charset,$string);
+        return htmlspecialchars($string);
     }
 
     // If we don't use recode and iconv, we'll do it old way.
@@ -94,15 +132,15 @@ function charset_decode ($charset, $string) {
 
     /* controls cpu and memory intensive decoding cycles */
     if (! isset($aggressive_decoding) || $aggressive_decoding=="" ) {
-         $aggressive_decoding=false; }
+        $aggressive_decoding=false; }
 
     $decode=fixcharset($charset);
     $decodefile=SM_PATH . 'functions/decode/' . $decode . '.php';
     if (file_exists($decodefile)) {
-      include_once($decodefile);
-      $ret = call_user_func('charset_decode_'.$decode, $string);
+        include_once($decodefile);
+        $ret = call_user_func('charset_decode_'.$decode, $string);
     } else {
-      $ret = $string;
+        $ret = $string;
     }
     return( $ret );
 }
@@ -115,23 +153,23 @@ function charset_decode ($charset, $string) {
  * @param string
  */
 function charset_encode($string,$charset,$htmlencode=true) {
-  global $default_charset;
+    global $default_charset;
 
-  // Undo html special chars
-  if (! $htmlencode ) {
-      $string = str_replace(array('&amp;','&gt;','&lt;','&quot;'),array('&','>','<','"'),$string);
-  }
+    // Undo html special chars
+    if (! $htmlencode ) {
+        $string = str_replace(array('&amp;','&gt;','&lt;','&quot;'),array('&','>','<','"'),$string);
+    }
 
-  $encode=fixcharset($charset);
-  $encodefile=SM_PATH . 'functions/encode/' . $encode . '.php';
-  if (file_exists($encodefile)) {
-      include_once($encodefile);
-      $ret = call_user_func('charset_encode_'.$encode, $string);
-  } else {
-      include_once(SM_PATH . 'functions/encode/us_ascii.php');
-      $ret = charset_encode_us_ascii($string);
-  }
-  return( $ret );
+    $encode=fixcharset($charset);
+    $encodefile=SM_PATH . 'functions/encode/' . $encode . '.php';
+    if (file_exists($encodefile)) {
+        include_once($encodefile);
+        $ret = call_user_func('charset_encode_'.$encode, $string);
+    } else {
+        include_once(SM_PATH . 'functions/encode/us_ascii.php');
+        $ret = charset_encode_us_ascii($string);
+    }
+    return( $ret );
 }
 
 /**
@@ -220,7 +258,7 @@ function set_up_language($sm_language, $do_search = false, $default = false) {
     // System reverts to English translation if user prefs contain translation
     // that is not available in $languages array
     if (!isset($languages[$sm_notAlias])) {
-      $sm_notAlias="en_US";
+        $sm_notAlias="en_US";
     }
 
     while (isset($languages[$sm_notAlias]['ALIAS'])) {
@@ -231,19 +269,19 @@ function set_up_language($sm_language, $do_search = false, $default = false) {
          $use_gettext &&
          $sm_language != '' &&
          isset($languages[$sm_notAlias]['CHARSET']) ) {
-        bindtextdomain( 'squirrelmail', SM_PATH . 'locale/' );
-        textdomain( 'squirrelmail' );
+        sq_bindtextdomain( 'squirrelmail', SM_PATH . 'locale/' );
+        sq_textdomain( 'squirrelmail' );
         if (function_exists('bind_textdomain_codeset')) {
-          if ($sm_notAlias == 'ja_JP') {
-            bind_textdomain_codeset ("squirrelmail", 'EUC-JP');
+            if ($sm_notAlias == 'ja_JP') {
+                bind_textdomain_codeset ("squirrelmail", 'EUC-JP');
             } else {
-              bind_textdomain_codeset ("squirrelmail", $languages[$sm_notAlias]['CHARSET'] );
+                bind_textdomain_codeset ("squirrelmail", $languages[$sm_notAlias]['CHARSET'] );
             }
         }
         if (isset($languages[$sm_notAlias]['LOCALE'])){
-          $longlocale=$languages[$sm_notAlias]['LOCALE'];
+            $longlocale=$languages[$sm_notAlias]['LOCALE'];
         } else {
-          $longlocale=$sm_notAlias;
+            $longlocale=$sm_notAlias;
         }
         if ( !ini_get('safe_mode') &&
              getenv( 'LC_ALL' ) != $longlocale ) {
@@ -258,40 +296,40 @@ function set_up_language($sm_language, $do_search = false, $default = false) {
         // Set text direction/alignment variables
         if (isset($languages[$sm_notAlias]['DIR']) &&
             $languages[$sm_notAlias]['DIR'] == 'rtl') {
-          /**
-           * Text direction
-           * @global string $text_direction
-           */
-          $text_direction='rtl';
-          /**
-           * Left alignment
-           * @global string $left_align
-           */
-          $left_align='right';
-          /**
-           * Right alignment
-           * @global string $right_align
-           */
-          $right_align='left';
+            /**
+             * Text direction
+             * @global string $text_direction
+             */
+            $text_direction='rtl';
+            /**
+             * Left alignment
+             * @global string $left_align
+             */
+            $left_align='right';
+            /**
+             * Right alignment
+             * @global string $right_align
+             */
+            $right_align='left';
         } else {
-          $text_direction='ltr';
-          $left_align='left';
-          $right_align='right';
+            $text_direction='ltr';
+            $left_align='left';
+            $right_align='right';
         }
 
         $squirrelmail_language = $sm_notAlias;
         if ($squirrelmail_language == 'ja_JP') {
             header ('Content-Type: text/html; charset=EUC-JP');
             if (!function_exists('mb_internal_encoding')) {
-              // Error messages can't be displayed here
-              $error = 1;
-              // Revert to English if possible.
-              if (function_exists('setPref')  && $username!='' && $data_dir!="") {
-                setPref($data_dir, $username, 'language', "en_US");
-                $error = 2;
-              }
-              // stop further execution in order not to get php errors on mb_internal_encoding().
-              return $error;
+                // Error messages can't be displayed here
+                $error = 1;
+                // Revert to English if possible.
+                if (function_exists('setPref')  && $username!='' && $data_dir!="") {
+                    setPref($data_dir, $username, 'language', "en_US");
+                    $error = 2;
+                }
+                // stop further execution in order not to get php errors on mb_internal_encoding().
+                return $error;
             }
             if (function_exists('mb_language')) {
                 mb_language('Japanese');
@@ -331,7 +369,7 @@ function set_my_charset(){
     }
     // Catch removed translation
     if (!isset($languages[$my_language])) {
-      $my_language="en_US";
+        $my_language="en_US";
     }
     while (isset($languages[$my_language]['ALIAS'])) {
         $my_language = $languages[$my_language]['ALIAS'];
@@ -652,11 +690,23 @@ if (function_exists('bindtextdomain')) {
 if (function_exists('textdomain')) {
     $gettext_flags += 4;
 }
+if (function_exists('ngettext')) {
+    $gettext_flags += 8;
+}
 
 /* If gettext is fully loaded, cool */
-if ($gettext_flags == 7) {
+if ($gettext_flags == 15) {
     $use_gettext = true;
 }
+
+/* If ngettext support is missing, load it */
+elseif ($gettext_flags == 7) {
+    $use_gettext = true;
+    // load internal ngettext functions
+    include_once(SM_PATH . 'class/l10n.class.php');
+    include_once(SM_PATH . 'functions/ngettext.php');
+}
+
 /* If we can fake gettext, try that */
 elseif ($gettext_flags == 0) {
     $use_gettext = true;
@@ -690,6 +740,19 @@ elseif ($gettext_flags == 0) {
             return;
         }
     }
+    if (! $gettext_flags & 8) {
+        /**
+         * Function is used as replacemet in broken installs
+         * @ignore
+         */
+        function ngettext($str,$str2,$number) {
+            if ($number>1) {
+                return $str2;
+            } else {
+                return $str;
+            }
+        }
+    }
 }
 
 
diff --git a/functions/ngettext.php b/functions/ngettext.php
new file mode 100644 (file)
index 0000000..bcf690c
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * SquirrelMail internal ngettext functions
+ *
+ * Uses php-gettext classes
+ *
+ * Copyright (c) 2004 The SquirrelMail Project Team
+ * Licensed under the GNU GPL. For full terms see the file COPYING.
+ *
+ * @copyright (c) 2004 The SquirrelMail Project Team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public Licens
+ * @link http://www.php.net/gettext Original php gettext manual
+ * @link http://savannah.nongnu.org/projects/php-gettext php-gettext classes
+ * @version $Id$
+ * @package squirrelmail
+ * @subpackage i18n
+ */
+
+/**
+ * internal ngettext wrapper.
+ *
+ * provides ngettext support
+ * @link http://www.php.net/function.ngettext
+ * @param string $single English string, singular form
+ * @param string $plural English string, plural form
+ * @param integer $number number that shows used quantity
+ * @return string translated string
+ */
+function ngettext($single, $plural, $number) {
+    global $l10n, $gettext_domain;
+    if ($l10n[$gettext_domain]->error==1) return $single;
+    return $l10n[$gettext_domain]->ngettext($single, $plural, $number);
+}
+?>
\ No newline at end of file