alecpl
2008-04-23 ae0c82b0e4883268d977c377b9d023c658887a5d
program/include/main.inc
@@ -5,7 +5,7 @@
 | program/include/main.inc                                              |
 |                                                                       |
 | This file is part of the RoundCube Webmail client                     |
 | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
 | Copyright (C) 2005-2008, RoundCube Dev, - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 | PURPOSE:                                                              |
@@ -26,13 +26,12 @@
 * @author Thomas Bruederli <roundcube@gmail.com>
 */
require_once('lib/des.inc');
require_once('lib/utf7.inc');
require_once('lib/utf8.class.php');
require_once('include/rcube_user.inc');
require_once('include/rcube_shared.inc');
require_once('include/rcmail_template.inc');
// fallback if not PHP modules are available
@include_once('lib/des.inc');
@include_once('lib/utf8.class.php');
// define constannts for input reading
define('RCUBE_INPUT_GET', 0x0101);
@@ -49,13 +48,19 @@
function rcmail_startup($task='mail')
  {
  global $sess_id, $sess_user_lang;
  global $CONFIG, $INSTALL_PATH, $BROWSER, $OUTPUT, $_SESSION, $IMAP, $DB, $USER;
  global $CONFIG, $OUTPUT, $IMAP, $DB, $USER;
  // check client
  $BROWSER = rcube_browser();
  // start output buffering, we don't need any output yet,
  // it'll be cleared after reading of config files, etc.
  ob_start();
  // load configuration
  $CONFIG = rcmail_load_config();
  // set session domain
  if (isset($CONFIG['session_domain']) && !empty($CONFIG['session_domain'])) {
    ini_set('session.cookie_domain', $CONFIG['session_domain']);
  }
  // set session garbage collecting time according to session_lifetime
  if (!empty($CONFIG['session_lifetime']))
@@ -64,14 +69,17 @@
  // prepare DB connection
  $dbwrapper = empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend'];
  $dbclass = "rcube_" . $dbwrapper;
  require_once("include/$dbclass.inc");
  
  $DB = new $dbclass($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']);
  $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql';
  $DB->sqlite_initials = INSTALL_PATH.'SQL/sqlite.initial.sql';
  $DB->set_debug((bool)$CONFIG['sql_debug']);
  $DB->db_connect('w');
  // use database for storing session data
  include_once('include/session.inc');
  // clear output buffer
  ob_end_clean();
  // init session
  session_start();
@@ -92,9 +100,7 @@
  $USER = new rcube_user($_SESSION['user_id']);
  // overwrite config with user preferences
  if (is_array($_SESSION['user_prefs']))
    $CONFIG = array_merge($CONFIG, $_SESSION['user_prefs']);
  $CONFIG = array_merge($CONFIG, (array)$USER->get_prefs());
  // reset some session parameters when changing task
  if ($_SESSION['task'] != $task)
@@ -107,13 +113,11 @@
  if ($task=='mail')
    rcmail_imap_init();
  // set localization
  if ($CONFIG['locale_string'])
    setlocale(LC_ALL, $CONFIG['locale_string']);
  else if ($sess_user_lang)
    setlocale(LC_ALL, $sess_user_lang);
  register_shutdown_function('rcmail_shutdown');
  }
@@ -126,8 +130,6 @@
 */
function rcmail_load_config()
  {
  global $INSTALL_PATH;
  // load config file
  include_once('config/main.inc.php');
  $conf = is_array($rcmail_config) ? $rcmail_config : array();
@@ -142,7 +144,7 @@
  $conf = array_merge($conf, $rcmail_config);
  if (empty($conf['log_dir']))
    $conf['log_dir'] = $INSTALL_PATH.'logs';
    $conf['log_dir'] = INSTALL_PATH.'logs';
  else
    $conf['log_dir'] = unslashify($conf['log_dir']);
@@ -236,7 +238,8 @@
    $valid = $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] == $SESS_CLIENT_IP : true;
  
  // check session filetime
  if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED) && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time())
  if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED)
      && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time())
    $valid = false;
  
  return $valid;
@@ -283,6 +286,9 @@
function rcmail_set_imap_prop()
  {
  global $CONFIG, $IMAP;
  if (!empty($CONFIG['default_charset']))
    $IMAP->set_charset($CONFIG['default_charset']);
  // set root dir from config
  if (!empty($CONFIG['imap_root']))
@@ -338,6 +344,30 @@
  $USER->reset();
  }
