Changeset 622 in subversion


Ignore:
Timestamp:
Jun 18, 2007 4:33:17 PM (6 years ago)
Author:
till
Message:

+ created a bootstrap file (for later use in plugins :-))
+ a lot of CS changes (whereever I saw them)
+ started switching all references of globals to rc_registry-calls
+ create a class for all functions in main_inc: rc_main()

  • todo: fix all references, NARF!
  • RELEASE BROKEN, BROKEN, BROKEN (checking in for backup :-))
Location:
branches/devel-vnext
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • branches/devel-vnext/index.php

    r610 r622  
    4141*/ 
    4242 
    43 /** 
    44  * tfk_debug 
    45  * 
    46  * @param string $str 
    47  * @ignore 
    48  */ 
    49 function tfk_debug($str) 
    50 { 
    51     $str = "\n\n" . @date('Y-m-d H:i:s') . "\n" . $str; 
    52     $fp = @fopen(dirname(__FILE__) . '/logs/debug.tfk', 'a'); 
    53     if ($fp !== false) { 
    54         @fwrite($fp, $str); 
    55         @fclose($fp); 
    56     } else { 
    57         die('Could not open logs/debug.tfk.'); 
    58     } 
    59 } 
    60 /** 
    61  * log all $_POST 
    62  * @author Till Klampaeckel <till@php.net> 
    63  * @ignore 
    64  */ 
    65 if ($_SERVER['REQUEST_METHOD'] == 'POST') { 
    66     tfk_debug(var_export($_POST, true)); 
    67     tfk_debug(var_export($_GET, true)); 
    68 } 
    69 else { 
    70     tfk_debug('We are GET.'); 
    71 } 
    72  
    73 // application constants 
    74 define('RCMAIL_VERSION', 'devel-vnext (0.1-rc1)'); 
    75 define('RCMAIL_CHARSET', 'UTF-8'); 
    76 define('JS_OBJECT_NAME', 'rcmail'); 
    77  
    78 // define global vars 
    79 $OUTPUT_TYPE  = 'html'; 
    8043$INSTALL_PATH = dirname(__FILE__); 
    81 $MAIN_TASKS   = array( 
    82                     'mail', 
    83                     'settings', 
    84                     'logout' 
    85 ); // addressbook 
    86  
    87 if (empty($INSTALL_PATH)) { 
    88     $INSTALL_PATH = './'; 
    89 } 
    90 else { 
    91     $INSTALL_PATH .= '/'; 
    92 } 
    93  
    94 // make sure path_separator is defined 
    95 if (!defined('PATH_SEPARATOR')) { 
    96     define('PATH_SEPARATOR', (eregi('win', PHP_OS) ? ';' : ':')); 
    97 } 
    98  
    99 // RC include folders MUST be included FIRST to avoid other 
    100 // possible not compatible libraries (i.e PEAR) to be included 
    101 // instead the ones provided by RC 
    102 $include_path = $INSTALL_PATH . PATH_SEPARATOR; 
    103 $include_path.= $INSTALL_PATH . 'program' . PATH_SEPARATOR; 
    104 $include_path.= $INSTALL_PATH . 'program/lib' . PATH_SEPARATOR; 
    105 $include_path.= ini_get('include_path'); 
    106  
    107 ini_set('include_path', $include_path); 
    108  
    109 ini_set('session.name', 'sessid'); 
    110 ini_set('session.use_cookies', 1); 
    111 ini_set('session.gc_maxlifetime', 21600); 
    112 ini_set('session.gc_divisor', 500); 
    113 ini_set('error_reporting', E_ALL&~E_NOTICE); 
    114  
    115 // increase maximum execution time for php scripts 
    116 // (does not work in safe mode) 
    117 if (!ini_get('safe_mode')) { 
    118     @set_time_limit(120); 
    119 } 
    120  
    121 tfk_debug('About to include files.'); 
     44require_once dirname(__FILE__) . '/program/include/bootstrap.php'; 
    12245 
    12346// include base files 
     
    12952require_once 'PEAR.php'; 
    13053 
    131 tfk_debug('Passed!'); 
     54$registry = rc_registry::getInstance(); 
     55$registry->set('INSTALL_PATH', $INSTALL_PATH, 'core'); 
     56$registry->set('s_mbstring_loaded', null, 'core'); 
     57$registry->set('sa_languages', null, 'core'); 
     58 
     59/** 
     60 * log all $_POST 
     61 * @author Till Klampaeckel <till@php.net> 
     62 * @ignore 
     63 */ 
     64if ($_SERVER['REQUEST_METHOD'] == 'POST') { 
     65    rc_main::tfk_debug(var_export($_POST, true)); 
     66    rc_main::tfk_debug(var_export($_GET, true)); 
     67} 
     68else { 
     69    rc_main::tfk_debug('We are GET.'); 
     70} 
     71 
     72rc_main::tfk_debug('Included all files!'); 
    13273 
    13374// set PEAR error handling 
     
    13677 
    13778// catch some url/post parameters 
    138 $_task   = strip_quotes(get_input_value('_task', RCUBE_INPUT_GPC)); 
    139 $_action = strip_quotes(get_input_value('_action', RCUBE_INPUT_GPC)); 
     79$_task   = rc_main::strip_quotes(rc_main::get_input_value('_task', RCUBE_INPUT_GPC)); 
     80$_action = rc_main::strip_quotes(rc_main::get_input_value('_action', RCUBE_INPUT_GPC)); 
    14081$_framed = (!empty($_GET['_framed']) || !empty($_POST['_framed'])); 
    14182 
     
    15899 
    159100// start session with requested task 
    160 rcmail_startup($_task); 
    161  
    162 tfk_debug('// rcmail_startup'); 
     101rc_main::rcmail_startup($_task); 
     102 
     103rc_main::tfk_debug('// rcmail_startup'); 
    163104 
    164105// set session related variables 
     
    172113    $SESS_HIDDEN_FIELD .= "\n".'<input type="hidden" name="_framed" value="1" />'; 
    173114} 
    174  
     115$registry->set('COMM_PATH', $COMM_PATH, 'core'); 
     116$registry->set('SESS_HIDDEN_FIELD', $SESS_HIDDEN_FIELD, 'core'); 
     117$registry->set('s_username', '', 'core'); 
    175118 
    176119// init necessary objects for GUI 
    177 rcmail_load_gui(); 
    178  
     120rc_main::rcmail_load_gui(); 
     121 
     122rc_main::tfk_debug('// rcmail_load_gui'); 
     123 
     124$OUTPUT     = $registry->get('OUTPUT', 'core'); 
     125$DB         = $registry->get('DB', 'core'); 
    179126 
    180127// check DB connections and exit on failure 
     
    185132        'message' => $err_str), FALSE, TRUE 
    186133    ); 
    187 } 
    188  
     134 
     135    rc_main::tfk_debug('// DB ERROR'); 
     136} 
     137 
     138rc_main::tfk_debug('// NO DB ERROR'); 
    189139 
    190140// error steps 
     
    193143} 
    194144 
     145rc_main::tfk_debug('// going'); 
     146 
     147rc_main::tfk_debug("task {$_task} / action {$_action}"); 
     148 
    195149// try to log in 
    196150if ($_action=='login' && $_task=='mail') { 
    197151 
    198     tfk_debug('Here we go, a login.'); 
    199  
    200     $host = rcmail_autoselect_host(); 
    201  
    202     tfk_debug('Selected host: ' . $host); 
     152    rc_main::tfk_debug('Here we go, a login.'); 
     153 
     154    $host = rc_main::rcmail_autoselect_host(); 
     155 
     156    rc_main::tfk_debug('Selected host: ' . $host); 
    203157 
    204158    // check if client supports cookies 
     
    210164        && !empty($_POST['_user']) 
    211165        && isset($_POST['_pass']) 
    212         && rcmail_login( 
    213                 get_input_value('_user', RCUBE_INPUT_POST), 
    214                 get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'), 
     166        && rc_main::rcmail_login( 
     167                rc_main::get_input_value('_user', RCUBE_INPUT_POST), 
     168                rc_main::get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'), 
    215169                $host 
    216170        ) 
     
    220174        sess_regenerate_id(); 
    221175 
    222         tfk_debug('Yay, we log in.'); 
     176        rc_main::tfk_debug('Yay, we log in.'); 
    223177 
    224178        // send auth cookie if necessary 
    225         rcmail_authenticate_session(); 
     179        rc_main::rcmail_authenticate_session(); 
    226180 
    227181        // send redirect 
     
    231185    else { 
    232186 
    233         tfk_debug('Oops, failed.'); 
     187        rc_main::tfk_debug('Oops, failed.'); 
    234188        if (empty($_POST['_user']) === true) { 
    235             tfk_debug('Login: no _user'); 
     189            rc_main::tfk_debug('Login: no _user'); 
    236190        } 
    237191        if (isset($_POST['_pass']) === false) { 
    238             tfk_debug('Login: no _pass'); 
     192            rc_main::tfk_debug('Login: no _pass'); 
    239193        } 
    240         $status = rcmail_login( 
    241                     get_input_value('_user', RCUBE_INPUT_POST), 
    242                     get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'), 
     194        $status = rc_main::rcmail_login( 
     195                    rc_main::get_input_value('_user', RCUBE_INPUT_POST), 
     196                    rc_main::get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'), 
    243197                    $host 
    244198        ); 
    245         tfk_debug('Login: status: ' . $status); 
    246  
    247         tfk_debug(var_export($_SESSION['temp'], true)); 
    248         //tfk_debug(date('Y-m-d H:i:s', $_SESSION['auth_time'])); 
     199        rc_main::tfk_debug('Login: status: ' . $status); 
     200 
     201        rc_main::tfk_debug(var_export($_SESSION['temp'], true)); 
     202        //rc_main::tfk_debug(date('Y-m-d H:i:s', $_SESSION['auth_time'])); 
    249203 
    250204        $OUTPUT->show_message("loginfailed", 'warning'); 
     
    256210else if (($_task=='logout' || $_action=='logout') && isset($_SESSION['user_id'])) { 
    257211    $OUTPUT->show_message('loggedout'); 
    258     rcmail_kill_session(); 
     212    rc_main::rcmail_kill_session(); 
    259213} 
    260214 
    261215// check session and auth cookie 
    262216else if ($_action != 'login' && $_SESSION['user_id'] && $_action != 'send') { 
    263     if (!rcmail_authenticate_session()) { 
     217    if (!rc_main::rcmail_authenticate_session()) { 
    264218        $OUTPUT->show_message('sessionerror', 'error'); 
    265         rcmail_kill_session(); 
    266     } 
    267 } 
    268  
     219        rc_main::rcmail_kill_session(); 
     220    } 
     221} 
     222 
     223rc_main::tfk_debug('// going #2'); 
     224 
     225$IMAP = $registry->get('IMAP', 'core'); 
     226rc_main::tfk_debug(var_export($IMAP, true) . "\n\nIMAP LOADED."); 
    269227 
    270228// log in to imap server 
    271229if (!empty($_SESSION['user_id']) && $_task=='mail') { 
     230 
     231    rc_main::tfk_debug('// trying to login'); 
     232 
    272233    $conn = $IMAP->connect( 
    273234                $_SESSION['imap_host'], 
    274235                $_SESSION['username'], 
    275                 decrypt_passwd($_SESSION['password']), 
     236                rc_main::decrypt_passwd($_SESSION['password']), 
    276237                $_SESSION['imap_port'], 
    277238                $_SESSION['imap_ssl'] 
     
    282243    } 
    283244    else { 
    284         rcmail_set_imap_prop(); 
    285  
     245        rc_main::rcmail_set_imap_prop(); 
    286246    } 
    287247} 
     
    290250// not logged in -> set task to 'login 
    291251if (empty($_SESSION['user_id'])) { 
     252 
     253    rc_main::tfk_debug('// we need a login'); 
     254 
    292255    if ($OUTPUT->ajax_call){ 
    293256        $OUTPUT->remote_response("setTimeout(\"location.href='\"+this.env.comm_path+\"'\", 2000);"); 
     
    296259} 
    297260 
    298  
     261rc_main::tfk_debug("// task {$_task} action {$_action}"); 
    299262 
    300263// set task and action to client 
     
    307270// not logged in -> show login page 
    308271if (!$_SESSION['user_id']) { 
     272 
     273    rc_main::tfk_debug('// finally: login'); 
     274 
    309275    $OUTPUT->task = 'login'; 
    310276    $OUTPUT->send('login'); 
     
    370336    } 
    371337 
    372     tfk_debug('Mail: ' . $_name); 
     338    rc_main::tfk_debug('Mail: ' . $_name); 
    373339 
    374340    // make sure the message count is refreshed 
     
    432398    } 
    433399    else { 
    434         tfk_debug('Does not exist: ' . $_file); 
     400        rc_main::tfk_debug('Does not exist: ' . $_file); 
    435401    } 
    436402} 
  • branches/devel-vnext/program/include/main.inc

    r610 r622  
    11<?php 
    2  
    32/* 
    43 +-----------------------------------------------------------------------+ 
     
    3130define('RCUBE_INPUT_GPC',  0x0103); 
    3231 
    33  
    34 /** 
    35  * register session and connect to server 
    36  * 
    37  * @access public 
    38  * @todo   Remove this include from here. This is not good for bytecode caching. 
    39  * @param  string $task 
    40  */ 
    41 function rcmail_startup($task = 'mail') 
     32class rc_main 
    4233{ 
    43     global $sess_id, $sess_user_lang; 
    44     global $CONFIG, $INSTALL_PATH, $BROWSER, $OUTPUT, $_SESSION, $IMAP, $DB; 
    45  
    46     tfk_debug('Start me up.'); 
    47  
    48     // check client 
    49     $BROWSER = rcube_browser(); 
    50  
    51     tfk_debug('// load browser'); 
    52  
    53     // load configuration 
    54     $CONFIG = rcmail_load_config(); 
    55  
    56     tfk_debug('// load config'); 
    57  
    58     // set session garbage collecting time according to session_lifetime 
    59     if (empty($CONFIG['session_lifetime']) === FALSE) { 
    60         ini_set('session.gc_maxlifetime', ($CONFIG['session_lifetime']) * 120); 
    61     } 
    62     // prepare DB connection 
    63     require_once 'include/rcube_'.(empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend']).'.inc'; 
    64  
    65     $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']); 
    66     $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql'; 
    67     $DB->db_connect('w'); 
    68  
    69     tfk_debug('// init db'); 
    70  
    71     // use database for storing session data 
    72     include_once 'include/session.inc'; 
    73  
    74     // init session 
    75     session_start(); 
    76     $sess_id = session_id(); 
    77  
    78     // create session and set session vars 
    79     if (!isset($_SESSION['auth_time'])) { 
    80         $_SESSION['user_lang'] = rcube_language_prop($CONFIG['locale_string']); 
    81         $_SESSION['auth_time'] = time(); 
    82         $_SESSION['temp'] = true; 
    83     } 
    84  
    85     // set session vars global 
    86     $sess_user_lang = rcube_language_prop($_SESSION['user_lang']); 
    87  
    88  
    89     // overwrite config with user preferences 
    90     if (is_array($_SESSION['user_prefs'])) { 
    91         $CONFIG = array_merge($CONFIG, $_SESSION['user_prefs']); 
    92     } 
    93  
    94     // reset some session parameters when changing task 
    95     if ($_SESSION['task'] != $task) { 
    96         unset($_SESSION['page']); 
    97     } 
    98     // set current task to session 
    99     $_SESSION['task'] = $task; 
    100  
    101     // create IMAP object 
    102     if ($task=='mail') { 
    103         rcmail_imap_init(); 
    104     } 
    105  
    106     // set localization 
    107     if ($CONFIG['locale_string']) { 
    108         setlocale(LC_ALL, $CONFIG['locale_string']); 
    109     } 
    110     else if ($sess_user_lang) { 
    111         setlocale(LC_ALL, $sess_user_lang); 
    112     } 
    113     register_shutdown_function('rcmail_shutdown'); 
    114 } 
    115  
    116  
    117 // load roundcube configuration into global var 
    118 function rcmail_load_config() 
    119 { 
    120     global $INSTALL_PATH; 
    121  
    122     // load config file 
    123     $status = @include_once 'config/main.inc.php'; 
    124     if ($status === FALSE) { 
    125         die('Could not open config/main.inc.php.'); 
    126     } 
    127     $conf = is_array($rcmail_config) ? $rcmail_config : array(); 
    128  
    129     // load host-specific configuration 
    130     rcmail_load_host_config($conf); 
    131  
    132     $conf['skin_path'] = $conf['skin_path'] ? unslashify($conf['skin_path']) : 'skins/default'; 
    133  
    134     // load db conf 
    135     @include_once 'config/db.inc.php'; 
    136     $conf = array_merge($conf, $rcmail_config); 
    137  
    138     if (empty($conf['log_dir'])) { 
    139         $conf['log_dir'] = $INSTALL_PATH.'logs'; 
    140     } 
    141     else { 
    142         $conf['log_dir'] = unslashify($conf['log_dir']); 
    143     } 
    144     // set PHP error logging according to config 
    145     if ($conf['debug_level'] & 1) { 
    146         ini_set('log_errors', 1); 
    147         ini_set('error_log', $conf['log_dir'].'/errors'); 
    148     } 
    149     if ($conf['debug_level'] & 4) { 
    150         ini_set('display_errors', 1); 
    151     } 
    152     else { 
    153         ini_set('display_errors', 0); 
    154     } 
    155     return $conf; 
    156 } 
    157  
    158  
    159 // load a host-specific config file if configured 
    160 function rcmail_load_host_config(&$config) 
    161 { 
    162     $fname = NULL; 
    163  
    164     if (is_array($config['include_host_config'])) { 
    165         $fname = $config['include_host_config'][$_SERVER['HTTP_HOST']]; 
    166     } 
    167     else if (!empty($config['include_host_config'])) { 
    168         $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php'; 
    169     } 
    170     if ($fname && is_file('config/'.$fname)) { 
    171         include('config/'.$fname); 
    172         $config = array_merge($config, $rcmail_config); 
    173     } 
    174 } 
    175  
    176  
    177 // create authorization hash 
    178 function rcmail_auth_hash($sess_id, $ts) 
    179 { 
    180     global $CONFIG; 
    181  
    182     $auth_string = sprintf( 
    183                         'rcmail*sess%sR%s*Chk:%s;%s', 
    184                         $sess_id, 
    185                         $ts, 
    186                         $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***', 
    187                         $_SERVER['HTTP_USER_AGENT'] 
    188     ); 
    189  
    190     if (function_exists('sha1')) { 
    191         return sha1($auth_string); 
    192     } 
    193     return md5($auth_string); 
    194 } 
    195  
    196  
    197 // compare the auth hash sent by the client with the local session credentials 
    198 function rcmail_authenticate_session() 
    199 { 
    200     global $CONFIG, $SESS_CLIENT_IP, $SESS_CHANGED; 
    201  
    202     // advanced session authentication 
    203     if ($CONFIG['double_auth']) { 
    204         $now = time(); 
    205         $valid = ($_COOKIE['sessauth'] == rcmail_auth_hash(session_id(), $_SESSION['auth_time']) || 
    206               $_COOKIE['sessauth'] == rcmail_auth_hash(session_id(), $_SESSION['last_auth'])); 
    207  
    208         // renew auth cookie every 5 minutes (only for GET requests) 
    209         if (!$valid || ($_SERVER['REQUEST_METHOD']!='POST' && $now-$_SESSION['auth_time'] > 300)) { 
    210             $_SESSION['last_auth'] = $_SESSION['auth_time']; 
    211             $_SESSION['auth_time'] = $now; 
    212             setcookie('sessauth', rcmail_auth_hash(session_id(), $now)); 
    213         } 
    214     } 
    215     else { 
    216         $valid = $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] == $SESS_CLIENT_IP : true; 
    217     } 
    218     // check session filetime 
    219     if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED) && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time()) { 
    220         $valid = false; 
    221     } 
    222     return $valid; 
    223 } 
    224  
    225  
    226 // create IMAP object and connect to server 
    227 function rcmail_imap_init($connect=FALSE) 
    228 { 
    229     global $CONFIG, $DB, $IMAP, $OUTPUT; 
    230  
    231     $IMAP = new rcube_imap($DB); 
    232     $IMAP->debug_level = $CONFIG['debug_level']; 
    233     $IMAP->skip_deleted = $CONFIG['skip_deleted']; 
    234  
    235  
    236     // connect with stored session data 
    237     if ($connect) { 
    238         $conn = $IMAP->connect( 
    239                         $_SESSION['imap_host'], 
    240                         $_SESSION['username'], 
    241                         decrypt_passwd($_SESSION['password']), 
    242                         $_SESSION['imap_port'], 
    243                         $_SESSION['imap_ssl'] 
     34 
     35    private function __construct() 
     36    { 
     37 
     38    } 
     39    /** 
     40     * tfk_debug 
     41     * 
     42     * @param string $str 
     43     * @ignore 
     44     */ 
     45    static function tfk_debug($str) 
     46    { 
     47        $str = "\n\n" . @date('Y-m-d H:i:s') . "\n" . $str; 
     48        $fp = @fopen(dirname(__FILE__) . '/../../logs/debug.tfk', 'a'); 
     49        if ($fp !== false) { 
     50            @fwrite($fp, $str); 
     51            @fclose($fp); 
     52        } else { 
     53            die('Could not open logs/debug.tfk.'); 
     54        } 
     55    } 
     56 
     57    /** 
     58     * register session and connect to server 
     59     * 
     60     * @access public 
     61     * @todo   Remove this include from here. This is not good for bytecode caching. 
     62     * @param  string $task 
     63     */ 
     64    static function rcmail_startup($task = 'mail') 
     65    { 
     66        //global $sess_id, $sess_user_lang; 
     67        //global $CONFIG, $INSTALL_PATH, $BROWSER, $OUTPUT, $_SESSION, $IMAP, $DB; 
     68 
     69        $registry     = rc_registry::getInstance(); 
     70        $INSTALL_PATH = $registry->get('INSTALL_PATH', 'core'); 
     71 
     72        self::tfk_debug('Start me up.'); 
     73 
     74        // check client 
     75        $BROWSER = rcube_browser(); 
     76 
     77        self::tfk_debug('// load browser'); 
     78 
     79        // load configuration 
     80        $CONFIG = self::rcmail_load_config(); 
     81        $registry->set('CONFIG', $CONFIG, 'core'); 
     82 
     83        self::tfk_debug('// load config'); 
     84 
     85        // set session garbage collecting time according to session_lifetime 
     86        if (empty($CONFIG['session_lifetime']) === FALSE) { 
     87            ini_set('session.gc_maxlifetime', ($CONFIG['session_lifetime']) * 120); 
     88        } 
     89        // prepare DB connection 
     90        require_once 'include/rcube_'.(empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend']).'.inc'; 
     91 
     92        $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']); 
     93        $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql'; 
     94        $DB->db_connect('w'); 
     95 
     96        $registry->set('DB', $DB, 'core'); 
     97 
     98        self::tfk_debug('// init db'); 
     99 
     100        // use database for storing session data 
     101        include_once 'include/session.inc'; 
     102 
     103        // init session 
     104        session_start(); 
     105        $sess_id = session_id(); 
     106 
     107        // create session and set session vars 
     108        if (!isset($_SESSION['auth_time'])) { 
     109            $_SESSION['user_lang'] = self::rcube_language_prop($CONFIG['locale_string']); 
     110            $_SESSION['auth_time'] = time(); 
     111            $_SESSION['temp'] = true; 
     112        } 
     113 
     114        // set session vars global 
     115        $sess_user_lang = self::rcube_language_prop($_SESSION['user_lang']); 
     116 
     117 
     118        // overwrite config with user preferences 
     119        if (is_array($_SESSION['user_prefs'])) { 
     120            $CONFIG = array_merge($CONFIG, $_SESSION['user_prefs']); 
     121        } 
     122 
     123        // reset some session parameters when changing task 
     124        if ($_SESSION['task'] != $task) { 
     125            unset($_SESSION['page']); 
     126        } 
     127        // set current task to session 
     128        $_SESSION['task'] = $task; 
     129 
     130        // create IMAP object 
     131        if ($task=='mail') { 
     132            self::rcmail_imap_init(); 
     133        } 
     134 
     135        // set localization 
     136        if ($CONFIG['locale_string']) { 
     137            setlocale(LC_ALL, $CONFIG['locale_string']); 
     138        } 
     139        else if ($sess_user_lang) { 
     140            setlocale(LC_ALL, $sess_user_lang); 
     141        } 
     142        register_shutdown_function(array('rc_main', 'rcmail_shutdown')); 
     143 
     144        $registry->set('sess_id', $sess_id, 'core'); 
     145        $registry->set('sess_user_lang', $sess_user_lang, 'core'); 
     146        $registry->set('CONFIG', $CONFIG, 'core'); 
     147        $registry->set('BROWSER', $BROWSER, 'core'); 
     148 
     149        //global $OUTPUT, $IMAP 
     150    } 
     151 
     152 
     153    // load roundcube configuration into global var 
     154    static function rcmail_load_config() 
     155    { 
     156        $registry     = rc_registry::getInstance(); 
     157        $INSTALL_PATH = $registry->get('INSTALL_PATH', 'core'); 
     158 
     159        // load config file 
     160        $status = @include_once 'config/main.inc.php'; 
     161        if ($status === FALSE) { 
     162            die('Could not open config/main.inc.php.'); 
     163        } 
     164        $conf = is_array($rcmail_config) ? $rcmail_config : array(); 
     165 
     166        // load host-specific configuration 
     167        $conf = self::rcmail_load_host_config($conf); 
     168 
     169        $conf['skin_path'] = $conf['skin_path'] ? unslashify($conf['skin_path']) : 'skins/default'; 
     170 
     171        // load db conf 
     172        @include_once 'config/db.inc.php'; 
     173        $conf = array_merge($conf, $rcmail_config); 
     174 
     175        if (empty($conf['log_dir'])) { 
     176            $conf['log_dir'] = $INSTALL_PATH . 'logs'; 
     177        } 
     178        else { 
     179            $conf['log_dir'] = unslashify($conf['log_dir']); 
     180        } 
     181        // set PHP error logging according to config 
     182        if ($conf['debug_level'] & 1) { 
     183            ini_set('log_errors', 1); 
     184            ini_set('error_log', $conf['log_dir'].'/errors'); 
     185        } 
     186        if ($conf['debug_level'] & 4) { 
     187            ini_set('display_errors', 1); 
     188        } 
     189        else { 
     190            ini_set('display_errors', 0); 
     191        } 
     192        return $conf; 
     193    } 
     194 
     195 
     196    // load a host-specific config file if configured 
     197    static function rcmail_load_host_config($config) 
     198    { 
     199        $fname = NULL; 
     200 
     201        if (is_array($config['include_host_config'])) { 
     202            $fname = $config['include_host_config'][$_SERVER['HTTP_HOST']]; 
     203        } 
     204        else if (!empty($config['include_host_config'])) { 
     205            $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php'; 
     206        } 
     207        if ($fname && is_file('config/'.$fname)) { 
     208            include('config/'.$fname); 
     209            $config = array_merge($config, $rcmail_config); 
     210        } 
     211        return $config; 
     212    } 
     213 
     214 
     215    // create authorization hash 
     216    static function rcmail_auth_hash($sess_id, $ts) 
     217    { 
     218        $registry = rc_registry::getInstance(); 
     219        $CONFIG   = $registry->get('CONFIG', 'core'); 
     220 
     221        $auth_string = sprintf( 
     222                            'rcmail*sess%sR%s*Chk:%s;%s', 
     223                            $sess_id, 
     224                            $ts, 
     225                            $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***', 
     226                            $_SERVER['HTTP_USER_AGENT'] 
    244227        ); 
    245         if ($conn === false) { 
    246             $OUTPUT->show_message('imaperror', 'error'); 
    247         } 
    248         rcmail_set_imap_prop(); 
    249     } 
    250  
    251     // enable caching of imap data 
    252     if ($CONFIG['enable_caching']===TRUE) { 
    253         $IMAP->set_caching(TRUE); 
    254     } 
    255     // set pagesize from config 
    256     if (isset($CONFIG['pagesize'])) { 
    257         $IMAP->set_pagesize($CONFIG['pagesize']); 
    258     } 
    259 } 
    260  
    261  
    262 // set root dir and last stored mailbox 
    263 // this must be done AFTER connecting to the server 
    264 function rcmail_set_imap_prop() 
    265 { 
    266     global $CONFIG, $IMAP; 
    267  
    268     // set root dir from config 
    269     if (!empty($CONFIG['imap_root'])) { 
    270         $IMAP->set_rootdir($CONFIG['imap_root']); 
    271     } 
    272     if (is_array($CONFIG['default_imap_folders'])) { 
    273         $IMAP->set_default_mailboxes($CONFIG['default_imap_folders']); 
    274     } 
    275     if (!empty($_SESSION['mbox'])) { 
    276         $IMAP->set_mailbox($_SESSION['mbox']); 
    277     } 
    278     if (isset($_SESSION['page'])) { 
    279         $IMAP->set_page($_SESSION['page']); 
    280     } 
    281 } 
    282  
    283  
    284 // do these things on script shutdown 
    285 function rcmail_shutdown() 
    286 { 
    287     global $IMAP; 
    288  
    289     if (is_object($IMAP)) { 
    290         $IMAP->close(); 
    291         $IMAP->write_cache(); 
    292     } 
    293  
    294     // before closing the database connection, write session data 
    295     session_write_close(); 
    296 } 
    297  
    298 // destroy session data and remove cookie 
    299 function rcmail_kill_session() 
    300 { 
    301     // save user preferences 
    302     $a_user_prefs = $_SESSION['user_prefs']; 
    303     if (!is_array($a_user_prefs)) { 
    304         $a_user_prefs = array(); 
    305     } 
    306     if ( 
    307         ( 
    308             isset($_SESSION['sort_col']) 
    309             && $_SESSION['sort_col'] != $a_user_prefs['message_sort_col'] 
    310         ) 
    311         || 
    312         ( 
    313             isset($_SESSION['sort_order']) 
    314             && $_SESSION['sort_order'] != $a_user_prefs['message_sort_order'] 
    315         ) 
    316     ) { 
    317         $a_user_prefs['message_sort_col'] = $_SESSION['sort_col']; 
    318         $a_user_prefs['message_sort_order'] = $_SESSION['sort_order']; 
    319         rcmail_save_user_prefs($a_user_prefs); 
    320     } 
    321  
    322     $_SESSION = array( 
    323                     'user_lang' => $GLOBALS['sess_user_lang'], 
    324                     'auth_time' => time(), 
    325                     'temp' => true 
    326     ); 
    327     setcookie('sessauth', '-del-', time()-60); 
    328 } 
    329  
    330  
    331 // return correct name for a specific database table 
    332 function get_table_name($table) 
    333 { 
    334     global $CONFIG; 
    335  
    336     // return table name if configured 
    337     $config_key = 'db_table_'.$table; 
    338  
    339     if (strlen($CONFIG[$config_key])) { 
    340         return $CONFIG[$config_key]; 
    341     } 
    342     return $table; 
    343 } 
    344  
    345  
    346 // return correct name for a specific database sequence 
    347 // (used for Postres only) 
    348 function get_sequence_name($sequence) 
    349 { 
    350     global $CONFIG; 
    351  
    352     // return table name if configured 
    353     $config_key = 'db_sequence_'.$sequence; 
    354  
    355     if (strlen($CONFIG[$config_key])) { 
    356         return $CONFIG[$config_key]; 
    357     } 
    358     return $table; 
    359 } 
    360  
    361  
    362 // check the given string and returns language properties 
    363 function rcube_language_prop($lang, $prop='lang') 
    364 { 
    365     global $INSTALL_PATH; 
    366     static $rcube_languages, $rcube_language_aliases, $rcube_charsets; 
    367  
    368     if (empty($rcube_languages)) { 
    369         @include($INSTALL_PATH.'program/localization/index.inc'); 
    370     } 
    371     // check if we have an alias for that language 
    372     if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) { 
    373         $lang = $rcube_language_aliases[$lang]; 
    374     } 
    375     // try the first two chars 
    376     if (!isset($rcube_languages[$lang]) && strlen($lang)>2) { 
    377         $lang = substr($lang, 0, 2); 
    378         $lang = rcube_language_prop($lang); 
    379     } 
    380  
    381     if (!isset($rcube_languages[$lang])) { 
    382         $lang = 'en_US'; 
    383     } 
    384     // language has special charset configured 
    385     if (isset($rcube_charsets[$lang])) { 
    386         $charset = $rcube_charsets[$lang]; 
    387     } 
    388     else { 
    389         $charset = 'UTF-8'; 
    390     } 
    391     if ($prop=='charset') { 
    392         return $charset; 
    393     } 
    394     return $lang; 
    395 } 
    396  
    397  
    398 // init output object for GUI and add common scripts 
    399 function rcmail_load_gui() 
    400 { 
    401     global $CONFIG, $OUTPUT, $sess_user_lang; 
    402  
    403     // init output page 
    404     $OUTPUT = new rcmail_template($CONFIG, $GLOBALS['_task']); 
    405     $OUTPUT->set_env('comm_path', $GLOBALS['COMM_PATH']); 
    406  
    407     if (is_array($CONFIG['javascript_config'])) { 
    408         foreach ($CONFIG['javascript_config'] as $js_config_var) { 
    409             $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]); 
    410         } 
    411     } 
    412  
    413     if (!empty($GLOBALS['_framed'])) { 
    414         $OUTPUT->set_env('framed', true); 
    415     } 
    416     // set locale setting 
    417     rcmail_set_locale($sess_user_lang); 
    418  
    419     // set user-selected charset 
    420     if (!empty($CONFIG['charset'])) { 
    421         $OUTPUT->set_charset($CONFIG['charset']); 
    422     } 
    423     // register common UI objects 
    424     $OUTPUT->add_handlers( 
    425             array( 
    426                 'loginform' => 'rcmail_login_form', 
    427                 'username'  => 'rcmail_current_username', 
    428                 'message' => 'rcmail_message_container', 
    429                 'charsetselector' => 'rcmail_charset_selector', 
     228 
     229        if (function_exists('sha1')) { 
     230            return sha1($auth_string); 
     231        } 
     232        return md5($auth_string); 
     233    } 
     234 
     235 
     236    // compare the auth hash sent by the client with the local session credentials 
     237    function rcmail_authenticate_session() 
     238    { 
     239        $registry       = rc_registry::getInstance(); 
     240        $CONFIG         = $registry->get('CONFIG', 'core'); 
     241        $SESS_CLIENT_IP = $registry->get('SESS_CLIENT_IP', 'core'); 
     242        $SESS_CHANGED   = $registry->get('SESS_CHANGED', 'core'); 
     243 
     244        // advanced session authentication 
     245        if ($CONFIG['double_auth']) { 
     246            $now = time(); 
     247            $valid = ($_COOKIE['sessauth'] == self::rcmail_auth_hash(session_id(), $_SESSION['auth_time']) || 
     248                  $_COOKIE['sessauth'] == self::rcmail_auth_hash(session_id(), $_SESSION['last_auth'])); 
     249 
     250            // renew auth cookie every 5 minutes (only for GET requests) 
     251            if (!$valid || ($_SERVER['REQUEST_METHOD']!='POST' && $now-$_SESSION['auth_time'] > 300)) { 
     252                $_SESSION['last_auth'] = $_SESSION['auth_time']; 
     253                $_SESSION['auth_time'] = $now; 
     254                setcookie('sessauth', self::rcmail_auth_hash(session_id(), $now)); 
     255            } 
     256        } 
     257        else { 
     258            $valid = $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] == $SESS_CLIENT_IP : true; 
     259        } 
     260        // check session filetime 
     261        if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED) && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time()) { 
     262            $valid = false; 
     263        } 
     264        return $valid; 
     265    } 
     266 
     267 
     268    // create IMAP object and connect to server 
     269    static function rcmail_imap_init($connect=FALSE) 
     270    { 
     271        $registry = rc_registry::getInstance(); 
     272        $CONFIG   = $registry->get('CONFIG', 'core'); 
     273        $DB       = $registry->get('DB', 'core'); 
     274        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     275 
     276        $IMAP = new rcube_imap($DB); 
     277        $IMAP->debug_level = $CONFIG['debug_level']; 
     278        $IMAP->skip_deleted = $CONFIG['skip_deleted']; 
     279 
     280        // connect with stored session data 
     281        if ($connect) { 
     282            $conn = $IMAP->connect( 
     283                            $_SESSION['imap_host'], 
     284                            $_SESSION['username'], 
     285                            decrypt_passwd($_SESSION['password']), 
     286                            $_SESSION['imap_port'], 
     287                            $_SESSION['imap_ssl'] 
     288            ); 
     289            $registry->set('IMAP', $IMAP, 'core'); 
     290            if ($conn === false) { 
     291                $OUTPUT->show_message('imaperror', 'error'); 
     292            } 
     293            self::rcmail_set_imap_prop(); 
     294        } 
     295 
     296        // enable caching of imap data 
     297        if ($CONFIG['enable_caching']===TRUE) { 
     298            $IMAP->set_caching(TRUE); 
     299        } 
     300        // set pagesize from config 
     301        if (isset($CONFIG['pagesize'])) { 
     302            $IMAP->set_pagesize($CONFIG['pagesize']); 
     303        } 
     304        $registry->set('IMAP', $IMAP, 'core'); 
     305    } 
     306 
     307 
     308    // set root dir and last stored mailbox 
     309    // this must be done AFTER connecting to the server 
     310    static function rcmail_set_imap_prop() 
     311    { 
     312        $registry = rc_registry::getInstance(); 
     313        $CONFIG   = $registry->get('CONFIG', 'core'); 
     314        $IMAP     = $registry->get('IMAP', 'core'); 
     315 
     316        // set root dir from config 
     317        if (!empty($CONFIG['imap_root'])) { 
     318            $IMAP->set_rootdir($CONFIG['imap_root']); 
     319        } 
     320        if (is_array($CONFIG['default_imap_folders'])) { 
     321            $IMAP->set_default_mailboxes($CONFIG['default_imap_folders']); 
     322        } 
     323        if (!empty($_SESSION['mbox'])) { 
     324            $IMAP->set_mailbox($_SESSION['mbox']); 
     325        } 
     326        if (isset($_SESSION['page'])) { 
     327            $IMAP->set_page($_SESSION['page']); 
     328        } 
     329        $registry->set('IMAP', $IMAP, 'core'); 
     330    } 
     331 
     332 
     333    // do these things on script shutdown 
     334    static function rcmail_shutdown() 
     335    { 
     336        $registry = rc_registry::getInstance(); 
     337        $IMAP     = $registry->get('IMAP', 'core'); 
     338 
     339        if (is_object($IMAP)) { 
     340            $IMAP->close(); 
     341            $IMAP->write_cache(); 
     342        } 
     343 
     344        // before closing the database connection, write session data 
     345        session_write_close(); 
     346    } 
     347 
     348    // destroy session data and remove cookie 
     349    static function rcmail_kill_session() 
     350    { 
     351        // save user preferences 
     352        $a_user_prefs = $_SESSION['user_prefs']; 
     353        if (!is_array($a_user_prefs)) { 
     354            $a_user_prefs = array(); 
     355        } 
     356        if ( 
     357            ( 
     358                isset($_SESSION['sort_col']) 
     359                && $_SESSION['sort_col'] != $a_user_prefs['message_sort_col'] 
    430360            ) 
    431     ); 
    432  
    433     // add some basic label to client 
    434     if (!$OUTPUT->ajax_call) { 
    435         rcube_add_label('loading'); 
    436     } 
    437 } 
    438  
    439  
    440 // set localization charset based on the given language 
    441 function rcmail_set_locale($lang) 
    442 { 
    443     global $OUTPUT, $MBSTRING; 
    444     static $s_mbstring_loaded = NULL; 
    445  
    446     // settings for mbstring module (by Tadashi Jokagi) 
    447     if (is_null($s_mbstring_loaded)) { 
    448         $MBSTRING = $s_mbstring_loaded = extension_loaded("mbstring"); 
    449     } 
    450     else { 
    451         $MBSTRING = $s_mbstring_loaded = FALSE; 
    452     } 
    453     if ($MBSTRING) { 
    454         mb_internal_encoding(RCMAIL_CHARSET); 
    455     } 
    456     $OUTPUT->set_charset(rcube_language_prop($lang, 'charset')); 
    457 } 
    458  
    459  
    460 // auto-select IMAP host based on the posted login information 
    461 function rcmail_autoselect_host() 
    462 { 
    463     global $CONFIG; 
    464  
    465     $host = isset($_POST['_host']) ? get_input_value('_host', RCUBE_INPUT_POST) : $CONFIG['default_host']; 
    466     if (is_array($host)) { 
    467         list($user, $domain) = explode('@', get_input_value('_user', RCUBE_INPUT_POST)); 
    468         if (!empty($domain)) { 
    469             foreach ($host as $imap_host => $mail_domains) { 
    470                 if (is_array($mail_domains) && in_array($domain, $mail_domains)) { 
    471                     $host = $imap_host; 
     361            || 
     362            ( 
     363                isset($_SESSION['sort_order']) 
     364                && $_SESSION['sort_order'] != $a_user_prefs['message_sort_order'] 
     365            ) 
     366        ) { 
     367            $a_user_prefs['message_sort_col'] = $_SESSION['sort_col']; 
     368            $a_user_prefs['message_sort_order'] = $_SESSION['sort_order']; 
     369            rcmail_save_user_prefs($a_user_prefs); 
     370        } 
     371 
     372        $_SESSION = array( 
     373                        'user_lang' => $GLOBALS['sess_user_lang'], 
     374                        'auth_time' => time(), 
     375                        'temp' => true 
     376        ); 
     377        setcookie('sessauth', '-del-', time()-60); 
     378    } 
     379 
     380 
     381    // return correct name for a specific database table 
     382    static function get_table_name($table) 
     383    { 
     384        $registry = rc_registry::getInstance(); 
     385        $CONFIG   = $registry->get('CONFIG', 'core'); 
     386 
     387        // return table name if configured 
     388        $config_key = 'db_table_'.$table; 
     389 
     390        if (strlen($CONFIG[$config_key])) { 
     391            return $CONFIG[$config_key]; 
     392        } 
     393        return $table; 
     394    } 
     395 
     396 
     397    // return correct name for a specific database sequence 
     398    // (used for Postres only) 
     399    static function get_sequence_name($sequence) 
     400    { 
     401        $registry = rc_registry::getInstance(); 
     402        $CONFIG   = $registry->get('CONFIG', 'core'); 
     403 
     404        // return table name if configured 
     405        $config_key = 'db_sequence_'.$sequence; 
     406 
     407        if (strlen($CONFIG[$config_key])) { 
     408            return $CONFIG[$config_key]; 
     409        } 
     410        return $table; 
     411    } 
     412 
     413 
     414    // check the given string and returns language properties 
     415    static function rcube_language_prop($lang, $prop='lang') 
     416    { 
     417        $registry               = rc_registry::getInstance(); 
     418        $INSTALL_PATH           = $registry->get('INSTALL_PATH', 'core'); 
     419        $rcube_languages        = $registry->get('rcube_languages', 'core'); 
     420        $rcube_language_aliases = $registry->get('rcube_language_aliases', 'core'); 
     421        $rcube_charsets         = $registry->get('rcube_charsets', 'core'); 
     422 
     423        if (empty($rcube_languages)) { 
     424            $status = @include($INSTALL_PATH.'program/localization/index.inc'); 
     425            if ($status === false) { 
     426                self::tfk_debug("Couldn't include localization/index.inc"); 
     427            } 
     428        } 
     429        // check if we have an alias for that language 
     430        if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) { 
     431            $lang = $rcube_language_aliases[$lang]; 
     432        } 
     433        // try the first two chars 
     434        if (!isset($rcube_languages[$lang]) && strlen($lang)>2) { 
     435            $registry->set('rcube_languages', $rcube_languages, 'core'); 
     436            $registry->set('rcube_language_aliases', $rcube_language_aliases, 'core'); 
     437            $registry->set('rcube_charsets', $rcube_charsets, 'core'); 
     438 
     439            $lang = substr($lang, 0, 2); 
     440            $lang = self::rcube_language_prop($lang); 
     441        } 
     442 
     443        if (!isset($rcube_languages[$lang])) { 
     444            $lang = 'en_US'; 
     445        } 
     446        // language has special charset configured 
     447        if (isset($rcube_charsets[$lang])) { 
     448            $charset = $rcube_charsets[$lang]; 
     449        } 
     450        else { 
     451            $charset = 'UTF-8'; 
     452        } 
     453 
     454        $registry->set('rcube_languages', $rcube_languages, 'core'); 
     455        $registry->set('rcube_language_aliases', $rcube_language_aliases, 'core'); 
     456        $registry->set('rcube_charsets', $rcube_charsets, 'core'); 
     457 
     458        if ($prop=='charset') { 
     459            return $charset; 
     460        } 
     461 
     462        return $lang; 
     463    } 
     464 
     465 
     466    // init output object for GUI and add common scripts 
     467    static function rcmail_load_gui() 
     468    { 
     469        $registry       = rc_registry::getInstance(); 
     470        $CONFIG         = $registry->get('CONFIG', 'core'); 
     471        $sess_user_lang = $registry->get('sess_user_lang', 'core'); 
     472 
     473        // init output page 
     474        $OUTPUT = new rcmail_template($CONFIG, $GLOBALS['_task']); 
     475        $OUTPUT->set_env('comm_path', $GLOBALS['COMM_PATH']); 
     476 
     477        if (is_array($CONFIG['javascript_config'])) { 
     478            foreach ($CONFIG['javascript_config'] as $js_config_var) { 
     479                $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]); 
     480            } 
     481        } 
     482 
     483        if (!empty($GLOBALS['_framed'])) { 
     484            $OUTPUT->set_env('framed', true); 
     485        } 
     486        $registry->set('OUTPUT', $OUTPUT, 'core'); 
     487        // set locale setting 
     488        self::rcmail_set_locale($sess_user_lang); 
     489 
     490        // set user-selected charset 
     491        if (!empty($CONFIG['charset'])) { 
     492            $OUTPUT->set_charset($CONFIG['charset']); 
     493        } 
     494        $registry->set('OUTPUT', $OUTPUT, 'core'); 
     495        // register common UI objects 
     496        $OUTPUT->add_handlers( 
     497                array( 
     498                    'loginform' => 'rcmail_login_form', 
     499                    'username'  => 'rcmail_current_username', 
     500                    'message' => 'rcmail_message_container', 
     501                    'charsetselector' => 'rcmail_charset_selector', 
     502                ) 
     503        ); 
     504        // add some basic label to client 
     505        if (!$OUTPUT->ajax_call) { 
     506            self::rcube_add_label('loading'); 
     507        } 
     508    } 
     509 
     510 
     511    // set localization charset based on the given language 
     512    static function rcmail_set_locale($lang) 
     513    { 
     514        $registry          = rc_registry::getInstance(); 
     515        $OUTPUT            = $registry->get('OUTPUT', 'core'); 
     516        $MBSTRING          = $registry->get('MBSTRING', 'core'); 
     517        $s_mbstring_loaded = $registry->get('s_mbstring_loaded', 'core'); 
     518 
     519        // settings for mbstring module (by Tadashi Jokagi) 
     520        if (is_null($s_mbstring_loaded)) { 
     521            $MBSTRING = $s_mbstring_loaded = extension_loaded("mbstring"); 
     522        } 
     523        else { 
     524            $MBSTRING = $s_mbstring_loaded = FALSE; 
     525        } 
     526        $registry->set('MBSTRING', $MBSTRING, 'core'); 
     527        $registry->set('s_mbstring_loaded', $s_mbstring_loaded, 'core'); 
     528 
     529        if ($MBSTRING) { 
     530            mb_internal_encoding(RCMAIL_CHARSET); 
     531        } 
     532        $OUTPUT->set_charset(self::rcube_language_prop($lang, 'charset')); 
     533    } 
     534 
     535 
     536    // auto-select IMAP host based on the posted login information 
     537    static function rcmail_autoselect_host() 
     538    { 
     539        $registry = rc_registry::getInstance(); 
     540        $CONFIG   = $registry->get('CONFIG', 'core'); 
     541 
     542        $host = isset($_POST['_host']) ? self::get_input_value('_host', RCUBE_INPUT_POST) : $CONFIG['default_host']; 
     543        if (is_array($host)) { 
     544            list($user, $domain) = explode('@', self::get_input_value('_user', RCUBE_INPUT_POST)); 
     545            if (!empty($domain)) { 
     546                foreach ($host as $imap_host => $mail_domains) { 
     547                    if (is_array($mail_domains) && in_array($domain, $mail_domains)) { 
     548                        $host = $imap_host; 
     549                        break; 
     550                    } 
     551                } 
     552            } 
     553 
     554            // take the first entry if $host is still an array 
     555            if (is_array($host)) { 
     556                $host = array_shift($host); 
     557            } 
     558        } 
     559        return $host; 
     560    } 
     561 
     562 
     563    // perfom login to the IMAP server and to the webmail service 
     564    static function rcmail_login($user, $pass, $host=NULL) 
     565    { 
     566        $user_id = NULL; 
     567 
     568        $registry       = rc_registry::getInstance(); 
     569        $CONFIG         = $registry->get('CONFIG', 'core'); 
     570        $IMAP           = $registry->get('IMAP', 'core'); 
     571        $DB             = $registry->get('DB', 'core'); 
     572        $sess_user_lang = $registry->get('sess_user_lang', 'core'); 
     573 
     574        if (is_null($host) === true) { 
     575            $host = $CONFIG['default_host']; 
     576        } 
     577        // Validate that selected host is in the list of configured hosts 
     578        if (is_array($CONFIG['default_host'])) { 
     579            $allowed = FALSE; 
     580            foreach ($CONFIG['default_host'] as $key => $host_allowed) { 
     581                if (!is_numeric($key)) { 
     582                    $host_allowed = $key; 
     583                } 
     584                if ($host == $host_allowed) { 
     585                    $allowed = TRUE; 
    472586                    break; 
    473587                } 
    474588            } 
    475         } 
    476  
    477         // take the first entry if $host is still an array 
    478         if (is_array($host)) { 
    479             $host = array_shift($host); 
    480         } 
    481     } 
    482     return $host; 
     589            if (!$allowed) { 
     590                return FALSE; 
     591            } 
     592        } 
     593        else if (!empty($CONFIG['default_host']) && $host != $CONFIG['default_host']) { 
     594            return FALSE; 
     595        } 
     596 
     597        // parse $host URL 
     598        $a_host = parse_url($host); 
     599        if ($a_host['host']) { 
     600            $host = $a_host['host']; 
     601            $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE; 
     602            $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $CONFIG['default_port']); 
     603        } 
     604        else { 
     605            $imap_port = $CONFIG['default_port']; 
     606        } 
     607 
     608        /** 
     609         * Modify username with domain if required 
     610         * Inspired by Marco <P0L0_notspam_binware.org> 
     611         */ 
     612        // Check if we need to add domain 
     613        //tfk_debug('User #1: ' . $user); 
     614        //tfk_debug('Host: ' . $CONFIG['username_domain']); 
     615        if (!empty($CONFIG['username_domain']) && !strstr($user, '@')) { 
     616            if (is_array($CONFIG['username_domain']) && isset($CONFIG['username_domain'][$host])) { 
     617                $user .= '@' . $CONFIG['username_domain'][$host]; 
     618            } 
     619            else if (is_string($CONFIG['username_domain'])) { 
     620                $user .= '@' . $CONFIG['username_domain']; 
     621            } 
     622        } 
     623        //tfk_debug('User #2: ' . $user); 
     624 
     625        // query if user already registered 
     626        $_query = "SELECT user_id, username, language, preferences"; 
     627        $_query.= " FROM " . self::get_table_name('users'); 
     628        $_query.= " WHERE mail_host=?"; 
     629        $_query.= " AND (username=? OR alias=?)"; 
     630 
     631        $sql_result = $DB->query( 
     632                            $_query, 
     633                            $host, 
     634                            $user, 
     635                            $user 
     636        ); 
     637        if ($DB->db_error === true) { 
     638            return FALSE; 
     639        } 
     640        // user already registered -> overwrite username 
     641        if ($sql_arr = $DB->fetch_assoc($sql_result)) { 
     642            $user_id = $sql_arr['user_id']; 
     643            $user    = $sql_arr['username']; 
     644        } 
     645 
     646        // try to resolve email address from virtuser table 
     647        if (!empty($CONFIG['virtuser_file']) && strstr($user, '@')) { 
     648            $user = rcmail_email2user($user); 
     649        } 
     650 
     651        // exit if IMAP login failed 
     652        if (!($imap_login  = $IMAP->connect($host, $user, $pass, $imap_port, $imap_ssl))) { 
     653            return FALSE; 
     654        } 
     655        // user already registered 
     656        if ($user_id && !empty($sql_arr)) { 
     657            // get user prefs 
     658            if (strlen($sql_arr['preferences'])) { 
     659                $user_prefs = unserialize($sql_arr['preferences']); 
     660                $_SESSION['user_prefs'] = $user_prefs; 
     661                array_merge($CONFIG, $user_prefs); 
     662            } 
     663 
     664 
     665            // set user specific language 
     666            if (strlen($sql_arr['language'])) { 
     667                $sess_user_lang = $_SESSION['user_lang'] = $sql_arr['language']; 
     668            } 
     669            // update user's record 
     670            $_query = "UPDATE " . self::get_table_name('users'); 
     671            $_query.= " SET last_login=" . $DB->now(); 
     672            $_query.= " WHERE user_id=?"; 
     673            $DB->query($_query, $user_id); 
     674        } 
     675        // create new system user 
     676        else if ($CONFIG['auto_create_user']) { 
     677            $user_id = self::rcmail_create_user($user, $host); 
     678        } 
     679 
     680        //tfk_debug('User id: ' . $user_id); 
     681 
     682        if (empty($user_id) === true) { 
     683            return false; 
     684        } 
     685        $_SESSION['user_id']    = $user_id; 
     686        $_SESSION['imap_host']  = $host; 
     687        $_SESSION['imap_port']  = $imap_port; 
     688        $_SESSION['imap_ssl']   = $imap_ssl; 
     689        $_SESSION['username']   = $user; 
     690        $_SESSION['user_lang']  = $sess_user_lang; 
     691        $_SESSION['password']   = self::encrypt_passwd($pass); 
     692        $_SESSION['login_time'] = mktime(); 
     693 
     694        /** 
     695         * If multi-SMTP servers, use correct one 
     696         * Otherwise, use the general SMTP server 
     697         * or use phpMail function 
     698         * 
     699         * @author Brett Patterson <brett@bpatterson.net> 
     700         * @author Till Klampaeckel <till@php.net> 
     701         */ 
     702        if(is_array($CONFIG['smtp_server']) === true) { 
     703            if (isset($CONFIG['smtp_server'][$host]) === true) { 
     704                $_SESSION['smtp_server'] = $CONFIG['smtp_server'][$host]; 
     705            } 
     706            else { 
     707                $_SESSION['smtp_server'] = 'phpMail'; 
     708            } 
     709        } 
     710        else { 
     711            if (empty($CONFIG['smtp_server']) === false) { 
     712                $_SESSION['smtp_server'] = $CONFIG['smtp_server']; 
     713            } 
     714            else { 
     715                $_SESSION['smtp_server'] = 'phpMail'; 
     716            } 
     717        } 
     718 
     719        // force reloading complete list of subscribed mailboxes 
     720        self::rcmail_set_imap_prop(); 
     721        $IMAP->clear_cache('mailboxes'); 
     722        $IMAP->create_default_folders(); 
     723 
     724        return TRUE; 
     725    } 
     726 
     727 
     728    // create new entry in users and identities table 
     729    static function rcmail_create_user($user, $host) 
     730    { 
     731        $registry = rc_registry::getInstance(); 
     732        $DB       = $registry->get('DB', 'core'); 
     733        $CONFIG   = $registry->get('CONFIG', 'core'); 
     734        $IMAP     = $registry->get('IMAP', 'core'); 
     735 
     736        $user_email = ''; 
     737 
     738        // try to resolve user in virtusertable 
     739        if (!empty($CONFIG['virtuser_file']) && strstr($user, '@')==FALSE) { 
     740            $user_email = self::rcmail_user2email($user); 
     741        } 
     742        $_query = "INSERT INTO " . self::get_table_name('users'); 
     743        $_query.= " (created, last_login, username, mail_host, alias, language)"; 
     744        $_query.= " VALUES (" . $DB->now() . ", " . $DB->now() . ", ?, ?, ?, ?)"; 
     745        $DB->query( 
     746                $_query, 
     747                self::strip_newlines($user), 
     748                self::strip_newlines($host), 
     749                self::strip_newlines($user_email), 
     750                $_SESSION['user_lang'] 
     751        ); 
     752 
     753        if ($user_id = $DB->insert_id(self::get_sequence_name('users'))) { 
     754            $mail_domain = self::rcmail_mail_domain($host); 
     755 
     756            if ($user_email=='') { 
     757                $user_email = strstr($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain); 
     758            } 
     759            $user_name = $user!=$user_email ? $user : ''; 
     760 
     761            // try to resolve the e-mail address from the virtuser table 
     762            if ( 
     763                !empty($CONFIG['virtuser_query']) 
     764                && ($sql_result = $DB->query(preg_replace('/%u/', $user, $CONFIG['virtuser_query']))) 
     765                && ($DB->num_rows()>0) 
     766            ) { 
     767                while ($sql_arr = $DB->fetch_array($sql_result)) { 
     768                    $_query = "INSERT INTO " . self::get_table_name('identities'); 
     769                    $_query.= " (user_id, del, standard, name, email)"; 
     770                    $_query.= " VALUES (?, 0, 1, ?, ?)"; 
     771                    $DB->query( 
     772                            $_query, 
     773                            $user_id, 
     774                            self::strip_newlines($user_name), 
     775                            preg_replace('/^@/', $user . '@', $sql_arr[0]) 
     776                    ); 
     777                } 
     778            } 
     779            else { 
     780                // also create new identity records 
     781                $_query = "INSERT INTO " . self::get_table_name('identities'); 
     782                $_query.= " (user_id, del, standard, name, email)"; 
     783                $_query.= " VALUES (?, 0, 1, ?, ?)"; 
     784                $DB->query( 
     785                        $_query, 
     786                        $user_id, 
     787                        self::strip_newlines($user_name), 
     788                        self::strip_newlines($user_email) 
     789                ); 
     790            } 
     791 
     792            // get existing mailboxes 
     793            $a_mailboxes = $IMAP->list_mailboxes(); 
     794        } 
     795        else { 
     796            raise_error( 
     797                array( 
     798                    'code' => 500, 
     799                    'type' => 'php', 
     800                    'line' => __LINE__, 
     801                    'file' => __FILE__, 
     802                    'message' => "Failed to create new user" 
     803                ), 
     804                TRUE, 
     805                FALSE 
     806            ); 
     807        } 
     808        return $user_id; 
     809    } 
     810 
     811 
     812    // load virtuser table in array 
     813    function rcmail_getvirtualfile() 
     814    { 
     815        $registry = rc_registry::getInstance(); 
     816        $registry->get('CONFIG', 'core'); 
     817        if (empty($CONFIG['virtuser_file']) || !is_file($CONFIG['virtuser_file'])) { 
     818            return FALSE; 
     819        } 
     820        // read file 
     821        $a_lines = file($CONFIG['virtuser_file']); 
     822        return $a_lines; 
     823    } 
     824 
     825 
     826    // find matches of the given pattern in virtuser table 
     827    static function rcmail_findinvirtual($pattern) 
     828    { 
     829        $result  = array(); 
     830        $virtual = self::rcmail_getvirtualfile(); 
     831        if ($virtual==FALSE) { 
     832            return $result; 
     833        } 
     834        // check each line for matches 
     835        foreach ($virtual as $line) { 
     836            $line = trim($line); 
     837            if (empty($line) || $line{0}=='#') { 
     838                continue; 
     839            } 
     840            if (eregi($pattern, $line)) { 
     841                $result[] = $line; 
     842            } 
     843        } 
     844        return $result; 
     845    } 
     846 
     847 
     848    // resolve username with virtuser table 
     849    static function rcmail_email2user($email) 
     850    { 
     851        $user = $email; 
     852        $r = self::rcmail_findinvirtual("^$email"); 
     853 
     854        for ($i=0; $i<count($r); $i++) { 
     855            $data = $r[$i]; 
     856            $arr = preg_split('/\s+/', $data); 
     857            if (count($arr)>0) { 
     858                $user = trim($arr[count($arr)-1]); 
     859                break; 
     860            } 
     861        } 
     862        return $user; 
     863    } 
     864 
     865 
     866    // resolve e-mail address with virtuser table 
     867    static function rcmail_user2email($user) 
     868    { 
     869        $email = ""; 
     870        $r = self::rcmail_findinvirtual("$user$"); 
     871 
     872        for ($i=0; $i<count($r); $i++) { 
     873            $data=$r[$i]; 
     874            $arr = preg_split('/\s+/', $data); 
     875            if (count($arr)>0) { 
     876                $email = trim($arr[0]); 
     877                break; 
     878            } 
     879        } 
     880        return $email; 
     881    } 
     882 
     883 
     884    function rcmail_save_user_prefs($a_user_prefs) 
     885    { 
     886        $registry       = rc_registry::getInstance(); 
     887        $DB             = $registry->get('DB', 'core'); 
     888        $CONFIG         = $registry->get('CONFIG', 'core'); 
     889        $sess_user_lang = $registry->get('sess_user_lang', 'core'); 
     890 
     891        $_query = "UPDATE " . self::get_table_name('users'); 
     892        $_query.= " SET preferences=?,"; 
     893        $_query.= " language=?"; 
     894        $_query.= " WHERE user_id=?"; 
     895        $DB->query( 
     896                $_query, 
     897                serialize($a_user_prefs), 
     898                $sess_user_lang, 
     899                $_SESSION['user_id'] 
     900        ); 
     901 
     902        if ($DB->affected_rows()) { 
     903            $_SESSION['user_prefs'] = $a_user_prefs; 
     904            $CONFIG = array_merge($CONFIG, $a_user_prefs); 
     905            $registry->set('CONFIG', $CONFIG, 'core'); 
     906            return TRUE; 
     907        } 
     908 
     909        return FALSE; 
     910    } 
     911 
     912 
     913    // overwrite action variable 
     914    static function rcmail_overwrite_action($action) 
     915    { 
     916        $registry = rc_registry::getInstance(); 
     917        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     918        $GLOBALS['_action'] = $action; 
     919        $OUTPUT->set_env('action', $action); 
     920    } 
     921 
     922 
     923    /** 
     924     * Compose an URL for a specific action 
     925     * 
     926     * @param string  Request action 
     927     * @param array   More URL parameters 
     928     * @param string  Request task (omit if the same) 
     929     * @return The application URL 
     930     */ 
     931    static function rcmail_url($action, $p=array(), $task=null) 
     932    { 
     933        $registry   = rc_registry::getInstance(); 
     934        $COMM_PATH  = $registry->get('COMM_PATH', 'core'); 
     935        $MAIN_TASKS = $registry->get('MAIN_TASKS', 'core'); 
     936 
     937        $qstring = ''; 
     938        $base = $COMM_PATH; 
     939 
     940        if ($task && in_array($task, $MAIN_TASKS)) { 
     941            $base = ereg_replace('_task=[a-z]+', '_task='.$task, $COMM_PATH); 
     942        } 
     943        if (is_array($p)) { 
     944            foreach ($p as $key => $val) { 
     945                $qstring .= '&'.urlencode($key).'='.urlencode($val); 
     946            } 
     947        } 
     948        return $base . ($action ? '&_action='.$action : '') . $qstring; 
     949    } 
     950 
     951 
     952    /** 
     953     *@deprecated 
     954     */ 
     955 
     956    function show_message($message, $type='notice', $vars=NULL) 
     957    { 
     958        $registry = rc_registry::getInstance(); 
     959        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     960        $OUTPUT->show_message($message, $type, $vars); 
     961 
     962    } 
     963 
     964 
     965 
     966    // encrypt IMAP password using DES encryption 
     967    static function encrypt_passwd($pass) 
     968    { 
     969        $cypher = des(self::get_des_key(), $pass, 1, 0, NULL); 
     970        return base64_encode($cypher); 
     971    } 
     972 
     973    // decrypt IMAP password using DES encryption 
     974    static function decrypt_passwd($cypher) 
     975    { 
     976        $pass = des(self::get_des_key(), base64_decode($cypher), 0, 0, NULL); 
     977        return preg_replace('/\x00/', '', $pass); 
     978    } 
     979 
     980 
     981    // return a 24 byte key for the DES encryption 
     982    static function get_des_key() 
     983    { 
     984        $registry = rc_registry::getInstance(); 
     985        $CONFIG   = $registry->get('CONFIG', 'core'); 
     986        $key = !empty($CONFIG['des_key']) ? $CONFIG['des_key'] : 'rcmail?24BitPwDkeyF**ECB'; 
     987        $len = strlen($key); 
     988 
     989        // make sure the key is exactly 24 chars long 
     990        if ($len<24) { 
     991            $key .= str_repeat('_', 24-$len); 
     992        } 
     993        else if ($len>24) { 
     994            substr($key, 0, 24); 
     995        } 
     996        return $key; 
     997    } 
     998 
     999 
     1000    // read directory program/localization/ and return a list of available languages 
     1001    function rcube_list_languages() 
     1002    { 
     1003        $registry     = rc_registry::getInstance(); 
     1004        $CONFIG       = $registry->get('CONFIG', 'core'); 
     1005        $INSTALL_PATH = $registry->get('INSTALL_PATH', 'core'); 
     1006        $sa_languages = $registry->get('sa_languages', 'core'); 
     1007 
     1008        if (is_null($sa_languages)) { 
     1009            @include($INSTALL_PATH.'program/localization/index.inc'); 
     1010 
     1011            if ($dh = @opendir($INSTALL_PATH.'program/localization')) { 
     1012                while (($name = readdir($dh)) !== false) { 
     1013                    if ($name{0}=='.' || !is_dir($INSTALL_PATH.'program/localization/'.$name)) 
     1014                        continue; 
     1015 
     1016                    if ($label = $rcube_languages[$name]) 
     1017                        $sa_languages[$name] = $label ? $label : $name; 
     1018                } 
     1019                closedir($dh); 
     1020            } 
     1021            $registry->set('sa_languages', $sa_languages, 'core'); 
     1022        } 
     1023        return $sa_languages; 
     1024    } 
     1025 
     1026 
     1027    // add a localized label to the client environment 
     1028    static function rcube_add_label() 
     1029    { 
     1030        $registry = rc_registry::getInstance(); 
     1031        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     1032        $arg_list = func_get_args(); 
     1033        foreach ($arg_list as $i => $name) { 
     1034            $OUTPUT->command('add_label', $name, rcube_label($name)); 
     1035        } 
     1036    } 
     1037 
     1038 
     1039    // remove temp files older than two day 
     1040    function rcmail_temp_gc() 
     1041    { 
     1042        $registry = rc_registry::getInstance(); 
     1043        $CONFIG   = $registry->get('CONFIG', 'core'); 
     1044        $tmp      = self::unslashify($CONFIG['temp_dir']); 
     1045        $expire   = mktime() - 172800;  // expire in 48 hours 
     1046 
     1047        if (($dir = opendir($tmp)) === false) { 
     1048            return false; 
     1049        } 
     1050        while (($fname = readdir($dir)) !== false) { 
     1051            if ($fname{0} == '.') 
     1052                continue; 
     1053 
     1054            if (filemtime($tmp.'/'.$fname) < $expire) 
     1055                @unlink($tmp.'/'.$fname); 
     1056        } 
     1057        closedir($dir); 
     1058    } 
     1059 
     1060 
     1061    // remove all expired message cache records 
     1062    static function rcmail_message_cache_gc() 
     1063    { 
     1064        $registry = rc_registry::getInstance(); 
     1065        $DB       = $registry->get('DB', 'core'); 
     1066        $CONFIG   = $registry->get('CONFIG', 'core'); 
     1067 
     1068        // no cache lifetime configured 
     1069        if (empty($CONFIG['message_cache_lifetime'])) { 
     1070            return; 
     1071        } 
     1072        // get target timestamp 
     1073        $ts = get_offset_time($CONFIG['message_cache_lifetime'], -1); 
     1074 
     1075        $_query = "DELETE FROM " . self::get_table_name('messages'); 
     1076        $_query.= " WHERE created < " . $DB->fromunixtime($ts); 
     1077        $DB->query($_query); 
     1078    } 
     1079 
     1080 
     1081    /** 
     1082     * Convert a string from one charset to another. 
     1083     * Uses mbstring and iconv functions if possible 
     1084     * 
     1085     * @param  string Input string 
     1086     * @param  string Suspected charset of the input string 
     1087     * @param  string Target charset to convert to; defaults to RCMAIL_CHARSET 
     1088     * @return Converted string 
     1089     */ 
     1090    static function rcube_charset_convert($str, $from, $to=NULL) 
     1091    { 
     1092        $registry = rc_registry::getInstance(); 
     1093        $MBSTRING = $registry->get('MBSTRING', 'core'); 
     1094 
     1095        $from = strtoupper($from); 
     1096        $to = $to==NULL ? strtoupper(RCMAIL_CHARSET) : strtoupper($to); 
     1097 
     1098        if ($from==$to || $str=='' || empty($from)) { 
     1099            return $str; 
     1100        } 
     1101        // convert charset using mbstring module 
     1102        if ($MBSTRING) { 
     1103            $to = $to=="UTF-7" ? "UTF7-IMAP" : $to; 
     1104            $from = $from=="UTF-7" ? "UTF7-IMAP": $from; 
     1105 
     1106            // return if convert succeeded 
     1107            if (($out = mb_convert_encoding($str, $to, $from)) != '') { 
     1108                return $out; 
     1109            } 
     1110        } 
     1111 
     1112        // convert charset using iconv module 
     1113        if (function_exists('iconv') && $from!='UTF-7' && $to!='UTF-7') 
     1114            return iconv($from, $to, $str); 
     1115 
     1116        $conv = new utf8(); 
     1117 
     1118        // convert string to UTF-8 
     1119        if ($from=='UTF-7') { 
     1120            $str = utf7_to_utf8($str); 
     1121        } 
     1122        else if (($from=='ISO-8859-1') && function_exists('utf8_encode')) { 
     1123            $str = utf8_encode($str); 
     1124        } 
     1125        else if ($from!='UTF-8') { 
     1126            $conv->loadCharset($from); 
     1127            $str = $conv->strToUtf8($str); 
     1128        } 
     1129 
     1130        // encode string for output 
     1131        if ($to=='UTF-7') { 
     1132            return utf8_to_utf7($str); 
     1133        } 
     1134        else if ($to=='ISO-8859-1' && function_exists('utf8_decode')) { 
     1135            return utf8_decode($str); 
     1136        } 
     1137        else if ($to!='UTF-8') { 
     1138            $conv->loadCharset($to); 
     1139            return $conv->utf8ToStr($str); 
     1140        } 
     1141 
     1142        // return UTF-8 string 
     1143        return $str; 
     1144    } 
     1145 
     1146 
     1147    /** 
     1148     * Replacing specials characters to a specific encoding type 
     1149     * 
     1150     * @param  string  Input string 
     1151     * @param  string  Encoding type: text|html|xml|js|url 
     1152     * @param  string  Replace mode for tags: show|replace|remove 
     1153     * @param  boolean Convert newlines 
     1154     * @return The quoted string 
     1155     */ 
     1156    static function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE) 
     1157    { 
     1158        $registry        = rc_registry::getInstance(); 
     1159        $OUTPUT_TYPE     = $registry->get('OUTPUT_TYPE', 'core'); 
     1160        $OUTPUT          = $registry->get('OUTPUT', 'core'); 
     1161        $html_encode_arr = $registry->get('html_encode_arr', 'core'); 
     1162        $js_rep_table    = $registry->get('js_rep_table', 'core'); 
     1163        $xml_rep_table   = $registry->get('xml_rep_table', 'core'); 
     1164 
     1165        if (!$enctype) { 
     1166            $enctype = $OUTPUT_TYPE; 
     1167        } 
     1168        // convert nbsps back to normal spaces if not html 
     1169        if ($enctype!='html') { 
     1170            $str = str_replace(chr(160), ' ', $str); 
     1171        } 
     1172        // encode for plaintext 
     1173        if ($enctype=='text') { 
     1174            return str_replace( 
     1175                        "\r\n", 
     1176                        "\n", 
     1177                        $mode=='remove' ? strip_tags($str) : $str 
     1178            ); 
     1179        } 
     1180        // encode for HTML output 
     1181        if ($enctype=='html') { 
     1182            if (is_null($html_encode_arr)) { 
     1183                $html_encode_arr = get_html_translation_table(HTML_SPECIALCHARS); 
     1184                unset($html_encode_arr['?']); 
     1185                $registry->set('html_encode_arr', $html_encode_arr, 'core'); 
     1186            } 
     1187 
     1188            $ltpos = strpos($str, '<'); 
     1189            $encode_arr = $html_encode_arr; 
     1190 
     1191            // don't replace quotes and html tags 
     1192            if ( 
     1193                ($mode=='show' || $mode=='') 
     1194                && $ltpos!==false 
     1195                && strpos($str, '>', $ltpos)!==false 
     1196            ) { 
     1197                unset($encode_arr['"']); 
     1198                unset($encode_arr['<']); 
     1199                unset($encode_arr['>']); 
     1200                unset($encode_arr['&']); 
     1201            } 
     1202            else if ($mode=='remove') { 
     1203                $str = strip_tags($str); 
     1204            } 
     1205            // avoid douple quotation of & 
     1206            $out = preg_replace( 
     1207                    '/&amp;([a-z]{2,5}|#[0-9]{2,4});/', 
     1208                    '&\\1;', 
     1209                    strtr($str, $encode_arr) 
     1210            ); 
     1211            return $newlines ? nl2br($out) : $out; 
     1212        } 
     1213 
     1214        if ($enctype=='url') { 
     1215            return rawurlencode($str); 
     1216        } 
     1217        // if the replace tables for XML and JS are not yet defined 
     1218        if (is_null($js_rep_table)) { 
     1219            $js_rep_table = $xml_rep_table = array(); 
     1220            $xml_rep_table['&'] = '&amp;'; 
     1221 
     1222            for ($c=160; $c<256; $c++)  // can be increased to support more charsets 
     1223            { 
     1224                $hex = dechex($c); 
     1225                $xml_rep_table[Chr($c)] = "&#$c;"; 
     1226 
     1227                if ($OUTPUT->get_charset()=='ISO-8859-1') { 
     1228                    $js_rep_table[Chr($c)] = sprintf( 
     1229                                                "\u%s%s", 
     1230                                                str_repeat('0', 4-strlen($hex)), 
     1231                                                $hex 
     1232                    ); 
     1233                } 
     1234            } 
     1235            $xml_rep_table['"'] = '&quot;'; 
     1236            $registry->set('js_rep_table', $js_rep_table, 'core'); 
     1237        } 
     1238 
     1239        // encode for XML 
     1240        if ($enctype=='xml') { 
     1241            return strtr($str, $xml_rep_table); 
     1242        } 
     1243        // encode for javascript use 
     1244        if ($enctype=='js') { 
     1245            if ($OUTPUT->get_charset()!='UTF-8') { 
     1246                $str = self::rcube_charset_convert( 
     1247                            $str, 
     1248                            RCMAIL_CHARSET, 
     1249                            $OUTPUT->get_charset() 
     1250                ); 
     1251            } 
     1252            return preg_replace( 
     1253                        array("/\r?\n/", "/\r/"), 
     1254                        array('\n', '\n'), 
     1255                        addslashes(strtr($str, $js_rep_table)) 
     1256            ); 
     1257        } 
     1258        // no encoding given -> return original string 
     1259        return $str; 
     1260    } 
     1261 
     1262    /** 
     1263     * Quote a given string. Alias function for rep_specialchars_output 
     1264     * @see rep_specialchars_output 
     1265     */ 
     1266    static function Q($str, $mode='strict', $newlines=TRUE) 
     1267    { 
     1268        return self::rep_specialchars_output($str, 'html', $mode, $newlines); 
     1269    } 
     1270 
     1271    /** 
     1272     * Quote a given string. Alias function for rep_specialchars_output 
     1273     * @see rep_specialchars_output 
     1274     */ 
     1275    static function JQ($str) 
     1276    { 
     1277        return self::rep_specialchars_output($str, 'js'); 
     1278    } 
     1279 
     1280 
     1281    /** 
     1282     * Read input value and convert it for internal use 
     1283     * Performs stripslashes() and charset conversion if necessary 
     1284     * 
     1285     * @param  string   Field name to read 
     1286     * @param  int      Source to get value from (GPC) 
     1287     * @param  boolean  Allow HTML tags in field value 
     1288     * @param  string   Charset to convert into 
     1289     * @return string   Field value or NULL if not available 
     1290     */ 
     1291    static function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL) 
     1292    { 
     1293        $registry = rc_registry::getInstance(); 
     1294        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     1295        $value = NULL; 
     1296 
     1297        if ($source == RCUBE_INPUT_GET && isset($_GET[$fname])) { 
     1298            $value = $_GET[$fname]; 
     1299        } 
     1300        else if ($source == RCUBE_INPUT_POST && isset($_POST[$fname])) { 
     1301            $value = $_POST[$fname]; 
     1302        } 
     1303        else if ($source == RCUBE_INPUT_GPC) { 
     1304            if (isset($_POST[$fname])) 
     1305                $value = $_POST[$fname]; 
     1306            else if (isset($_GET[$fname])) 
     1307                $value = $_GET[$fname]; 
     1308            else if (isset($_COOKIE[$fname])) 
     1309                $value = $_COOKIE[$fname]; 
     1310        } 
     1311 
     1312        // strip slashes if magic_quotes enabled 
     1313        if ((bool)get_magic_quotes_gpc()) 
     1314            $value = stripslashes($value); 
     1315 
     1316        // remove HTML tags if not allowed 
     1317        if (!$allow_html) { 
     1318            $value = strip_tags($value); 
     1319        } 
     1320        // convert to internal charset 
     1321        if (is_object($OUTPUT)) { 
     1322            return self::rcube_charset_convert($value, $OUTPUT->get_charset(), $charset); 
     1323        } 
     1324        return $value; 
     1325      } 
     1326 
     1327    /** 
     1328     * Remove single and double quotes from given string 
     1329     */ 
     1330    static function strip_quotes($str) 
     1331    { 
     1332        return preg_replace('/[\'"]/', '', $str); 
     1333    } 
     1334 
     1335    /** 
     1336     * Remove new lines characters from given string 
     1337     */ 
     1338    static function strip_newlines($str) 
     1339    { 
     1340        return preg_replace('/[\r\n]/', '', $str); 
     1341    } 
     1342 
     1343 
     1344    // return boolean if a specific template exists 
     1345    static function template_exists($name) 
     1346    { 
     1347        $registry = rc_registry::getInstance(); 
     1348        $CONFIG   = $registry->get('CONFIG', 'core'); 
     1349        $skin_path = $CONFIG['skin_path']; 
     1350 
     1351        // check template file 
     1352        return is_file("$skin_path/templates/$name.html"); 
     1353    } 
     1354 
     1355 
     1356    // Wrapper for rcmail_template::parse() 
     1357    // @deprecated 
     1358    static function parse_template($name='main', $exit=true) 
     1359    { 
     1360        $registry = rc_registry::getInstance(); 
     1361        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     1362        $OUTPUT->parse($name, $exit); 
     1363    } 
     1364 
     1365    static function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col) 
     1366    { 
     1367        $registry = rc_registry::getInstance(); 
     1368        $DB       = $registry->get('DB', 'core'); 
     1369 
     1370        // allow the following attributes to be added to the <table> tag 
     1371        $attrib_str = self::create_attrib_string( 
     1372                        $attrib, 
     1373                        array( 
     1374                            'style', 
     1375                            'class', 
     1376                            'id', 
     1377                            'cellpadding', 
     1378                            'cellspacing', 
     1379                            'border', 
     1380                            'summary' 
     1381                        ) 
     1382        ); 
     1383        $table = '<table' . $attrib_str . ">\n"; 
     1384 
     1385        // add table title 
     1386        $table .= "<thead><tr>\n"; 
     1387 
     1388        foreach ($a_show_cols as $col) { 
     1389            $table .= '<td class="'.$col.'">' . self::Q(rcube_label($col)) . "</td>\n"; 
     1390        } 
     1391        $table .= "</tr></thead>\n<tbody>\n"; 
     1392 
     1393        $c = 0; 
     1394        if (!is_array($table_data)) { 
     1395            while ($table_data && ($sql_arr = $DB->fetch_assoc($table_data))) { 
     1396                $zebra_class = $c%2 ? 'even' : 'odd'; 
     1397 
     1398                $table .= sprintf( 
     1399                            '<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", 
     1400                            $sql_arr[$id_col] 
     1401                ); 
     1402 
     1403                // format each col 
     1404                foreach ($a_show_cols as $col) { 
     1405                    $cont = self::Q($sql_arr[$col]); 
     1406                    $table .= '<td class="'.$col.'">' . $cont . "</td>\n"; 
     1407                } 
     1408 
     1409                $table .= "</tr>\n"; 
     1410                $c++; 
     1411            } 
     1412        } 
     1413        else { 
     1414            foreach ($table_data as $row_data) { 
     1415                $zebra_class = $c%2 ? 'even' : 'odd'; 
     1416 
     1417                $table .= sprintf( 
     1418                            '<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", 
     1419                            $row_data[$id_col] 
     1420                ); 
     1421 
     1422                // format each col 
     1423                foreach ($a_show_cols as $col) { 
     1424                    $cont = self::Q($row_data[$col]); 
     1425                    $table .= '<td class="'.$col.'">' . $cont . "</td>\n"; 
     1426                } 
     1427 
     1428                $table .= "</tr>\n"; 
     1429                $c++; 
     1430            } 
     1431        } 
     1432 
     1433        // complete message table 
     1434        $table .= "</tbody></table>\n"; 
     1435 
     1436        return $table; 
     1437    } 
     1438 
     1439 
     1440    /** 
     1441     * Create an edit field for inclusion on a form 
     1442     * 
     1443     * @param string col field name 
     1444     * @param string value field value 
     1445     * @param array attrib HTML element attributes for field 
     1446     * @param string type HTML element type (default 'text') 
     1447     * @return string HTML field definition 
     1448     */ 
     1449    static function rcmail_get_edit_field($col, $value, $attrib, $type='text') 
     1450    { 
     1451        $fname = '_'.$col; 
     1452        $attrib['name'] = $fname; 
     1453 
     1454        if ($type=='checkbox') { 
     1455            $attrib['value'] = '1'; 
     1456            $input = new checkbox($attrib); 
     1457        } 
     1458        else if ($type=='textarea') { 
     1459            $attrib['cols'] = $attrib['size']; 
     1460            $input = new textarea($attrib); 
     1461        } 
     1462        else { 
     1463            $input = new textfield($attrib); 
     1464        } 
     1465        // use value from post 
     1466        if (!empty($_POST[$fname])) { 
     1467            $value = $_POST[$fname]; 
     1468        } 
     1469        $out = $input->show($value); 
     1470 
     1471        return $out; 
     1472    } 
     1473 
     1474 
     1475    // return the mail domain configured for the given host 
     1476    static function rcmail_mail_domain($host) 
     1477    { 
     1478        $registry = rc_registry::getInstance(); 
     1479        $CONFIG   = $regisry->get('CONFIG', 'core'); 
     1480 
     1481        $domain = $host; 
     1482        if (is_array($CONFIG['mail_domain'])) { 
     1483            if (isset($CONFIG['mail_domain'][$host])) { 
     1484                $domain = $CONFIG['mail_domain'][$host]; 
     1485            } 
     1486        } 
     1487        else if (!empty($CONFIG['mail_domain'])) { 
     1488            $domain = $CONFIG['mail_domain']; 
     1489        } 
     1490        return $domain; 
     1491    } 
     1492 
     1493 
     1494    // compose a valid attribute string for HTML tags 
     1495    static function create_attrib_string($attrib, $allowed_attribs=array('id', 'class', 'style')) 
     1496    { 
     1497        // allow the following attributes to be added to the <iframe> tag 
     1498        $attrib_str = ''; 
     1499        foreach ($allowed_attribs as $a) { 
     1500            if (isset($attrib[$a])) { 
     1501                $attrib_str .= sprintf( 
     1502                                ' %s="%s"', 
     1503                                $a, str_replace('"', '&quot;', $attrib[$a]) 
     1504                ); 
     1505            } 
     1506        } 
     1507        return $attrib_str; 
     1508    } 
     1509 
     1510 
     1511    // convert a HTML attribute string attributes to an associative array (name => value) 
     1512    function parse_attrib_string($str) 
     1513    { 
     1514        $attrib = array(); 
     1515        preg_match_all( 
     1516                '/\s*([-_a-z]+)=(["\'])([^"]+)\2/Ui', 
     1517                stripslashes($str), 
     1518                $regs, 
     1519                PREG_SET_ORDER 
     1520        ); 
     1521 
     1522        // convert attributes to an associative array (name => value) 
     1523        if ($regs) { 
     1524            foreach ($regs as $attr) { 
     1525                $attrib[strtolower($attr[1])] = $attr[3]; 
     1526            } 
     1527        } 
     1528        return $attrib; 
     1529    } 
     1530 
     1531 
     1532    static function format_date($date, $format=NULL) 
     1533    { 
     1534        $registry       = rc_registry::getInstance(); 
     1535        $CONFIG         = $registry->get('CONFIG', 'core'); 
     1536        $sess_user_lang = $registry->get('sess_user_lang', 'core'); 
     1537 
     1538        $ts = NULL; 
     1539 
     1540        if (is_numeric($date)) { 
     1541            $ts = $date; 
     1542        } 
     1543        else if (!empty($date)) { 
     1544            $ts = @strtotime($date); 
     1545        } 
     1546        if (empty($ts)) { 
     1547            return ''; 
     1548        } 
     1549        // get user's timezone 
     1550        $tz = $CONFIG['timezone']; 
     1551        if ($CONFIG['dst_active']) { 
     1552            $tz++; 
     1553        } 
     1554        // convert time to user's timezone 
     1555        $timestamp = $ts - date('Z', $ts) + ($tz * 3600); 
     1556 
     1557        // get current timestamp in user's timezone 
     1558        $now      = time();  // local time 
     1559        $now     -= (int)date('Z'); // make GMT time 
     1560        $now     += ($tz * 3600); // user's time 
     1561        $now_date = getdate($now); 
     1562 
     1563        $today_limit = mktime( 
     1564                        0, 0, 0, 
     1565                        $now_date['mon'], 
     1566                        $now_date['mday'], 
     1567                        $now_date['year'] 
     1568        ); 
     1569        $week_limit  = mktime( 
     1570                        0, 0, 0, 
     1571                        $now_date['mon'], 
     1572                        $now_date['mday']-6, 
     1573                        $now_date['year'] 
     1574        ); 
     1575 
     1576        // define date format depending on current time 
     1577        if ( 
     1578            $CONFIG['prettydate'] 
     1579            && !$format 
     1580            && $timestamp > $today_limit 
     1581            && $timestamp < $now 
     1582        ) { 
     1583            return sprintf( 
     1584                    '%s %s', 
     1585                    rcube_label('today'), 
     1586                    date( 
     1587                        $CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i', 
     1588                        $timestamp 
     1589                    ) 
     1590            ); 
     1591        } 
     1592        elseif ( 
     1593            $CONFIG['prettydate'] 
     1594            && !$format 
     1595            && $timestamp > $week_limit 
     1596            && $timestamp < $now 
     1597        ) { 
     1598            $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i'; 
     1599        } 
     1600        elseif (!$format) { 
     1601            $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i'; 
     1602        } 
     1603 
     1604        // parse format string manually in order to provide localized weekday and month names 
     1605        // an alternative would be to convert the date() format string to fit with strftime() 
     1606        $out = ''; 
     1607        for($i=0; $i<strlen($format); $i++) { 
     1608            if ($format{$i}=='\\') {  // skip escape chars 
     1609                continue; 
     1610            } 
     1611            // write char "as-is" 
     1612            if ($format{$i}==' ' || $format{$i-1}=='\\') { 
     1613                $out .= $format{$i}; 
     1614            // weekday (short) 
     1615            } 
     1616            elseif ($format{$i}=='D') { 
     1617                $out .= rcube_label(strtolower(date('D', $timestamp))); 
     1618            // weekday long 
     1619            } 
     1620            elseif ($format{$i}=='l') { 
     1621                $out .= rcube_label(strtolower(date('l', $timestamp))); 
     1622            // month name (short) 
     1623            } 
     1624            elseif ($format{$i}=='M') { 
     1625                $out .= rcube_label(strtolower(date('M', $timestamp))); 
     1626            // month name (long) 
     1627            } 
     1628            elseif ($format{$i}=='F') { 
     1629                $out .= rcube_label(strtolower(date('F', $timestamp))); 
     1630            } 
     1631            else { 
     1632                $out .= date($format{$i}, $timestamp); 
     1633            } 
     1634        } 
     1635        return $out; 
     1636    } 
     1637 
     1638 
     1639    static function format_email_recipient($email, $name='') 
     1640    { 
     1641        if ($name && $name != $email) { 
     1642            return sprintf('%s <%s>', strpos($name, ",") ? '"'.$name.'"' : $name, $email); 
     1643        } 
     1644        else { 
     1645            return $email; 
     1646        } 
     1647    } 
     1648 
     1649 
     1650 
     1651    // ************** functions delivering gui objects ************** 
     1652 
     1653 
     1654 
     1655    static function rcmail_message_container($attrib) 
     1656    { 
     1657        $registry = rc_registry::getInstance(); 
     1658        $OUPUT    = $registry->get('OUTPUT', 'core'); 
     1659 
     1660        if (!$attrib['id']) { 
     1661            $attrib['id'] = 'rcmMessageContainer'; 
     1662        } 
     1663        // allow the following attributes to be added to the <table> tag 
     1664        $attrib_str = self::create_attrib_string( 
     1665                            $attrib, 
     1666                            array('style', 'class', 'id') 
     1667        ); 
     1668        $out = '<div' . $attrib_str . "></div>"; 
     1669 
     1670        $OUTPUT->add_gui_object('message', $attrib['id']); 
     1671 
     1672        return $out; 
     1673    } 
     1674 
     1675 
     1676    // return the IMAP username of the current session 
     1677    static function rcmail_current_username($attrib) 
     1678    { 
     1679        $registry   = rc_registry::getInstance(); 
     1680        $DB         = $registry->get('DB', 'core'); 
     1681        $s_username = $registry->get('s_username', 'core'); 
     1682 
     1683        // alread fetched 
     1684        if (!empty($s_username)) { 
     1685            return $s_username; 
     1686        } 
     1687        // get e-mail address form default identity 
     1688        $_query = "SELECT email AS mailto"; 
     1689        $_query.= " FROM " . self::get_table_name('identities'); 
     1690        $_query.= " WHERE user_id=?"; 
     1691        $_query.= " AND standard=1"; 
     1692        $_query.= " AND del<>1"; 
     1693        $sql_result = $DB->query( 
     1694                            $_query, 
     1695                            $_SESSION['user_id'] 
     1696        ); 
     1697 
     1698        if ($DB->num_rows($sql_result)) { 
     1699            $sql_arr = $DB->fetch_assoc($sql_result); 
     1700            $s_username = $sql_arr['mailto']; 
     1701        } 
     1702        elseif (strstr($_SESSION['username'], '@')) { 
     1703            $s_username = $_SESSION['username']; 
     1704        } 
     1705        else { 
     1706            $s_username = $_SESSION['username'].'@'.$_SESSION['imap_host']; 
     1707        } 
     1708        return $s_username; 
     1709    } 
     1710 
     1711 
     1712    // return code for the webmail login form 
     1713    function rcmail_login_form($attrib) 
     1714    { 
     1715        $registry          = rc_registry::getInstance(); 
     1716        $CONFIG            = $registry->get('CONFIG', 'core'); 
     1717        $OUTPUT            = $registry->get('OUTPUT', 'core'); 
     1718        $SESS_HIDDEN_FIELD = $registry->get('SESS_HIDDEN_FIELD', 'core'); 
     1719 
     1720        $_SESSION['temp'] = true; 
     1721 
     1722        $labels         = array(); 
     1723        $labels['user'] = rcube_label('username'); 
     1724        $labels['pass'] = rcube_label('password'); 
     1725        $labels['host'] = rcube_label('server'); 
     1726 
     1727        $input_user   = new textfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30, 'autocomplete' => 'off')); 
     1728        $input_pass   = new passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30)); 
     1729        $input_action = new hiddenfield(array('name' => '_action', 'value' => 'login')); 
     1730 
     1731        $fields           = array(); 
     1732        $fields['user']   = $input_user->show(self::get_input_value('_user', RCUBE_INPUT_POST)); 
     1733        $fields['pass']   = $input_pass->show(); 
     1734        $fields['action'] = $input_action->show(); 
     1735 
     1736        if (is_array($CONFIG['default_host'])) { 
     1737            $select_host = new select(array('name' => '_host', 'id' => 'rcmloginhost')); 
     1738 
     1739            foreach ($CONFIG['default_host'] as $key => $value) { 
     1740                if (!is_array($value)) { 
     1741                    $select_host->add($value, (is_numeric($key) ? $value : $key)); 
     1742                } 
     1743                else { 
     1744                    unset($select_host); 
     1745                    break; 
     1746                } 
     1747            } 
     1748            $fields['host'] = isset($select_host) ? $select_host->show($_POST['_host']) : null; 
     1749        } 
     1750        else if (!strlen($CONFIG['default_host'])) { 
     1751            $input_host     = new textfield(array('name' => '_host', 'id' => 'rcmloginhost', 'size' => 30)); 
     1752            $fields['host'] = $input_host->show($_POST['_host']); 
     1753        } 
     1754 
     1755        $form_name  = strlen($attrib['form']) ? $attrib['form'] : 'form'; 
     1756        $form_start = !strlen($attrib['form']) ? '<form name="form" action="./" method="post">' : ''; 
     1757        $form_end   = !strlen($attrib['form']) ? '</form>' : ''; 
     1758        $form_host  = ''; 
     1759 
     1760        if ($fields['host']) { 
     1761            $form_host.= "</tr><tr>"; 
     1762            $form_host.= "<td class=\"title\"><label for=\"rcmloginhost\">$labels[host]</label></td>"; 
     1763            $form_host.= "<td>$fields[host]</td>"; 
     1764 
     1765        } 
     1766        $OUTPUT->add_gui_object('loginform', $form_name); 
     1767 
     1768        $out = ''; 
     1769        $out.= $form_start; 
     1770        $out.= $SESS_HIDDEN_FIELD; 
     1771        $out.= $fields[action]; 
     1772        $out.= '<table><tr>'; 
     1773        $out.= '<td class="title"><label for="rcmloginuser">'; 
     1774        $out.= "$labels[user]</label></td>"; 
     1775        $out.= "<td>$fields[user]</td>"; 
     1776        $out.= '</tr><tr>'; 
     1777        $out.= '<td class="title"><label for="rcmloginpwd">'; 
     1778        $out.= "$labels[pass]</label></td>"; 
     1779        $out.= "<td>$fields[pass]</td>"; 
     1780        $out.= $form_host; 
     1781        $out.= '</tr></table>'; 
     1782        $out.= $form_end; 
     1783 
     1784        return $out; 
     1785    } 
     1786 
     1787 
     1788    static function rcmail_charset_selector($attrib) 
     1789    { 
     1790        $registry = rc_registry::getInstance(); 
     1791        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     1792 
     1793        // pass the following attributes to the form class 
     1794        $field_attrib = array('name' => '_charset'); 
     1795        foreach ($attrib as $attr => $value) { 
     1796            if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) { 
     1797                $field_attrib[$attr] = $value; 
     1798            } 
     1799        } 
     1800        $charsets = array( 
     1801            'US-ASCII'     => 'ASCII (English)', 
     1802            'EUC-JP'       => 'EUC-JP (Japanese)', 
     1803            'EUC-KR'       => 'EUC-KR (Korean)', 
     1804            'BIG5'         => 'BIG5 (Chinese)', 
     1805            'GB2312'       => 'GB2312 (Chinese)', 
     1806            'ISO-2022-JP'  => 'ISO-2022-JP (Japanese)', 
     1807            'ISO-8859-1'   => 'ISO-8859-1 (Latin-1)', 
     1808            'ISO-8859-2'   => 'ISO-8895-2 (Central European)', 
     1809            'ISO-8859-7'   => 'ISO-8859-7 (Greek)', 
     1810            'ISO-8859-9'   => 'ISO-8859-9 (Turkish)', 
     1811            'Windows-1251' => 'Windows-1251 (Cyrillic)', 
     1812            'Windows-1252' => 'Windows-1252 (Western)', 
     1813            'Windows-1255' => 'Windows-1255 (Hebrew)', 
     1814            'Windows-1256' => 'Windows-1256 (Arabic)', 
     1815            'Windows-1257' => 'Windows-1257 (Baltic)', 
     1816            'UTF-8'        => 'UTF-8' 
     1817        ); 
     1818 
     1819        $select = new select($field_attrib); 
     1820        $select->add(array_values($charsets), array_keys($charsets)); 
     1821 
     1822        $set = $_POST['_charset'] ? $_POST['_charset'] : $OUTPUT->get_charset(); 
     1823        return $select->show($set); 
     1824    } 
     1825 
     1826 
     1827    // return code for search function 
     1828    static function rcmail_search_form($attrib) 
     1829    { 
     1830        $registry = rc_registry::getInstance(); 
     1831        $OUTPUT   = $registry->get('OUTPUT', 'core'); 
     1832 
     1833        // add some labels to client 
     1834        self::rcube_add_label('searching'); 
     1835 
     1836        $attrib['name'] = '_q'; 
     1837 
     1838        if (empty($attrib['id'])) { 
     1839            $attrib['id'] = 'rcmqsearchbox'; 
     1840        } 
     1841        $input_q = new textfield($attrib); 
     1842        $out = $input_q->show(); 
     1843 
     1844        $OUTPUT->add_gui_object('qsearchbox', $attrib['id']); 
     1845 
     1846        // add form tag around text field 
     1847        if (empty($attrib['form'])) { 
     1848            $_html = '<form name="rcmqsearchform" action="./" '; 
     1849            $_html.= 'onsubmit="%s.command(\'search\');return false" '; 
     1850            $_html.= ' style="display:inline;">%s</form>'; 
     1851            $out = sprintf( 
     1852                    $_html, 
     1853                    JS_OBJECT_NAME, 
     1854                    $out 
     1855            ); 
     1856        } 
     1857        return $out; 
     1858    } 
     1859 
     1860 
     1861    /****** debugging functions ********/ 
     1862 
     1863 
     1864    /** 
     1865     * Print or write debug messages 
     1866     * 
     1867     * @param mixed Debug message or data 
     1868     */ 
     1869    function console($msg) 
     1870    { 
     1871        $registry = rc_registry::getInstance(); 
     1872        $CONFIG   = $registry->get('CONFIG', 'core'); 
     1873        if (!is_string($msg)) { 
     1874            $msg = var_export($msg, true); 
     1875        } 
     1876        if (!($CONFIG['debug_level'] & 4)) { 
     1877            write_log('console', $msg); 
     1878        } 
     1879        elseif ($GLOBALS['REMOTE_REQUEST']) { 
     1880            echo "/*\n $msg \n*/\n"; 
     1881        } 
     1882        else { 
     1883            echo '<div style="background:#eee; border:1px solid #ccc; '; 
     1884            echo 'margin-bottom:3px; padding:6px"><pre>'; 
     1885            echo $msg; 
     1886            echo "</pre></div>\n"; 
     1887        } 
     1888    } 
     1889 
     1890 
     1891    /** 
     1892     * Append a line to a logfile in the logs directory. 
     1893     * Date will be added automatically to the line. 
     1894     * 
     1895     * @param $name Name of logfile 
     1896     * @param $line Line to append 
     1897     */ 
     1898    function write_log($name, $line) 
     1899    { 
     1900        $registry = rc_registry::getInstance(); 
     1901        $CONFIG  = $registry->get('CONFIG', 'core'); 
     1902 
     1903        if (!is_string($line)) { 
     1904            $line = var_export($line, true); 
     1905        } 
     1906        $log_entry = sprintf("[%s]: %s\n", 
     1907                     date("d-M-Y H:i:s O", mktime()), 
     1908                     $line); 
     1909 
     1910        if (empty($CONFIG['log_dir'])) { 
     1911            $CONFIG['log_dir'] = $INSTALL_PATH.'logs'; 
     1912        } 
     1913        // try to open specific log file for writing 
     1914        if ($fp = @fopen($CONFIG['log_dir'].'/'.$name, 'a')) { 
     1915            fwrite($fp, $log_entry); 
     1916            fclose($fp); 
     1917        } 
     1918    } 
     1919 
     1920 
     1921    function rcube_timer() 
     1922    { 
     1923        list($usec, $sec) = explode(" ", microtime()); 
     1924        return ((float)$usec + (float)$sec); 
     1925    } 
     1926 
     1927 
     1928    function rcube_print_time($timer, $label='Timer') 
     1929    { 
     1930        static $print_count = 0; 
     1931 
     1932        $print_count++; 
     1933        $now = rcube_timer(); 
     1934        $diff = $now-$timer; 
     1935 
     1936        if (empty($label)) { 
     1937            $label = 'Timer '.$print_count; 
     1938        } 
     1939        console(sprintf("%s: %0.4f sec", $label, $diff)); 
     1940    } 
    4831941} 
    484  
    485  
    486 // perfom login to the IMAP server and to the webmail service 
    487 function rcmail_login($user, $pass, $host=NULL) 
    488 { 
    489     global $CONFIG, $IMAP, $DB, $sess_user_lang; 
    490     $user_id = NULL; 
    491  
    492     if (!$host) { 
    493         $host = $CONFIG['default_host']; 
    494     } 
    495     // Validate that selected host is in the list of configured hosts 
    496     if (is_array($CONFIG['default_host'])) { 
    497         $allowed = FALSE; 
    498         foreach ($CONFIG['default_host'] as $key => $host_allowed) { 
    499             if (!is_numeric($key)) { 
    500                 $host_allowed = $key; 
    501             } 
    502             if ($host == $host_allowed) { 
    503                 $allowed = TRUE; 
    504                 break; 
    505             } 
    506         } 
    507         if (!$allowed) { 
    508             return FALSE; 
    509         } 
    510     } 
    511     else if (!empty($CONFIG['default_host']) && $host != $CONFIG['default_host']) { 
    512         return FALSE; 
    513     } 
    514  
    515     // parse $host URL 
    516     $a_host = parse_url($host); 
    517     if ($a_host['host']) { 
    518         $host = $a_host['host']; 
    519         $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE; 
    520         $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $CONFIG['default_port']); 
    521     } 
    522     else { 
    523         $imap_port = $CONFIG['default_port']; 
    524     } 
    525  
    526     /** 
    527      * Modify username with domain if required 
    528      * Inspired by Marco <P0L0_notspam_binware.org> 
    529      */ 
    530     // Check if we need to add domain 
    531     //tfk_debug('User #1: ' . $user); 
    532     //tfk_debug('Host: ' . $CONFIG['username_domain']); 
    533     if (!empty($CONFIG['username_domain']) && !strstr($user, '@')) { 
    534         if (is_array($CONFIG['username_domain']) && isset($CONFIG['username_domain'][$host])) { 
    535             $user .= '@' . $CONFIG['username_domain'][$host]; 
    536         } 
    537         else if (is_string($CONFIG['username_domain'])) { 
    538             $user .= '@' . $CONFIG['username_domain']; 
    539         } 
    540     } 
    541     //tfk_debug('User #2: ' . $user); 
    542  
    543     // query if user already registered 
    544     $_query = "SELECT user_id, username, language, preferences"; 
    545     $_query.= " FROM " . get_table_name('users'); 
    546     $_query.= " WHERE mail_host=?"; 
    547     $_query.= " AND (username=? OR alias=?)"; 
    548  
    549     $sql_result = $DB->query( 
    550                         $_query, 
    551                         $host, 
    552                         $user, 
    553                         $user 
    554     ); 
    555     if ($DB->db_error === true) { 
    556         return FALSE; 
    557     } 
    558     // user already registered -> overwrite username 
    559     if ($sql_arr = $DB->fetch_assoc($sql_result)) { 
    560         $user_id = $sql_arr['user_id']; 
    561         $user    = $sql_arr['username']; 
    562     } 
    563  
    564     // try to resolve email address from virtuser table 
    565     if (!empty($CONFIG['virtuser_file']) && strstr($user, '@')) { 
    566         $user = rcmail_email2user($user); 
    567     } 
    568  
    569     // exit if IMAP login failed 
    570     if (!($imap_login  = $IMAP->connect($host, $user, $pass, $imap_port, $imap_ssl))) { 
    571         return FALSE; 
    572     } 
    573     // user already registered 
    574     if ($user_id && !empty($sql_arr)) { 
    575         // get user prefs 
    576         if (strlen($sql_arr['preferences'])) { 
    577             $user_prefs = unserialize($sql_arr['preferences']); 
    578             $_SESSION['user_prefs'] = $user_prefs; 
    579             array_merge($CONFIG, $user_prefs); 
    580         } 
    581  
    582  
    583         // set user specific language 
    584         if (strlen($sql_arr['language'])) { 
    585             $sess_user_lang = $_SESSION['user_lang'] = $sql_arr['language']; 
    586         } 
    587         // update user's record 
    588         $_query = "UPDATE ".get_table_name('users'); 
    589         $_query.= " SET last_login=".$DB->now(); 
    590         $_query.= " WHERE user_id=?"; 
    591         $DB->query($_query, $user_id); 
    592     } 
    593     // create new system user 
    594     else if ($CONFIG['auto_create_user']) { 
    595         $user_id = rcmail_create_user($user, $host); 
    596     } 
    597  
    598     //tfk_debug('User id: ' . $user_id); 
    599  
    600     if (empty($user_id) === true) { 
    601         return false; 
    602     } 
    603     $_SESSION['user_id']   = $user_id; 
    604     $_SESSION['imap_host'] = $host; 
    605     $_SESSION['imap_port'] = $imap_port; 
    606     $_SESSION['imap_ssl']  = $imap_ssl; 
    607     $_SESSION['username']  = $user; 
    608     $_SESSION['user_lang'] = $sess_user_lang; 
    609     $_SESSION['password']  = encrypt_passwd($pass); 
    610     $_SESSION['login_time'] = mktime(); 
    611  
    612     /** 
    613      * If multi-SMTP servers, use correct one 
    614      * Otherwise, use the general SMTP server 
    615      * or use phpMail function 
    616      * 
    617      * @author Brett Patterson <brett@bpatterson.net> 
    618      * @author Till Klampaeckel <till@php.net> 
    619      */ 
    620     if(is_array($CONFIG['smtp_server']) === true) { 
    621         if (isset($CONFIG['smtp_server'][$host]) === true) { 
    622             $_SESSION['smtp_server'] = $CONFIG['smtp_server'][$host]; 
    623         } 
    624         else { 
    625             $_SESSION['smtp_server'] = 'phpMail'; 
    626         } 
    627     } 
    628     else { 
    629         if (empty($CONFIG['smtp_server']) === false) { 
    630             $_SESSION['smtp_server'] = $CONFIG['smtp_server']; 
    631         } 
    632         else { 
    633             $_SESSION['smtp_server'] = 'phpMail'; 
    634         } 
    635     } 
    636  
    637     // force reloading complete list of subscribed mailboxes 
    638     rcmail_set_imap_prop(); 
    639     $IMAP->clear_cache('mailboxes'); 
    640     $IMAP->create_default_folders(); 
    641  
    642     return TRUE; 
    643 } 
    644  
    645  
    646 // create new entry in users and identities table 
    647 function rcmail_create_user($user, $host) 
    648   { 
    649   global $DB, $CONFIG, $IMAP; 
    650  
    651   $user_email = ''; 
    652  
    653   // try to resolve user in virtusertable 
    654   if (!empty($CONFIG['virtuser_file']) && strstr($user, '@')==FALSE) 
    655     $user_email = rcmail_user2email($user); 
    656  
    657   $DB->query("INSERT INTO ".get_table_name('users')." 
    658               (created, last_login, username, mail_host, alias, language) 
    659               VALUES (".$DB->now().", ".$DB->now().", ?, ?, ?, ?)", 
    660               strip_newlines($user), 
    661               strip_newlines($host), 
    662               strip_newlines($user_email), 
    663               $_SESSION['user_lang']); 
    664  
    665   if ($user_id = $DB->insert_id(get_sequence_name('users'))) 
    666     { 
    667     $mail_domain = rcmail_mail_domain($host); 
    668  
    669     if ($user_email=='') 
    670       $user_email = strstr($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain); 
    671  
    672     $user_name = $user!=$user_email ? $user : ''; 
    673  
    674     // try to resolve the e-mail address from the virtuser table 
    675     if (!empty($CONFIG['virtuser_query']) && 
    676         ($sql_result = $DB->query(preg_replace('/%u/', $user, $CONFIG['virtuser_query']))) && 
    677         ($DB->num_rows()>0)) 
    678       while ($sql_arr = $DB->fetch_array($sql_result)) 
    679         { 
    680         $DB->query("INSERT INTO ".get_table_name('identities')." 
    681                    (user_id, del, standard, name, email) 
    682                    VALUES (?, 0, 1, ?, ?)", 
    683                    $user_id, 
    684                    strip_newlines($user_name), 
    685                    preg_replace('/^@/', $user . '@', $sql_arr[0])); 
    686         } 
    687     else 
    688       { 
    689       // also create new identity records 
    690       $DB->query("INSERT INTO ".get_table_name('identities')." 
    691                   (user_id, del, standard, name, email) 
    692                   VALUES (?, 0, 1, ?, ?)", 
    693                   $user_id, 
    694                   strip_newlines($user_name), 
    695                   strip_newlines($user_email)); 
    696       } 
    697  
    698     // get existing mailboxes 
    699     $a_mailboxes = $IMAP->list_mailboxes(); 
    700     } 
    701   else 
    702     { 
    703     raise_error(array('code' => 500, 
    704                       'type' => 'php', 
    705                       'line' => __LINE__, 
    706                       'file' => __FILE__, 
    707                       'message' => "Failed to create new user"), TRUE, FALSE); 
    708     } 
    709  
    710   return $user_id; 
    711   } 
    712  
    713  
    714 // load virtuser table in array 
    715 function rcmail_getvirtualfile() 
    716   { 
    717   global $CONFIG; 
    718   if (empty($CONFIG['virtuser_file']) || !is_file($CONFIG['virtuser_file'])) 
    719     return FALSE; 
    720  
    721   // read file 
    722   $a_lines = file($CONFIG['virtuser_file']); 
    723   return $a_lines; 
    724   } 
    725  
    726  
    727 // find matches of the given pattern in virtuser table 
    728 function rcmail_findinvirtual($pattern) 
    729 { 
    730     $result = array(); 
    731     $virtual = rcmail_getvirtualfile(); 
    732     if ($virtual==FALSE) { 
    733         return $result; 
    734     } 
    735     // check each line for matches 
    736     foreach ($virtual as $line) { 
    737         $line = trim($line); 
    738         if (empty($line) || $line{0}=='#') { 
    739             continue; 
    740         } 
    741         if (eregi($pattern, $line)) { 
    742             $result[] = $line; 
    743         } 
    744     } 
    745     return $result; 
    746 } 
    747  
    748  
    749 // resolve username with virtuser table 
    750 function rcmail_email2user($email) 
    751   { 
    752   $user = $email; 
    753   $r = rcmail_findinvirtual("^$email"); 
    754  
    755   for ($i=0; $i<count($r); $i++) 
    756     { 
    757     $data = $r[$i]; 
    758     $arr = preg_split('/\s+/', $data); 
    759     if(count($arr)>0) 
    760       { 
    761       $user = trim($arr[count($arr)-1]); 
    762       break; 
    763       } 
    764     } 
    765  
    766   return $user; 
    767   } 
    768  
    769  
    770 // resolve e-mail address with virtuser table 
    771 function rcmail_user2email($user) 
    772   { 
    773   $email = ""; 
    774   $r = rcmail_findinvirtual("$user$"); 
    775  
    776   for ($i=0; $i<count($r); $i++) 
    777     { 
    778     $data=$r[$i]; 
    779     $arr = preg_split('/\s+/', $data); 
    780     if (count($arr)>0) 
    781       { 
    782       $email = trim($arr[0]); 
    783       break; 
    784       } 
    785     } 
    786  
    787   return $email; 
    788   } 
    789  
    790  
    791 function rcmail_save_user_prefs($a_user_prefs) 
    792   { 
    793   global $DB, $CONFIG, $sess_user_lang; 
    794  
    795   $DB->query("UPDATE ".get_table_name('users')." 
    796               SET    preferences=?, 
    797                      language=? 
    798               WHERE  user_id=?", 
    799               serialize($a_user_prefs), 
    800               $sess_user_lang, 
    801               $_SESSION['user_id']); 
    802  
    803   if ($DB->affected_rows()) 
    804     { 
    805     $_SESSION['user_prefs'] = $a_user_prefs; 
    806     $CONFIG = array_merge($CONFIG, $a_user_prefs); 
    807     return TRUE; 
    808     } 
    809  
    810   return FALSE; 
    811   } 
    812  
    813  
    814 // overwrite action variable 
    815 function rcmail_overwrite_action($action) 
    816   { 
    817   global $OUTPUT; 
    818   $GLOBALS['_action'] = $action; 
    819   $OUTPUT->set_env('action', $action); 
    820   } 
    821  
    822  
    823 /** 
    824  * Compose an URL for a specific action 
    825  * 
    826  * @param string  Request action 
    827  * @param array   More URL parameters 
    828  * @param string  Request task (omit if the same) 
    829  * @return The application URL 
    830  */ 
    831 function rcmail_url($action, $p=array(), $task=null) 
    832 { 
    833   global $MAIN_TASKS, $COMM_PATH; 
    834   $qstring = ''; 
    835   $base = $COMM_PATH; 
    836  
    837   if ($task && in_array($task, $MAIN_TASKS)) 
    838     $base = ereg_replace('_task=[a-z]+', '_task='.$task, $COMM_PATH); 
    839  
    840   if (is_array($p)) 
    841     foreach ($p as $key => $val) 
    842       $qstring .= '&'.urlencode($key).'='.urlencode($val); 
    843  
    844   return $base . ($action ? '&_action='.$action : '') . $qstring; 
    845 } 
    846  
    847  
    848 // @deprecated 
    849 function show_message($message, $type='notice', $vars=NULL) 
    850   { 
    851   global $OUTPUT; 
    852   $OUTPUT->show_message($message, $type, $vars); 
    853   } 
    854  
    855  
    856 // encrypt IMAP password using DES encryption 
    857 function encrypt_passwd($pass) 
    858   { 
    859   $cypher = des(get_des_key(), $pass, 1, 0, NULL); 
    860   return base64_encode($cypher); 
    861   } 
    862  
    863  
    864 // decrypt IMAP password using DES encryption 
    865 function decrypt_passwd($cypher) 
    866   { 
    867   $pass = des(get_des_key(), base64_decode($cypher), 0, 0, NULL); 
    868   return preg_replace('/\x00/', '', $pass); 
    869   } 
    870  
    871  
    872 // return a 24 byte key for the DES encryption 
    873 function get_des_key() 
    874   { 
    875   $key = !empty($GLOBALS['CONFIG']['des_key']) ? $GLOBALS['CONFIG']['des_key'] : 'rcmail?24BitPwDkeyF**ECB'; 
    876   $len = strlen($key); 
    877  
    878   // make sure the key is exactly 24 chars long 
    879   if ($len<24) 
    880     $key .= str_repeat('_', 24-$len); 
    881   else if ($len>24) 
    882     substr($key, 0, 24); 
    883  
    884   return $key; 
    885   } 
    886  
    887  
    888 // read directory program/localization/ and return a list of available languages 
    889 function rcube_list_languages() 
    890   { 
    891   global $CONFIG, $INSTALL_PATH; 
    892   static $sa_languages = array(); 
    893  
    894   if (!sizeof($sa_languages)) 
    895     { 
    896     @include($INSTALL_PATH.'program/localization/index.inc'); 
    897  
    898     if ($dh = @opendir($INSTALL_PATH.'program/localization')) 
    899       { 
    900       while (($name = readdir($dh)) !== false) 
    901         { 
    902         if ($name{0}=='.' || !is_dir($INSTALL_PATH.'program/localization/'.$name)) 
    903           continue; 
    904  
    905         if ($label = $rcube_languages[$name]) 
    906           $sa_languages[$name] = $label ? $label : $name; 
    907         } 
    908       closedir($dh); 
    909       } 
    910     } 
    911   return $sa_languages; 
    912   } 
    913  
    914  
    915 // add a localized label to the client environment 
    916 function rcube_add_label() 
    917   { 
    918   global $OUTPUT; 
    919  
    920   $arg_list = func_get_args(); 
    921   foreach ($arg_list as $i => $name) 
    922     $OUTPUT->command('add_label', $name, rcube_label($name)); 
    923   } 
    924  
    925  
    926 // remove temp files older than two day 
    927 function rcmail_temp_gc() 
    928   { 
    929   $tmp = unslashify($CONFIG['temp_dir']); 
    930   $expire = mktime() - 172800;  // expire in 48 hours 
    931  
    932   if ($dir = opendir($tmp)) 
    933     { 
    934     while (($fname = readdir($dir)) !== false) 
    935       { 
    936       if ($fname{0} == '.') 
    937         continue; 
    938  
    939       if (filemtime($tmp.'/'.$fname) < $expire) 
    940         @unlink($tmp.'/'.$fname); 
    941       } 
    942  
    943     closedir($dir); 
    944     } 
    945   } 
    946  
    947  
    948 // remove all expired message cache records 
    949 function rcmail_message_cache_gc() 
    950   { 
    951   global $DB, $CONFIG; 
    952  
    953   // no cache lifetime configured 
    954   if (empty($CONFIG['message_cache_lifetime'])) 
    955     return; 
    956  
    957   // get target timestamp 
    958   $ts = get_offset_time($CONFIG['message_cache_lifetime'], -1); 
    959  
    960   $DB->query("DELETE FROM ".get_table_name('messages')." 
    961              WHERE  created < ".$DB->fromunixtime($ts)); 
    962   } 
    963  
    964  
    965 /** 
    966  * Convert a string from one charset to another. 
    967  * Uses mbstring and iconv functions if possible 
    968  * 
    969  * @param  string Input string 
    970  * @param  string Suspected charset of the input string 
    971  * @param  string Target charset to convert to; defaults to RCMAIL_CHARSET 
    972  * @return Converted string 
    973  */ 
    974 function rcube_charset_convert($str, $from, $to=NULL) 
    975   { 
    976   global $MBSTRING; 
    977  
    978   $from = strtoupper($from); 
    979   $to = $to==NULL ? strtoupper(RCMAIL_CHARSET) : strtoupper($to); 
    980  
    981   if ($from==$to || $str=='' || empty($from)) 
    982     return $str; 
    983  
    984   // convert charset using mbstring module 
    985   if ($MBSTRING) 
    986     { 
    987     $to = $to=="UTF-7" ? "UTF7-IMAP" : $to; 
    988     $from = $from=="UTF-7" ? "UTF7-IMAP": $from; 
    989  
    990     // return if convert succeeded 
    991     if (($out = mb_convert_encoding($str, $to, $from)) != '') 
    992       return $out; 
    993     } 
    994  
    995   // convert charset using iconv module 
    996   if (function_exists('iconv') && $from!='UTF-7' && $to!='UTF-7') 
    997     return iconv($from, $to, $str); 
    998  
    999   $conv = new utf8(); 
    1000  
    1001   // convert string to UTF-8 
    1002   if ($from=='UTF-7') 
    1003     $str = utf7_to_utf8($str); 
    1004   else if (($from=='ISO-8859-1') && function_exists('utf8_encode')) 
    1005     $str = utf8_encode($str); 
    1006   else if ($from!='UTF-8') 
    1007     { 
    1008     $conv->loadCharset($from); 
    1009     $str = $conv->strToUtf8($str); 
    1010     } 
    1011  
    1012   // encode string for output 
    1013   if ($to=='UTF-7') 
    1014     return utf8_to_utf7($str); 
    1015   else if ($to=='ISO-8859-1' && function_exists('utf8_decode')) 
    1016     return utf8_decode($str); 
    1017   else if ($to!='UTF-8') 
    1018     { 
    1019     $conv->loadCharset($to); 
    1020     return $conv->utf8ToStr($str); 
    1021     } 
    1022  
    1023   // return UTF-8 string 
    1024   return $str; 
    1025   } 
    1026  
    1027  
    1028 /** 
    1029  * Replacing specials characters to a specific encoding type 
    1030  * 
    1031  * @param  string  Input string 
    1032  * @param  string  Encoding type: text|html|xml|js|url 
    1033  * @param  string  Replace mode for tags: show|replace|remove 
    1034  * @param  boolean Convert newlines 
    1035  * @return The quoted string 
    1036  */ 
    1037 function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE) 
    1038   { 
    1039   global $OUTPUT_TYPE, $OUTPUT; 
    1040   static $html_encode_arr, $js_rep_table, $xml_rep_table; 
    1041  
    1042   if (!$enctype) 
    1043     $enctype = $GLOBALS['OUTPUT_TYPE']; 
    1044  
    1045   // convert nbsps back to normal spaces if not html 
    1046   if ($enctype!='html') 
    1047     $str = str_replace(chr(160), ' ', $str); 
    1048  
    1049   // encode for plaintext 
    1050   if ($enctype=='text') 
    1051     return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str); 
    1052  
    1053   // encode for HTML output 
    1054   if ($enctype=='html') 
    1055     { 
    1056     if (!$html_encode_arr) 
    1057       { 
    1058       $html_encode_arr = get_html_translation_table(HTML_SPECIALCHARS); 
    1059       unset($html_encode_arr['?']); 
    1060       } 
    1061  
    1062     $ltpos = strpos($str, '<'); 
    1063     $encode_arr = $html_encode_arr; 
    1064  
    1065     // don't replace quotes and html tags 
    1066     if (($mode=='show' || $mode=='') && $ltpos!==false && strpos($str, '>', $ltpos)!==false) 
    1067       { 
    1068       unset($encode_arr['"']); 
    1069       unset($encode_arr['<']); 
    1070       unset($encode_arr['>']); 
    1071       unset($encode_arr['&']); 
    1072       } 
    1073     else if ($mode=='remove') 
    1074       $str = strip_tags($str); 
    1075  
    1076     // avoid douple quotation of & 
    1077     $out = preg_replace('/&amp;([a-z]{2,5}|#[0-9]{2,4});/', '&\\1;', strtr($str, $encode_arr)); 
    1078  
    1079     return $newlines ? nl2br($out) : $out; 
    1080     } 
    1081  
    1082   if ($enctype=='url') 
    1083     return rawurlencode($str); 
    1084  
    1085   // if the replace tables for XML and JS are not yet defined 
    1086   if (!$js_rep_table) 
    1087     { 
    1088     $js_rep_table = $xml_rep_table = array(); 
    1089     $xml_rep_table['&'] = '&amp;'; 
    1090  
    1091     for ($c=160; $c<256; $c++)  // can be increased to support more charsets 
    1092       { 
    1093       $hex = dechex($c); 
    1094       $xml_rep_table[Chr($c)] = "&#$c;"; 
    1095  
    1096       if ($OUTPUT->get_charset()=='ISO-8859-1') 
    1097         $js_rep_table[Chr($c)] = sprintf("\u%s%s", str_repeat('0', 4-strlen($hex)), $hex); 
    1098       } 
    1099  
    1100     $xml_rep_table['"'] = '&quot;'; 
    1101     } 
    1102  
    1103   // encode for XML 
    1104   if ($enctype=='xml') 
    1105     return strtr($str, $xml_rep_table); 
    1106  
    1107   // encode for javascript use 
    1108   if ($enctype=='js') 
    1109     { 
    1110     if ($OUTPUT->get_charset()!='UTF-8') 
    1111       $str = rcube_charset_convert($str, RCMAIL_CHARSET, $OUTPUT->get_charset()); 
    1112  
    1113     return preg_replace(array("/\r?\n/", "/\r/"), array('\n', '\n'), addslashes(strtr($str, $js_rep_table))); 
    1114     } 
    1115  
    1116   // no encoding given -> return original string 
    1117   return $str; 
    1118   } 
    1119  
    1120 /** 
    1121  * Quote a given string. Alias function for rep_specialchars_output 
    1122  * @see rep_specialchars_output 
    1123  */ 
    1124 function Q($str, $mode='strict', $newlines=TRUE) 
    1125   { 
    1126   return rep_specialchars_output($str, 'html', $mode, $newlines); 
    1127   } 
    1128  
    1129 /** 
    1130  * Quote a given string. Alias function for rep_specialchars_output 
    1131  * @see rep_specialchars_output 
    1132  */ 
    1133 function JQ($str) 
    1134   { 
    1135   return rep_specialchars_output($str, 'js'); 
    1136   } 
    1137  
    1138  
    1139 /** 
    1140  * Read input value and convert it for internal use 
    1141  * Performs stripslashes() and charset conversion if necessary 
    1142  * 
    1143  * @param  string   Field name to read 
    1144  * @param  int      Source to get value from (GPC) 
    1145  * @param  boolean  Allow HTML tags in field value 
    1146  * @param  string   Charset to convert into 
    1147  * @return string   Field value or NULL if not available 
    1148  */ 
    1149 function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL) 
    1150   { 
    1151   global $OUTPUT; 
    1152   $value = NULL; 
    1153  
    1154   if ($source==RCUBE_INPUT_GET && isset($_GET[$fname])) 
    1155     $value = $_GET[$fname]; 
    1156   else if ($source==RCUBE_INPUT_POST && isset($_POST[$fname])) 
    1157     $value = $_POST[$fname]; 
    1158   else if ($source==RCUBE_INPUT_GPC) 
    1159     { 
    1160     if (isset($_POST[$fname])) 
    1161       $value = $_POST[$fname]; 
    1162     else if (isset($_GET[$fname])) 
    1163       $value = $_GET[$fname]; 
    1164     else if (isset($_COOKIE[$fname])) 
    1165       $value = $_COOKIE[$fname]; 
    1166     } 
    1167  
    1168   // strip slashes if magic_quotes enabled 
    1169   if ((bool)get_magic_quotes_gpc()) 
    1170     $value = stripslashes($value); 
    1171  
    1172   // remove HTML tags if not allowed 
    1173   if (!$allow_html) 
    1174     $value = strip_tags($value); 
    1175  
    1176   // convert to internal charset 
    1177   if (is_object($OUTPUT)) 
    1178     return rcube_charset_convert($value, $OUTPUT->get_charset(), $charset); 
    1179   else 
    1180     return $value; 
    1181   } 
    1182  
    1183 /** 
    1184  * Remove single and double quotes from given string 
    1185  */ 
    1186 function strip_quotes($str) 
    1187 { 
    1188   return preg_replace('/[\'"]/', '', $str); 
    1189 } 
    1190  
    1191 /** 
    1192  * Remove new lines characters from given string 
    1193  */ 
    1194 function strip_newlines($str) 
    1195 { 
    1196   return preg_replace('/[\r\n]/', '', $str); 
    1197 } 
    1198  
    1199  
    1200 // return boolean if a specific template exists 
    1201 function template_exists($name) 
    1202   { 
    1203   global $CONFIG; 
    1204   $skin_path = $CONFIG['skin_path']; 
    1205  
    1206   // check template file 
    1207   return is_file("$skin_path/templates/$name.html"); 
    1208   } 
    1209  
    1210  
    1211 // Wrapper for rcmail_template::parse() 
    1212 // @deprecated 
    1213 function parse_template($name='main', $exit=true) 
    1214   { 
    1215   $GLOBALS['OUTPUT']->parse($name, $exit); 
    1216   } 
    1217  
    1218  
    1219  
    1220 function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col) 
    1221   { 
    1222   global $DB; 
    1223  
    1224   // allow the following attributes to be added to the <table> tag 
    1225   $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary')); 
    1226  
    1227   $table = '<table' . $attrib_str . ">\n"; 
    1228  
    1229   // add table title 
    1230   $table .= "<thead><tr>\n"; 
    1231  
    1232   foreach ($a_show_cols as $col) 
    1233     $table .= '<td class="'.$col.'">' . Q(rcube_label($col)) . "</td>\n"; 
    1234  
    1235   $table .= "</tr></thead>\n<tbody>\n"; 
    1236  
    1237   $c = 0; 
    1238   if (!is_array($table_data)) 
    1239     { 
    1240     while ($table_data && ($sql_arr = $DB->fetch_assoc($table_data))) 
    1241       { 
    1242       $zebra_class = $c%2 ? 'even' : 'odd'; 
    1243  
    1244       $table .= sprintf('<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", $sql_arr[$id_col]); 
    1245  
    1246       // format each col 
    1247       foreach ($a_show_cols as $col) 
    1248         { 
    1249         $cont = Q($sql_arr[$col]); 
    1250         $table .= '<td class="'.$col.'">' . $cont . "</td>\n"; 
    1251         } 
    1252  
    1253       $table .= "</tr>\n"; 
    1254       $c++; 
    1255       } 
    1256     } 
    1257   else 
    1258     { 
    1259     foreach ($table_data as $row_data) 
    1260       { 
    1261       $zebra_class = $c%2 ? 'even' : 'odd'; 
    1262  
    1263       $table .= sprintf('<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", $row_data[$id_col]); 
    1264  
    1265       // format each col 
    1266       foreach ($a_show_cols as $col) 
    1267         { 
    1268         $cont = Q($row_data[$col]); 
    1269         $table .= '<td class="'.$col.'">' . $cont . "</td>\n"; 
    1270         } 
    1271  
    1272       $table .= "</tr>\n"; 
    1273       $c++; 
    1274       } 
    1275     } 
    1276  
    1277   // complete message table 
    1278   $table .= "</tbody></table>\n"; 
    1279  
    1280   return $table; 
    1281   } 
    1282  
    1283  
    1284 /** 
    1285  * Create an edit field for inclusion on a form 
    1286  * 
    1287  * @param string col field name 
    1288  * @param string value field value 
    1289  * @param array attrib HTML element attributes for field 
    1290  * @param string type HTML element type (default 'text') 
    1291  * @return string HTML field definition 
    1292  */ 
    1293 function rcmail_get_edit_field($col, $value, $attrib, $type='text') 
    1294   { 
    1295   $fname = '_'.$col; 
    1296   $attrib['name'] = $fname; 
    1297  
    1298   if ($type=='checkbox') 
    1299     { 
    1300     $attrib['value'] = '1'; 
    1301     $input = new checkbox($attrib); 
    1302     } 
    1303   else if ($type=='textarea') 
    1304     { 
    1305     $attrib['cols'] = $attrib['size']; 
    1306     $input = new textarea($attrib); 
    1307     } 
    1308   else 
    1309     $input = new textfield($attrib); 
    1310  
    1311   // use value from post 
    1312   if (!empty($_POST[$fname])) 
    1313     $value = $_POST[$fname]; 
    1314  
    1315   $out = $input->show($value); 
    1316  
    1317   return $out; 
    1318   } 
    1319  
    1320  
    1321 // return the mail domain configured for the given host 
    1322 function rcmail_mail_domain($host) 
    1323   { 
    1324   global $CONFIG; 
    1325  
    1326   $domain = $host; 
    1327   if (is_array($CONFIG['mail_domain'])) 
    1328     { 
    1329     if (isset($CONFIG['mail_domain'][$host])) 
    1330       $domain = $CONFIG['mail_domain'][$host]; 
    1331     } 
    1332   else if (!empty($CONFIG['mail_domain'])) 
    1333     $domain = $CONFIG['mail_domain']; 
    1334  
    1335   return $domain; 
    1336   } 
    1337  
    1338  
    1339 // compose a valid attribute string for HTML tags 
    1340 function create_attrib_string($attrib, $allowed_attribs=array('id', 'class', 'style')) 
    1341   { 
    1342   // allow the following attributes to be added to the <iframe> tag 
    1343   $attrib_str = ''; 
    1344   foreach ($allowed_attribs as $a) 
    1345     if (isset($attrib[$a])) 
    1346       $attrib_str .= sprintf(' %s="%s"', $a, str_replace('"', '&quot;', $attrib[$a])); 
    1347  
    1348   return $attrib_str; 
    1349   } 
    1350  
    1351  
    1352 // convert a HTML attribute string attributes to an associative array (name => value) 
    1353 function parse_attrib_string($str) 
    1354   { 
    1355   $attrib = array(); 
    1356   preg_match_all('/\s*([-_a-z]+)=(["\'])([^"]+)\2/Ui', stripslashes($str), $regs, PREG_SET_ORDER); 
    1357  
    1358   // convert attributes to an associative array (name => value) 
    1359   if ($regs) 
    1360     foreach ($regs as $attr) 
    1361       $attrib[strtolower($attr[1])] = $attr[3]; 
    1362  
    1363   return $attrib; 
    1364   } 
    1365  
    1366  
    1367 function format_date($date, $format=NULL) 
    1368   { 
    1369   global $CONFIG, $sess_user_lang; 
    1370  
    1371   $ts = NULL; 
    1372  
    1373   if (is_numeric($date)) 
    1374     $ts = $date; 
    1375   else if (!empty($date)) 
    1376     $ts = @strtotime($date); 
    1377  
    1378   if (empty($ts)) 
    1379     return ''; 
    1380  
    1381   // get user's timezone 
    1382   $tz = $CONFIG['timezone']; 
    1383   if ($CONFIG['dst_active']) 
    1384     $tz++; 
    1385  
    1386   // convert time to user's timezone 
    1387   $timestamp = $ts - date('Z', $ts) + ($tz * 3600); 
    1388  
    1389   // get current timestamp in user's timezone 
    1390   $now = time();  // local time 
    1391   $now -= (int)date('Z'); // make GMT time 
    1392   $now += ($tz * 3600); // user's time 
    1393   $now_date = getdate($now); 
    1394  
    1395   $today_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'], $now_date['year']); 
    1396   $week_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']); 
    1397  
    1398   // define date format depending on current time 
    1399   if ($CONFIG['prettydate'] && !$format && $timestamp > $today_limit && $timestamp < $now) 
    1400     return sprintf('%s %s', rcube_label('today'), date($CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i', $timestamp)); 
    1401   else if ($CONFIG['prettydate'] && !$format && $timestamp > $week_limit && $timestamp < $now) 
    1402     $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i'; 
    1403   else if (!$format) 
    1404     $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i'; 
    1405  
    1406  
    1407   // parse format string manually in order to provide localized weekday and month names 
    1408   // an alternative would be to convert the date() format string to fit with strftime() 
    1409   $out = ''; 
    1410   for($i=0; $i<strlen($format); $i++) 
    1411     { 
    1412     if ($format{$i}=='\\')  // skip escape chars 
    1413       continue; 
    1414  
    1415     // write char "as-is" 
    1416     if ($format{$i}==' ' || $format{$i-1}=='\\') 
    1417       $out .= $format{$i}; 
    1418     // weekday (short) 
    1419     else if ($format{$i}=='D') 
    1420       $out .= rcube_label(strtolower(date('D', $timestamp))); 
    1421     // weekday long 
    1422     else if ($format{$i}=='l') 
    1423       $out .= rcube_label(strtolower(date('l', $timestamp))); 
    1424     // month name (short) 
    1425     else if ($format{$i}=='M') 
    1426       $out .= rcube_label(strtolower(date('M', $timestamp))); 
    1427     // month name (long) 
    1428     else if ($format{$i}=='F') 
    1429       $out .= rcube_label(strtolower(date('F', $timestamp))); 
    1430     else 
    1431       $out .= date($format{$i}, $timestamp); 
    1432     } 
    1433  
    1434   return $out; 
    1435   } 
    1436  
    1437  
    1438 function format_email_recipient($email, $name='') 
    1439   { 
    1440   if ($name && $name != $email) 
    1441     return sprintf('%s <%s>', strpos($name, ",") ? '"'.$name.'"' : $name, $email); 
    1442   else 
    1443     return $email; 
    1444   } 
    1445  
    1446  
    1447  
    1448 // ************** functions delivering gui objects ************** 
    1449  
    1450  
    1451  
    1452 function rcmail_message_container($attrib) 
    1453 { 
    1454     global $OUTPUT; 
    1455  
    1456     if (!$attrib['id']) { 
    1457         $attrib['id'] = 'rcmMessageContainer'; 
    1458     } 
    1459     // allow the following attributes to be added to the <table> tag 
    1460     $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id')); 
    1461     $out = '<div' . $attrib_str . "></div>"; 
    1462  
    1463     $OUTPUT->add_gui_object('message', $attrib['id']); 
    1464  
    1465     return $out; 
    1466 } 
    1467  
    1468  
    1469 // return the IMAP username of the current session 
    1470 function rcmail_current_username($attrib) 
    1471 { 
    1472     global $DB; 
    1473     static $s_username; 
    1474  
    1475     // alread fetched 
    1476     if (!empty($s_username)) { 
    1477         return $s_username; 
    1478     } 
    1479     // get e-mail address form default identity 
    1480     $_query = "SELECT email AS mailto"; 
    1481     $_query.= " FROM " . get_table_name('identities'); 
    1482     $_query.= " WHERE user_id=?"; 
    1483     $_query.= " AND standard=1"; 
    1484     $_query.= " AND del<>1"; 
    1485     $sql_result = $DB->query( 
    1486                         $_query, 
    1487                         $_SESSION['user_id'] 
    1488     ); 
    1489  
    1490     if ($DB->num_rows($sql_result)) { 
    1491         $sql_arr = $DB->fetch_assoc($sql_result); 
    1492         $s_username = $sql_arr['mailto']; 
    1493     } 
    1494     elseif (strstr($_SESSION['username'], '@')) { 
    1495         $s_username = $_SESSION['username']; 
    1496     } 
    1497     else { 
    1498         $s_username = $_SESSION['username'].'@'.$_SESSION['imap_host']; 
    1499     } 
    1500     return $s_username; 
    1501 } 
    1502  
    1503  
    1504 // return code for the webmail login form 
    1505 function rcmail_login_form($attrib) 
    1506 { 
    1507     global $CONFIG, $OUTPUT, $SESS_HIDDEN_FIELD; 
    1508  
    1509     $_SESSION['temp'] = true; 
    1510  
    1511     $labels = array(); 
    1512     $labels['user'] = rcube_label('username'); 
    1513     $labels['pass'] = rcube_label('password'); 
    1514     $labels['host'] = rcube_label('server'); 
    1515  
    1516     $input_user = new textfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30, 'autocomplete' => 'off')); 
    1517     $input_pass = new passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30)); 
    1518     $input_action = new hiddenfield(array('name' => '_action', 'value' => 'login')); 
    1519  
    1520     $fields = array(); 
    1521     $fields['user'] = $input_user->show(get_input_value('_user', RCUBE_INPUT_POST)); 
    1522     $fields['pass'] = $input_pass->show(); 
    1523     $fields['action'] = $input_action->show(); 
    1524  
    1525     if (is_array($CONFIG['default_host'])) { 
    1526         $select_host = new select(array('name' => '_host', 'id' => 'rcmloginhost')); 
    1527  
    1528         foreach ($CONFIG['default_host'] as $key => $value) { 
    1529             if (!is_array($value)) { 
    1530                 $select_host->add($value, (is_numeric($key) ? $value : $key)); 
    1531             } 
    1532             else { 
    1533                 unset($select_host); 
    1534                 break; 
    1535             } 
    1536         } 
    1537         $fields['host'] = isset($select_host) ? $select_host->show($_POST['_host']) : null; 
    1538     } 
    1539     else if (!strlen($CONFIG['default_host'])) { 
    1540         $input_host = new textfield(array('name' => '_host', 'id' => 'rcmloginhost', 'size' => 30)); 
    1541         $fields['host'] = $input_host->show($_POST['_host']); 
    1542     } 
    1543  
    1544     $form_name  = strlen($attrib['form']) ? $attrib['form'] : 'form'; 
    1545     $form_start = !strlen($attrib['form']) ? '<form name="form" action="./" method="post">' : ''; 
    1546     $form_end   = !strlen($attrib['form']) ? '</form>' : ''; 
    1547     $form_host  = ''; 
    1548  
    1549     if ($fields['host']) { 
    1550         $form_host.= "</tr><tr>"; 
    1551         $form_host.= "<td class=\"title\"><label for=\"rcmloginhost\">$labels[host]</label></td>"; 
    1552         $form_host.= "<td>$fields[host]</td>"; 
    1553  
    1554     } 
    1555     $OUTPUT->add_gui_object('loginform', $form_name); 
    1556  
    1557     $out = ''; 
    1558     $out.= $form_start; 
    1559     $out.= $SESS_HIDDEN_FIELD; 
    1560     $out.= $fields[action]; 
    1561     $out.= '<table><tr>'; 
    1562     $out.= '<td class="title"><label for="rcmloginuser">'; 
    1563     $out.= "$labels[user]</label></td>"; 
    1564     $out.= "<td>$fields[user]</td>"; 
    1565     $out.= '</tr><tr>'; 
    1566     $out.= '<td class="title"><label for="rcmloginpwd">'; 
    1567     $out.= "$labels[pass]</label></td>"; 
    1568     $out.= "<td>$fields[pass]</td>"; 
    1569     $out.= $form_host; 
    1570     $out.= '</tr></table>'; 
    1571     $out.= $form_end; 
    1572  
    1573     return $out; 
    1574 } 
    1575  
    1576  
    1577 function rcmail_charset_selector($attrib) 
    1578 { 
    1579     global $OUTPUT; 
    1580  
    1581     // pass the following attributes to the form class 
    1582     $field_attrib = array('name' => '_charset'); 
    1583     foreach ($attrib as $attr => $value) { 
    1584         if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) { 
    1585             $field_attrib[$attr] = $value; 
    1586         } 
    1587     } 
    1588     $charsets = array( 
    1589         'US-ASCII'     => 'ASCII (English)', 
    1590         'EUC-JP'       => 'EUC-JP (Japanese)', 
    1591         'EUC-KR'       => 'EUC-KR (Korean)', 
    1592         'BIG5'         => 'BIG5 (Chinese)', 
    1593         'GB2312'       => 'GB2312 (Chinese)', 
    1594         'ISO-2022-JP'  => 'ISO-2022-JP (Japanese)', 
    1595         'ISO-8859-1'   => 'ISO-8859-1 (Latin-1)', 
    1596         'ISO-8859-2'   => 'ISO-8895-2 (Central European)', 
    1597         'ISO-8859-7'   => 'ISO-8859-7 (Greek)', 
    1598         'ISO-8859-9'   => 'ISO-8859-9 (Turkish)', 
    1599         'Windows-1251' => 'Windows-1251 (Cyrillic)', 
    1600         'Windows-1252' => 'Windows-1252 (Western)', 
    1601         'Windows-1255' => 'Windows-1255 (Hebrew)', 
    1602         'Windows-1256' => 'Windows-1256 (Arabic)', 
    1603         'Windows-1257' => 'Windows-1257 (Baltic)', 
    1604         'UTF-8'        => 'UTF-8' 
    1605     ); 
    1606  
    1607     $select = new select($field_attrib); 
    1608     $select->add(array_values($charsets), array_keys($charsets)); 
    1609  
    1610     $set = $_POST['_charset'] ? $_POST['_charset'] : $OUTPUT->get_charset(); 
    1611     return $select->show($set); 
    1612 } 
    1613  
    1614  
    1615 // return code for search function 
    1616 function rcmail_search_form($attrib) 
    1617 { 
    1618     global $OUTPUT; 
    1619  
    1620     // add some labels to client 
    1621     rcube_add_label('searching'); 
    1622  
    1623     $attrib['name'] = '_q'; 
    1624  
    1625     if (empty($attrib['id'])) { 
    1626         $attrib['id'] = 'rcmqsearchbox'; 
    1627     } 
    1628     $input_q = new textfield($attrib); 
    1629     $out = $input_q->show(); 
    1630  
    1631     $OUTPUT->add_gui_object('qsearchbox', $attrib['id']); 
    1632  
    1633     // add form tag around text field 
    1634     if (empty($attrib['form'])) { 
    1635         $_html = '<form name="rcmqsearchform" action="./" '; 
    1636         $_html.= 'onsubmit="%s.command(\'search\');return false" '; 
    1637         $_html.= ' style="display:inline;">%s</form>'; 
    1638         $out = sprintf( 
    1639                 $_html, 
    1640                 JS_OBJECT_NAME, 
    1641                 $out 
    1642         ); 
    1643     } 
    1644     return $out; 
    1645 } 
    1646  
    1647  
    1648 /****** debugging functions ********/ 
    1649  
    1650  
    1651 /** 
    1652  * Print or write debug messages 
    1653  * 
    1654  * @param mixed Debug message or data 
    1655  */ 
    1656 function console($msg) 
    1657 { 
    1658     if (!is_string($msg)) { 
    1659         $msg = var_export($msg, true); 
    1660     } 
    1661     if (!($GLOBALS['CONFIG']['debug_level'] & 4)) { 
    1662         write_log('console', $msg); 
    1663     } 
    1664     elseif ($GLOBALS['REMOTE_REQUEST']) { 
    1665         echo "/*\n $msg \n*/\n"; 
    1666     } 
    1667     else { 
    1668         echo '<div style="background:#eee; border:1px solid #ccc; '; 
    1669         echo 'margin-bottom:3px; padding:6px"><pre>'; 
    1670         echo $msg; 
    1671         echo "</pre></div>\n"; 
    1672     } 
    1673 } 
    1674  
    1675  
    1676 /** 
    1677  * Append a line to a logfile in the logs directory. 
    1678  * Date will be added automatically to the line. 
    1679  * 
    1680  * @param $name Name of logfile 
    1681  * @param $line Line to append 
    1682  */ 
    1683 function write_log($name, $line) 
    1684 { 
    1685     global $CONFIG; 
    1686  
    1687     if (!is_string($line)) { 
    1688         $line = var_export($line, true); 
    1689     } 
    1690     $log_entry = sprintf("[%s]: %s\n", 
    1691                  date("d-M-Y H:i:s O", mktime()), 
    1692                  $line); 
    1693  
    1694     if (empty($CONFIG['log_dir'])) { 
    1695         $CONFIG['log_dir'] = $INSTALL_PATH.'logs'; 
    1696     } 
    1697     // try to open specific log file for writing 
    1698     if ($fp = @fopen($CONFIG['log_dir'].'/'.$name, 'a')) { 
    1699         fwrite($fp, $log_entry); 
    1700         fclose($fp); 
    1701     } 
    1702 } 
    1703  
    1704  
    1705 function rcube_timer() 
    1706 { 
    1707     list($usec, $sec) = explode(" ", microtime()); 
    1708     return ((float)$usec + (float)$sec); 
    1709 } 
    1710  
    1711  
    1712 function rcube_print_time($timer, $label='Timer') 
    1713 { 
    1714     static $print_count = 0; 
    1715  
    1716     $print_count++; 
    1717     $now = rcube_timer(); 
    1718     $diff = $now-$timer; 
    1719  
    1720     if (empty($label)) { 
    1721         $label = 'Timer '.$print_count; 
    1722     } 
    1723     console(sprintf("%s: %0.4f sec", $label, $diff)); 
    1724 } 
    1725  
    1726 ?> 
  • branches/devel-vnext/program/include/rcmail_template.inc

    r589 r622  
    2121*/ 
    2222 
    23 require_once 'include/rcube_shared.inc'; 
     23require_once dirname(__FILE__) . '/rcube_shared.inc'; 
    2424 
    2525/** 
     
    5353     * @todo   Use jQuery's $(document).ready() here. 
    5454     */ 
    55     function __construct(&$config, $task) 
     55    function __construct($config, $task) 
    5656    { 
    5757        parent::__construct(); 
     
    7676    } 
    7777 
     78    /* 
    7879    // PHP 4 compatibility 
    7980    function rcmail_template(&$config, $task) 
    8081    { 
    8182        $this->__construct($config, $task); 
    82     } 
     83    }*/ 
    8384 
    8485 
     
    182183   * @param boolean True if script should terminate (default) 
    183184   */ 
    184   function send($templ=null, $exit=true) 
    185   { 
    186     if ($this->ajax_call) 
    187       $this->remote_response('', !$exit); 
    188     else if ($templ != 'iframe') 
    189       $this->parse($templ, false); 
    190     else 
    191     { 
    192       $this->framed = $templ == 'iframe' ? true : $this->framed; 
    193       $this->write(); 
    194     } 
    195  
    196     if ($exit) 
    197       exit; 
    198   } 
     185    function send($templ=null, $exit=true) 
     186    { 
     187        if ($this->ajax_call) 
     188            $this->remote_response('', !$exit); 
     189        else if ($templ != 'iframe') 
     190            $this->parse($templ, false); 
     191        else { 
     192            $this->framed = $templ == 'iframe' ? true : $this->framed; 
     193            $this->write(); 
     194        } 
     195 
     196        if ($exit) 
     197            exit; 
     198    } 
    199199 
    200200 
     
    257257    { 
    258258        $skin_path = $this->config['skin_path']; 
     259 
     260        //rc_main::tfk_debug(var_export($this->config, true)); 
    259261 
    260262        // read template file 
     
    364366                return $matches[0] . $this->parse_conditions($matches[3]); 
    365367            } 
    366             $attrib = parse_attrib_string($matches[2]); 
     368            $attrib = rc_main::parse_attrib_string($matches[2]); 
    367369            if (isset($attrib['condition'])) { 
    368370                $condmet = $this->check_condition($attrib['condition']); 
     
    436438    { 
    437439        $command = strtolower($command); 
    438         $attrib = parse_attrib_string($str_attrib) + $add_attrib; 
     440        $attrib  = rc_main::parse_attrib_string($str_attrib) + $add_attrib; 
    439441 
    440442        // empty output if required condition is not met 
     
    454456            case 'label': 
    455457                if ($attrib['name'] || $attrib['command']) 
    456                     return Q(rcube_label($attrib + array('vars' => array('product' => $this->config['product_name'])))); 
     458                    return rc_main::Q(rcube_label($attrib + array('vars' => array('product' => $this->config['product_name'])))); 
    457459                break; 
    458460 
     
    480482                if ($object=='productname') { 
    481483                    $name = !empty($this->config['product_name']) ? $this->config['product_name'] : 'RoundCube Webmail'; 
    482                     return Q($name); 
     484                    return rc_main::Q($name); 
    483485                } 
    484486                if ($object=='version') { 
     
    496498                        $title .= ucfirst($task); 
    497499 
    498                     return Q($title); 
     500                    return rc_main::Q($title); 
    499501                } 
    500502                break; 
     
    568570        // get localized text for labels and titles 
    569571        if ($attrib['title']) { 
    570             $attrib['title'] = Q(rcube_label($attrib['title'])); 
     572            $attrib['title'] = rc_main::Q(rcube_label($attrib['title'])); 
    571573        } 
    572574        if ($attrib['label']) { 
    573             $attrib['label'] = Q(rcube_label($attrib['label'])); 
     575            $attrib['label'] = rc_main::Q(rcube_label($attrib['label'])); 
    574576        } 
    575577        if ($attrib['alt']) { 
    576             $attrib['alt'] = Q(rcube_label($attrib['alt'])); 
     578            $attrib['alt'] = rc_main::Q(rcube_label($attrib['alt'])); 
    577579        } 
    578580        // set title to alt attribute for IE browsers 
     
    605607            // make valid href to specific buttons 
    606608            if (in_array($attrib['command'], $MAIN_TASKS)) { 
    607                 $attrib['href'] = Q(rcmail_url(null, null, $attrib['command'])); 
     609                $attrib['href'] = rc_main::Q(rcmail_url(null, null, $attrib['command'])); 
    608610            } 
    609611            else if (in_array($attrib['command'], $a_static_commands)) { 
    610                 $attrib['href'] = Q(rcmail_url($attrib['command'])); 
     612                $attrib['href'] = rc_main::Q(rcmail_url($attrib['command'])); 
    611613            } 
    612614        } 
  • branches/devel-vnext/program/include/rcube/registry.php

    r621 r622  
    11<?php 
    22/** 
    3  * rcRegistry 
     3 * rc_registry 
    44 * 
    5  * Implements a singleton. 
     5 * Implements a singleton-style registry for roundcube and plugins 
     6 * to store variables not in the global scope. 
    67 * 
    78 * @final 
     
    1112class rc_registry 
    1213{ 
    13     var $holder = null; 
     14    /** 
     15     * @var    rc_registry 
     16     * @access private 
     17     * @access static 
     18     */ 
     19    private static $registry; 
    1420 
    1521    /** 
    16      * rc_registry 
    17      * 
    18      * @return false 
     22     * @access protected 
     23     * @var    array 
    1924     */ 
    20     function rc_registry() 
    21     { 
    22         return false; 
    23     } 
     25    protected $holder = null; 
    2426 
    2527    /** 
     
    2931     * @return false 
    3032     */ 
    31     function __construct() 
     33    private function __construct() 
    3234    { 
    33         return $this->rc_registry(); 
    3435    } 
    3536 
     
    4243     * @return rc_registry 
    4344     */ 
    44     function getInstance() 
     45    static function getInstance() 
    4546    { 
    46         static $registry = null; 
    47         if (is_null($registry) === true) 
     47        if (is_null(self::$registry) === true) 
    4848        { 
    49             $registry = new rc_registry; 
     49            self::$registry = new rc_registry; 
    5050        } 
    51         return $registry; 
     51        return self::$registry; 
    5252    } 
    5353 
     
    5858     * optional argument $ns (namespace). 
    5959     * 
    60      * Returns boolean - true on success, false if things go wrong. 
     60     * Returns boolean (false) if things go wrong, otherwise the value of the 
     61     * variable. 
    6162     * 
    6263     * @access public 
     
    6465     * @param  mixed $val 
    6566     * @param  string $ns 
    66      * @return boolean 
     67     * @return mixed 
    6768     * @uses   rc_registry::$holder 
    6869     */ 
    69     function set($var, $val = '', $ns = null) 
     70    public function set($var, $val = '', $ns = null) 
    7071    { 
    7172        if (empty($var) === true) { 
     
    7374        } 
    7475        if (is_null($ns) === true) { 
    75             $this->holder[$var] = $val; 
    76             return true; 
     76            return $this->holder[$var] = $val; 
    7777        } 
    7878        if (isset($this->holder[$ns]) === false) { 
    7979            $this->holder[$ns] = array(); 
    8080        } 
    81         $this->holder[$ns][$var] = $val; 
    82         return true; 
     81        return $this->holder[$ns][$var] = $val; 
    8382    } 
    8483 
     
    9695     * @uses   rc_registry::$holder 
    9796     */ 
    98     function get($var, $ns = null) 
     97    public function get($var, $ns = null) 
    9998    { 
    10099        if (empty($var) === true) { 
     
    103102        if (is_null($ns) === true) { 
    104103            if (isset($this->holder[$var]) === false) { 
    105                 return false; 
     104                return null; 
    106105            } 
    107106            return $this->holder[$var]; 
    108107        } 
    109108        if (isset($this->holder[$ns]) === false) { 
    110             return false; 
     109            return null; 
    111110        } 
    112111        if (isset($this->holder[$ns][$var]) === false) { 
     
    126125     * @see    rc_registry::__destruct 
    127126     */ 
    128     function purge() 
     127    public function purge() 
    129128    { 
    130129        $this->holder = null; 
     
    140139     * @return mixed 
    141140     */ 
    142     function getAll() 
     141    public function getAll() 
    143142    { 
    144143        if (is_null($this->holder) === true) { 
     
    154153     * @uses   rc_registry::purge() 
    155154     */ 
    156     function __destruct() 
     155    public function __destruct() 
    157156    { 
    158157        return $this->purge(); 
  • branches/devel-vnext/program/include/rcube_imap.inc

    r610 r622  
    2525 * Obtain classes from the Iloha IMAP library 
    2626 */ 
    27 require_once('lib/imap.inc'); 
    28 require_once('lib/mime.inc'); 
     27require_once 'lib/imap.inc'; 
     28require_once 'lib/mime.inc'; 
    2929 
    3030 
     
    18771877      $sql_result = $this->db->query( 
    18781878        "SELECT cache_id, data 
    1879          FROM ".get_table_name('cache')." 
     1879         FROM ". rc_main::get_table_name('cache')." 
    18801880         WHERE  user_id=? 
    18811881         AND    cache_key=?", 
     
    19041904      $sql_result = $this->db->query( 
    19051905        "SELECT cache_id 
    1906          FROM ".get_table_name('cache')." 
     1906         FROM ".rc_main::get_table_name('cache')." 
    19071907         WHERE  user_id=? 
    19081908         AND    cache_key=?", 
     
    19201920      { 
    19211921      $this->db->query( 
    1922         "UPDATE ".get_table_name('cache')." 
     1922        "UPDATE ".rc_main::get_table_name('cache')." 
    19231923         SET    created=".$this->db->now().", 
    19241924                data=? 
     
    19331933      { 
    19341934      $this->db->query( 
    1935         "INSERT INTO ".get_table_name('cache')." 
     1935        "INSERT INTO ". rc_main::get_table_name('cache')." 
    19361936         (created, user_id, cache_key, data) 
    19371937         VALUES (".$this->db->now().", ?, ?, ?)", 
     
    19461946    { 
    19471947    $this->db->query( 
    1948       "DELETE FROM ".get_table_name('cache')." 
     1948      "DELETE FROM ". rc_main::get_table_name('cache')." 
    19491949       WHERE  user_id=? 
    19501950       AND    cache_key=?", 
     
    20082008      $sql_result = $this->db->limitquery( 
    20092009        "SELECT idx, uid, headers 
    2010          FROM ".get_table_name('messages')." 
     2010         FROM ". rc_main::get_table_name('messages')." 
    20112011         WHERE  user_id=? 
    20122012         AND    cache_key=? 
     
    20412041      $sql_result = $this->db->query( 
    20422042        "SELECT $sql_select 
    2043          FROM ".get_table_name('messages')." 
     2043         FROM ". rc_main::get_table_name('messages')." 
    20442044         WHERE  user_id=? 
    20452045         AND    cache_key=? 
     
    20752075    $sql_result = $this->db->query( 
    20762076      "SELECT idx, uid 
    2077        FROM ".get_table_name('messages')." 
     2077       FROM ". rc_main::get_table_name('messages')." 
    20782078       WHERE  user_id=? 
    20792079       AND    cache_key=? 
     
    20972097    $sql_result = $this->db->query( 
    20982098        "SELECT message_id 
    2099          FROM ".get_table_name('messages')." 
     2099         FROM ". rc_main::get_table_name('messages')." 
    21002100         WHERE  user_id=? 
    21012101         AND    cache_key=? 
     
    21102110      { 
    21112111      $this->db->query( 
    2112         "UPDATE ".get_table_name('messages')." 
     2112        "UPDATE ". rc_main::get_table_name('messages')." 
    21132113         SET   idx=?, headers=?, structure=? 
    21142114         WHERE message_id=?", 
     
    21222122      { 
    21232123      $this->db->query( 
    2124         "INSERT INTO ".get_table_name('messages')." 
     2124        "INSERT INTO ". rc_main::get_table_name('messages')." 
    21252125         (user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers, structure) 
    21262126         VALUES (?, 0, ?, ".$this->db->now().", ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?, ?)", 
     
    21442144    { 
    21452145    $this->db->query( 
    2146       "DELETE FROM ".get_table_name('messages')." 
     2146      "DELETE FROM ". rc_main::get_table_name('messages')." 
    21472147       WHERE  user_id=? 
    21482148       AND    cache_key=? 
     
    21572157    { 
    21582158    $this->db->query( 
    2159       "DELETE FROM ".get_table_name('messages')." 
     2159      "DELETE FROM ". rc_main::get_table_name('messages')." 
    21602160       WHERE  user_id=? 
    21612161       AND    cache_key=? 
  • branches/devel-vnext/program/include/rcube_shared.inc

    r599 r622  
    2222 
    2323// ********* round cube schared classes ********* 
    24  
    25 class rcube_html_page 
    26 { 
    27     var $css; 
    28  
    29     var $scripts_path = ''; 
    30     var $script_files = array(); 
    31     var $external_scripts = array(); 
    32     var $scripts = array(); 
    33     var $charset = 'ISO-8859-1'; 
    34  
    35     var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n"; 
    36     var $script_tag      = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n"; 
    37     var $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>"; 
    38     var $tag_format_external_script = "<script type=\"text/javascript\" src=\"%s\"></script>\n"; 
    39  
    40     var $title = ''; 
    41     var $header = ''; 
    42     var $footer = ''; 
    43     var $body = ''; 
    44     var $body_attrib = array(); 
    45     var $meta_tags = array(); 
    46  
    47  
    48     // PHP 5 constructor 
    49     function __construct() 
    50     { 
    51         $this->css = new rcube_css(); 
    52     } 
    53  
    54     // PHP 4 compatibility 
    55     function rcube_html_page() 
    56     { 
    57         $this->__construct(); 
    58     } 
    59  
    60  
    61     function include_script($file, $position='head') 
    62     { 
    63         static $sa_files = array(); 
    64  
    65         if (in_array($file, $sa_files)) { 
    66             return; 
    67         } 
    68         if (!is_array($this->script_files[$position])) { 
    69             $this->script_files[$position] = array(); 
    70         } 
    71         $this->script_files[$position][] = $file; 
    72     } 
    73  
    74     function include_external_script($script_location, $position='head') 
    75     { 
    76         if (!is_array($this->external_scripts[$position])) { 
    77             $this->external_scripts[$position] = array(); 
    78         } 
    79  
    80         $this->external_scripts[$position][] = $script_location; 
    81     } 
    82  
    83     function add_script($script, $position='head') 
    84     { 
    85         if (!isset($this->scripts[$position])) { 
    86             $this->scripts[$position] = "\n".rtrim($script); 
    87         } 
    88         else { 
    89             $this->scripts[$position] .= "\n".rtrim($script); 
    90         } 
    91     } 
    92  
    93     function add_header($str) 
    94     { 
    95         $this->header .= "\n".$str; 
    96     } 
    97  
    98     function add_footer($str) 
    99     { 
    100         $this->footer .= "\n".$str; 
    101     } 
    102  
    103     function set_title($t) 
    104     { 
    105         $this->title = $t; 
    106     } 
    107  
    108  
    109     function set_charset($charset) 
    110     { 
    111         global $MBSTRING; 
    112  
    113         $this->charset = $charset; 
    114  
    115         if ($MBSTRING && function_exists("mb_internal_encoding")) { 
    116             if(!@mb_internal_encoding($charset)) { 
    117                 $MBSTRING = FALSE; 
    118             } 
    119         } 
    120     } 
    121  
    122     function get_charset() 
    123     { 
    124         return $this->charset; 
    125     } 
    126  
    127  
    128     function reset() 
    129     { 
    130         $this->css = new rcube_css(); 
    131         $this->script_files = array(); 
    132         $this->scripts = array(); 
    133         $this->title = ''; 
    134         $this->header = ''; 
    135         $this->footer = ''; 
    136     } 
    137  
    138  
    139     function write($templ='', $base_path='') 
    140     { 
    141         $output = empty($templ) ? $this->default_template : trim($templ); 
    142  
    143         // set default page title 
    144         if (empty($this->title) === true) { 
    145             $this->title = 'RoundCube Mail'; 
    146         } 
    147         // replace specialchars in content 
    148         $__page_title = Q($this->title, 'show', FALSE); 
    149         $__page_header = $__page_body = $__page_footer = ''; 
    150  
    151  
    152         // include meta tag with charset 
    153         if (!empty($this->charset)) { 
    154             header('Content-Type: text/html; charset='.$this->charset); 
    155             $__page_header = '<meta http-equiv="content-type" content="text/html; charset='.$this->charset.'" />'."\n"; 
    156         } 
    157  
    158  
    159     // definition of the code to be placed in the document header and footer 
    160     if (is_array($this->script_files['head'])) 
    161       foreach ($this->script_files['head'] as $file) 
    162         $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file); 
    163  
    164     if (is_array($this->external_scripts['head'])) 
    165       foreach ($this->external_scripts['head'] as $xscript) 
    166         $__page_header .= sprintf($this->tag_format_external_script, $xscript); 
    167  
    168     $head_script = $this->scripts['head_top'] . $this->scripts['head']; 
    169     if (!empty($head_script)) 
    170       $__page_header .= sprintf($this->script_tag, $head_script); 
    171  
    172     if (!empty($this->header)) 
    173       $__page_header .= $this->header; 
    174  
    175     if (is_array($this->script_files['foot'])) 
    176       foreach ($this->script_files['foot'] as $file) 
    177         $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file); 
    178  
    179     if (!empty($this->scripts['foot'])) 
    180       $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']); 
    181  
    182     if (!empty($this->footer)) 
    183       $__page_footer .= $this->footer; 
    184  
    185     $__page_header .= $this->css->show(); 
    186  
    187     // find page header 
    188     if($hpos = strpos(strtolower($output), '</head>')) 
    189       $__page_header .= "\n"; 
    190     else 
    191       { 
    192       if (!is_numeric($hpos)) 
    193         $hpos = strpos(strtolower($output), '<body'); 
    194       if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html'))) 
    195         { 
    196         while($output[$hpos]!='>') 
    197         $hpos++; 
    198         $hpos++; 
    199         } 
    200  
    201       $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n"; 
    202       } 
    203  
    204     // add page hader 
    205     if($hpos) 
    206       $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output)); 
    207     else 
    208       $output = $__page_header . $output; 
    209  
    210  
    211     // find page body 
    212     if($bpos = strpos(strtolower($output), '<body')) 
    213       { 
    214       while($output[$bpos]!='>') $bpos++; 
    215       $bpos++; 
    216       } 
    217     else 
    218       $bpos = strpos(strtolower($output), '</head>')+7; 
    219  
    220     // add page body 
    221     if($bpos && $__page_body) 
    222       $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output)); 
    223  
    224  
    225     // find and add page footer 
    226     $output_lc = strtolower($output); 
    227     if(($fpos = strrstr($output_lc, '</body>')) || 
    228        ($fpos = strrstr($output_lc, '</html>'))) 
    229       $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos); 
    230     else 
    231       $output .= "\n$__page_footer"; 
    232  
    233  
    234     // reset those global vars 
    235     $__page_header = $__page_footer = ''; 
    236  
    237  
    238     // correct absolute paths in images and other tags 
    239     $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output); 
    240     $output = str_replace('$__skin_path', $base_path, $output); 
    241  
    242     print rcube_charset_convert($output, 'UTF-8', $this->charset); 
    243     } 
    244  
    245  
    246   function _parse($templ) 
    247     { 
    248  
    249     } 
    250   } 
    251  
    252  
    253  
    254  
    255 class rcube_css 
    256   { 
    257   var $css_data = array(); 
    258  
    259   var $css_groups = array(); 
    260  
    261   var $include_files = array(); 
    262  
    263   var $grouped_output = TRUE; 
    264  
    265   var $content_type = 'text/css'; 
    266  
    267   var $base_path = ''; 
    268  
    269   var $indent_chars = "\t"; 
    270  
    271  
    272   // add or overwrite a css definition 
    273   // either pass porperty and value as separate arguments 
    274   // or provide an associative array as second argument 
    275   function set_style($selector, $property, $value='') 
    276     { 
    277     $a_elements = $this->_parse_selectors($selector); 
    278     foreach ($a_elements as $element) 
    279       { 
    280       if (!is_array($property)) 
    281         $property = array($property => $value); 
    282  
    283       foreach ($property as $name => $value) 
    284         $this->css_data[$element][strtolower($name)] = $value; 
    285       } 
    286  
    287     // clear goups array 
    288     $this->css_groups = array(); 
    289     } 
    290  
    291  
    292   // unset a style property 
    293   function remove_style($selector, $property) 
    294     { 
    295     if (!is_array($property)) 
    296       $property = array($property); 
    297  
    298     foreach ($property as $key) 
    299       unset($this->css_data[$selector][strtolower($key)]); 
    300  
    301     // clear goups array 
    302     $this->css_groups = array(); 
    303     } 
    304  
    305  
    306   // define base path for external css files 
    307   function set_basepath($path) 
    308     { 
    309     $this->base_path = preg_replace('/\/$/', '', $path); 
    310     } 
    311  
    312  
    313   // enable/disable grouped output 
    314   function set_grouped_output($grouped) 
    315     { 
    316     $this->grouped_output = $grouped; 
    317     } 
    318  
    319  
    320   // add a css file as external source 
    321   function include_file($filename, $media='') 
    322     { 
    323     // include multiple files 
    324     if (is_array($filename)) 
    325       { 
    326       foreach ($filename as $file) 
    327         $this->include_file($file, $media); 
    328       } 
    329     // add single file 
    330     else if (!in_array($filename, $this->include_files)) 
    331       $this->include_files[] = array('file' => $filename, 
    332                                      'media' => $media); 
    333     } 
    334  
    335  
    336   // parse css code 
    337   function import_string($str) 
    338     { 
    339     $ret = FALSE; 
    340     if (strlen($str)) 
    341       $ret = $this->_parse($str); 
    342  
    343     return $ret; 
    344     } 
    345  
    346  
    347   // open and parse a css file 
    348   function import_file($file) 
    349     { 
    350     $ret = FALSE; 
    351  
    352     if (!is_file($file)) 
    353       return $ret; 
    354  
    355     // for php version >= 4.3.0 
    356     if (function_exists('file_get_contents')) 
    357       $ret = $this->_parse(file_get_contents($file)); 
    358  
    359     // for order php versions 
    360     else if ($fp = fopen($file, 'r')) 
    361       { 
    362       $ret = $this->_parse(fread($fp, filesize($file))); 
    363       fclose($fp); 
    364       } 
    365  
    366     return $ret; 
    367     } 
    368  
    369  
    370   // copy all properties inherited from superior styles to a specific selector 
    371   function copy_inherited_styles($selector) 
    372     { 
    373     // get inherited props from body and tag/class selectors 
    374     $css_props = $this->_get_inherited_styles($selector); 
    375  
    376     // write modified props back and clear goups array 
    377     if (sizeof($css_props)) 
    378       { 
    379       $this->css_data[$selector] = $css_props; 
    380       $this->css_groups = array(); 
    381       } 
    382     } 
    383  
    384  
    385   // return css definition for embedding in HTML 
    386   function show() 
    387     { 
    388     $out = ''; 
    389  
    390     // include external css files 
    391     if (sizeof($this->include_files)) 
    392       foreach ($this->include_files as $file_arr) 
    393       $out .= sprintf('<link rel="stylesheet" type="%s" href="%s"%s>'."\n", 
    394                         $this->content_type, 
    395                         $this->_get_file_path($file_arr['file']), 
    396                         $file_arr['media'] ? ' media="'.$file_arr['media'].'"' : ''); 
    397  
    398  
    399     // compose css string 
    400     if (sizeof($this->css_data)) 
    401       $out .= sprintf("<style type=\"%s\">\n<!--\n\n%s-->\n</style>", 
    402                       $this->content_type, 
    403                       $this->to_string()); 
    404  
    405  
    406     return $out; 
    407     } 
    408  
    409  
    410   // return valid css code of the current styles grid 
    411   function to_string($selector=NULL) 
    412     { 
    413     // return code for a single selector 
    414     if ($selector) 
    415       { 
    416       $indent_str = $this->indent_chars; 
    417       $this->indent_chars = ''; 
    418  
    419       $prop_arr = $this->to_array($selector); 
    420       $out = $this->_style2string($prop_arr, TRUE); 
    421  
    422       $this->indent_chars = $indent_str; 
    423       } 
    424  
    425     // compose css code for complete data grid 
    426     else 
    427       { 
    428       $out = ''; 
    429       $css_data = $this->to_array(); 
    430  
    431       foreach ($css_data as $key => $prop_arr) 
    432         $out .= sprintf("%s {\n%s}\n\n", 
    433                         $key, 
    434                         $this->_style2string($prop_arr, TRUE)); 
    435       } 
    436  
    437     return $out; 
    438     } 
    439  
    440  
    441   // return a single-line string of a css definition 
    442   function to_inline($selector) 
    443     { 
    444     if ($this->css_data[$selector]) 
    445       return str_replace('"', '\\"', $this->_style2string($this->css_data[$selector], FALSE)); 
    446     } 
    447  
    448  
    449   // return an associative array with selector(s) as key and styles array as value 
    450   function to_array($selector=NULL) 
    451     { 
    452     if (!$selector && $this->grouped_output) 
    453       { 
    454       // build groups if desired 
    455       if (!sizeof($this->css_groups)) 
    456         $this->_build_groups(); 
    457  
    458       // modify group array to get an array(selector => properties) 
    459       $out_arr = array(); 
    460       foreach ($this->css_groups as $group_arr) 
    461         { 
    462         $key = join(', ', $group_arr['selectors']); 
    463         $out_arr[$key] = $group_arr['properties']; 
    464         } 
    465       } 
    466     else 
    467       $out_arr = $this->css_data; 
    468  
    469     return $selector ? $out_arr[$selector] : $out_arr; 
    470     } 
    471  
    472  
    473   // create a css file 
    474   function to_file($filepath) 
    475     { 
    476     if ($fp = fopen($filepath, 'w')) 
    477       { 
    478       fwrite($fp, $this->to_string()); 
    479       fclose($fp); 
    480       return TRUE; 
    481       } 
    482  
    483     return FALSE; 
    484     } 
    485  
    486  
    487   // alias method for import_string() [DEPRECATED] 
    488   function add($str) 
    489     { 
    490     $this->import_string($str); 
    491     } 
    492  
    493   // alias method for to_string() [DEPRECATED] 
    494   function get() 
    495     { 
    496     return $this->to_string(); 
    497     } 
    498  
    499  
    500  
    501   // ******** private methods ******** 
    502  
    503  
    504   // parse a string and add styles to internal data grid 
    505   function _parse($str) 
    506     { 
    507     // remove comments 
    508     $str = preg_replace("/\/\*(.*)?\*\//Usi", '', $str); 
    509  
    510     // parse style definitions 
    511     if (!preg_match_all ('/([a-z0-9\.#*:_][a-z0-9\.\-_#:*,\[\]\(\)\s\"\'\+\|>~=]+)\s*\{([^\}]*)\}/ims', $str, $matches, PREG_SET_ORDER)) 
    512       return FALSE; 
    513  
    514  
    515     foreach ($matches as $match_arr) 
    516       { 
    517       // split selectors into array 
    518       $a_keys = $this->_parse_selectors(trim($match_arr[1])); 
    519  
    520       // parse each property of an element 
    521       $codes = explode(";", trim($match_arr[2])); 
    522       foreach ($codes as $code) 
    523         { 
    524         if (strlen(trim($code))>0) 
    525           { 
    526           // find the property and the value 
    527           if (!($sep = strpos($code, ':'))) 
    528             continue; 
    529  
    530           $property = strtolower(trim(substr($code, 0, $sep))); 
    531           $value    = trim(substr($code, $sep+1)); 
    532  
    533           // add the property to the object array 
    534           foreach ($a_keys as $key) 
    535             $this->css_data[$key][$property] = $value; 
    536           } 
    537         } 
    538       } 
    539  
    540     // clear goups array 
    541     if (sizeof($matches)) 
    542       { 
    543       $this->css_groups = array(); 
    544       return TRUE; 
    545       } 
    546  
    547     return FALSE; 
    548     } 
    549  
    550  
    551   // split selector group 
    552   function _parse_selectors($selector) 
    553     { 
    554     // trim selector and remove multiple spaces 
    555     $selector = preg_replace('/\s+/', ' ', trim($selector)); 
    556  
    557     if (strpos($selector, ',')) 
    558       return preg_split('/[\t\s\n\r]*,[\t\s\n\r]*/mi', $selector); 
    559     else 
    560       return array($selector); 
    561     } 
    562  
    563  
    564   // compare identical styles and make groups 
    565   function _build_groups() 
    566     { 
    567     // clear group array 
    568     $this->css_groups = array(); 
    569     $string_group_map = array(); 
    570  
    571     // bulild css string for each selector and check if the same is already defines 
    572     foreach ($this->css_data as $selector => $prop_arr) 
    573       { 
    574       // make shure to compare props in the same order 
    575       ksort($prop_arr); 
    576       $compare_str = preg_replace('/[\s\t]+/', '', $this->_style2string($prop_arr, FALSE)); 
    577  
    578       // add selector to extisting group 
    579       if (isset($string_group_map[$compare_str])) 
    580         { 
    581         $group_index = $string_group_map[$compare_str]; 
    582         $this->css_groups[$group_index]['selectors'][] = $selector; 
    583         } 
    584  
    585       // create new group 
    586       else 
    587         { 
    588         $i = sizeof($this->css_groups); 
    589         $string_group_map[$compare_str] = $i; 
    590         $this->css_groups[$i] = array('selectors' => array($selector), 
    591                                       'properties' => $this->css_data[$selector]); 
    592         } 
    593       } 
    594     } 
    595  
    596  
    597   // convert the prop array into a valid css definition 
    598   function _style2string($prop_arr, $multiline=TRUE) 
    599     { 
    600     $out = ''; 
    601     $delm   = $multiline ? "\n" : ''; 
    602     $spacer = $multiline ? ' ' : ''; 
    603     $indent = $multiline ? $this->indent_chars : ''; 
    604  
    605     if (is_array($prop_arr)) 
    606       foreach ($prop_arr as $prop => $value) 
    607         if (strlen($value)) 
    608           $out .= sprintf('%s%s:%s%s;%s', 
    609                           $indent, 
    610                           $prop, 
    611                           $spacer, 
    612                           $value, 
    613                           $delm); 
    614  
    615     return $out; 
    616     } 
    617  
    618  
    619   // copy all properties inherited from superior styles to a specific selector 
    620   function _get_inherited_styles($selector, $loop=FALSE) 
    621     { 
    622     $css_props = $this->css_data[$selector] ? $this->css_data[$selector] : array(); 
    623  
    624     // get styles from tag selector 
    625     if (preg_match('/(([a-z0-9]*)(\.[^\s]+)?)$/i', $selector, $regs)) 
    626       { 
    627       $sel = $regs[1]; 
    628       $tagname = $regs[2]; 
    629       $class = $regs[3]; 
    630  
    631       if ($sel && is_array($this->css_data[$sel])) 
    632         $css_props = $this->_merge_styles($this->css_data[$sel], $css_props); 
    633  
    634       if ($class && is_array($this->css_data[$class])) 
    635         $css_props = $this->_merge_styles($this->css_data[$class], $css_props); 
    636  
    637       if ($tagname && is_array($this->css_data[$tagname])) 
    638         $css_props = $this->_merge_styles($this->css_data[$tagname], $css_props); 
    639       } 
    640  
    641     // analyse inheritance 
    642     if (strpos($selector, ' ')) 
    643       { 
    644       $a_hier = split(' ', $selector); 
    645       if (sizeof($a_hier)>1) 
    646         { 
    647         array_pop($a_hier); 
    648         $base_selector = join(' ', $a_hier); 
    649  
    650         // call this method recursively 
    651         $new_props = $this->_get_inherited_styles($base_selector, TRUE); 
    652         $css_props = $this->_merge_styles($new_props, $css_props); 
    653         } 
    654       } 
    655  
    656     // get body style 
    657     if (!$loop && is_array($this->css_data['body'])) 
    658       $css_props = $this->_merge_styles($this->css_data['body'], $css_props); 
    659  
    660     return $css_props; 
    661     } 
    662  
    663  
    664   // merge two arrays with style properties together like a browser would do 
    665   function _merge_styles($one, $two) 
    666     { 
    667     // these properties are additive 
    668     foreach (array('text-decoration') as $prop) 
    669       if ($one[$prop] && $two[$prop]) 
    670         { 
    671         // if value contains 'none' it's ignored 
    672         if (strstr($one[$prop], 'none')) 
    673           continue; 
    674         else if (strstr($two[$prop], 'none')) 
    675           unset($two[$prop]); 
    676  
    677         $a_values_one = split(' ', $one[$prop]); 
    678         $a_values_two = split(' ', $two[$prop]); 
    679         $two[$prop] = join(' ', array_unique(array_merge($a_values_one, $a_values_two))); 
    680         } 
    681  
    682     return array_merge($one, $two); 
    683     } 
    684  
    685  
    686   // resolve file path 
    687   function _get_file_path($file) 
    688     { 
    689     if (!$this->base_path && $GLOBALS['CSS_PATH']) 
    690       $this->set_basepath($GLOBALS['CSS_PATH']); 
    691  
    692     $base = ($file{0}=='/' || $file{0}=='.' || substr($file, 0, 7)=='http://') ? '' : 
    693             ($this->base_path ? $this->base_path.'/' : ''); 
    694     return $base.$file; 
    695     } 
    696  
    697   } 
    698  
    699  
    700  
    701 class base_form_element 
    702   { 
    703   var $uppertags = FALSE; 
    704   var $upperattribs = FALSE; 
    705   var $upperprops = FALSE; 
    706   var $newline = FALSE; 
    707  
    708   var $attrib = array(); 
    709  
    710  
    711   // create string with attributes 
    712   function create_attrib_string($tagname='') 
    713     { 
    714     if (!sizeof($this->attrib)) 
    715       return ''; 
    716  
    717     if ($this->name!='') 
    718       $this->attrib['name'] = $this->name; 
    719  
    720     $attrib_arr = array(); 
    721     foreach ($this->attrib as $key => $value) 
    722       { 
    723       // don't output some internally used attributes 
    724       if (in_array($key, array('form', 'quicksearch'))) 
    725         continue; 
    726  
    727       // skip if size if not numeric 
    728       if (($key=='size' && !is_numeric($value))) 
    729         continue; 
    730  
    731       // skip empty eventhandlers 
    732       if ((strpos($key,'on')===0 && $value=='')) 
    733         continue; 
    734  
    735       // encode textarea content 
    736       if ($key=='value') 
    737         $value = Q($value, 'strict', FALSE); 
    738  
    739       // attributes with no value 
    740       if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) 
    741         { 
    742         if ($value) 
    743           $attrib_arr[] = $key; 
    744         } 
    745       // don't convert size of value attribute 
    746       else if ($key=='value') 
    747         $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $value, 'value'); 
    748  
    749       // regular tag attributes 
    750       else 
    751         $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $this->_conv_case($value, 'value')); 
    752       } 
    753  
    754     return sizeof($attrib_arr) ? ' '.implode(' ', $attrib_arr) : ''; 
    755     } 
    756  
    757  
    758   // convert tags and attributes to upper-/lowercase 
    759   // $type can either be "tag" or "attrib" 
    760   function _conv_case($str, $type='attrib') 
    761     { 
    762     if ($type == 'tag') 
    763       return $this->uppertags ? strtoupper($str) : strtolower($str); 
    764     else if ($type == 'attrib') 
    765       return $this->upperattribs ? strtoupper($str) : strtolower($str); 
    766     else if ($type == 'value') 
    767       return $this->upperprops ? strtoupper($str) : strtolower($str); 
    768     } 
    769   } 
    770  
    771  
    772 class input_field extends base_form_element 
    773   { 
    774   var $type = 'text'; 
    775  
    776   // PHP 5 constructor 
    777   function __construct($attrib=NULL) 
    778     { 
    779     if (is_array($attrib)) 
    780       $this->attrib = $attrib; 
    781  
    782     if ($attrib['type']) 
    783       $this->type = $attrib['type']; 
    784  
    785     if ($attrib['newline']) 
    786       $this->newline = TRUE; 
    787     } 
    788  
    789   // PHP 4 compatibility 
    790   function input_field($attrib=array()) 
    791     { 
    792     $this->__construct($attrib); 
    793     } 
    794  
    795   // compose input tag 
    796   function show($value=NULL, $attrib=NULL) 
    797     { 
    798     // overwrite object attributes 
    799     if (is_array($attrib)) 
    800       $this->attrib = array_merge($this->attrib, $attrib); 
    801  
    802     // set value attribute 
    803     if ($value!==NULL) 
    804       $this->attrib['value'] = $value; 
    805  
    806     $this->attrib['type'] = $this->type; 
    807  
    808     // return final tag 
    809     return sprintf('<%s%s />%s', 
    810                    $this->_conv_case('input', 'tag'), 
    811                    $this->create_attrib_string(), 
    812                    ($this->newline ? "\n" : "")); 
    813     } 
    814   } 
    815  
    816  
    817 class textfield extends input_field 
    818   { 
    819   var $type = 'text'; 
    820   } 
    821  
    822 class passwordfield extends input_field 
    823   { 
    824   var $type = 'password'; 
    825   } 
    826  
    827 class radiobutton extends input_field 
    828   { 
    829   var $type = 'radio'; 
    830   } 
    831  
    832 class checkbox extends input_field 
    833   { 
    834   var $type = 'checkbox'; 
    835  
    836  
    837   function show($value='', $attrib=NULL) 
    838     { 
    839     // overwrite object attributes 
    840     if (is_array($attrib)) 
    841       $this->attrib = array_merge($this->attrib, $attrib); 
    842  
    843     $this->attrib['type'] = $this->type; 
    844  
    845     if ($value && (string)$value==(string)$this->attrib['value']) 
    846       $this->attrib['checked'] = TRUE; 
    847     else 
    848       $this->attrib['checked'] = FALSE; 
    849  
    850     // return final tag 
    851     return sprintf('<%s%s />%s', 
    852                    $this->_conv_case('input', 'tag'), 
    853                    $this->create_attrib_string(), 
    854                    ($this->newline ? "\n" : "")); 
    855     } 
    856   } 
    857  
    858  
    859 class textarea extends base_form_element 
    860   { 
    861   // PHP 5 constructor 
    862   function __construct($attrib=array()) 
    863     { 
    864     $this->attrib = $attrib; 
    865  
    866     if ($attrib['newline']) 
    867       $this->newline = TRUE; 
    868     } 
    869  
    870   // PHP 4 compatibility 
    871   function textarea($attrib=array()) 
    872     { 
    873     $this->__construct($attrib); 
    874     } 
    875  
    876   function show($value='', $attrib=NULL) 
    877     { 
    878     // overwrite object attributes 
    879     if (is_array($attrib)) 
    880       $this->attrib = array_merge($this->attrib, $attrib); 
    881  
    882     // take value attribute as content 
    883     if ($value=='') 
    884       $value = $this->attrib['value']; 
    885  
    886     // make shure we don't print the value attribute 
    887     if (isset($this->attrib['value'])) 
    888       unset($this->attrib['value']); 
    889  
    890     if (!empty($value) && !isset($this->attrib['mce_editable'])) 
    891       $value = Q($value, 'strict', FALSE); 
    892  
    893     // return final tag 
    894     return sprintf('<%s%s>%s</%s>%s', 
    895                    $this->_conv_case('textarea', 'tag'), 
    896                    $this->create_attrib_string(), 
    897                    $value, 
    898                    $this->_conv_case('textarea', 'tag'), 
    899                    ($this->newline ? "\n" : "")); 
    900     } 
    901   } 
    902  
    903  
    904 class hiddenfield extends base_form_element 
    905   { 
    906   var $fields_arr = array(); 
    907   var $newline = TRUE; 
    908  
    909   // PHP 5 constructor 
    910   function __construct($attrib=NULL) 
    911     { 
    912     if (is_array($attrib)) 
    913       $this->add($attrib); 
    914     } 
    915  
    916   // PHP 4 compatibility 
    917   function hiddenfield($attrib=NULL) 
    918     { 
    919     $this->__construct($attrib); 
    920     } 
    921  
    922   // add a hidden field to this instance 
    923   function add($attrib) 
    924     { 
    925     $this->fields_arr[] = $attrib; 
    926     } 
    927  
    928  
    929   function show() 
    930     { 
    931     $out = ''; 
    932     foreach ($this->fields_arr as $attrib) 
    933       { 
    934       $this->attrib = $attrib; 
    935       $this->attrib['type'] = 'hidden'; 
    936  
    937       $out .= sprintf('<%s%s />%s', 
    938                    $this->_conv_case('input', 'tag'), 
    939                    $this->create_attrib_string(), 
    940                    ($this->newline ? "\n" : "")); 
    941       } 
    942  
    943     return $out; 
    944     } 
    945   } 
    946  
    947  
    948 class select extends base_form_element 
    949   { 
    950   var $options = array(); 
    951  
    952   /* 
    953   syntax: 
    954   ------- 
    955   // create instance. arguments are used to set attributes of select-tag 
    956   $select = new select(array('name' => 'fieldname')); 
    957  
    958   // add one option 
    959   $select->add('Switzerland', 'CH'); 
    960  
    961   // add multiple options 
    962   $select->add(array('Switzerland', 'Germany'), 
    963                array('CH', 'DE')); 
    964  
    965   // add 10 blank options with 50 chars 
    966   // used to fill with javascript (necessary for 4.x browsers) 
    967   $select->add_blank(10, 50); 
    968  
    969   // generate pulldown with selection 'Switzerland'  and return html-code 
    970   // as second argument the same attributes available to instanciate can be used 
    971   print $select->show('CH'); 
    972   */ 
    973  
    974   // PHP 5 constructor 
    975   function __construct($attrib=NULL) 
    976     { 
    977     if (is_array($attrib)) 
    978       $this->attrib = $attrib; 
    979  
    980     if ($attrib['newline']) 
    981       $this->newline = TRUE; 
    982     } 
    983  
    984   // PHP 4 compatibility 
    985   function select($attrib=NULL) 
    986     { 
    987     $this->__construct($attrib); 
    988     } 
    989  
    990  
    991   function add($names, $values=NULL) 
    992     { 
    993     if (is_array($names)) 
    994       { 
    995       foreach ($names as $i => $text) 
    996         $this->options[] = array('text' => $text, 'value' => (string)$values[$i]); 
    997       } 
    998     else 
    999       { 
    1000       $this->options[] = array('text' => $names, 'value' => (string)$values); 
    1001       } 
    1002     } 
    1003  
    1004  
    1005   function add_blank($nr, $width=0) 
    1006     { 
    1007     $text = $width ? str_repeat('&nbsp;', $width) : ''; 
    1008  
    1009     for ($i=0; $i < $nr; $i++) 
    1010       $this->options[] = array('text' => $text); 
    1011     } 
    1012  
    1013  
    1014   function show($select=array(), $attrib=NULL) 
    1015     { 
    1016     $options_str = "\n"; 
    1017     $value_str = $this->_conv_case(' value="%s"', 'attrib'); 
    1018  
    1019     if (!is_array($select)) 
    1020       $select = array((string)$select); 
    1021  
    1022     foreach ($this->options as $option) 
    1023       { 
    1024       $selected = ((isset($option['value']) && 
    1025                     in_array($option['value'], $select, TRUE)) || 
    1026                    (in_array($option['text'], $select, TRUE))) ? 
    1027         $this->_conv_case(' selected', 'attrib') : ''; 
    1028  
    1029       $options_str .= sprintf("<%s%s%s>%s</%s>\n", 
    1030                              $this->_conv_case('option', 'tag'), 
    1031                              !empty($option['value']) ? sprintf($value_str, Q($option['value'])) : '', 
    1032                              $selected, 
    1033                              Q($option['text'], 'strict', FALSE), 
    1034                              $this->_conv_case('option', 'tag')); 
    1035       } 
    1036  
    1037     // return final tag 
    1038     return sprintf('<%s%s>%s</%s>%s', 
    1039                    $this->_conv_case('select', 'tag'), 
    1040                    $this->create_attrib_string(), 
    1041                    $options_str, 
    1042                    $this->_conv_case('select', 'tag'), 
    1043                    ($this->newline ? "\n" : "")); 
    1044     } 
    1045   } 
     24require_once dirname(__FILE__) . '/rcube/html_page.php'; 
     25 
     26require_once dirname(__FILE__) . '/rcube/css.php'; 
     27 
     28require_once dirname(__FILE__) . '/rcube/base_form_element.php'; 
     29 
     30require_once dirname(__FILE__) . '/rcube/form_elements.php'; 
    104631 
    104732 
     
    110691function rcube_label($attrib) 
    110792{ 
    1108     global $sess_user_lang, $INSTALL_PATH, $OUTPUT; 
     93    $registry       = rc_registry::getInstance(); 
     94    $sess_user_lang = $registry->get('sess_user_lang', 'core'); 
     95    $INSTALL_PATH   = $registry->get('INSTALL_PATH', 'core'); 
     96    $OUTPUT         = $registry->get('OUTPUT', 'core'); 
     97 
    110998    static $sa_text_data, $s_language, $utf8_decode; 
    111099 
     
    1341330      return $var ? '1' : '0'; 
    1342331    else 
    1343       return "'".JQ($var)."'"; 
     332      return "'" . rc_main::JQ($var) . "'"; 
    1344333 
    1345334  } 
  • branches/devel-vnext/program/include/session.inc

    r589 r622  
    2222 
    2323function sess_open($save_path, $session_name) 
    24   { 
    25   return TRUE; 
    26   } 
     24{ 
     25    return TRUE; 
     26} 
    2727 
    2828 
    2929 
    3030function sess_close() 
    31   { 
    32   return TRUE; 
    33   } 
     31{ 
     32    return TRUE; 
     33} 
    3434 
    3535 
    3636// read session data 
    3737function sess_read($key) 
    38   { 
    39   global $DB, $SESS_CHANGED, $SESS_CLIENT_IP; 
    40    
    41   if ($DB->is_error()) 
     38{ 
     39    $registry       = rc_registry::getInstance(); 
     40    $DB             = $registry->get('DB', 'core'); 
     41    $SESS_CHANGED   = $registry->get('SESS_CHANGED', 'core'); 
     42    $SESS_CLIENT_IP = $registry->get('SESS_CLIENT_IP', 'core'); 
     43 
     44    if ($DB->is_error()) 
     45        return FALSE; 
     46 
     47    $_query = "SELECT vars, ip, ".$DB->unixtimestamp('changed')." AS changed"; 
     48    $_query.= " FROM " . rc_main::get_table_name('session'); 
     49    $_query.= " WHERE sess_id=?"; 
     50    $sql_result = $DB->query($_query, $key); 
     51 
     52    if ($sql_arr = $DB->fetch_assoc($sql_result)) { 
     53        $SESS_CHANGED   = $sql_arr['changed']; 
     54        $SESS_CLIENT_IP = $sql_arr['ip']; 
     55 
     56        $registry->set('SESS_CHANGED', $SESS_CHANGED, 'core'); 
     57        $registry->set('SESS_CLIENT_IP', $SESS_CLIENT_IP, 'core'); 
     58 
     59        if (strlen($sql_arr['vars'])) { 
     60            return $sql_arr['vars']; 
     61        } 
     62    } 
    4263    return FALSE; 
    43    
    44   $sql_result = $DB->query("SELECT vars, ip, ".$DB->unixtimestamp('changed')." AS changed 
    45                             FROM ".get_table_name('session')." 
     64} 
     65 
     66 
     67// save session data 
     68function sess_write($key, $vars) 
     69{ 
     70    $registry = rc_registry::getInstance(); 
     71    $DB       = $registry->get('DB', 'core'); 
     72 
     73    if ($DB->is_error()) 
     74        return FALSE; 
     75 
     76    $sql_result = $DB->query("SELECT 1 
     77                            FROM " . rc_main::get_table_name('session') . " 
    4678                            WHERE  sess_id=?", 
    4779                            $key); 
    4880 
    49   if ($sql_arr = $DB->fetch_assoc($sql_result)) 
    50     { 
    51     $SESS_CHANGED = $sql_arr['changed']; 
    52     $SESS_CLIENT_IP = $sql_arr['ip']; 
    53  
    54     if (strlen($sql_arr['vars'])) 
    55       return $sql_arr['vars']; 
    56     } 
    57  
    58   return FALSE; 
    59   } 
    60    
    61  
    62 // save session data 
    63 function sess_write($key, $vars) 
    64   { 
    65   global $DB; 
    66    
    67   if ($DB->is_error()) 
    68     return FALSE; 
    69  
    70   $sql_result = $DB->query("SELECT 1 
    71                             FROM ".get_table_name('session')." 
    72                             WHERE  sess_id=?", 
    73                             $key); 
    74  
    75   if ($DB->num_rows($sql_result)) 
    76     { 
    77     session_decode($vars); 
    78     $DB->query("UPDATE ".get_table_name('session')." 
     81    if ($DB->num_rows($sql_result)) { 
     82        session_decode($vars); 
     83        $DB->query("UPDATE " . rc_main::get_table_name('session') . " 
    7984                SET    vars=?, 
    8085                       changed=".$DB->now()." 
     
    8388                $key); 
    8489    } 
    85   else 
    86     { 
    87     $DB->query("INSERT INTO ".get_table_name('session')." 
     90    else { 
     91        $DB->query("INSERT INTO " . rc_main::get_table_name('session') . " 
    8892                (sess_id, vars, ip, created, changed) 
    8993                VALUES (?, ?, ?, ".$DB->now().", ".$DB->now().")", 
     
    9195                $vars, 
    9296                $_SERVER['REMOTE_ADDR']); 
    93                  
     97 
    9498 
    9599    } 
    96  
    97   return TRUE; 
    98   } 
     100    return TRUE; 
     101} 
    99102 
    100103 
    101104// handler for session_destroy() 
    102105function sess_destroy($key) 
    103   { 
    104   global $DB; 
    105    
    106   if ($DB->is_error()) 
    107     return FALSE; 
    108    
    109   // delete session entries in cache table 
    110   $DB->query("DELETE FROM ".get_table_name('cache')." 
     106{ 
     107    $registry = rc_registry::getInstance(); 
     108    $DB       = $registry->get('DB', 'core'); 
     109 
     110     if ($DB->is_error()) 
     111        return FALSE; 
     112 
     113    // delete session entries in cache table 
     114    $DB->query("DELETE FROM ".rc_main::get_table_name('cache')." 
    111115              WHERE  session_id=?", 
    112116              $key); 
    113                
    114   $DB->query("DELETE FROM ".get_table_name('session')." 
     117 
     118    $DB->query("DELETE FROM ".rc_main::get_table_name('session')." 
    115119              WHERE sess_id=?", 
    116120              $key); 
    117121 
    118   return TRUE; 
    119   } 
     122    return TRUE; 
     123} 
    120124 
    121125 
    122126// garbage collecting function 
    123127function sess_gc($maxlifetime) 
    124   { 
    125   global $DB; 
     128{ 
     129    $registry = rc_registry::getInstance(); 
     130    $DB       = $registry->get('DB', 'core'); 
    126131 
    127   if ($DB->is_error()) 
    128     return FALSE; 
     132    if ($DB->is_error()) { 
     133        return FALSE; 
     134    } 
     135    // get all expired sessions 
     136    $_query = "SELECT sess_id"; 
     137    $_query.= " FROM " . rc_main::get_table_name('session'); 
     138    $_query.= " WHERE " . $DB->unixtimestamp($DB->now()); 
     139    $_query.= "-" . $DB->unixtimestamp('changed')." > ?"; 
     140    $sql_result = $DB->query($_query, $maxlifetime); 
    129141 
    130   // get all expired sessions   
    131   $sql_result = $DB->query("SELECT sess_id 
    132                             FROM ".get_table_name('session')." 
    133                             WHERE ".$DB->unixtimestamp($DB->now())."-".$DB->unixtimestamp('changed')." > ?", 
    134                             $maxlifetime); 
    135                                     
    136   $a_exp_sessions = array(); 
    137   while ($sql_arr = $DB->fetch_assoc($sql_result)) 
    138     $a_exp_sessions[] = $sql_arr['sess_id']; 
     142    $a_exp_sessions = array(); 
     143    while ($sql_arr = $DB->fetch_assoc($sql_result)) { 
     144        $a_exp_sessions[] = $sql_arr['sess_id']; 
     145    } 
    139146 
    140    
    141   if (sizeof($a_exp_sessions)) 
    142     { 
    143     // delete session cache records 
    144     $DB->query("DELETE FROM ".get_table_name('cache')." 
     147    if (sizeof($a_exp_sessions)) { 
     148        // delete session cache records 
     149        $DB->query("DELETE FROM ".rc_main::get_table_name('cache')." 
    145150                WHERE  session_id IN ('".join("','", $a_exp_sessions)."')"); 
    146                  
    147     // delete session records 
    148     $DB->query("DELETE FROM ".get_table_name('session')." 
     151 
     152        // delete session records 
     153        $DB->query("DELETE FROM ".rc_main::get_table_name('session')." 
    149154                WHERE sess_id IN ('".join("','", $a_exp_sessions)."')"); 
    150155    } 
    151156 
    152   // also run message cache GC 
    153   rcmail_message_cache_gc(); 
    154   rcmail_temp_gc(); 
     157    // also run message cache GC 
     158    rcmail_message_cache_gc(); 
     159    rcmail_temp_gc(); 
    155160 
    156   return TRUE; 
    157   } 
     161    return TRUE; 
     162} 
    158163 
    159164 
    160165function sess_regenerate_id() 
    161   { 
    162   $randlen = 32; 
    163   $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    164   $random = ""; 
    165   for ($i=1; $i <= $randlen; $i++) 
    166     $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1); 
     166{ 
     167    $randlen = 32; 
     168    $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     169    $random = ""; 
     170    for ($i=1; $i <= $randlen; $i++) { 
     171        $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1); 
     172    } 
    167173 
    168   // use md5 value for id or remove capitals from string $randval 
    169   $random = md5($random); 
     174    // use md5 value for id or remove capitals from string $randval 
     175    $random = md5($random); 
    170176 
    171   // delete old session record 
    172   sess_destroy(session_id()); 
     177    // delete old session record 
     178    sess_destroy(session_id()); 
    173179 
    174   session_id($random); 
    175   $cookie = session_get_cookie_params(); 
    176   setcookie(session_name(), $random, $cookie['lifetime'], $cookie['path']); 
     180    session_id($random); 
     181    $cookie = session_get_cookie_params(); 
     182    setcookie(session_name(), $random, $cookie['lifetime'], $cookie['path']); 
    177183 
    178   return true; 
    179   } 
     184    return true; 
     185} 
    180186 
    181187 
  • branches/devel-vnext/program/steps/error.inc

    r589 r622  
    2323// browser is not compatible with this application 
    2424if ($ERROR_CODE==409) 
    25   { 
    26   $user_agent = $GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT']; 
    27   $__error_title = 'Your browser does not suit the requirements for this application'; 
     25{ 
     26    $user_agent = $GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT']; 
     27    $__error_title = 'Your browser does not suit the requirements for this application'; 
    2828  $__error_text = <<<EOF 
    2929<i>Supported browsers:</i><br /> 
     
    4949                   "Please contact your server-administrator."; 
    5050  } 
    51    
     51 
    5252// failed request (wrong step in URL) 
    5353else if ($ERROR_CODE==404) 
     
    6969  $__error_title = "DATABASE ERROR: CONNECTION FAILED!"; 
    7070  $__error_text  =  <<<EOF 
    71 Unable to connect to the database!<br />  
    72 Please contact your server-administrator.  
     71Unable to connect to the database!<br /> 
     72Please contact your server-administrator. 
    7373EOF; 
    7474  } 
     
    7676// system error 
    7777else 
    78   { 
    79   $__error_title = "SERVICE CURRENTLY NOT AVAILABLE!"; 
    80   $__error_text  = "Please contact your server-administrator."; 
     78{ 
     79    $__error_title = "SERVICE CURRENTLY NOT AVAILABLE!"; 
     80    $__error_text  = "Please contact your server-administrator."; 
    8181 
    82   if (($CONFIG['debug_level'] & 4) && $ERROR_MESSAGE) 
    83     $__error_text = $ERROR_MESSAGE; 
    84   else 
    85     $__error_text = sprintf('Error No. [0x%04X]', $ERROR_CODE); 
    86   } 
     82    if (($CONFIG['debug_level'] & 4) && $ERROR_MESSAGE) 
     83        $__error_text = $ERROR_MESSAGE; 
     84    else 
     85        $__error_text = sprintf('Error No. [0x%04X]', $ERROR_CODE); 
     86} 
    8787 
    8888 
     
    9898 
    9999 
    100 if (template_exists('error')) 
    101   { 
    102   $OUTPUT->scripts = array(); 
    103   $OUTPUT->script_files = array(); 
    104   parse_template('error'); 
    105   } 
     100if (rc_main::template_exists('error')) 
     101{ 
     102    $OUTPUT->scripts = array(); 
     103    $OUTPUT->script_files = array(); 
     104    rc_main::parse_template('error'); 
     105} 
    106106 
    107107 
  • branches/devel-vnext/program/steps/mail/func.inc

    r620 r622  
    2020*/ 
    2121 
    22 require_once('lib/html2text.inc'); 
    23 require_once('lib/enriched.inc'); 
     22require_once 'lib/html2text.inc'; 
     23require_once 'lib/enriched.inc'; 
    2424 
    2525 
    2626$EMAIL_ADDRESS_PATTERN = '/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i'; 
    27  
    28 if (empty($_SESSION['mbox'])) 
    29   $_SESSION['mbox'] = $IMAP->get_mailbox_name(); 
    30  
     27$registry = rc_registry::getInstance(); 
     28$registry->set('EMAIL_ADDRESS_PATTERN', $EMAIL_ADDRESS_PATTERN, 'core'); 
     29 
     30if (empty($_SESSION['mbox'])) { 
     31    $_SESSION['mbox'] = $IMAP->get_mailbox_name(); 
     32} 
    3133// set imap properties and session vars 
    32 if ($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC)) 
    33   { 
    34   $IMAP->set_mailbox($mbox); 
    35   $_SESSION['mbox'] = $mbox; 
    36   } 
    37  
    38 if (!empty($_GET['_page'])) 
    39   { 
    40   $IMAP->set_page((int)$_GET['_page']); 
    41   $_SESSION['page'] = (int)$_GET['_page']; 
    42   } 
     34if ($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC)) { 
     35    $IMAP->set_mailbox($mbox); 
     36    $_SESSION['mbox'] = $mbox; 
     37} 
     38 
     39if (!empty($_GET['_page'])) { 
     40    $IMAP->set_page((int)$_GET['_page']); 
     41    $_SESSION['page'] = (int)$_GET['_page']; 
     42} 
    4343 
    4444// set mailbox to INBOX if not set 
    45 if (empty($_SESSION['mbox'])) 
    46   $_SESSION['mbox'] = $IMAP->get_mailbox_name(); 
    47  
     45if (empty($_SESSION['mbox'])) { 
     46    $_SESSION['mbox'] = $IMAP->get_mailbox_name(); 
     47} 
    4848// set default sort col/order to session 
    49 if (!isset($_SESSION['sort_col'])) 
    50   $_SESSION['sort_col'] = $CONFIG['message_sort_col']; 
    51 if (!isset($_SESSION['sort_order'])) 
    52   $_SESSION['sort_order'] = $CONFIG['message_sort_order']; 
    53  
     49if (!isset($_SESSION['sort_col'])) { 
     50    $_SESSION['sort_col'] = $CONFIG['message_sort_col']; 
     51} 
     52if (!isset($_SESSION['sort_order'])) { 
     53    $_SESSION['sort_order'] = $CONFIG['message_sort_order']; 
     54} 
    5455// set message set for search result 
    55 if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) 
    56   $IMAP->set_search_set($_SESSION['search'][$_REQUEST['_search']]); 
    57  
     56if ( 
     57    !empty($_REQUEST['_search']) 
     58    && isset($_SESSION['search'][$_REQUEST['_search']]) 
     59) { 
     60    $IMAP->set_search_set($_SESSION['search'][$_REQUEST['_search']]); 
     61} 
    5862 
    5963// define url for getting message parts 
    60 if (strlen($_GET['_uid'])) 
    61   $GET_URL = rcmail_url('get', array('_mbox'=>$IMAP->get_mailbox_name(), '_uid'=>get_input_value('_uid', RCUBE_INPUT_GET))); 
    62  
     64if (strlen($_GET['_uid'])) { 
     65  $GET_URL = rcmail_url( 
     66                'get', 
     67                array( 
     68                    '_mbox' => $IMAP->get_mailbox_name(), 
     69                    '_uid'  => get_input_value('_uid', RCUBE_INPUT_GET) 
     70                ) 
     71    ); 
     72} 
    6373 
    6474// set current mailbox in client environment 
     
    6676$OUTPUT->set_env('quota', $IMAP->get_capability('quota')); 
    6777 
    68 if ($CONFIG['trash_mbox']) 
    69   $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']); 
    70 if ($CONFIG['drafts_mbox']) 
    71   $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); 
    72 if ($CONFIG['junk_mbox']) 
    73   $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']); 
    74  
    75 if (!$OUTPUT->ajax_call) 
    76   rcube_add_label('checkingmail'); 
    77  
     78if ($CONFIG['trash_mbox']) { 
     79    $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']); 
     80} 
     81if ($CONFIG['drafts_mbox']) { 
     82    $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); 
     83} 
     84if ($CONFIG['junk_mbox']) { 
     85    $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']); 
     86} 
     87if (!$OUTPUT->ajax_call) { 
     88    rcube_add_label('checkingmail'); 
     89} 
    7890 
    7991// return the mailboxlist in HTML 
    8092function rcmail_mailbox_list($attrib) 
    81   { 
    82   global $IMAP, $CONFIG, $OUTPUT, $COMM_PATH; 
    83   static $s_added_script = FALSE; 
    84   static $a_mailboxes; 
    85  
    86   // add some labels to client 
    87   rcube_add_label('purgefolderconfirm'); 
    88   rcube_add_label('deletemessagesconfirm'); 
    89    
    90 // $mboxlist_start = rcube_timer(); 
    91    
    92   $type = $attrib['type'] ? $attrib['type'] : 'ul'; 
    93   $add_attrib = $type=='select' ? array('style', 'class', 'id', 'name', 'onchange') : 
     93{ 
     94    $registry  = rc_registry::getInstance(); 
     95    $IMAP      = $registry->get('IMAP', 'core'); 
     96    $CONFIG    = $registry->get('CONFIG', 'core'); 
     97    $OUTPUT    = $registry->get('OUTPUT', 'core'); 
     98    $COMM_PATH = $registry->get('COMM_PATH', 'core'); 
     99 
     100    $s_added_script = $registry->get('s_added_script', 'core'); 
     101    if (is_null($s_added_script)) { 
     102        $s_added_script = FALSE; 
     103        $registry->get('s_added_script', $s_added_script); 
     104    } 
     105    $a_mailboxes = $registry->get('a_mailboxes', 'core'); 
     106 
     107    // add some labels to client 
     108    rcube_add_label('purgefolderconfirm'); 
     109    rcube_add_label('deletemessagesconfirm'); 
     110 
     111    // $mboxlist_start = rcube_timer(); 
     112 
     113    $type = $attrib['type'] ? $attrib['type'] : 'ul'; 
     114    $add_attrib = $type=='select' ? array('style', 'class', 'id', 'name', 'onchange') : 
    94115                                  array('style', 'class', 'id'); 
    95                                    
    96   if ($type=='ul' && !$attrib['id']) 
    97     $attrib['id'] = 'rcmboxlist'; 
    98  
    99   // allow the following attributes to be added to the <ul> tag 
    100   $attrib_str = create_attrib_string($attrib, $add_attrib); 
    101   
    102   $out = '<' . $type . $attrib_str . ">\n"; 
    103    
    104   // add no-selection option 
    105   if ($type=='select' && $attrib['noselection']) 
    106     $out .= sprintf('<option value="0">%s</option>'."\n", 
    107                     rcube_label($attrib['noselection'])); 
    108    
    109   // get mailbox list 
    110   $mbox_name = $IMAP->get_mailbox_name(); 
    111    
    112   // for these mailboxes we have localized labels 
    113   $special_mailboxes = array('inbox', 'sent', 'drafts', 'trash', 'junk'); 
    114  
    115  
    116   // build the folders tree 
    117   if (empty($a_mailboxes)) 
    118     { 
     116 
     117    if ($type=='ul' && !$attrib['id']) { 
     118        $attrib['id'] = 'rcmboxlist'; 
     119    } 
     120    // allow the following attributes to be added to the <ul> tag 
     121    $attrib_str = rc_main::create_attrib_string($attrib, $add_attrib); 
     122 
     123    $out = '<' . $type . $attrib_str . ">\n"; 
     124 
     125    // add no-selection option 
     126    if ($type=='select' && $attrib['noselection']) { 
     127        $out .= sprintf( 
     128                    '<option value="0">%s</option>'."\n", 
     129                    rcube_label($attrib['noselection']) 
     130        ); 
     131    } 
    119132    // get mailbox list 
    120     $a_folders = $IMAP->list_mailboxes(); 
    121     $delimiter = $IMAP->get_hierarchy_delimiter(); 
    122     $a_mailboxes = array(); 
    123  
    124 // rcube_print_time($mboxlist_start, 'list_mailboxes()'); 
    125  
    126     foreach ($a_folders as $folder) 
    127       rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); 
    128     } 
    129  
    130 // var_dump($a_mailboxes); 
    131  
    132   if ($type=='select') 
    133     $out .= rcmail_render_folder_tree_select($a_mailboxes, $special_mailboxes, $mbox_name, $attrib['maxlength']); 
    134    else 
    135     $out .= rcmail_render_folder_tree_html($a_mailboxes, $special_mailboxes, $mbox_name, $attrib['maxlength']); 
    136  
    137 // rcube_print_time($mboxlist_start, 'render_folder_tree()'); 
    138  
    139  
    140   if ($type=='ul') 
    141     $OUTPUT->add_gui_object('mailboxlist', $attrib['id']); 
    142  
    143   return $out . "</$type>"; 
    144   } 
     133    $mbox_name = $IMAP->get_mailbox_name(); 
     134 
     135    // for these mailboxes we have localized labels 
     136    $special_mailboxes = array('inbox', 'sent', 'drafts', 'trash', 'junk'); 
     137 
     138 
     139    // build the folders tree 
     140    if (empty($a_mailboxes)) { 
     141        // get mailbox list 
     142        $a_folders = $IMAP->list_mailboxes(); 
     143        $delimiter = $IMAP->get_hierarchy_delimiter(); 
     144        $a_mailboxes = array(); 
     145 
     146        // rcube_print_time($mboxlist_start, 'list_mailboxes()'); 
     147 
     148        foreach ($a_folders as $folder) { 
     149            rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); 
     150        } 
     151    } 
     152 
     153    //var_dump($a_mailboxes); 
     154 
     155    if ($type=='select') { 
     156        $out .= rcmail_render_folder_tree_select( 
     157                    $a_mailboxes, 
     158                    $special_mailboxes, 
     159                    $mbox_name, 
     160                    $attrib['maxlength'] 
     161        ); 
     162    } 
     163    else { 
     164        $out .= rcmail_render_folder_tree_html( 
     165                    $a_mailboxes, 
     166                    $special_mailboxes, 
     167                    $mbox_name, 
     168                    $attrib['maxlength'] 
     169        ); 
     170    } 
     171    $registry->set('a_mailboxes', $a_mailboxes); 
     172    // rcube_print_time($mboxlist_start, 'render_folder_tree()'); 
     173 
     174 
     175    if ($type=='ul') { 
     176        $OUTPUT->add_gui_object('mailboxlist', $attrib['id']); 
     177    } 
     178    return $out . "</$type>"; 
     179} 
    145180 
    146181 
     
    149184// create a hierarchical array of the mailbox list 
    150185function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') 
    151   { 
    152   $pos = strpos($folder, $delm); 
    153   if ($pos !== false) 
    154     { 
    155     $subFolders = substr($folder, $pos+1); 
    156     $currentFolder = substr($folder, 0, $pos); 
    157     } 
    158   else 
    159     { 
    160     $subFolders = false; 
    161     $currentFolder = $folder; 
    162     } 
    163  
    164   $path .= $currentFolder; 
    165  
    166   if (!isset($arrFolders[$currentFolder])) 
    167     { 
    168     $arrFolders[$currentFolder] = array('id' => $path, 
    169                                         'name' => rcube_charset_convert($currentFolder, 'UTF-7'), 
    170                                         'folders' => array()); 
    171     } 
    172  
    173   if (!empty($subFolders)) 
    174     rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm); 
    175   } 
    176    
     186{ 
     187    $pos = strpos($folder, $delm); 
     188    if ($pos !== false) { 
     189        $subFolders = substr($folder, $pos+1); 
     190        $currentFolder = substr($folder, 0, $pos); 
     191    } 
     192    else { 
     193        $subFolders = false; 
     194        $currentFolder = $folder; 
     195    } 
     196 
     197    $path .= $currentFolder; 
     198 
     199    if (!isset($arrFolders[$currentFolder])) { 
     200        $arrFolders[$currentFolder] = array( 
     201                                        'id'      => $path, 
     202                                        'name'    => rc_main::rcube_charset_convert($currentFolder, 'UTF-7'), 
     203                                        'folders' => array() 
     204        ); 
     205    } 
     206 
     207    if (!empty($subFolders)) { 
     208        rcmail_build_folder_tree( 
     209                $arrFolders[$currentFolder]['folders'], 
     210                $subFolders, 
     211                $delm, 
     212                $path.$delm 
     213        ); 
     214    } 
     215} 
     216 
    177217 
    178218// return html for a structured list <ul> for the mailbox tree 
    179219function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox_name, $maxlength, $nestLevel=0) 
    180   { 
    181   global $COMM_PATH, $IMAP, $CONFIG, $OUTPUT; 
    182  
    183   $idx = 0; 
    184   $out = ''; 
    185   foreach ($arrFolders as $key => $folder) 
     220{ 
     221    $registry  = rc_registry::getInstance(); 
     222    $IMAP      = $registry->get('IMAP', 'core'); 
     223    $CONFIG    = $registry->get('CONFIG', 'core'); 
     224    $OUTPUT    = $registry->get('OUTPUT', 'core'); 
     225    $COMM_PATH = $registry->get('COMM_PATH', 'core'); 
     226 
     227    $idx = 0; 
     228    $out = ''; 
     229    foreach ($arrFolders as $key => $folder) 
    186230    { 
    187     $zebra_class = ($nestLevel*$idx)%2 ? 'even' : 'odd'; 
    188     $title = ''; 
    189  
    190     $folder_lc = strtolower($folder['id']); 
    191     if (in_array($folder_lc, $special)) 
    192       $foldername = rcube_label($folder_lc); 
    193     else 
    194       { 
    195       $foldername = $folder['name']; 
    196  
    197       // shorten the folder name to a given length 
    198       if ($maxlength && $maxlength>1) 
    199         { 
    200         $fname = abbrevate_string($foldername, $maxlength); 
    201         if ($fname != $foldername) 
    202           $title = ' title="'.Q($foldername).'"'; 
    203         $foldername = $fname; 
    204         } 
    205       } 
    206  
    207     // add unread message count display 
    208     if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox_name))) 
    209       $foldername .= sprintf(' (%d)', $unread_count); 
    210  
    211     // make folder name safe for ids and class names 
    212     $folder_id = preg_replace('/[^A-Za-z0-9\-_]/', '', $folder['id']); 
    213     $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_lc); 
    214  
    215     // set special class for Sent, Drafts, Trash and Junk 
    216     if ($folder['id']==$CONFIG['sent_mbox']) 
    217       $class_name = 'sent'; 
    218     else if ($folder['id']==$CONFIG['drafts_mbox']) 
    219       $class_name = 'drafts'; 
    220     else if ($folder['id']==$CONFIG['trash_mbox']) 
    221       $class_name = 'trash'; 
    222     else if ($folder['id']==$CONFIG['junk_mbox']) 
    223       $class_name = 'junk'; 
    224  
    225     $js_name = htmlspecialchars(JQ($folder['id'])); 
    226     $out .= sprintf('<li id="rcmli%s" class="mailbox %s %s%s%s"><a href="%s"'. 
    227                     ' onclick="return %s.command(\'list\',\'%s\',this)"'. 
    228                     ' onmouseover="return %s.focus_folder(\'%s\')"' . 
    229                     ' onmouseout="return %s.unfocus_folder(\'%s\')"' . 
    230                     ' onmouseup="return %s.folder_mouse_up(\'%s\')"%s>%s</a>', 
     231        $zebra_class = ($nestLevel*$idx)%2 ? 'even' : 'odd'; 
     232        $title = ''; 
     233 
     234        $folder_lc = strtolower($folder['id']); 
     235        if (in_array($folder_lc, $special)) 
     236            $foldername = rcube_label($folder_lc); 
     237        else { 
     238            $foldername = $folder['name']; 
     239 
     240            // shorten the folder name to a given length 
     241            if ($maxlength && $maxlength>1) { 
     242                $fname = abbrevate_string($foldername, $maxlength); 
     243                if ($fname != $foldername) 
     244                    $title = ' title="'.rc_main::Q($foldername).'"'; 
     245                $foldername = $fname; 
     246            } 
     247        } 
     248 
     249        // add unread message count display 
     250        if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox_name))) 
     251            $foldername .= sprintf(' (%d)', $unread_count); 
     252 
     253        // make folder name safe for ids and class names 
     254        $folder_id  = preg_replace('/[^A-Za-z0-9\-_]/', '', $folder['id']); 
     255        $class_name = preg_replace('/[^a-z0-9\-_]/', '', $folder_lc); 
     256 
     257        // set special class for Sent, Drafts, Trash and Junk 
     258        if ($folder['id']==$CONFIG['sent_mbox']) 
     259            $class_name = 'sent'; 
     260        else if ($folder['id']==$CONFIG['drafts_mbox']) 
     261            $class_name = 'drafts'; 
     262        else if ($folder['id']==$CONFIG['trash_mbox']) 
     263            $class_name = 'trash'; 
     264        else if ($folder['id']==$CONFIG['junk_mbox']) 
     265            $class_name = 'junk'; 
     266 
     267        $js_name = htmlspecialchars(rc_main::JQ($folder['id'])); 
     268 
     269        $_string_out = '<li id="rcmli%s" class="mailbox %s %s%s%s"><a href="%s"'; 
     270        $_string_out.= ' onclick="return %s.command(\'list\',\'%s\',this)"'; 
     271        $_string_out.= ' onmouseover="return %s.focus_folder(\'%s\')"'; 
     272        $_string_out.= ' onmouseout="return %s.unfocus_folder(\'%s\')"'; 
     273        $_string_out.= ' onmouseup="return %s.folder_mouse_up(\'%s\')"%s>%s</a>'; 
     274 
     275        $out .= sprintf( 
     276                    $_string_out, 
    231277                    $folder_id, 
    232278                    $class_name, 
     
    234280                    $unread_count ? ' unread' : '', 
    235281                    $folder['id']==$mbox_name ? ' selected' : '', 
    236                     Q(rcmail_url('', array('_mbox' => $folder['id']))), 
     282                    rc_main::Q(rcmail_url('', array('_mbox' => $folder['id']))), 
    237283                    JS_OBJECT_NAME, 
    238284                    $js_name, 
     
    244290                    $js_name, 
    245291                    $title, 
    246                     Q($foldername)); 
     292                    rc_main::Q($foldername)); 
     293 
     294        if (!empty($folder['folders'])) { 
     295            $out .= "\n<ul>\n"; 
     296            $out .= rcmail_render_folder_tree_html($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1) . "</ul>\n"; 
     297        } 
     298        $out .= "</li>\n"; 
     299        $idx++; 
     300    } 
     301 
     302    return $out; 
     303} 
     304 
     305 
     306// return html for a flat list <select> for the mailbox tree 
     307function rcmail_render_folder_tree_select(&$arrFolders, &$special, &$mbox_name, $maxlength, $nestLevel=0) 
     308{ 
     309    $registry  = rc_registry::getInstance(); 
     310    $IMAP      = $registry->get('IMAP', 'core'); 
     311    $OUTPUT    = $registry->get('OUTPUT', 'core'); 
     312 
     313    $idx = 0; 
     314    $out = ''; 
     315    foreach ($arrFolders as $key=>$folder) { 
     316        $folder_lc = strtolower($folder['id']); 
     317        if (in_array($folder_lc, $special)) 
     318            $foldername = rcube_label($folder_lc); 
     319        else { 
     320            $foldername = $folder['name']; 
     321 
     322            // shorten the folder name to a given length 
     323            if ($maxlength && $maxlength>1) 
     324                $foldername = abbrevate_string($foldername, $maxlength); 
     325        } 
     326 
     327        $out .= sprintf( 
     328                    '<option value="%s">%s%s</option>'."\n", 
     329                    htmlspecialchars($folder['id']), 
     330                    str_repeat('&nbsp;', $nestLevel*4), 
     331                    rc_main::Q($foldername)); 
    247332 
    248333    if (!empty($folder['folders'])) 
    249       $out .= "\n<ul>\n" . rcmail_render_folder_tree_html($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1) . "</ul>\n"; 
    250  
    251     $out .= "</li>\n"; 
     334      $out .= rcmail_render_folder_tree_select($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1); 
     335 
    252336    $idx++; 
    253337    } 
     
    257341 
    258342 
    259 // return html for a flat list <select> for the mailbox tree 
    260 function rcmail_render_folder_tree_select(&$arrFolders, &$special, &$mbox_name, $maxlength, $nestLevel=0) 
    261   { 
    262   global $IMAP, $OUTPUT; 
    263  
    264   $idx = 0; 
    265   $out = ''; 
    266   foreach ($arrFolders as $key=>$folder) 
    267     { 
    268     $folder_lc = strtolower($folder['id']); 
    269     if (in_array($folder_lc, $special)) 
    270       $foldername = rcube_label($folder_lc); 
    271     else 
    272       { 
    273       $foldername = $folder['name']; 
    274        
    275       // shorten the folder name to a given length 
    276       if ($maxlength && $maxlength>1) 
    277         $foldername = abbrevate_string($foldername, $maxlength); 
    278       } 
    279  
    280     $out .= sprintf('<option value="%s">%s%s</option>'."\n", 
    281                     htmlspecialchars($folder['id']), 
    282                     str_repeat('&nbsp;', $nestLevel*4), 
    283                     Q($foldername)); 
    284  
    285     if (!empty($folder['folders'])) 
    286       $out .= rcmail_render_folder_tree_select($folder['folders'], $special, $mbox_name, $maxlength, $nestLevel+1); 
    287  
    288     $idx++; 
    289     } 
    290  
    291   return $out; 
    292   } 
    293  
    294  
    295 // return the message list as HTML table 
     343/** 
     344 * rcmail_message_list 
     345 * 
     346 * return the message list as HTML table 
     347 * 
     348 * @todo   Changed icon > icon1/icon2 
     349 * @access public 
     350 * @param  array $attrib 
     351 * @return string 
     352 */ 
    296353function rcmail_message_list($attrib) 
    297354{ 
     
    304361    $sort_col   = $_SESSION['sort_col']; 
    305362    $sort_order = $_SESSION['sort_order']; 
    306    
     363 
    307364    // add some labels to client 
    308365    rcube_add_label('from', 'to'); 
     
    317374 
    318375    // allow the following attributes to be added to the <table> tag 
    319     $attrib_str = create_attrib_string( 
     376    $attrib_str = rc_main::create_attrib_string( 
    320377                        $attrib, 
    321378                        array( 
     
    334391 
    335392    $mbox = $IMAP->get_mailbox_name(); 
    336    
     393 
    337394    // show 'to' instead of from in sent messages 
    338395