/**
 * Do server side actions on logout
 */
function rcmail_logout_actions()
  {
  global $CONFIG, $IMAP;
  // on logout action we're not connected to imap server
  if (($CONFIG['logout_purge'] && !empty($CONFIG['trash_mbox']))
      || $CONFIG['logout_expunge'])
    {
      if (!rcmail_authenticate_session())
        return;
      rcmail_imap_init(true);
    }
  if ($CONFIG['logout_purge'] && !empty($CONFIG['trash_mbox']))
    $IMAP->clear_mailbox($CONFIG['trash_mbox']);
  if ($CONFIG['logout_expunge'])
    $IMAP->expunge('INBOX');
  }
/**
 * Return correct name for a specific database table
@@ -348,20 +378,20 @@
function get_table_name($table)
  {
  global $CONFIG;
  // return table name if configured
  $config_key = 'db_table_'.$table;
  if (strlen($CONFIG[$config_key]))
    return $CONFIG[$config_key];
  return $table;
  }
/**
 * Return correct name for a specific database sequence
 * (used for Postres only)
 * (used for Postgres only)
 *
 * @param string Secuence name
 * @return string Translated sequence name
@@ -369,14 +399,14 @@
function get_sequence_name($sequence)
  {
  global $CONFIG;
  // return table name if configured
  $config_key = 'db_sequence_'.$sequence;
  if (strlen($CONFIG[$config_key]))
    return $CONFIG[$config_key];
  return $table;
  return $sequence;
  }
@@ -389,11 +419,10 @@
 */
function rcube_language_prop($lang, $prop='lang')
  {
  global $INSTALL_PATH;
  static $rcube_languages, $rcube_language_aliases, $rcube_charsets;
  if (empty($rcube_languages))
    @include($INSTALL_PATH.'program/localization/index.inc');
    @include(INSTALL_PATH.'program/localization/index.inc');
    
  // check if we have an alias for that language
  if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang]))
@@ -413,7 +442,7 @@
  if (isset($rcube_charsets[$lang]))
    $charset = $rcube_charsets[$lang];
  else
    $charset = 'UTF-8';
    $charset = 'UTF-8';
  if ($prop=='charset')
@@ -429,18 +458,15 @@
 * environment vars according to the current session and configuration
 */
function rcmail_load_gui()
  {
{
  global $CONFIG, $OUTPUT, $sess_user_lang;
  // init output page
  $OUTPUT = new rcmail_template($CONFIG, $GLOBALS['_task']);
  $OUTPUT = new rcube_template($CONFIG, $GLOBALS['_task']);
  $OUTPUT->set_env('comm_path', $GLOBALS['COMM_PATH']);
  if (is_array($CONFIG['javascript_config']))
  {
    foreach ($CONFIG['javascript_config'] as $js_config_var)
      $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]);
  }
  foreach (array('flag_for_deletion') as $js_config_var)
    $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]);
  if (!empty($GLOBALS['_framed']))
    $OUTPUT->set_env('framed', true);
@@ -452,19 +478,23 @@
  if (!empty($CONFIG['charset']))
    $OUTPUT->set_charset($CONFIG['charset']);
    
  // register common UI objects
  $OUTPUT->add_handlers(array(
    'loginform' => 'rcmail_login_form',
    'username'  => 'rcmail_current_username',
    'message' => 'rcmail_message_container',
    'charsetselector' => 'rcmail_charset_selector',
  ));
  // add some basic label to client
  if (!$OUTPUT->ajax_call)
    rcube_add_label('loading', 'movingmessage');
  }
  $OUTPUT->add_label('loading', 'movingmessage');
}
/**
 * Create an output object for JSON responses
 */
function rcmail_init_json()
{
  global $CONFIG, $OUTPUT;
  // init output object
  $OUTPUT = new rcube_json_output($CONFIG, $GLOBALS['_task']);
  // set locale setting
  rcmail_set_locale($sess_user_lang);
}
/**
 * Set localization charset based on the given language.
@@ -562,7 +592,7 @@
  if ($a_host['host'])
    {
    $host = $a_host['host'];
    $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
    $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null;
    $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $CONFIG['default_port']);
    }
  else
@@ -591,7 +621,7 @@
  // query if user already registered
  if ($existing = rcube_user::query($user, $host))
  $USER = $existing;
    $USER = $existing;
  // user already registered -> overwrite username
  if ($USER->ID)
@@ -608,8 +638,7 @@
  if ($USER->ID)
    {
    // get user prefs
    $_SESSION['user_prefs'] = $USER->get_prefs();
    array_merge($CONFIG, $_SESSION['user_prefs']);
    $CONFIG = array_merge($CONFIG, (array)$USER->get_prefs());
    // set user specific language
    if (!empty($USER->data['language']))
@@ -762,10 +791,30 @@
 * @return string Encryprted string
 */
function encrypt_passwd($pass)
  {
  $cypher = des(get_des_key(), $pass, 1, 0, NULL);
  return base64_encode($cypher);
{
  if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, get_des_key(), $iv);
    $cypher = mcrypt_generic($td, $pass);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
  }
  else if (function_exists('des')) {
    $cypher = des(get_des_key(), $pass, 1, 0, NULL);
  }
  else {
    $cypher = $pass;
    raise_error(array(
      'code' => 500,
      'type' => 'php',
      'file' => __FILE__,
      'message' => "Could not convert encrypt password. Make sure Mcrypt is installed or lib/des.inc is available"
      ), true, false);
  }
  return base64_encode($cypher);
}
/**
@@ -775,8 +824,21 @@
 * @return string Plain password
 */
function decrypt_passwd($cypher)
  {
  $pass = des(get_des_key(), base64_decode($cypher), 0, 0, NULL);
{
  if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, get_des_key(), $iv);
    $pass = mdecrypt_generic($td, base64_decode($cypher));
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
  }
  else if (function_exists('des')) {
    $pass = des(get_des_key(), base64_decode($cypher), 0, 0, NULL);
  }
  else {
    $pass = base64_decode($cypher);
  }
  return preg_replace('/\x00/', '', $pass);
  }
@@ -808,18 +870,18 @@
 */
function rcube_list_languages()
  {
  global $CONFIG, $INSTALL_PATH;
  global $CONFIG;
  static $sa_languages = array();
  if (!sizeof($sa_languages))
    {
    @include($INSTALL_PATH.'program/localization/index.inc');
    @include(INSTALL_PATH.'program/localization/index.inc');
    if ($dh = @opendir($INSTALL_PATH.'program/localization'))
    if ($dh = @opendir(INSTALL_PATH.'program/localization'))
      {
      while (($name = readdir($dh)) !== false)
        {
        if ($name{0}=='.' || !is_dir($INSTALL_PATH.'program/localization/'.$name))
        if ($name{0}=='.' || !is_dir(INSTALL_PATH.'program/localization/'.$name))
          continue;
        if ($label = $rcube_languages[$name])
@@ -834,6 +896,7 @@
/**
 * Add a localized label to the client environment
 * @deprecated
 */
function rcube_add_label()
  {
@@ -841,7 +904,7 @@
  
  $arg_list = func_get_args();
  foreach ($arg_list as $i => $name)
    $OUTPUT->command('add_label', $name, rcube_label($name));
    $OUTPUT->add_label($name);
  }
@@ -902,54 +965,84 @@
function rcube_charset_convert($str, $from, $to=NULL)
  {
  global $MBSTRING;
  static $convert_warning = false;
  $from = strtoupper($from);
  $to = $to==NULL ? strtoupper(RCMAIL_CHARSET) : strtoupper($to);
  $error = false; $conv = null;
  if ($from==$to || $str=='' || empty($from))
    return $str;
  $aliases = array(
    'UNKNOWN-8BIT'   => 'ISO-8859-15',
    'X-UNKNOWN'      => 'ISO-8859-15',
    'X-USER-DEFINED' => 'ISO-8859-15',
    'ISO-8859-8-I'   => 'ISO-8859-8',
    'KS_C_5601-1987' => 'EUC-KR',
  );
  // convert charset using iconv module  
  if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7')
    {
    $iconv_map = array('KS_C_5601-1987' => 'EUC-KR');
    return iconv(($iconv_map[$from] ? $iconv_map[$from] : $from), ($iconv_map[$to] ? $iconv_map[$to] : $to) . "//IGNORE", $str);
    $aliases['GB2312'] = 'GB18030';
    return iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str);
    }
  // convert charset using mbstring module  
  if ($MBSTRING)
    {
    $mb_map = array('UTF-7' => 'UTF7-IMAP', 'KS_C_5601-1987' => 'EUC-KR');
    $aliases['UTF-7'] = 'UTF7-IMAP';
    $aliases['WINDOWS-1257'] = 'ISO-8859-13';
    
    // return if convert succeeded
    if (($out = mb_convert_encoding($str, ($mb_map[$to] ? $mb_map[$to] : $to), ($mb_map[$from] ? $mb_map[$from] : $from))) != '')
    if (($out = mb_convert_encoding($str, ($aliases[$to] ? $aliases[$to] : $to), ($aliases[$from] ? $aliases[$from] : $from))) != '')
      return $out;
    }
  $conv = new utf8();
  if (class_exists('utf8'))
    $conv = new utf8();
  // convert string to UTF-8
  if ($from=='UTF-7')
  if ($from == 'UTF-7')
    $str = utf7_to_utf8($str);
  else if (($from=='ISO-8859-1') && function_exists('utf8_encode'))
  else if (($from == 'ISO-8859-1') && function_exists('utf8_encode'))
    $str = utf8_encode($str);
  else if ($from!='UTF-8')
  else if ($from != 'UTF-8' && $conv)
    {
    $conv->loadCharset($from);
    $str = $conv->strToUtf8($str);
    }
  else if ($from != 'UTF-8')
    $error = true;
  // encode string for output
  if ($to=='UTF-7')
  if ($to == 'UTF-7')
    return utf8_to_utf7($str);
  else if ($to=='ISO-8859-1' && function_exists('utf8_decode'))
  else if ($to == 'ISO-8859-1' && function_exists('utf8_decode'))
    return utf8_decode($str);
  else if ($to!='UTF-8')
  else if ($to != 'UTF-8' && $conv)
    {
    $conv->loadCharset($to);
    return $conv->utf8ToStr($str);
    }
  else if ($to != 'UTF-8')
    $error = true;
  // report error
  if ($error && !$convert_warning)
    {
    raise_error(array(
      'code' => 500,
      'type' => 'php',
      'file' => __FILE__,
      'message' => "Could not convert string charset. Make sure iconv is installed or lib/utf8.class is available"
      ), true, false);
    $convert_warning = true;
    }
  // return UTF-8 string
  return $str;
  }
@@ -1035,7 +1128,7 @@
    if ($OUTPUT->get_charset()!='UTF-8')
      $str = rcube_charset_convert($str, RCMAIL_CHARSET, $OUTPUT->get_charset());
      
    return preg_replace(array("/\r?\n/", "/\r/"), array('\n', '\n'), addslashes(strtr($str, $js_rep_table)));
    return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), addslashes(strtr($str, $js_rep_table)));
    }
  // no encoding given -> return original string
@@ -1161,16 +1254,6 @@
/**
 * Wrapper for rcmail_template::parse()
 * @deprecated
 */
function parse_template($name='main', $exit=true)
  {
  $GLOBALS['OUTPUT']->parse($name, $exit);
  }
/**
 * Create a HTML table based on the given data
 *
 * @param  array  Named table attributes
@@ -1260,15 +1343,15 @@
  if ($type=='checkbox')
    {
    $attrib['value'] = '1';
    $input = new checkbox($attrib);
    $input = new html_checkbox($attrib);
    }
  else if ($type=='textarea')
    {
    $attrib['cols'] = $attrib['size'];
    $input = new textarea($attrib);
    $input = new html_textarea($attrib);
    }
  else
    $input = new textfield($attrib);
    $input = new html_inputfield($attrib);
  // use value from post
  if (!empty($_POST[$fname]))
@@ -1305,6 +1388,7 @@
/**
 * Replace all css definitions with #container [def]
 * and remove css-inlined scripting
 *
 * @param string CSS source code
 * @param string Container ID to use as prefix
@@ -1314,6 +1398,10 @@
  {
  $a_css_values = array();
  $last_pos = 0;
  // ignore the whole block if evil styles are detected
  if (stristr($source, 'expression') || stristr($source, 'behavior'))
    return '';
  // cut out all contents between { and }
  while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos)))
@@ -1324,7 +1412,7 @@
    $last_pos = $pos+2;
  }
  // remove html commends and add #container to each tag selector.
  // remove html comments and add #container to each tag selector.
  // also replace body definition because we also stripped off the <body> tag
  $styles = preg_replace(
    array(
@@ -1395,12 +1483,14 @@
function parse_attrib_string($str)
  {
  $attrib = array();
  preg_match_all('/\s*([-_a-z]+)=(["\'])([^"]+)\2/Ui', stripslashes($str), $regs, PREG_SET_ORDER);
  preg_match_all('/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]+)\2|(\S+?))/Ui', stripslashes($str), $regs, PREG_SET_ORDER);
  // convert attributes to an associative array (name => value)
  if ($regs)
    foreach ($regs as $attr)
      $attrib[strtolower($attr[1])] = $attr[3];
      {
      $attrib[strtolower($attr[1])] = $attr[3] . $attr[4];
      }
  return $attrib;
  }
@@ -1419,12 +1509,22 @@
  global $CONFIG, $sess_user_lang;
  
  $ts = NULL;
  if (is_numeric($date))
    $ts = $date;
  else if (!empty($date))
    $ts = @strtotime($date);
    {
    while (($ts = @strtotime($date))===false)
      {
        // if we have a date in non-rfc format
   // remove token from the end and try again
        $d = explode(' ', $date);
   array_pop($d);
   if (!$d) break;
   $date = implode(' ', $d);
      }
    }
  if (empty($ts))
    return '';
   
@@ -1476,7 +1576,7 @@
      $out .= rcube_label(strtolower(date('M', $timestamp)));
    // month name (long)
    else if ($format{$i}=='F')
      $out .= rcube_label(strtolower(date('F', $timestamp)));
      $out .= rcube_label('long'.strtolower(date('M', $timestamp)));
    else
      $out .= date($format{$i}, $timestamp);
    }
@@ -1495,7 +1595,10 @@
function format_email_recipient($email, $name='')
  {
  if ($name && $name != $email)
    return sprintf('%s <%s>', strpos($name, ",") ? '"'.$name.'"' : $name, $email);
    {
    // Special chars as defined by RFC 822 need to in quoted string (or escaped).
    return sprintf('%s <%s>', preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name) ? '"'.addcslashes($name, '"').'"' : $name, $email);
    }
  else
    return $email;
  }
@@ -1532,12 +1635,12 @@
 * Append a line to a logfile in the logs directory.
 * Date will be added automatically to the line.
 *
 * @param $name Name of logfile
 * @param $line Line to append
 * @param $name name of log file
 * @param line Line to append
 */
function write_log($name, $line)
  {
  global $CONFIG, $INSTALL_PATH;
  global $CONFIG;
  if (!is_string($line))
    $line = var_export($line, true);
@@ -1547,7 +1650,7 @@
                 $line);
                 
  if (empty($CONFIG['log_dir']))
    $CONFIG['log_dir'] = $INSTALL_PATH.'logs';
    $CONFIG['log_dir'] = INSTALL_PATH.'logs';
      
  // try to open specific log file for writing
  if ($fp = @fopen($CONFIG['log_dir'].'/'.$name, 'a'))    
@@ -1624,10 +1727,6 @@
  // get mailbox list
  $mbox_name = $IMAP->get_mailbox_name();
  
  // for these mailboxes we have localized labels
  $special_mailboxes = array('inbox', 'sent', 'drafts', 'trash', 'junk');
  // build the folders tree
  if (empty($a_mailboxes))
    {
@@ -1645,9 +1744,9 @@
// var_dump($a_mailboxes);
  if ($type=='select')
    $out .= rcmail_render_folder_tree_select($a_mailboxes, $special_mailboxes, $mbox_name, $attrib['maxlength']);
    $out .= rcmail_render_folder_tree_select($a_mailboxes, $mbox_name, $attrib['maxlength']);
   else
    $out .= rcmail_render_folder_tree_html($a_mailboxes, $special_mailboxes, $mbox_name, $attrib['maxlength']);
    $out .= rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $attrib['maxlength']);
// rcube_print_time($mboxlist_start, 'render_folder_tree()');
@@ -1697,7 +1796,7 @@
 * Return html for a structured list &lt;ul&gt; for the mailbox tree
 * @access private
 */
function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox_name, $maxlength, $nestLevel=0)
function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, $maxlength, $nestLevel=0)
  {
  global $COMM_PATH, $IMAP, $CONFIG, $OUTPUT;
@@ -1708,9 +1807,8 @@
    $zebra_class = ($nestLevel*$idx)%2 ? 'even' : 'odd';
    $title = '';
    $folder_lc = strtolower($folder['id']);
    if (in_array($folder_lc, $special))
      $foldername = rcube_label($folder_lc);
    if ($folder_class = rcmail_folder_classname($folder['id']))
      $foldername = rcube_label($folder_class);
    else
      {
      $foldername = $folder['name'];
@@ -1718,20 +1816,16 @@
      // shorten the folder name to a given length
      if ($maxlength && $maxlength>1)
        {
        $fname = abbrevate_string($foldername, $maxlength);
        $fname = abbreviate_string($foldername, $maxlength);
        if ($fname != $foldername)
          $title = ' title="'.Q($foldername).'"';
        $foldername = $fname;
        }
      }
    // add unread message count display
    if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox_name)))
      $foldername .= sprintf(' (%d)', $unread_count);
    // make folder name safe for ids and class names
    $folder_id = preg_replace('/[^A-Za-z0-9\-_]/', '', $folder['id']);
    $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_lc);
    $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_class ? $folder_class : strtolower($folder['id']));
    // set special class for Sent, Drafts, Trash and Junk
    if ($folder['id']==$CONFIG['sent_mbox'])
@@ -1767,7 +1861,7 @@
                    Q($foldername));
    if (!empty($folder['folders']))
      $out .= "\n<ul>\n" . rcmail_render_folder_tree_html($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1) . "</ul>\n";
      $out .= "\n<ul>\n" . rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $maxlength, $nestLevel+1) . "</ul>\n";
    $out .= "</li>\n";
    $idx++;
@@ -1781,7 +1875,7 @@
 * Return html for a flat list <select> for the mailbox tree
 * @access private
 */
function rcmail_render_folder_tree_select(&$arrFolders, &$special, &$mbox_name, $maxlength, $nestLevel=0)
function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, $nestLevel=0)
  {
  global $IMAP, $OUTPUT;
@@ -1789,16 +1883,15 @@
  $out = '';
  foreach ($arrFolders as $key=>$folder)
    {
    $folder_lc = strtolower($folder['id']);
    if (in_array($folder_lc, $special))
      $foldername = rcube_label($folder_lc);
    if ($folder_class = rcmail_folder_classname($folder['id']))
      $foldername = rcube_label($folder_class);
    else
      {
      $foldername = $folder['name'];
      
      // shorten the folder name to a given length
      if ($maxlength && $maxlength>1)
        $foldername = abbrevate_string($foldername, $maxlength);
        $foldername = abbreviate_string($foldername, $maxlength);
      }
    $out .= sprintf('<option value="%s">%s%s</option>'."\n",
@@ -1807,7 +1900,7 @@
                    Q($foldername));
    if (!empty($folder['folders']))
      $out .= rcmail_render_folder_tree_select($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1);
      $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, $nestLevel+1);
    $idx++;
    }
@@ -1815,4 +1908,43 @@
  return $out;
  }
/**
 * Return internal name for the given folder if it matches the configured special folders
 * @access private
 */
function rcmail_folder_classname($folder_id)
{
  global $CONFIG;
  $cname = null;
  $folder_lc = strtolower($folder_id);
  // for these mailboxes we have localized labels and css classes
  foreach (array('inbox', 'sent', 'drafts', 'trash', 'junk') as $smbx)
  {
    if ($folder_lc == $smbx || $folder_id == $CONFIG[$smbx.'_mbox'])
      $cname = $smbx;
  }
  return $cname;
}
/**
 * Try to localize the given IMAP folder name.
 * UTF-7 decode it in case no localized text was found
 *
 * @param string Folder name
 * @return string Localized folder name in UTF-8 encoding
 */
function rcmail_localize_foldername($name)
{
  if ($folder_class = rcmail_folder_classname($name))
    return rcube_label($folder_class);
  else
    return rcube_charset_convert($name, 'UTF-7');
}
?>