Changeset 6073 in subversion


Ignore:
Timestamp:
Apr 13, 2012 4:52:02 AM (13 months ago)
Author:
alec
Message:
  • Merge devel-framework branch, resolved conflicts
Location:
trunk/roundcubemail
Files:
4 deleted
38 edited
8 copied

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail

  • trunk/roundcubemail/CHANGELOG

    r6062 r6073  
    22=========================== 
    33 
     4- Roundcube Framework: 
     5    Add possibility to replace IMAP driver with custom class 
     6    Add IMAP auto-connection feature, improving performance with caching enabled 
     7    Replace imap_init hook with storage_init (with additional 'driver' argument) 
     8    Improved performance by caching IMAP server's capabilities in session 
     9    Unified global functions naming (rcube_ prefix) 
     10    Move global functions from main.inc and rcube_shared.inc into classes 
     11    Better classes separation 
     12 
     13RELEASE 0.8-rc 
     14---------------- 
    415- Set flexible width to login form fields (#1488418) 
    516- Fix re-draw bug on list columns change in IE8 (#1487822) 
  • trunk/roundcubemail/bin/msgexport.sh

    r5781 r6073  
    3535 
    3636    $index = $IMAP->index($mbox, null, 'ASC'); 
    37     $count = $index->countMessages(); 
     37    $count = $index->count(); 
    3838    $index = $index->get(); 
    3939 
  • trunk/roundcubemail/index.php

    r5787 r6073  
    33 +-------------------------------------------------------------------------+ 
    44 | Roundcube Webmail IMAP Client                                           | 
    5  | Version 0.8-svn                                                         | 
     5 | Version 0.9-svn                                                         | 
    66 |                                                                         | 
    77 | Copyright (C) 2005-2012, The Roundcube Dev Team                         | 
     
    4646 
    4747// Make the whole PHP output non-cacheable (#1487797) 
    48 send_nocacheing_headers(); 
     48$RCMAIL->output->nocacheing_headers(); 
    4949 
    5050// turn on output buffering 
     
    6868 
    6969// error steps 
    70 if ($RCMAIL->action=='error' && !empty($_GET['_code'])) { 
     70if ($RCMAIL->action == 'error' && !empty($_GET['_code'])) { 
    7171  raise_error(array('code' => hexdec($_GET['_code'])), FALSE, TRUE); 
    7272} 
     
    7575if (empty($_SESSION['user_id']) && ($force_https = $RCMAIL->config->get('force_https', false))) { 
    7676  $https_port = is_bool($force_https) ? 443 : $force_https; 
    77   if (!rcube_https_check($https_port)) { 
     77  if (!rcube_ui::https_check($https_port)) { 
    7878    $host  = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']); 
    7979    $host .= ($https_port != 443 ? ':' . $https_port : ''); 
     
    9090// try to log in 
    9191if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') { 
    92   $request_valid = $_SESSION['temp'] && $RCMAIL->check_request(RCUBE_INPUT_POST, 'login'); 
     92  $request_valid = $_SESSION['temp'] && $RCMAIL->check_request(rcube_ui::INPUT_POST, 'login'); 
    9393 
    9494  // purge the session in case of new login when a session already exists  
     
    9797  $auth = $RCMAIL->plugins->exec_hook('authenticate', array( 
    9898    'host' => $RCMAIL->autoselect_host(), 
    99     'user' => trim(get_input_value('_user', RCUBE_INPUT_POST)), 
    100     'pass' => get_input_value('_pass', RCUBE_INPUT_POST, true, 
     99    'user' => trim(rcube_ui::get_input_value('_user', rcube_ui::INPUT_POST)), 
     100    'pass' => rcube_ui::get_input_value('_pass', rcube_ui::INPUT_POST, true, 
    101101       $RCMAIL->config->get('password_charset', 'ISO-8859-1')), 
    102102    'cookiecheck' => true, 
     
    120120 
    121121    // log successful login 
    122     rcmail_log_login(); 
     122    $RCMAIL->log_login(); 
    123123 
    124124    // restore original request parameters 
    125125    $query = array(); 
    126     if ($url = get_input_value('_url', RCUBE_INPUT_POST)) { 
     126    if ($url = rcube_ui::get_input_value('_url', rcube_ui::INPUT_POST)) { 
    127127      parse_str($url, $query); 
    128128 
     
    150150 
    151151// end session (after optional referer check) 
    152 else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) && (!$RCMAIL->config->get('referer_check') || rcube_check_referer())) { 
     152else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) && (!$RCMAIL->config->get('referer_check') || rcmail::check_referer())) { 
    153153  $userdata = array( 
    154154    'user' => $_SESSION['username'], 
     
    173173if (empty($RCMAIL->user->ID)) { 
    174174  // log session failures 
    175   if (($task = get_input_value('_task', RCUBE_INPUT_GPC)) && !in_array($task, array('login','logout')) && !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])) { 
     175  $task = rcube_ui::get_input_value('_task', rcube_ui::INPUT_GPC); 
     176  if ($task && !in_array($task, array('login','logout')) && !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])) { 
    176177    $RCMAIL->session->log("Aborted session " . $sess_id . "; no valid session data found"); 
    177178    $session_error = true; 
     
    209210  // check client X-header to verify request origin 
    210211  if ($OUTPUT->ajax_call) { 
    211     if (rc_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token() && !$RCMAIL->config->get('devel_mode')) { 
     212    if (rcube_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token() && !$RCMAIL->config->get('devel_mode')) { 
    212213      header('HTTP/1.1 403 Forbidden'); 
    213214      die("Invalid Request"); 
     
    221222 
    222223  // check referer if configured 
    223   if (!$request_check_whitelist[$RCMAIL->action] && $RCMAIL->config->get('referer_check') && !rcube_check_referer()) { 
     224  if (!$request_check_whitelist[$RCMAIL->action] && $RCMAIL->config->get('referer_check') && !rcmail::check_referer()) { 
    224225    raise_error(array( 
    225226      'code' => 403, 
  • trunk/roundcubemail/installer/index.php

    r6036 r6073  
    5454 
    5555require_once 'utils.php'; 
     56require_once 'rcube_shared.inc'; 
     57// deprecated aliases (to be removed) 
    5658require_once 'main.inc'; 
    5759 
  • trunk/roundcubemail/installer/utils.php

    r5787 r6073  
    4646} 
    4747 
    48  
    49 /** 
    50  * Fake internal error handler to catch errors 
    51  */ 
    52 function raise_error($p) 
    53 { 
    54     $rci = rcube_install::get_instance(); 
    55     $rci->raise_error($p); 
    56 } 
    57  
    5848/** 
    5949 * Local callback function for PEAR errors 
    6050 */ 
    61 function rcube_pear_error($err) 
     51function __pear_error($err) 
    6252{ 
    63     raise_error(array( 
     53    rcmail::raise_error(array( 
    6454        'code' => $err->getCode(), 
    6555        'message' => $err->getMessage(), 
     
    6858 
    6959// set PEAR error handling (will also load the PEAR main class) 
    70 PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error'); 
     60PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, '__pear_error'); 
  • trunk/roundcubemail/plugins

  • trunk/roundcubemail/program/include/clisetup.php

    r5787 r6073  
    5656 
    5757                $args[$key] = preg_replace(array('/^["\']/', '/["\']$/'), '', $value); 
    58                  
     58 
    5959                if ($alias = $aliases[$key]) 
    6060                        $args[$alias] = $args[$key]; 
  • trunk/roundcubemail/program/include/html.php

    r5992 r6073  
    278278        foreach ($attrib as $key => $value) { 
    279279            // skip size if not numeric 
    280             if (($key=='size' && !is_numeric($value))) { 
     280            if ($key == 'size' && !is_numeric($value)) { 
    281281                continue; 
    282282            } 
     
    298298                } 
    299299            } 
    300             else if ($key=='value') { 
    301                 $attrib_arr[] = $key . '="' . Q($value, 'strict', false) . '"'; 
    302             } 
    303300            else { 
    304                 $attrib_arr[] = $key . '="' . Q($value) . '"'; 
    305             } 
    306         } 
     301                $attrib_arr[] = $key . '="' . self::quote($value) . '"'; 
     302            } 
     303        } 
     304 
    307305        return count($attrib_arr) ? ' '.implode(' ', $attrib_arr) : ''; 
    308306    } 
     307 
     308    /** 
     309     * Convert a HTML attribute string attributes to an associative array (name => value) 
     310     * 
     311     * @param string Input string 
     312     * @return array Key-value pairs of parsed attributes 
     313     */ 
     314    public static function parse_attrib_string($str) 
     315    { 
     316        $attrib = array(); 
     317        $regexp = '/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]*)\2|(\S+?))/Ui'; 
     318 
     319        preg_match_all($regexp, stripslashes($str), $regs, PREG_SET_ORDER); 
     320 
     321        // convert attributes to an associative array (name => value) 
     322        if ($regs) { 
     323            foreach ($regs as $attr) { 
     324                $attrib[strtolower($attr[1])] = html_entity_decode($attr[3] . $attr[4]); 
     325            } 
     326        } 
     327 
     328        return $attrib; 
     329    } 
     330 
     331    /** 
     332     * Replacing specials characters in html attribute value 
     333     * 
     334     * @param  string  $str  Input string 
     335     * 
     336     * @return string  The quoted string 
     337     */ 
     338    public static function quote($str) 
     339    { 
     340        $str = htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET); 
     341 
     342        // avoid douple quotation of & 
     343        // @TODO: get rid of it? 
     344        $str = preg_replace('/&([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $str); 
     345 
     346        return $str; 
     347    } 
    309348} 
     349 
    310350 
    311351/** 
     
    318358    protected $tagname = 'input'; 
    319359    protected $type = 'text'; 
    320     protected $allowed = array('type','name','value','size','tabindex', 
     360    protected $allowed = array( 
     361        'type','name','value','size','tabindex', 
    321362        'autocomplete','checked','onchange','onclick','disabled','readonly', 
    322         'spellcheck','results','maxlength','src','multiple','placeholder'); 
     363        'spellcheck','results','maxlength','src','multiple','placeholder', 
     364    ); 
    323365 
    324366    /** 
     
    518560 
    519561        if (!empty($value) && !preg_match('/mce_editor/', $this->attrib['class'])) { 
    520             $value = Q($value, 'strict', false); 
     562            $value = self::quote($value); 
    521563        } 
    522564 
    523565        return self::tag($this->tagname, $this->attrib, $value, 
    524             array_merge(self::$common_attrib, $this->allowed)); 
     566                array_merge(self::$common_attrib, $this->allowed)); 
    525567    } 
    526568} 
     
    551593    protected $allowed = array('name','size','tabindex','autocomplete', 
    552594        'multiple','onchange','disabled','rel'); 
    553      
     595 
    554596    /** 
    555597     * Add a new option to this drop-down 
     
    592634                  in_array($option['text'], $select, true)) ? 1 : null); 
    593635 
    594             $this->content .= self::tag('option', $attr, Q($option['text'])); 
    595         } 
     636            $this->content .= self::tag('option', $attr, self::quote($option['text'])); 
     637        } 
     638 
    596639        return parent::show(); 
    597640    } 
     
    804847 
    805848} 
    806  
  • trunk/roundcubemail/program/include/iniset.php

    r5958 r6073  
    4141 
    4242// application constants 
    43 define('RCMAIL_VERSION', '0.8-svn'); 
     43define('RCMAIL_VERSION', '0.9-svn'); 
    4444define('RCMAIL_CHARSET', 'UTF-8'); 
    4545define('JS_OBJECT_NAME', 'rcmail'); 
     
    5252if (!defined('RCMAIL_CONFIG_DIR')) { 
    5353    define('RCMAIL_CONFIG_DIR', INSTALL_PATH . 'config'); 
    54 } 
    55  
    56 // make sure path_separator is defined 
    57 if (!defined('PATH_SEPARATOR')) { 
    58     define('PATH_SEPARATOR', (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') ? ';' : ':'); 
    5954} 
    6055 
     
    8176} 
    8277 
    83 /** 
    84  * Use PHP5 autoload for dynamic class loading 
    85  *  
    86  * @todo Make Zend, PEAR etc play with this 
    87  * @todo Make our classes conform to a more straight forward CS. 
    88  */ 
    89 function rcube_autoload($classname) 
    90 { 
    91     $filename = preg_replace( 
    92         array( 
    93             '/MDB2_(.+)/', 
    94             '/Mail_(.+)/', 
    95             '/Net_(.+)/', 
    96             '/Auth_(.+)/', 
    97             '/^html_.+/', 
    98             '/^utf8$/', 
    99         ), 
    100         array( 
    101             'MDB2/\\1', 
    102             'Mail/\\1', 
    103             'Net/\\1', 
    104             'Auth/\\1', 
    105             'html', 
    106             'utf8.class', 
    107         ), 
    108         $classname 
    109     ); 
     78// include global functions 
     79require_once INSTALL_PATH . 'program/include/rcube_shared.inc'; 
    11080 
    111     if ($fp = @fopen("$filename.php", 'r', true)) { 
    112         fclose($fp); 
    113         include_once("$filename.php"); 
    114         return true; 
    115     } 
    116  
    117     return false; 
    118 } 
    119  
     81// Register autoloader 
    12082spl_autoload_register('rcube_autoload'); 
    121  
    122 /** 
    123  * Local callback function for PEAR errors 
    124  */ 
    125 function rcube_pear_error($err) 
    126 { 
    127     error_log(sprintf("%s (%s): %s", 
    128         $err->getMessage(), 
    129         $err->getCode(), 
    130         $err->getUserinfo()), 0); 
    131 } 
    13283 
    13384// set PEAR error handling (will also load the PEAR main class) 
    13485PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error'); 
    13586 
    136 // include global functions 
     87// backward compatybility (to be removed) 
    13788require_once INSTALL_PATH . 'program/include/main.inc'; 
    138 require_once INSTALL_PATH . 'program/include/rcube_shared.inc'; 
  • trunk/roundcubemail/program/include/main.inc

    r6050 r6073  
    66 |                                                                       | 
    77 | This file is part of the Roundcube Webmail client                     | 
    8  | Copyright (C) 2005-2011, The Roundcube Dev Team                       | 
     8 | Copyright (C) 2005-2012, The Roundcube Dev Team                       | 
    99 |                                                                       | 
    1010 | Licensed under the GNU General Public License version 3 or            | 
     
    1313 |                                                                       | 
    1414 | PURPOSE:                                                              | 
    15  |   Provide basic functions for the webmail package                     | 
     15 |   Provide deprecated functions aliases for backward compatibility     | 
    1616 |                                                                       | 
    1717 +-----------------------------------------------------------------------+ 
     
    2424 
    2525/** 
    26  * Roundcube Webmail common functions 
     26 * Roundcube Webmail deprecated functions 
    2727 * 
    2828 * @package Core 
     
    3030 */ 
    3131 
    32 require_once INSTALL_PATH . 'program/include/rcube_shared.inc'; 
    33  
    34 // define constannts for input reading 
    35 define('RCUBE_INPUT_GET', 0x0101); 
    36 define('RCUBE_INPUT_POST', 0x0102); 
    37 define('RCUBE_INPUT_GPC', 0x0103); 
    38  
    39  
    40  
    41 /** 
    42  * Return correct name for a specific database table 
    43  * 
    44  * @param string Table name 
    45  * @return string Translated table name 
    46  */ 
     32// constants for input reading 
     33define('RCUBE_INPUT_GET',  rcube_ui::INPUT_GET); 
     34define('RCUBE_INPUT_POST', rcube_ui::INPUT_POST); 
     35define('RCUBE_INPUT_GPC',  rcube_ui::INPUT_GPC); 
     36 
     37 
    4738function get_table_name($table) 
    48   { 
    49   global $CONFIG; 
    50  
    51   // return table name if configured 
    52   $config_key = 'db_table_'.$table; 
    53  
    54   if (strlen($CONFIG[$config_key])) 
    55     return $CONFIG[$config_key]; 
    56  
    57   return $table; 
    58   } 
    59  
    60  
    61 /** 
    62  * Return correct name for a specific database sequence 
    63  * (used for Postgres only) 
    64  * 
    65  * @param string Secuence name 
    66  * @return string Translated sequence name 
    67  */ 
     39{ 
     40    return rcmail::get_instance()->db->table_name($table); 
     41} 
     42 
    6843function get_sequence_name($sequence) 
    69   { 
    70   // return sequence name if configured 
    71   $config_key = 'db_sequence_'.$sequence; 
    72   $opt = rcmail::get_instance()->config->get($config_key); 
    73  
    74   if (!empty($opt)) 
    75     return $opt; 
    76      
    77   return $sequence; 
    78   } 
    79  
    80  
    81 /** 
    82  * Get localized text in the desired language 
    83  * It's a global wrapper for rcmail::gettext() 
    84  * 
    85  * @param mixed Named parameters array or label name 
    86  * @param string Domain to search in (e.g. plugin name) 
    87  * @return string Localized text 
    88  * @see rcmail::gettext() 
    89  */ 
     44{ 
     45    return rcmail::get_instance()->db->sequence_name($sequence); 
     46} 
     47 
    9048function rcube_label($p, $domain=null) 
    9149{ 
    92   return rcmail::get_instance()->gettext($p, $domain); 
    93 } 
    94  
    95  
    96 /** 
    97  * Global wrapper of rcmail::text_exists() 
    98  * to check whether a text label is defined 
    99  * 
    100  * @see rcmail::text_exists() 
    101  */ 
     50    return rcmail::get_instance()->gettext($p, $domain); 
     51} 
     52 
    10253function rcube_label_exists($name, $domain=null, &$ref_domain = null) 
    10354{ 
    104   return rcmail::get_instance()->text_exists($name, $domain, $ref_domain); 
    105 } 
    106  
    107  
    108 /** 
    109  * Overwrite action variable 
    110  * 
    111  * @param string New action value 
    112  */ 
     55    return rcmail::get_instance()->text_exists($name, $domain, $ref_domain); 
     56} 
     57 
    11358function rcmail_overwrite_action($action) 
    114   { 
    115   $app = rcmail::get_instance(); 
    116   $app->action = $action; 
    117   $app->output->set_env('action', $action); 
    118   } 
    119  
    120  
    121 /** 
    122  * Compose an URL for a specific action 
    123  * 
    124  * @param string  Request action 
    125  * @param array   More URL parameters 
    126  * @param string  Request task (omit if the same) 
    127  * @return The application URL 
    128  */ 
     59{ 
     60    rcmail::get_instance()->overwrite_action($action); 
     61} 
     62 
    12963function rcmail_url($action, $p=array(), $task=null) 
    13064{ 
    131   $app = rcmail::get_instance(); 
    132   return $app->url((array)$p + array('_action' => $action, 'task' => $task)); 
    133 } 
    134  
    135  
    136 /** 
    137  * Garbage collector function for temp files. 
    138  * Remove temp files older than two days 
    139  */ 
     65    return rcube_ui::url($action, $p, $task); 
     66} 
     67 
    14068function rcmail_temp_gc() 
    14169{ 
    142   $rcmail = rcmail::get_instance(); 
    143  
    144   $tmp = unslashify($rcmail->config->get('temp_dir')); 
    145   $expire = mktime() - 172800;  // expire in 48 hours 
    146  
    147   if ($dir = opendir($tmp)) { 
    148     while (($fname = readdir($dir)) !== false) { 
    149       if ($fname{0} == '.') 
    150         continue; 
    151  
    152       if (filemtime($tmp.'/'.$fname) < $expire) 
    153         @unlink($tmp.'/'.$fname); 
    154     } 
    155  
    156     closedir($dir); 
    157   } 
    158 } 
    159  
    160  
    161 // Deprecated 
     70  $rcmail = rcmail::get_instance()->temp_gc(); 
     71} 
     72 
    16273function rcube_charset_convert($str, $from, $to=NULL) 
    16374{ 
     
    16576} 
    16677 
    167  
    168 // Deprecated 
    16978function rc_detect_encoding($string, $failover='') 
    17079{ 
     
    17281} 
    17382 
    174  
    175 // Deprecated 
    17683function rc_utf8_clean($input) 
    17784{ 
     
    17986} 
    18087 
    181  
    182 /** 
    183  * Convert a variable into a javascript object notation 
    184  * 
    185  * @param mixed Input value 
    186  * @return string Serialized JSON string 
    187  */ 
    18888function json_serialize($input) 
    18989{ 
    190     $input = rcube_charset::clean($input); 
    191  
    192     // sometimes even using rcube_charset::clean() the input contains invalid UTF-8 sequences 
    193     // that's why we have @ here 
    194     return @json_encode($input); 
    195 } 
    196  
    197  
    198 /** 
    199  * Replacing specials characters to a specific encoding type 
    200  * 
    201  * @param  string  Input string 
    202  * @param  string  Encoding type: text|html|xml|js|url 
    203  * @param  string  Replace mode for tags: show|replace|remove 
    204  * @param  boolean Convert newlines 
    205  * @return string  The quoted string 
    206  */ 
     90    return rcube_output::json_serialize($input); 
     91} 
     92 
    20793function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE) 
    208   { 
    209   static $html_encode_arr = false; 
    210   static $js_rep_table = false; 
    211   static $xml_rep_table = false; 
    212  
    213   if (!$enctype) 
    214     $enctype = $OUTPUT->type; 
    215  
    216   // encode for HTML output 
    217   if ($enctype=='html') 
    218     { 
    219     if (!$html_encode_arr) 
    220       { 
    221       $html_encode_arr = get_html_translation_table(HTML_SPECIALCHARS); 
    222       unset($html_encode_arr['?']); 
    223       } 
    224  
    225     $ltpos = strpos($str, '<'); 
    226     $encode_arr = $html_encode_arr; 
    227  
    228     // don't replace quotes and html tags 
    229     if (($mode=='show' || $mode=='') && $ltpos!==false && strpos($str, '>', $ltpos)!==false) 
    230       { 
    231       unset($encode_arr['"']); 
    232       unset($encode_arr['<']); 
    233       unset($encode_arr['>']); 
    234       unset($encode_arr['&']); 
    235       } 
    236     else if ($mode=='remove') 
    237       $str = strip_tags($str); 
    238  
    239     $out = strtr($str, $encode_arr); 
    240  
    241     // avoid douple quotation of & 
    242     $out = preg_replace('/&amp;([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $out); 
    243  
    244     return $newlines ? nl2br($out) : $out; 
    245     } 
    246  
    247   // if the replace tables for XML and JS are not yet defined 
    248   if ($js_rep_table===false) 
    249     { 
    250     $js_rep_table = $xml_rep_table = array(); 
    251     $xml_rep_table['&'] = '&amp;'; 
    252  
    253     for ($c=160; $c<256; $c++)  // can be increased to support more charsets 
    254       $xml_rep_table[chr($c)] = "&#$c;"; 
    255  
    256     $xml_rep_table['"'] = '&quot;'; 
    257     $js_rep_table['"'] = '\\"'; 
    258     $js_rep_table["'"] = "\\'"; 
    259     $js_rep_table["\\"] = "\\\\"; 
    260     // Unicode line and paragraph separators (#1486310) 
    261     $js_rep_table[chr(hexdec(E2)).chr(hexdec(80)).chr(hexdec(A8))] = '&#8232;'; 
    262     $js_rep_table[chr(hexdec(E2)).chr(hexdec(80)).chr(hexdec(A9))] = '&#8233;'; 
    263     } 
    264  
    265   // encode for javascript use 
    266   if ($enctype=='js') 
    267     return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), strtr($str, $js_rep_table)); 
    268  
    269   // encode for plaintext 
    270   if ($enctype=='text') 
    271     return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str); 
    272  
    273   if ($enctype=='url') 
    274     return rawurlencode($str); 
    275  
    276   // encode for XML 
    277   if ($enctype=='xml') 
    278     return strtr($str, $xml_rep_table); 
    279  
    280   // no encoding given -> return original string 
    281   return $str; 
    282   } 
    283    
    284 /** 
    285  * Quote a given string. 
    286  * Shortcut function for rep_specialchars_output 
    287  * 
    288  * @return string HTML-quoted string 
    289  * @see rep_specialchars_output() 
    290  */ 
     94{ 
     95    return rcube_ui::rep_specialchars_output($str, $enctype, $mode, $newlines); 
     96} 
     97 
    29198function Q($str, $mode='strict', $newlines=TRUE) 
    292   { 
    293   return rep_specialchars_output($str, 'html', $mode, $newlines); 
    294   } 
    295  
    296 /** 
    297  * Quote a given string for javascript output. 
    298  * Shortcut function for rep_specialchars_output 
    299  *  
    300  * @return string JS-quoted string 
    301  * @see rep_specialchars_output() 
    302  */ 
     99{ 
     100    return rcube_ui::Q($str, $mode, $newlines); 
     101} 
     102 
    303103function JQ($str) 
    304   { 
    305   return rep_specialchars_output($str, 'js'); 
    306   } 
    307  
    308  
    309 /** 
    310  * Read input value and convert it for internal use 
    311  * Performs stripslashes() and charset conversion if necessary 
    312  *  
    313  * @param  string   Field name to read 
    314  * @param  int      Source to get value from (GPC) 
    315  * @param  boolean  Allow HTML tags in field value 
    316  * @param  string   Charset to convert into 
    317  * @return string   Field value or NULL if not available 
    318  */ 
     104{ 
     105    return rcube_ui::JQ($str); 
     106} 
     107 
    319108function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL) 
    320109{ 
    321   $value = NULL; 
    322  
    323   if ($source == RCUBE_INPUT_GET) { 
    324     if (isset($_GET[$fname])) 
    325       $value = $_GET[$fname]; 
    326   } 
    327   else if ($source == RCUBE_INPUT_POST) { 
    328     if (isset($_POST[$fname])) 
    329       $value = $_POST[$fname]; 
    330   } 
    331   else if ($source == RCUBE_INPUT_GPC) { 
    332     if (isset($_POST[$fname])) 
    333       $value = $_POST[$fname]; 
    334     else if (isset($_GET[$fname])) 
    335       $value = $_GET[$fname]; 
    336     else if (isset($_COOKIE[$fname])) 
    337       $value = $_COOKIE[$fname]; 
    338   } 
    339  
    340   return parse_input_value($value, $allow_html, $charset); 
    341 } 
    342  
    343 /** 
    344  * Parse/validate input value. See get_input_value() 
    345  * Performs stripslashes() and charset conversion if necessary 
    346  * 
    347  * @param  string   Input value 
    348  * @param  boolean  Allow HTML tags in field value 
    349  * @param  string   Charset to convert into 
    350  * @return string   Parsed value 
    351  */ 
     110    return rcube_ui::get_input_value($fname, $source, $allow_html, $charset); 
     111} 
     112 
    352113function parse_input_value($value, $allow_html=FALSE, $charset=NULL) 
    353114{ 
    354   global $OUTPUT; 
    355  
    356   if (empty($value)) 
    357     return $value; 
    358  
    359   if (is_array($value)) { 
    360     foreach ($value as $idx => $val) 
    361       $value[$idx] = parse_input_value($val, $allow_html, $charset); 
    362     return $value; 
    363   } 
    364  
    365   // strip single quotes if magic_quotes_sybase is enabled 
    366   if (ini_get('magic_quotes_sybase')) 
    367     $value = str_replace("''", "'", $value); 
    368   // strip slashes if magic_quotes enabled 
    369   else if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) 
    370     $value = stripslashes($value); 
    371  
    372   // remove HTML tags if not allowed 
    373   if (!$allow_html) 
    374     $value = strip_tags($value); 
    375  
    376   $output_charset = is_object($OUTPUT) ? $OUTPUT->get_charset() : null; 
    377  
    378   // remove invalid characters (#1488124) 
    379   if ($output_charset == 'UTF-8') 
    380     $value = rc_utf8_clean($value); 
    381  
    382   // convert to internal charset 
    383   if ($charset && $output_charset) 
    384     $value = rcube_charset_convert($value, $output_charset, $charset); 
    385  
    386   return $value; 
    387 } 
    388  
    389 /** 
    390  * Convert array of request parameters (prefixed with _) 
    391  * to a regular array with non-prefixed keys. 
    392  * 
    393  * @param  int   Source to get value from (GPC) 
    394  * @return array Hash array with all request parameters 
    395  */ 
     115    return rcube_ui::parse_input_value($value, $allow_html, $charset); 
     116} 
     117 
    396118function request2param($mode = RCUBE_INPUT_GPC, $ignore = 'task|action') 
    397119{ 
    398   $out = array(); 
    399   $src = $mode == RCUBE_INPUT_GET ? $_GET : ($mode == RCUBE_INPUT_POST ? $_POST : $_REQUEST); 
    400   foreach ($src as $key => $value) { 
    401     $fname = $key[0] == '_' ? substr($key, 1) : $key; 
    402     if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) 
    403       $out[$fname] = get_input_value($key, $mode); 
    404   } 
    405  
    406   return $out; 
    407 } 
    408  
    409 /** 
    410  * Remove all non-ascii and non-word chars 
    411  * except ., -, _ 
    412  */ 
    413 function asciiwords($str, $css_id = false, $replace_with = '') 
    414 { 
    415   $allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : ''); 
    416   return preg_replace("/[^$allowed]/i", $replace_with, $str); 
    417 } 
    418  
    419 /** 
    420  * Convert the given string into a valid HTML identifier 
    421  * Same functionality as done in app.js with rcube_webmail.html_identifier() 
    422  */ 
     120    return rcube_ui::request2param($mode, $ignore); 
     121} 
     122 
    423123function html_identifier($str, $encode=false) 
    424124{ 
    425   if ($encode) 
    426     return rtrim(strtr(base64_encode($str), '+/', '-_'), '='); 
    427   else 
    428     return asciiwords($str, true, '_'); 
    429 } 
    430  
    431 /** 
    432  * Remove single and double quotes from given string 
    433  * 
    434  * @param string Input value 
    435  * @return string Dequoted string 
    436  */ 
    437 function strip_quotes($str) 
    438 { 
    439   return str_replace(array("'", '"'), '', $str); 
    440 } 
    441  
    442  
    443 /** 
    444  * Remove new lines characters from given string 
    445  * 
    446  * @param string Input value 
    447  * @return string Stripped string 
    448  */ 
    449 function strip_newlines($str) 
    450 { 
    451   return preg_replace('/[\r\n]/', '', $str); 
    452 } 
    453  
    454  
    455 /** 
    456  * Create a HTML table based on the given data 
    457  * 
    458  * @param  array  Named table attributes 
    459  * @param  mixed  Table row data. Either a two-dimensional array or a valid SQL result set 
    460  * @param  array  List of cols to show 
    461  * @param  string Name of the identifier col 
    462  * @return string HTML table code 
    463  */ 
     125    return rcube_ui::html_identifier($str, $encode); 
     126} 
     127 
    464128function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col) 
    465129{ 
    466   global $RCMAIL; 
    467  
    468   $table = new html_table(/*array('cols' => count($a_show_cols))*/); 
    469  
    470   // add table header 
    471   if (!$attrib['noheader']) 
    472     foreach ($a_show_cols as $col) 
    473       $table->add_header($col, Q(rcube_label($col))); 
    474  
    475   $c = 0; 
    476   if (!is_array($table_data)) 
    477   { 
    478     $db = $RCMAIL->get_dbh(); 
    479     while ($table_data && ($sql_arr = $db->fetch_assoc($table_data))) 
    480     { 
    481       $table->add_row(array('id' => 'rcmrow' . html_identifier($sql_arr[$id_col]))); 
    482  
    483       // format each col 
    484       foreach ($a_show_cols as $col) 
    485         $table->add($col, Q($sql_arr[$col])); 
    486  
    487       $c++; 
    488     } 
    489   } 
    490   else { 
    491     foreach ($table_data as $row_data) 
    492     { 
    493       $class = !empty($row_data['class']) ? $row_data['class'] : ''; 
    494  
    495       $table->add_row(array('id' => 'rcmrow' . html_identifier($row_data[$id_col]), 'class' => $class)); 
    496  
    497       // format each col 
    498       foreach ($a_show_cols as $col) 
    499         $table->add($col, Q(is_array($row_data[$col]) ? $row_data[$col][0] : $row_data[$col])); 
    500  
    501       $c++; 
    502     } 
    503   } 
    504  
    505   return $table->show($attrib); 
    506 } 
    507  
    508  
    509 /** 
    510  * Create an edit field for inclusion on a form 
    511  *  
    512  * @param string col field name 
    513  * @param string value field value 
    514  * @param array attrib HTML element attributes for field 
    515  * @param string type HTML element type (default 'text') 
    516  * @return string HTML field definition 
    517  */ 
     130    return rcube_ui::table_output($attrib, $table_data, $a_show_cols, $id_col); 
     131} 
     132 
    518133function rcmail_get_edit_field($col, $value, $attrib, $type='text') 
    519134{ 
    520   static $colcounts = array(); 
    521  
    522   $fname = '_'.$col; 
    523   $attrib['name'] = $fname . ($attrib['array'] ? '[]' : ''); 
    524   $attrib['class'] = trim($attrib['class'] . ' ff_' . $col); 
    525  
    526   if ($type == 'checkbox') { 
    527     $attrib['value'] = '1'; 
    528     $input = new html_checkbox($attrib); 
    529   } 
    530   else if ($type == 'textarea') { 
    531     $attrib['cols'] = $attrib['size']; 
    532     $input = new html_textarea($attrib); 
    533   } 
    534   else if ($type == 'select') { 
    535     $input = new html_select($attrib); 
    536     $input->add('---', ''); 
    537     $input->add(array_values($attrib['options']), array_keys($attrib['options'])); 
    538   } 
    539   else if ($attrib['type'] == 'password') { 
    540     $input = new html_passwordfield($attrib); 
    541   } 
    542   else { 
    543     if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') 
    544         $attrib['type'] = 'text'; 
    545     $input = new html_inputfield($attrib); 
    546   } 
    547  
    548   // use value from post 
    549   if (isset($_POST[$fname])) { 
    550     $postvalue = get_input_value($fname, RCUBE_INPUT_POST, true); 
    551     $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue; 
    552   } 
    553  
    554   $out = $input->show($value); 
    555  
    556   return $out; 
    557 } 
    558  
    559  
    560 /** 
    561  * Replace all css definitions with #container [def] 
    562  * and remove css-inlined scripting 
    563  * 
    564  * @param string CSS source code 
    565  * @param string Container ID to use as prefix 
    566  * @return string Modified CSS source 
    567  */ 
     135  return rcube_ui::get_edit_field($col, $value, $attrib, $type); 
     136} 
     137 
    568138function rcmail_mod_css_styles($source, $container_id, $allow_remote=false) 
    569   { 
    570   $last_pos = 0; 
    571   $replacements = new rcube_string_replacer; 
    572  
    573   // ignore the whole block if evil styles are detected 
    574   $source = rcmail_xss_entity_decode($source); 
    575   $stripped = preg_replace('/[^a-z\(:;]/i', '', $source); 
    576   $evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\(' : ''); 
    577   if (preg_match("/$evilexpr/i", $stripped)) 
    578     return '/* evil! */'; 
    579  
    580   // cut out all contents between { and } 
    581   while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) { 
    582     $styles = substr($source, $pos+1, $pos2-($pos+1)); 
    583  
    584     // check every line of a style block... 
    585     if ($allow_remote) { 
    586       $a_styles = preg_split('/;[\r\n]*/', $styles, -1, PREG_SPLIT_NO_EMPTY); 
    587       foreach ($a_styles as $line) { 
    588         $stripped = preg_replace('/[^a-z\(:;]/i', '', $line); 
    589         // ... and only allow strict url() values 
    590         if (stripos($stripped, 'url(') && !preg_match('!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims', $line)) { 
    591           $a_styles = array('/* evil! */'); 
    592           break; 
    593         } 
    594       } 
    595       $styles = join(";\n", $a_styles); 
    596     } 
    597  
    598     $key = $replacements->add($styles); 
    599     $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2); 
    600     $last_pos = $pos+2; 
    601   } 
    602  
    603   // remove html comments and add #container to each tag selector. 
    604   // also replace body definition because we also stripped off the <body> tag 
    605   $styles = preg_replace( 
    606     array( 
    607       '/(^\s*<!--)|(-->\s*$)/', 
    608       '/(^\s*|,\s*|\}\s*)([a-z0-9\._#\*][a-z0-9\.\-_]*)/im', 
    609       '/'.preg_quote($container_id, '/').'\s+body/i', 
    610     ), 
    611     array( 
    612       '', 
    613       "\\1#$container_id \\2", 
    614       $container_id, 
    615     ), 
    616     $source); 
    617  
    618   // put block contents back in 
    619   $styles = $replacements->resolve($styles); 
    620  
    621   return $styles; 
    622   } 
    623  
    624  
    625 /** 
    626  * Decode escaped entities used by known XSS exploits. 
    627  * See http://downloads.securityfocus.com/vulnerabilities/exploits/26800.eml for examples 
    628  * 
    629  * @param string CSS content to decode 
    630  * @return string Decoded string 
    631  */ 
     139{ 
     140    return rcube_ui::mod_css_styles($source, $container_id, $allow_remote); 
     141} 
     142 
    632143function rcmail_xss_entity_decode($content) 
    633144{ 
    634   $out = html_entity_decode(html_entity_decode($content)); 
    635   $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entity_decode_callback', $out); 
    636   $out = preg_replace('#/\*.*\*/#Ums', '', $out); 
    637   return $out; 
    638 } 
    639  
    640  
    641 /** 
    642  * preg_replace_callback callback for rcmail_xss_entity_decode_callback 
    643  * 
    644  * @param array matches result from preg_replace_callback 
    645  * @return string decoded entity 
    646  */  
    647 function rcmail_xss_entity_decode_callback($matches) 
    648 {  
    649   return chr(hexdec($matches[1])); 
    650 } 
    651  
    652 /** 
    653  * Compose a valid attribute string for HTML tags 
    654  * 
    655  * @param array Named tag attributes 
    656  * @param array List of allowed attributes 
    657  * @return string HTML formatted attribute string 
    658  */ 
     145    return rcube_ui::xss_entity_decode($content); 
     146} 
     147 
    659148function create_attrib_string($attrib, $allowed_attribs=array('id', 'class', 'style')) 
    660   { 
    661   // allow the following attributes to be added to the <iframe> tag 
    662   $attrib_str = ''; 
    663   foreach ($allowed_attribs as $a) 
    664     if (isset($attrib[$a])) 
    665       $attrib_str .= sprintf(' %s="%s"', $a, str_replace('"', '&quot;', $attrib[$a])); 
    666  
    667   return $attrib_str; 
    668   } 
    669  
    670  
    671 /** 
    672  * Convert a HTML attribute string attributes to an associative array (name => value) 
    673  * 
    674  * @param string Input string 
    675  * @return array Key-value pairs of parsed attributes 
    676  */ 
     149{ 
     150    return html::attrib_string($attrib, $allowed_attribs); 
     151} 
     152 
    677153function parse_attrib_string($str) 
    678   { 
    679   $attrib = array(); 
    680   preg_match_all('/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]*)\2|(\S+?))/Ui', stripslashes($str), $regs, PREG_SET_ORDER); 
    681  
    682   // convert attributes to an associative array (name => value) 
    683   if ($regs) { 
    684     foreach ($regs as $attr) { 
    685       $attrib[strtolower($attr[1])] = html_entity_decode($attr[3] . $attr[4]); 
    686     } 
    687   } 
    688  
    689   return $attrib; 
    690   } 
    691  
    692  
    693 /** 
    694  * Improved equivalent to strtotime() 
    695  * 
    696  * @param string Date string 
    697  * @return int  
    698  */ 
    699 function rcube_strtotime($date) 
    700 { 
    701   // check for MS Outlook vCard date format YYYYMMDD 
    702   if (preg_match('/^([12][90]\d\d)([01]\d)(\d\d)$/', trim($date), $matches)) { 
    703     return mktime(0,0,0, intval($matches[2]), intval($matches[3]), intval($matches[1])); 
    704   } 
    705   else if (is_numeric($date)) 
    706     return $date; 
    707  
    708   // support non-standard "GMTXXXX" literal 
    709   $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date); 
    710  
    711   // if date parsing fails, we have a date in non-rfc format. 
    712   // remove token from the end and try again 
    713   while ((($ts = @strtotime($date)) === false) || ($ts < 0)) { 
    714     $d = explode(' ', $date); 
    715     array_pop($d); 
    716     if (!$d) break; 
    717     $date = implode(' ', $d); 
    718   } 
    719  
    720   return $ts; 
    721 } 
    722  
    723  
    724 /** 
    725  * Convert the given date to a human readable form 
    726  * This uses the date formatting properties from config 
    727  * 
    728  * @param mixed  Date representation (string, timestamp or DateTime object) 
    729  * @param string Date format to use 
    730  * @param bool   Enables date convertion according to user timezone 
    731  * 
    732  * @return string Formatted date string 
    733  */ 
     154{ 
     155    return html::parse_attrib_string($str); 
     156} 
     157 
    734158function format_date($date, $format=NULL, $convert=true) 
    735159{ 
    736   global $RCMAIL, $CONFIG; 
    737  
    738   if (is_object($date) && is_a($date, 'DateTime')) { 
    739     $timestamp = $date->format('U'); 
    740   } 
    741   else { 
    742     if (!empty($date)) 
    743       $timestamp = rcube_strtotime($date); 
    744  
    745     if (empty($timestamp)) 
    746       return ''; 
    747  
    748     try { 
    749       $date = new DateTime("@".$timestamp); 
    750     } 
    751     catch (Exception $e) { 
    752       return ''; 
    753     } 
    754   } 
    755  
    756   if ($convert) { 
    757     try { 
    758       // convert to the right timezone 
    759       $stz = date_default_timezone_get(); 
    760       $tz = new DateTimeZone($RCMAIL->config->get('timezone')); 
    761       $date->setTimezone($tz); 
    762       date_default_timezone_set($tz->getName()); 
    763  
    764       $timestamp = $date->format('U'); 
    765     } 
    766     catch (Exception $e) { 
    767     } 
    768   } 
    769  
    770   // define date format depending on current time 
    771   if (!$format) { 
    772     $now         = time(); 
    773     $now_date    = getdate($now); 
    774     $today_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'], $now_date['year']); 
    775     $week_limit  = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']); 
    776  
    777     if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now) { 
    778       $format = $RCMAIL->config->get('date_today', $RCMAIL->config->get('time_format', 'H:i')); 
    779       $today  = true; 
    780     } 
    781     else if ($CONFIG['prettydate'] && $timestamp > $week_limit && $timestamp < $now) 
    782       $format = $RCMAIL->config->get('date_short', 'D H:i'); 
    783     else 
    784       $format = $RCMAIL->config->get('date_long', 'Y-m-d H:i'); 
    785   } 
    786  
    787   // strftime() format 
    788   if (preg_match('/%[a-z]+/i', $format)) { 
    789     $format = strftime($format, $timestamp); 
    790  
    791     if ($convert && $stz) { 
    792       date_default_timezone_set($stz); 
    793     } 
    794  
    795     return $today ? (rcube_label('today') . ' ' . $format) : $format; 
    796   } 
    797  
    798   // parse format string manually in order to provide localized weekday and month names 
    799   // an alternative would be to convert the date() format string to fit with strftime() 
    800   $out = ''; 
    801   for ($i=0; $i<strlen($format); $i++) { 
    802     if ($format[$i]=='\\')  // skip escape chars 
    803       continue; 
    804  
    805     // write char "as-is" 
    806     if ($format[$i]==' ' || $format{$i-1}=='\\') 
    807       $out .= $format[$i]; 
    808     // weekday (short) 
    809     else if ($format[$i]=='D') 
    810       $out .= rcube_label(strtolower(date('D', $timestamp))); 
    811     // weekday long 
    812     else if ($format[$i]=='l') 
    813       $out .= rcube_label(strtolower(date('l', $timestamp))); 
    814     // month name (short) 
    815     else if ($format[$i]=='M') 
    816       $out .= rcube_label(strtolower(date('M', $timestamp))); 
    817     // month name (long) 
    818     else if ($format[$i]=='F') 
    819       $out .= rcube_label('long'.strtolower(date('M', $timestamp))); 
    820     else if ($format[$i]=='x') 
    821       $out .= strftime('%x %X', $timestamp); 
    822     else 
    823       $out .= date($format[$i], $timestamp); 
    824   } 
    825  
    826   if ($today) { 
    827     $label = rcube_label('today'); 
    828     // replcae $ character with "Today" label (#1486120) 
    829     if (strpos($out, '$') !== false) { 
    830       $out = preg_replace('/\$/', $label, $out, 1); 
    831     } 
    832     else { 
    833       $out = $label . ' ' . $out; 
    834     } 
    835   } 
    836  
    837   if ($convert && $stz) { 
    838     date_default_timezone_set($stz); 
    839   } 
    840  
    841   return $out; 
    842 } 
    843  
    844  
    845 /** 
    846  * Compose a valid representation of name and e-mail address 
    847  * 
    848  * @param string E-mail address 
    849  * @param string Person name 
    850  * @return string Formatted string 
    851  */ 
    852 function format_email_recipient($email, $name='') 
    853 { 
    854   if ($name && $name != $email) { 
    855     // Special chars as defined by RFC 822 need to in quoted string (or escaped). 
    856     return sprintf('%s <%s>', preg_match('/[\(\)\<\>\\\.\[\]@,;:"]/', $name) ? '"'.addcslashes($name, '"').'"' : $name, trim($email)); 
    857   } 
    858  
    859   return trim($email); 
    860 } 
    861  
    862  
    863 /** 
    864  * Return the mailboxlist in HTML 
    865  * 
    866  * @param array Named parameters 
    867  * @return string HTML code for the gui object 
    868  */ 
     160    return rcube_ui::format_date($date, $format, $convert); 
     161} 
     162 
    869163function rcmail_mailbox_list($attrib) 
    870164{ 
    871   global $RCMAIL; 
    872   static $a_mailboxes; 
    873  
    874   $attrib += array('maxlength' => 100, 'realnames' => false, 'unreadwrap' => ' (%s)'); 
    875  
    876   // add some labels to client 
    877   $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm'); 
    878  
    879   $type = $attrib['type'] ? $attrib['type'] : 'ul'; 
    880   unset($attrib['type']); 
    881  
    882   if ($type=='ul' && !$attrib['id']) 
    883     $attrib['id'] = 'rcmboxlist'; 
    884  
    885   if (empty($attrib['folder_name'])) 
    886     $attrib['folder_name'] = '*'; 
    887  
    888   // get mailbox list 
    889   $mbox_name = $RCMAIL->storage->get_folder(); 
    890  
    891   // build the folders tree 
    892   if (empty($a_mailboxes)) { 
    893     // get mailbox list 
    894     $a_folders = $RCMAIL->storage->list_folders_subscribed('', $attrib['folder_name'], $attrib['folder_filter']); 
    895     $delimiter = $RCMAIL->storage->get_hierarchy_delimiter(); 
    896     $a_mailboxes = array(); 
    897  
    898     foreach ($a_folders as $folder) 
    899       rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); 
    900   } 
    901  
    902   // allow plugins to alter the folder tree or to localize folder names 
    903   $hook = $RCMAIL->plugins->exec_hook('render_mailboxlist', array( 
    904     'list'      => $a_mailboxes, 
    905     'delimiter' => $delimiter, 
    906     'type'      => $type, 
    907     'attribs'   => $attrib, 
    908   )); 
    909  
    910   $a_mailboxes = $hook['list']; 
    911   $attrib      = $hook['attribs']; 
    912  
    913   if ($type == 'select') { 
    914     $select = new html_select($attrib); 
    915  
    916     // add no-selection option 
    917     if ($attrib['noselection']) 
    918       $select->add(rcube_label($attrib['noselection']), ''); 
    919  
    920     rcmail_render_folder_tree_select($a_mailboxes, $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']); 
    921     $out = $select->show($attrib['default']); 
    922   } 
    923   else { 
    924     $js_mailboxlist = array(); 
    925     $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib); 
    926  
    927     $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']); 
    928     $RCMAIL->output->set_env('mailboxes', $js_mailboxlist); 
    929     $RCMAIL->output->set_env('unreadwrap', $attrib['unreadwrap']); 
    930     $RCMAIL->output->set_env('collapsed_folders', (string)$RCMAIL->config->get('collapsed_folders')); 
    931   } 
    932  
    933   return $out; 
    934 } 
    935  
    936  
    937 /** 
    938  * Return the mailboxlist as html_select object 
    939  * 
    940  * @param array Named parameters 
    941  * @return html_select HTML drop-down object 
    942  */ 
    943 function rcmail_mailbox_select($p = array()) 
    944 { 
    945   global $RCMAIL; 
    946  
    947   $p += array('maxlength' => 100, 'realnames' => false); 
    948   $a_mailboxes = array(); 
    949   $storage = $RCMAIL->get_storage(); 
    950  
    951   if (empty($p['folder_name'])) { 
    952     $p['folder_name'] = '*'; 
    953   } 
    954  
    955   if ($p['unsubscribed']) 
    956     $list = $storage->list_folders('', $p['folder_name'], $p['folder_filter'], $p['folder_rights']); 
    957   else 
    958     $list = $storage->list_folders_subscribed('', $p['folder_name'], $p['folder_filter'], $p['folder_rights']); 
    959  
    960   $delimiter = $storage->get_hierarchy_delimiter(); 
    961  
    962   foreach ($list as $folder) { 
    963     if (empty($p['exceptions']) || !in_array($folder, $p['exceptions'])) 
    964       rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); 
    965   } 
    966  
    967   $select = new html_select($p); 
    968  
    969   if ($p['noselection']) 
    970     $select->add($p['noselection'], ''); 
    971  
    972   rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p); 
    973  
    974   return $select; 
    975 } 
    976  
    977  
    978 /** 
    979  * Create a hierarchical array of the mailbox list 
    980  * @access private 
    981  * @return void 
    982  */ 
    983 function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') 
    984 { 
    985   global $RCMAIL; 
    986  
    987   // Handle namespace prefix 
    988   $prefix = ''; 
    989   if (!$path) { 
    990     $n_folder = $folder; 
    991     $folder = $RCMAIL->storage->mod_folder($folder); 
    992  
    993     if ($n_folder != $folder) { 
    994       $prefix = substr($n_folder, 0, -strlen($folder)); 
    995     } 
    996   } 
    997  
    998   $pos = strpos($folder, $delm); 
    999  
    1000   if ($pos !== false) { 
    1001     $subFolders = substr($folder, $pos+1); 
    1002     $currentFolder = substr($folder, 0, $pos); 
    1003  
    1004     // sometimes folder has a delimiter as the last character 
    1005     if (!strlen($subFolders)) 
    1006       $virtual = false; 
    1007     else if (!isset($arrFolders[$currentFolder])) 
    1008       $virtual = true; 
    1009     else 
    1010       $virtual = $arrFolders[$currentFolder]['virtual']; 
    1011   } 
    1012   else { 
    1013     $subFolders = false; 
    1014     $currentFolder = $folder; 
    1015     $virtual = false; 
    1016   } 
    1017  
    1018   $path .= $prefix.$currentFolder; 
    1019  
    1020   if (!isset($arrFolders[$currentFolder])) { 
    1021     $arrFolders[$currentFolder] = array( 
    1022       'id' => $path, 
    1023       'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'), 
    1024       'virtual' => $virtual, 
    1025       'folders' => array()); 
    1026   } 
    1027   else 
    1028     $arrFolders[$currentFolder]['virtual'] = $virtual; 
    1029  
    1030   if (strlen($subFolders)) 
    1031     rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm); 
    1032 } 
    1033  
    1034  
    1035 /** 
    1036  * Return html for a structured list &lt;ul&gt; for the mailbox tree 
    1037  * @access private 
    1038  * @return string 
    1039  */ 
    1040 function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $attrib, $nestLevel=0) 
    1041 { 
    1042   global $RCMAIL, $CONFIG; 
    1043  
    1044   $maxlength = intval($attrib['maxlength']); 
    1045   $realnames = (bool)$attrib['realnames']; 
    1046   $msgcounts = $RCMAIL->storage->get_cache('messagecount'); 
    1047  
    1048   $out = ''; 
    1049   foreach ($arrFolders as $key => $folder) { 
    1050     $title        = null; 
    1051     $folder_class = rcmail_folder_classname($folder['id']); 
    1052     $collapsed    = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false; 
    1053     $unread       = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0; 
    1054  
    1055     if ($folder_class && !$realnames) { 
    1056       $foldername = rcube_label($folder_class); 
    1057     } 
    1058     else { 
    1059       $foldername = $folder['name']; 
    1060  
    1061       // shorten the folder name to a given length 
    1062       if ($maxlength && $maxlength > 1) { 
    1063         $fname = abbreviate_string($foldername, $maxlength); 
    1064         if ($fname != $foldername) 
    1065           $title = $foldername; 
    1066         $foldername = $fname; 
    1067       } 
    1068     } 
    1069  
    1070     // make folder name safe for ids and class names 
    1071     $folder_id = html_identifier($folder['id'], true); 
    1072     $classes = array('mailbox'); 
    1073  
    1074     // set special class for Sent, Drafts, Trash and Junk 
    1075     if ($folder_class) 
    1076       $classes[] = $folder_class; 
    1077  
    1078     if ($folder['id'] == $mbox_name) 
    1079       $classes[] = 'selected'; 
    1080  
    1081     if ($folder['virtual']) 
    1082       $classes[] = 'virtual'; 
    1083     else if ($unread) 
    1084       $classes[] = 'unread'; 
    1085  
    1086     $js_name = JQ($folder['id']); 
    1087     $html_name = Q($foldername) . ($unread ? html::span('unreadcount', sprintf($attrib['unreadwrap'], $unread)) : ''); 
    1088     $link_attrib = $folder['virtual'] ? array() : array( 
    1089       'href' => rcmail_url('', array('_mbox' => $folder['id'])), 
    1090       'onclick' => sprintf("return %s.command('list','%s',this)", JS_OBJECT_NAME, $js_name), 
    1091       'rel' => $folder['id'], 
    1092       'title' => $title, 
    1093     ); 
    1094  
    1095     $out .= html::tag('li', array( 
    1096         'id' => "rcmli".$folder_id, 
    1097         'class' => join(' ', $classes), 
    1098         'noclose' => true), 
    1099       html::a($link_attrib, $html_name) . 
    1100       (!empty($folder['folders']) ? html::div(array( 
    1101         'class' => ($collapsed ? 'collapsed' : 'expanded'), 
    1102         'style' => "position:absolute", 
    1103         'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name) 
    1104       ), '&nbsp;') : '')); 
    1105  
    1106     $jslist[$folder_id] = array('id' => $folder['id'], 'name' => $foldername, 'virtual' => $folder['virtual']); 
    1107  
    1108     if (!empty($folder['folders'])) { 
    1109       $out .= html::tag('ul', array('style' => ($collapsed ? "display:none;" : null)), 
    1110         rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $jslist, $attrib, $nestLevel+1)); 
    1111     } 
    1112  
    1113     $out .= "</li>\n"; 
    1114   } 
    1115  
    1116   return $out; 
    1117 } 
    1118  
    1119  
    1120 /** 
    1121  * Return html for a flat list <select> for the mailbox tree 
    1122  * @access private 
    1123  * @return string 
    1124  */ 
    1125 function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $opts=array()) 
    1126 { 
    1127   global $RCMAIL; 
    1128  
    1129   $out = ''; 
    1130  
    1131   foreach ($arrFolders as $key => $folder) { 
    1132     // skip exceptions (and its subfolders) 
    1133     if (!empty($opts['exceptions']) && in_array($folder['id'], $opts['exceptions'])) { 
    1134       continue; 
    1135     } 
    1136  
    1137     // skip folders in which it isn't possible to create subfolders 
    1138     if (!empty($opts['skip_noinferiors']) && ($attrs = $RCMAIL->storage->folder_attributes($folder['id'])) 
    1139         && in_array('\\Noinferiors', $attrs) 
    1140     ) { 
    1141       continue; 
    1142     } 
    1143  
    1144     if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id']))) 
    1145       $foldername = rcube_label($folder_class); 
    1146     else { 
    1147       $foldername = $folder['name']; 
    1148  
    1149       // shorten the folder name to a given length 
    1150       if ($maxlength && $maxlength>1) 
    1151         $foldername = abbreviate_string($foldername, $maxlength); 
    1152     } 
    1153  
    1154     $select->add(str_repeat('&nbsp;', $nestLevel*4) . $foldername, $folder['id']); 
    1155  
    1156     if (!empty($folder['folders'])) 
    1157       $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, 
    1158         $select, $realnames, $nestLevel+1, $opts); 
    1159   } 
    1160  
    1161   return $out; 
    1162 } 
    1163  
    1164  
    1165 /** 
    1166  * Return internal name for the given folder if it matches the configured special folders 
    1167  * @access private 
    1168  * @return string 
    1169  */ 
    1170 function rcmail_folder_classname($folder_id) 
    1171 { 
    1172   global $CONFIG; 
    1173  
    1174   if ($folder_id == 'INBOX') 
    1175     return 'inbox'; 
    1176  
    1177   // for these mailboxes we have localized labels and css classes 
    1178   foreach (array('sent', 'drafts', 'trash', 'junk') as $smbx) 
    1179   { 
    1180     if ($folder_id == $CONFIG[$smbx.'_mbox']) 
    1181       return $smbx; 
    1182   } 
    1183 } 
    1184  
    1185  
    1186 /** 
    1187  * Try to localize the given IMAP folder name. 
    1188  * UTF-7 decode it in case no localized text was found 
    1189  * 
    1190  * @param string Folder name 
    1191  * @return string Localized folder name in UTF-8 encoding 
    1192  */ 
     165    return rcube_ui::folder_list($attrib); 
     166} 
     167 
     168function rcmail_mailbox_select($attrib = array()) 
     169{ 
     170    return rcube_ui::folder_selector($attrib); 
     171} 
     172 
    1193173function rcmail_localize_foldername($name) 
    1194174{ 
    1195   if ($folder_class = rcmail_folder_classname($name)) 
    1196     return rcube_label($folder_class); 
    1197   else 
    1198     return rcube_charset_convert($name, 'UTF7-IMAP'); 
    1199 } 
    1200  
     175    return rcube_ui::localize_foldername($name); 
     176} 
    1201177 
    1202178function rcmail_localize_folderpath($path) 
    1203179{ 
    1204     global $RCMAIL; 
    1205  
    1206     $protect_folders = $RCMAIL->config->get('protect_default_folders'); 
    1207     $default_folders = (array) $RCMAIL->config->get('default_folders'); 
    1208     $delimiter       = $RCMAIL->storage->get_hierarchy_delimiter(); 
    1209     $path            = explode($delimiter, $path); 
    1210     $result          = array(); 
    1211  
    1212     foreach ($path as $idx => $dir) { 
    1213         $directory = implode($delimiter, array_slice($path, 0, $idx+1)); 
    1214         if ($protect_folders && in_array($directory, $default_folders)) { 
    1215             unset($result); 
    1216             $result[] = rcmail_localize_foldername($directory); 
    1217         } 
    1218         else { 
    1219             $result[] = rcube_charset_convert($dir, 'UTF7-IMAP'); 
    1220         } 
    1221     } 
    1222  
    1223     return implode($delimiter, $result); 
    1224 } 
    1225  
     180    return rcube_ui::localize_folderpath($path); 
     181} 
    1226182 
    1227183function rcmail_quota_display($attrib) 
    1228184{ 
    1229   global $OUTPUT; 
    1230  
    1231   if (!$attrib['id']) 
    1232     $attrib['id'] = 'rcmquotadisplay'; 
    1233  
    1234   $_SESSION['quota_display'] = !empty($attrib['display']) ? $attrib['display'] : 'text'; 
    1235  
    1236   $OUTPUT->add_gui_object('quotadisplay', $attrib['id']); 
    1237  
    1238   $quota = rcmail_quota_content($attrib); 
    1239  
    1240   $OUTPUT->add_script('rcmail.set_quota('.json_serialize($quota).');', 'docready'); 
    1241  
    1242   return html::span($attrib, ''); 
    1243 } 
    1244  
    1245  
    1246 function rcmail_quota_content($attrib=NULL) 
    1247 { 
    1248   global $RCMAIL; 
    1249  
    1250   $quota = $RCMAIL->storage->get_quota(); 
    1251   $quota = $RCMAIL->plugins->exec_hook('quota', $quota); 
    1252  
    1253   $quota_result = (array) $quota; 
    1254   $quota_result['type'] = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : ''; 
    1255  
    1256   if (!$quota['total'] && $RCMAIL->config->get('quota_zero_as_unlimited')) { 
    1257     $quota_result['title'] = rcube_label('unlimited'); 
    1258     $quota_result['percent'] = 0; 
    1259   } 
    1260   else if ($quota['total']) { 
    1261     if (!isset($quota['percent'])) 
    1262       $quota_result['percent'] = min(100, round(($quota['used']/max(1,$quota['total']))*100)); 
    1263  
    1264     $title = sprintf('%s / %s (%.0f%%)', 
    1265         show_bytes($quota['used'] * 1024), show_bytes($quota['total'] * 1024), 
    1266         $quota_result['percent']); 
    1267  
    1268     $quota_result['title'] = $title; 
    1269  
    1270     if ($attrib['width']) 
    1271       $quota_result['width'] = $attrib['width']; 
    1272     if ($attrib['height']) 
    1273       $quota_result['height']   = $attrib['height']; 
    1274   } 
    1275   else { 
    1276     $quota_result['title'] = rcube_label('unknown'); 
    1277     $quota_result['percent'] = 0; 
    1278   } 
    1279  
    1280   return $quota_result; 
    1281 } 
    1282  
    1283  
    1284 /** 
    1285  * Outputs error message according to server error/response codes 
    1286  * 
    1287  * @param string Fallback message label 
    1288  * @param string Fallback message label arguments 
    1289  * 
    1290  * @return void 
    1291  */ 
     185    return rcube_ui::quota_display($attrib); 
     186} 
     187 
     188function rcmail_quota_content($attrib = null) 
     189{ 
     190    return rcube_ui::quota_content($attrib); 
     191} 
     192 
    1292193function rcmail_display_server_error($fallback=null, $fallback_args=null) 
    1293194{ 
    1294     global $RCMAIL; 
    1295  
    1296     $err_code = $RCMAIL->storage->get_error_code(); 
    1297     $res_code = $RCMAIL->storage->get_response_code(); 
    1298  
    1299     if ($err_code < 0) { 
    1300         $RCMAIL->output->show_message('storageerror', 'error'); 
    1301     } 
    1302     else if ($res_code == rcube_storage::NOPERM) { 
    1303         $RCMAIL->output->show_message('errornoperm', 'error'); 
    1304     } 
    1305     else if ($res_code == rcube_storage::READONLY) { 
    1306         $RCMAIL->output->show_message('errorreadonly', 'error'); 
    1307     } 
    1308     else if ($err_code && ($err_str = $RCMAIL->storage->get_error_str())) { 
    1309         // try to detect access rights problem and display appropriate message 
    1310         if (stripos($err_str, 'Permission denied') !== false) 
    1311             $RCMAIL->output->show_message('errornoperm', 'error'); 
    1312         else 
    1313             $RCMAIL->output->show_message('servererrormsg', 'error', array('msg' => $err_str)); 
    1314     } 
    1315     else if ($fallback) { 
    1316         $RCMAIL->output->show_message($fallback, 'error', $fallback_args); 
    1317     } 
    1318  
    1319     return true; 
    1320 } 
    1321  
    1322  
    1323 /** 
    1324  * Generate CSS classes from mimetype and filename extension 
    1325  * 
    1326  * @param string Mimetype 
    1327  * @param string The filename 
    1328  * @return string CSS classes separated by space 
    1329  */ 
     195    rcube_ui::display_server_error($fallback, $fallback_args); 
     196} 
     197 
    1330198function rcmail_filetype2classname($mimetype, $filename) 
    1331199{ 
    1332   list($primary, $secondary) = explode('/', $mimetype); 
    1333  
    1334   $classes = array($primary ? $primary : 'unknown'); 
    1335   if ($secondary) { 
    1336     $classes[] = $secondary; 
    1337   } 
    1338   if (preg_match('/\.([a-z0-9]+)$/i', $filename, $m)) { 
    1339     $classes[] = $m[1]; 
    1340   } 
    1341  
    1342   return strtolower(join(" ", $classes)); 
    1343 } 
    1344  
    1345 /** 
    1346  * Output HTML editor scripts 
    1347  * 
    1348  * @param string Editor mode 
    1349  * @return void 
    1350  */ 
     200    return rcube_ui::file2class($mimetype, $filename); 
     201} 
     202 
    1351203function rcube_html_editor($mode='') 
    1352204{ 
    1353   global $RCMAIL; 
    1354  
    1355   $hook = $RCMAIL->plugins->exec_hook('html_editor', array('mode' => $mode)); 
    1356  
    1357   if ($hook['abort']) 
    1358     return; 
    1359  
    1360   $lang = strtolower($_SESSION['language']); 
    1361  
    1362   // TinyMCE uses two-letter lang codes, with exception of Chinese 
    1363   if (strpos($lang, 'zh_') === 0) 
    1364     $lang = str_replace('_', '-', $lang); 
    1365   else 
    1366     $lang = substr($lang, 0, 2); 
    1367  
    1368   if (!file_exists(INSTALL_PATH . 'program/js/tiny_mce/langs/'.$lang.'.js')) 
    1369     $lang = 'en'; 
    1370  
    1371   $RCMAIL->output->include_script('tiny_mce/tiny_mce.js'); 
    1372   $RCMAIL->output->include_script('editor.js'); 
    1373   $RCMAIL->output->add_script(sprintf("rcmail_editor_init(%s)", 
    1374     json_encode(array( 
    1375         'mode'       => $mode, 
    1376         'lang'       => $lang, 
    1377         'skin_path'  => $RCMAIL->output->get_skin_path(), 
    1378         'spellcheck' => intval($RCMAIL->config->get('enable_spellcheck')), 
    1379         'spelldict'  => intval($RCMAIL->config->get('spellcheck_dictionary')), 
    1380     ))), 'docready'); 
    1381 } 
    1382  
    1383  
    1384 /** 
    1385  * Replaces TinyMCE's emoticon images with plain-text representation 
    1386  * 
    1387  * @param string HTML content 
    1388  * @return string HTML content 
    1389  */ 
     205    rcube_ui::html_editor($mode); 
     206} 
     207 
    1390208function rcmail_replace_emoticons($html) 
    1391209{ 
    1392   $emoticons = array( 
    1393     '8-)' => 'smiley-cool', 
    1394     ':-#' => 'smiley-foot-in-mouth', 
    1395     ':-*' => 'smiley-kiss', 
    1396     ':-X' => 'smiley-sealed', 
    1397     ':-P' => 'smiley-tongue-out', 
    1398     ':-@' => 'smiley-yell', 
    1399     ":'(" => 'smiley-cry', 
    1400     ':-(' => 'smiley-frown', 
    1401     ':-D' => 'smiley-laughing', 
    1402     ':-)' => 'smiley-smile', 
    1403     ':-S' => 'smiley-undecided', 
    1404     ':-$' => 'smiley-embarassed', 
    1405     'O:-)' => 'smiley-innocent', 
    1406     ':-|' => 'smiley-money-mouth', 
    1407     ':-O' => 'smiley-surprised', 
    1408     ';-)' => 'smiley-wink', 
    1409   ); 
    1410  
    1411   foreach ($emoticons as $idx => $file) { 
    1412     // <img title="Cry" src="http://.../program/js/tiny_mce/plugins/emotions/img/smiley-cry.gif" border="0" alt="Cry" /> 
    1413     $search[]  = '/<img title="[a-z ]+" src="https?:\/\/[a-z0-9_.\/-]+\/tiny_mce\/plugins\/emotions\/img\/'.$file.'.gif"[^>]+\/>/i'; 
    1414     $replace[] = $idx; 
    1415   } 
    1416  
    1417   return preg_replace($search, $replace, $html); 
    1418 } 
    1419  
    1420  
    1421 /** 
    1422  * Send the given message using the configured method 
    1423  * 
    1424  * @param object $message    Reference to Mail_MIME object 
    1425  * @param string $from       Sender address string 
    1426  * @param array  $mailto     Array of recipient address strings 
    1427  * @param array  $smtp_error SMTP error array (reference) 
    1428  * @param string $body_file  Location of file with saved message body (reference), 
    1429  *                           used when delay_file_io is enabled 
    1430  * @param array  $smtp_opts  SMTP options (e.g. DSN request) 
    1431  * 
    1432  * @return boolean Send status. 
    1433  */ 
     210    return rcube_ui::replace_emoticons($html); 
     211} 
     212 
    1434213function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error, &$body_file=null, $smtp_opts=null) 
    1435214{ 
    1436   global $CONFIG, $RCMAIL; 
    1437  
    1438   $headers = $message->headers(); 
    1439  
    1440   // send thru SMTP server using custom SMTP library 
    1441   if ($CONFIG['smtp_server']) { 
    1442     // generate list of recipients 
    1443     $a_recipients = array($mailto); 
    1444  
    1445     if (strlen($headers['Cc'])) 
    1446       $a_recipients[] = $headers['Cc']; 
    1447     if (strlen($headers['Bcc'])) 
    1448       $a_recipients[] = $headers['Bcc']; 
    1449  
    1450     // clean Bcc from header for recipients 
    1451     $send_headers = $headers; 
    1452     unset($send_headers['Bcc']); 
    1453     // here too, it because txtHeaders() below use $message->_headers not only $send_headers 
    1454     unset($message->_headers['Bcc']); 
    1455  
    1456     $smtp_headers = $message->txtHeaders($send_headers, true); 
    1457  
    1458     if ($message->getParam('delay_file_io')) { 
    1459       // use common temp dir 
    1460       $temp_dir = $RCMAIL->config->get('temp_dir'); 
    1461       $body_file = tempnam($temp_dir, 'rcmMsg'); 
    1462       if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) { 
    1463         raise_error(array('code' => 650, 'type' => 'php', 
    1464             'file' => __FILE__, 'line' => __LINE__, 
    1465             'message' => "Could not create message: ".$mime_result->getMessage()), 
    1466             TRUE, FALSE); 
    1467         return false; 
    1468       } 
    1469       $msg_body = fopen($body_file, 'r'); 
    1470     } else { 
    1471       $msg_body = $message->get(); 
    1472     } 
    1473  
    1474     // send message 
    1475     if (!is_object($RCMAIL->smtp)) 
    1476       $RCMAIL->smtp_init(true); 
    1477  
    1478     $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $smtp_opts); 
    1479     $smtp_response = $RCMAIL->smtp->get_response(); 
    1480     $smtp_error = $RCMAIL->smtp->get_error(); 
    1481  
    1482     // log error 
    1483     if (!$sent) 
    1484       raise_error(array('code' => 800, 'type' => 'smtp', 'line' => __LINE__, 'file' => __FILE__, 
    1485                         'message' => "SMTP error: ".join("\n", $smtp_response)), TRUE, FALSE); 
    1486   } 
    1487   // send mail using PHP's mail() function 
    1488   else { 
    1489     // unset some headers because they will be added by the mail() function 
    1490     $headers_enc = $message->headers($headers); 
    1491     $headers_php = $message->_headers; 
    1492     unset($headers_php['To'], $headers_php['Subject']); 
    1493  
    1494     // reset stored headers and overwrite 
    1495     $message->_headers = array(); 
    1496     $header_str = $message->txtHeaders($headers_php); 
    1497  
    1498     // #1485779 
    1499     if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 
    1500       if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) { 
    1501         $headers_enc['To'] = implode(', ', $m[1]); 
    1502       } 
    1503     } 
    1504  
    1505     $msg_body = $message->get(); 
    1506  
    1507     if (PEAR::isError($msg_body)) 
    1508       raise_error(array('code' => 650, 'type' => 'php', 
    1509             'file' => __FILE__, 'line' => __LINE__, 
    1510             'message' => "Could not create message: ".$msg_body->getMessage()), 
    1511             TRUE, FALSE); 
    1512     else { 
    1513       $delim   = $RCMAIL->config->header_delimiter(); 
    1514       $to      = $headers_enc['To']; 
    1515       $subject = $headers_enc['Subject']; 
    1516       $header_str = rtrim($header_str); 
    1517  
    1518       if ($delim != "\r\n") { 
    1519         $header_str = str_replace("\r\n", $delim, $header_str); 
    1520         $msg_body   = str_replace("\r\n", $delim, $msg_body); 
    1521         $to         = str_replace("\r\n", $delim, $to); 
    1522         $subject    = str_replace("\r\n", $delim, $subject); 
    1523       } 
    1524  
    1525       if (ini_get('safe_mode')) 
    1526         $sent = mail($to, $subject, $msg_body, $header_str); 
    1527       else 
    1528         $sent = mail($to, $subject, $msg_body, $header_str, "-f$from"); 
    1529     } 
    1530   } 
    1531  
    1532   if ($sent) { 
    1533     $RCMAIL->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body)); 
    1534  
    1535     // remove MDN headers after sending 
    1536     unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']); 
    1537  
    1538     // get all recipients 
    1539     if ($headers['Cc']) 
    1540       $mailto .= $headers['Cc']; 
    1541     if ($headers['Bcc']) 
    1542       $mailto .= $headers['Bcc']; 
    1543     if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m)) 
    1544       $mailto = implode(', ', array_unique($m[1])); 
    1545  
    1546     if ($CONFIG['smtp_log']) { 
    1547       write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", 
    1548         $RCMAIL->user->get_username(), 
    1549         $_SERVER['REMOTE_ADDR'], 
    1550         $mailto, 
    1551         !empty($smtp_response) ? join('; ', $smtp_response) : '')); 
    1552     } 
    1553   } 
    1554  
    1555   if (is_resource($msg_body)) { 
    1556     fclose($msg_body); 
    1557   } 
    1558  
    1559   $message->_headers = array(); 
    1560   $message->headers($headers); 
    1561  
    1562   return $sent; 
    1563 } 
    1564  
    1565  
    1566 // Returns unique Message-ID 
     215    return rcmail::get_instance()->deliver_message($message, $from, $mailto, $smtp_error, $body_file, $smtp_opts); 
     216} 
     217 
    1567218function rcmail_gen_message_id() 
    1568219{ 
    1569   global $RCMAIL; 
    1570  
    1571   $local_part  = md5(uniqid('rcmail'.mt_rand(),true)); 
    1572   $domain_part = $RCMAIL->user->get_username('domain'); 
    1573  
    1574   // Try to find FQDN, some spamfilters doesn't like 'localhost' (#1486924) 
    1575   if (!preg_match('/\.[a-z]+$/i', $domain_part)) { 
    1576     if (($host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST'])) 
    1577       && preg_match('/\.[a-z]+$/i', $host)) { 
    1578         $domain_part = $host; 
    1579     } 
    1580     else if (($host = preg_replace('/:[0-9]+$/', '', $_SERVER['SERVER_NAME'])) 
    1581       && preg_match('/\.[a-z]+$/i', $host)) { 
    1582         $domain_part = $host; 
    1583     } 
    1584   } 
    1585  
    1586   return sprintf('<%s@%s>', $local_part, $domain_part); 
    1587 } 
    1588  
    1589  
    1590 // Returns RFC2822 formatted current date in user's timezone 
     220    return rcmail::get_instance()->gen_message_id(); 
     221} 
     222 
    1591223function rcmail_user_date() 
    1592224{ 
    1593   global $RCMAIL; 
    1594  
    1595   // get user's timezone 
    1596   try { 
    1597     $tz   = new DateTimeZone($RCMAIL->config->get('timezone')); 
    1598     $date = new DateTime('now', $tz); 
    1599   } 
    1600   catch (Exception $e) { 
    1601     $date = new DateTime(); 
    1602   } 
    1603  
    1604   return $date->format('r'); 
    1605 } 
    1606  
    1607  
    1608 /** 
    1609  * Check if we can process not exceeding memory_limit 
    1610  * 
    1611  * @param integer Required amount of memory 
    1612  * @return boolean 
    1613  */ 
     225    return rcmail::get_instance()->user_date(); 
     226} 
     227 
    1614228function rcmail_mem_check($need) 
    1615229{ 
    1616   $mem_limit = parse_bytes(ini_get('memory_limit')); 
    1617   $memory    = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB 
    1618  
    1619   return $mem_limit > 0 && $memory + $need > $mem_limit ? false : true; 
    1620 } 
    1621  
    1622  
    1623 /** 
    1624  * Check if working in SSL mode 
    1625  * 
    1626  * @param integer HTTPS port number 
    1627  * @param boolean Enables 'use_https' option checking 
    1628  * @return boolean 
    1629  */ 
     230    return rcube_ui::mem_check($need); 
     231} 
     232 
    1630233function rcube_https_check($port=null, $use_https=true) 
    1631234{ 
    1632   global $RCMAIL; 
    1633  
    1634   if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') 
    1635     return true; 
    1636   if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') 
    1637     return true; 
    1638   if ($port && $_SERVER['SERVER_PORT'] == $port) 
    1639     return true; 
    1640   if ($use_https && isset($RCMAIL) && $RCMAIL->config->get('use_https')) 
    1641     return true; 
    1642  
    1643   return false; 
    1644 } 
    1645  
    1646  
    1647 /** 
    1648  * For backward compatibility. 
    1649  * 
    1650  * @global rcmail $RCMAIL 
    1651  * @param string $var_name Variable name. 
    1652  * @return void 
    1653  */ 
     235    return rcube_ui::https_check($port, $use_https); 
     236} 
     237 
    1654238function rcube_sess_unset($var_name=null) 
    1655239{ 
    1656   global $RCMAIL; 
    1657  
    1658   $RCMAIL->session->remove($var_name); 
    1659 } 
    1660  
    1661  
    1662 /** 
    1663  * Replaces hostname variables 
    1664  * 
    1665  * @param string $name Hostname 
    1666  * @param string $host Optional IMAP hostname 
    1667  * @return string 
    1668  */ 
     240    rcmail::get_instance()->session->remove($var_name); 
     241} 
     242 
    1669243function rcube_parse_host($name, $host='') 
    1670244{ 
    1671   // %n - host 
    1672   $n = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']); 
    1673   // %d - domain name without first part, e.g. %n=mail.domain.tld, %d=domain.tld 
    1674   $d = preg_replace('/^[^\.]+\./', '', $n); 
    1675   // %h - IMAP host 
    1676   $h = $_SESSION['storage_host'] ? $_SESSION['storage_host'] : $host; 
    1677   // %z - IMAP domain without first part, e.g. %h=imap.domain.tld, %z=domain.tld 
    1678   $z = preg_replace('/^[^\.]+\./', '', $h); 
    1679   // %s - domain name after the '@' from e-mail address provided at login screen. Returns FALSE if an invalid email is provided 
    1680   if ( strpos($name, '%s') !== false ){ 
    1681     $user_email = rcube_idn_convert(get_input_value('_user', RCUBE_INPUT_POST), true); 
    1682     if ( preg_match('/(.*)@([a-z0-9\.\-\[\]\:]+)/i', $user_email, $s) < 1 || filter_var($s[1]."@".$s[2], FILTER_VALIDATE_EMAIL) === false ) 
    1683       return false; 
    1684   } 
    1685  
    1686   $name = str_replace(array('%n', '%d', '%h', '%z', '%s'), array($n, $d, $h, $z, $s[2]), $name); 
    1687   return $name; 
    1688 } 
    1689  
    1690  
    1691 /** 
    1692  * E-mail address validation 
    1693  * 
    1694  * @param string $email Email address 
    1695  * @param boolean $dns_check True to check dns 
    1696  * @return boolean 
    1697  */ 
     245    return rcmail::parse_host($name, $host); 
     246} 
     247 
    1698248function check_email($email, $dns_check=true) 
    1699249{ 
    1700   // Check for invalid characters 
    1701   if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email)) 
    1702     return false; 
    1703  
    1704   // Check for length limit specified by RFC 5321 (#1486453) 
    1705   if (strlen($email) > 254)  
    1706     return false; 
    1707  
    1708   $email_array = explode('@', $email); 
    1709  
    1710   // Check that there's one @ symbol 
    1711   if (count($email_array) < 2) 
    1712     return false; 
    1713  
    1714   $domain_part = array_pop($email_array); 
    1715   $local_part = implode('@', $email_array); 
    1716  
    1717   // from PEAR::Validate 
    1718   $regexp = '&^(?: 
    1719         ("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+")|                             #1 quoted name 
    1720         ([-\w!\#\$%\&\'*+~/^`|{}=]+(?:\.[-\w!\#\$%\&\'*+~/^`|{}=]+)*))  #2 OR dot-atom (RFC5322) 
    1721         $&xi'; 
    1722  
    1723   if (!preg_match($regexp, $local_part)) 
    1724     return false; 
    1725  
    1726   // Check domain part 
    1727   if (preg_match('/^\[*(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]*$/', $domain_part)) 
    1728     return true; // IP address 
    1729   else { 
    1730     // If not an IP address 
    1731     $domain_array = explode('.', $domain_part); 
    1732     if (sizeof($domain_array) < 2) 
    1733       return false; // Not enough parts to be a valid domain 
    1734  
    1735     foreach ($domain_array as $part) 
    1736       if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $part)) 
    1737         return false; 
    1738  
    1739     if (!$dns_check || !rcmail::get_instance()->config->get('email_dns_check')) 
    1740       return true; 
    1741  
    1742     if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<')) { 
    1743       $lookup = array(); 
    1744       @exec("nslookup -type=MX " . escapeshellarg($domain_part) . " 2>&1", $lookup); 
    1745       foreach ($lookup as $line) { 
    1746         if (strpos($line, 'MX preference')) 
    1747           return true; 
    1748       } 
    1749       return false; 
    1750     } 
    1751  
    1752     // find MX record(s) 
    1753     if (getmxrr($domain_part, $mx_records)) 
    1754       return true; 
    1755  
    1756     // find any DNS record 
    1757     if (checkdnsrr($domain_part, 'ANY')) 
    1758       return true; 
    1759   } 
    1760  
    1761   return false; 
    1762 } 
    1763  
    1764 /* 
    1765  * Idn_to_ascii wrapper. 
    1766  * Intl/Idn modules version of this function doesn't work with e-mail address 
    1767  */ 
    1768 function rcube_idn_to_ascii($str) 
    1769 { 
    1770   return rcube_idn_convert($str, true); 
    1771 } 
    1772  
    1773 /* 
    1774  * Idn_to_ascii wrapper. 
    1775  * Intl/Idn modules version of this function doesn't work with e-mail address 
    1776  */ 
    1777 function rcube_idn_to_utf8($str) 
    1778 { 
    1779   return rcube_idn_convert($str, false); 
    1780 } 
    1781  
    1782 function rcube_idn_convert($input, $is_utf=false) 
    1783 { 
    1784   if ($at = strpos($input, '@')) { 
    1785     $user   = substr($input, 0, $at); 
    1786     $domain = substr($input, $at+1); 
    1787   } 
    1788   else { 
    1789     $domain = $input; 
    1790   } 
    1791  
    1792   $domain = $is_utf ? idn_to_ascii($domain) : idn_to_utf8($domain); 
    1793  
    1794   if ($domain === false) { 
    1795     return ''; 
    1796   } 
    1797  
    1798   return $at ? $user . '@' . $domain : $domain; 
    1799 } 
    1800  
    1801  
    1802 /** 
    1803  * Helper class to turn relative urls into absolute ones 
    1804  * using a predefined base 
    1805  */ 
    1806 class rcube_base_replacer 
    1807 { 
    1808   private $base_url; 
    1809  
    1810   public function __construct($base) 
    1811   { 
    1812     $this->base_url = $base; 
    1813   } 
    1814  
    1815   public function callback($matches) 
    1816   { 
    1817     return $matches[1] . '="' . self::absolute_url($matches[3], $this->base_url) . '"'; 
    1818   } 
    1819  
    1820   public function replace($body) 
    1821   { 
    1822     return preg_replace_callback(array( 
    1823       '/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui', 
    1824       '/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui', 
    1825       ), 
    1826       array($this, 'callback'), $body); 
    1827   } 
    1828  
    1829   /** 
    1830    * Convert paths like ../xxx to an absolute path using a base url 
    1831    * 
    1832    * @param string $path     Relative path 
    1833    * @param string $base_url Base URL 
    1834    * 
    1835    * @return string Absolute URL 
    1836    */ 
    1837   public static function absolute_url($path, $base_url) 
    1838   { 
    1839     $host_url = $base_url; 
    1840     $abs_path = $path; 
    1841  
    1842     // check if path is an absolute URL 
    1843     if (preg_match('/^[fhtps]+:\/\//', $path)) { 
    1844       return $path; 
    1845     } 
    1846  
    1847     // check if path is a content-id scheme 
    1848     if (strpos($path, 'cid:') === 0) { 
    1849       return $path; 
    1850     } 
    1851  
    1852     // cut base_url to the last directory 
    1853     if (strrpos($base_url, '/') > 7) { 
    1854       $host_url = substr($base_url, 0, strpos($base_url, '/', 7)); 
    1855       $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
    1856     } 
    1857  
    1858     // $path is absolute 
    1859     if ($path[0] == '/') { 
    1860       $abs_path = $host_url.$path; 
    1861     } 
    1862     else { 
    1863       // strip './' because its the same as '' 
    1864       $path = preg_replace('/^\.\//', '', $path); 
    1865  
    1866       if (preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER)) { 
    1867         foreach ($matches as $a_match) { 
    1868           if (strrpos($base_url, '/')) { 
    1869             $base_url = substr($base_url, 0, strrpos($base_url, '/')); 
    1870           } 
    1871           $path = substr($path, 3); 
    1872         } 
    1873       } 
    1874  
    1875       $abs_path = $base_url.'/'.$path; 
    1876     } 
    1877  
    1878     return $abs_path; 
    1879   } 
    1880 } 
    1881  
    1882  
    1883 /****** debugging and logging functions ********/ 
    1884  
    1885 /** 
    1886  * Print or write debug messages 
    1887  * 
    1888  * @param mixed Debug message or data 
    1889  * @return void 
    1890  */ 
     250    return rcmail::get_instance()->check_email($email, $dns_check); 
     251} 
     252 
    1891253function console() 
    1892254{ 
    1893     $args = func_get_args(); 
    1894  
    1895     if (class_exists('rcmail', false)) { 
    1896         $rcmail = rcmail::get_instance(); 
    1897         if (is_object($rcmail->plugins)) { 
    1898             $plugin = $rcmail->plugins->exec_hook('console', array('args' => $args)); 
    1899             if ($plugin['abort']) 
    1900                 return; 
    1901             $args = $plugin['args']; 
    1902         } 
    1903     } 
    1904  
    1905     $msg = array(); 
    1906     foreach ($args as $arg) 
    1907         $msg[] = !is_string($arg) ? var_export($arg, true) : $arg; 
    1908  
    1909     write_log('console', join(";\n", $msg)); 
    1910 } 
    1911  
    1912  
    1913 /** 
    1914  * Append a line to a logfile in the logs directory. 
    1915  * Date will be added automatically to the line. 
    1916  * 
    1917  * @param $name name of log file 
    1918  * @param line Line to append 
    1919  * @return void 
    1920  */ 
     255    call_user_func_array(array('rcmail', 'console'), func_get_args()); 
     256} 
     257 
    1921258function write_log($name, $line) 
    1922259{ 
    1923   global $CONFIG, $RCMAIL; 
    1924  
    1925   if (!is_string($line)) 
    1926     $line = var_export($line, true); 
    1927   
    1928   if (empty($CONFIG['log_date_format'])) 
    1929     $CONFIG['log_date_format'] = 'd-M-Y H:i:s O'; 
    1930    
    1931   $date = date($CONFIG['log_date_format']); 
    1932    
    1933   // trigger logging hook 
    1934   if (is_object($RCMAIL) && is_object($RCMAIL->plugins)) { 
    1935     $log = $RCMAIL->plugins->exec_hook('write_log', array('name' => $name, 'date' => $date, 'line' => $line)); 
    1936     $name = $log['name']; 
    1937     $line = $log['line']; 
    1938     $date = $log['date']; 
    1939     if ($log['abort']) 
    1940       return true; 
    1941   } 
    1942   
    1943   if ($CONFIG['log_driver'] == 'syslog') { 
    1944     $prio = $name == 'errors' ? LOG_ERR : LOG_INFO; 
    1945     syslog($prio, $line); 
    1946     return true; 
    1947   } 
    1948   else { 
    1949     $line = sprintf("[%s]: %s\n", $date, $line); 
    1950  
    1951     // log_driver == 'file' is assumed here 
    1952     if (empty($CONFIG['log_dir'])) 
    1953       $CONFIG['log_dir'] = INSTALL_PATH.'logs'; 
    1954  
    1955     // try to open specific log file for writing 
    1956     $logfile = $CONFIG['log_dir'].'/'.$name; 
    1957     if ($fp = @fopen($logfile, 'a')) { 
    1958       fwrite($fp, $line); 
    1959       fflush($fp); 
    1960       fclose($fp); 
    1961       return true; 
    1962     } 
    1963     else 
    1964       trigger_error("Error writing to log file $logfile; Please check permissions", E_USER_WARNING); 
    1965   } 
    1966  
    1967   return false; 
    1968 } 
    1969  
    1970  
    1971 /** 
    1972  * Write login data (name, ID, IP address) to the 'userlogins' log file. 
    1973  * 
    1974  * @return void 
    1975  */ 
     260    return rcmail::write_log($name, $line); 
     261} 
     262 
    1976263function rcmail_log_login() 
    1977264{ 
    1978   global $RCMAIL; 
    1979  
    1980   if (!$RCMAIL->config->get('log_logins') || !$RCMAIL->user) 
    1981     return; 
    1982  
    1983   write_log('userlogins', sprintf('Successful login for %s (ID: %d) from %s in session %s', 
    1984     $RCMAIL->user->get_username(), $RCMAIL->user->ID, rcmail_remote_ip(), session_id())); 
    1985 } 
    1986  
    1987  
    1988 /** 
    1989  * Returns remote IP address and forwarded addresses if found 
    1990  * 
    1991  * @return string Remote IP address(es) 
    1992  */ 
     265    return rcmail::get_instance()->log_login(); 
     266} 
     267 
    1993268function rcmail_remote_ip() 
    1994269{ 
    1995     $address = $_SERVER['REMOTE_ADDR']; 
    1996  
    1997     // append the NGINX X-Real-IP header, if set 
    1998     if (!empty($_SERVER['HTTP_X_REAL_IP'])) { 
    1999         $remote_ip[] = 'X-Real-IP: ' . $_SERVER['HTTP_X_REAL_IP']; 
    2000     } 
    2001     // append the X-Forwarded-For header, if set 
    2002     if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    2003         $remote_ip[] = 'X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR']; 
    2004     } 
    2005  
    2006     if (!empty($remote_ip)) 
    2007         $address .= '(' . implode(',', $remote_ip) . ')'; 
    2008  
    2009     return $address; 
    2010 } 
    2011  
    2012  
    2013 /** 
    2014  * Check whether the HTTP referer matches the current request 
    2015  * 
    2016  * @return boolean True if referer is the same host+path, false if not 
    2017  */ 
     270    return rcmail::remote_ip(); 
     271} 
     272 
    2018273function rcube_check_referer() 
    2019274{ 
    2020   $uri = parse_url($_SERVER['REQUEST_URI']); 
    2021   $referer = parse_url(rc_request_header('Referer')); 
    2022   return $referer['host'] == rc_request_header('Host') && $referer['path'] == $uri['path']; 
    2023 } 
    2024  
    2025  
    2026 /** 
    2027  * @access private 
    2028  * @return mixed 
    2029  */ 
     275    return rcmail::check_referer(); 
     276} 
     277 
    2030278function rcube_timer() 
    2031279{ 
    2032   return microtime(true); 
    2033 } 
    2034  
    2035  
    2036 /** 
    2037  * @access private 
    2038  * @return void 
    2039  */ 
     280    return rcmail::timer(); 
     281} 
     282 
    2040283function rcube_print_time($timer, $label='Timer', $dest='console') 
    2041284{ 
    2042   static $print_count = 0; 
    2043  
    2044   $print_count++; 
    2045   $now = rcube_timer(); 
    2046   $diff = $now-$timer; 
    2047  
    2048   if (empty($label)) 
    2049     $label = 'Timer '.$print_count; 
    2050  
    2051   write_log($dest, sprintf("%s: %0.4f sec", $label, $diff)); 
    2052 } 
    2053  
    2054  
    2055 /** 
    2056  * Throw system error and show error page 
    2057  * 
    2058  * @param array Named parameters 
    2059  *  - code: Error code (required) 
    2060  *  - type: Error type [php|db|imap|javascript] (required) 
    2061  *  - message: Error message 
    2062  *  - file: File where error occured 
    2063  *  - line: Line where error occured 
    2064  * @param boolean True to log the error 
    2065  * @param boolean Terminate script execution 
    2066  */ 
    2067 // may be defined in Installer 
    2068 if (!function_exists('raise_error')) { 
     285    rcmail::print_timer($timer, $label, $dest); 
     286} 
     287 
    2069288function raise_error($arg=array(), $log=false, $terminate=false) 
    2070289{ 
    2071     global $__page_content, $CONFIG, $OUTPUT, $ERROR_CODE, $ERROR_MESSAGE; 
    2072  
    2073     // report bug (if not incompatible browser) 
    2074     if ($log && $arg['type'] && $arg['message']) 
    2075         rcube_log_bug($arg); 
    2076  
    2077     // display error page and terminate script 
    2078     if ($terminate) { 
    2079         $ERROR_CODE = $arg['code']; 
    2080         $ERROR_MESSAGE = $arg['message']; 
    2081         include INSTALL_PATH . 'program/steps/utils/error.inc'; 
    2082         exit; 
    2083     } 
    2084 } 
    2085 } 
    2086  
    2087  
    2088 /** 
    2089  * Report error according to configured debug_level 
    2090  * 
    2091  * @param array Named parameters 
    2092  * @return void 
    2093  * @see raise_error() 
    2094  */ 
     290    rcmail::raise_error($arg, $log, $terminate); 
     291} 
     292 
    2095293function rcube_log_bug($arg_arr) 
    2096294{ 
    2097     global $CONFIG; 
    2098  
    2099     $program = strtoupper($arg_arr['type']); 
    2100     $level   = $CONFIG['debug_level']; 
    2101  
    2102     // disable errors for ajax requests, write to log instead (#1487831) 
    2103     if (($level & 4) && !empty($_REQUEST['_remote'])) { 
    2104         $level = ($level ^ 4) | 1; 
    2105     } 
    2106  
    2107     // write error to local log file 
    2108     if ($level & 1) { 
    2109         $post_query = ($_SERVER['REQUEST_METHOD'] == 'POST' ? '?_task='.urlencode($_POST['_task']).'&_action='.urlencode($_POST['_action']) : ''); 
    2110         $log_entry = sprintf("%s Error: %s%s (%s %s)", 
    2111             $program, 
    2112             $arg_arr['message'], 
    2113             $arg_arr['file'] ? sprintf(' in %s on line %d', $arg_arr['file'], $arg_arr['line']) : '', 
    2114             $_SERVER['REQUEST_METHOD'], 
    2115             $_SERVER['REQUEST_URI'] . $post_query); 
    2116  
    2117         if (!write_log('errors', $log_entry)) { 
    2118             // send error to PHPs error handler if write_log didn't succeed 
    2119             trigger_error($arg_arr['message']); 
    2120         } 
    2121     } 
    2122  
    2123     // report the bug to the global bug reporting system 
    2124     if ($level & 2) { 
    2125         // TODO: Send error via HTTP 
    2126     } 
    2127  
    2128     // show error if debug_mode is on 
    2129     if ($level & 4) { 
    2130         print "<b>$program Error"; 
    2131  
    2132         if (!empty($arg_arr['file']) && !empty($arg_arr['line'])) 
    2133             print " in $arg_arr[file] ($arg_arr[line])"; 
    2134  
    2135         print ':</b>&nbsp;'; 
    2136         print nl2br($arg_arr['message']); 
    2137         print '<br />'; 
    2138         flush(); 
    2139     } 
     295    rcmail::log_bug($arg_arr); 
    2140296} 
    2141297 
    2142298function rcube_upload_progress() 
    2143299{ 
    2144     global $RCMAIL; 
    2145  
    2146     $prefix = ini_get('apc.rfc1867_prefix'); 
    2147     $params = array( 
    2148         'action' => $RCMAIL->action, 
    2149         'name' => get_input_value('_progress', RCUBE_INPUT_GET), 
    2150     ); 
    2151  
    2152     if (function_exists('apc_fetch')) { 
    2153         $status = apc_fetch($prefix . $params['name']); 
    2154  
    2155         if (!empty($status)) { 
    2156             $status['percent'] = round($status['current']/$status['total']*100); 
    2157             $params = array_merge($status, $params); 
    2158         } 
    2159     } 
    2160  
    2161     if (isset($params['percent'])) 
    2162         $params['text'] = rcube_label(array('name' => 'uploadprogress', 'vars' => array( 
    2163             'percent' => $params['percent'] . '%', 
    2164             'current' => show_bytes($params['current']), 
    2165             'total'   => show_bytes($params['total']) 
    2166         ))); 
    2167  
    2168     $RCMAIL->output->command('upload_progress_update', $params); 
    2169     $RCMAIL->output->send(); 
     300    rcube_ui::upload_progress(); 
    2170301} 
    2171302 
    2172303function rcube_upload_init() 
    2173304{ 
    2174     global $RCMAIL; 
    2175  
    2176     // Enable upload progress bar 
    2177     if (($seconds = $RCMAIL->config->get('upload_progress')) && ini_get('apc.rfc1867')) { 
    2178         if ($field_name = ini_get('apc.rfc1867_name')) { 
    2179             $RCMAIL->output->set_env('upload_progress_name', $field_name); 
    2180             $RCMAIL->output->set_env('upload_progress_time', (int) $seconds); 
    2181         } 
    2182     } 
    2183  
    2184     // find max filesize value 
    2185     $max_filesize = parse_bytes(ini_get('upload_max_filesize')); 
    2186     $max_postsize = parse_bytes(ini_get('post_max_size')); 
    2187     if ($max_postsize && $max_postsize < $max_filesize) 
    2188         $max_filesize = $max_postsize; 
    2189  
    2190     $RCMAIL->output->set_env('max_filesize', $max_filesize); 
    2191     $max_filesize = show_bytes($max_filesize); 
    2192     $RCMAIL->output->set_env('filesizeerror', rcube_label(array( 
    2193         'name' => 'filesizeerror', 'vars' => array('size' => $max_filesize)))); 
    2194  
    2195     return $max_filesize; 
    2196 } 
    2197  
    2198 /** 
    2199  * Initializes client-side autocompletion 
    2200  */ 
     305    return rcube_ui::upload_init(); 
     306} 
     307 
    2201308function rcube_autocomplete_init() 
    2202309{ 
    2203     global $RCMAIL; 
    2204     static $init; 
    2205  
    2206     if ($init) 
    2207         return; 
    2208  
    2209     $init = 1; 
    2210  
    2211     if (($threads = (int)$RCMAIL->config->get('autocomplete_threads')) > 0) { 
    2212       $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql'); 
    2213       if (count($book_types) > 1) { 
    2214         $RCMAIL->output->set_env('autocomplete_threads', $threads); 
    2215         $RCMAIL->output->set_env('autocomplete_sources', $book_types); 
    2216       } 
    2217     } 
    2218  
    2219     $RCMAIL->output->set_env('autocomplete_max', (int)$RCMAIL->config->get('autocomplete_max', 15)); 
    2220     $RCMAIL->output->set_env('autocomplete_min_length', $RCMAIL->config->get('autocomplete_min_length')); 
    2221     $RCMAIL->output->add_label('autocompletechars', 'autocompletemore'); 
     310    rcube_ui::autocomplete_init(); 
    2222311} 
    2223312 
    2224313function rcube_fontdefs($font = null) 
    2225314{ 
    2226   $fonts = array( 
    2227     'Andale Mono'   => '"Andale Mono",Times,monospace', 
    2228     'Arial'         => 'Arial,Helvetica,sans-serif', 
    2229     'Arial Black'   => '"Arial Black","Avant Garde",sans-serif', 
    2230     'Book Antiqua'  => '"Book Antiqua",Palatino,serif', 
    2231     'Courier New'   => '"Courier New",Courier,monospace', 
    2232     'Georgia'       => 'Georgia,Palatino,serif', 
    2233     'Helvetica'     => 'Helvetica,Arial,sans-serif', 
    2234     'Impact'        => 'Impact,Chicago,sans-serif', 
    2235     'Tahoma'        => 'Tahoma,Arial,Helvetica,sans-serif', 
    2236     'Terminal'      => 'Terminal,Monaco,monospace', 
    2237     'Times New Roman' => '"Times New Roman",Times,serif', 
    2238     'Trebuchet MS'  => '"Trebuchet MS",Geneva,sans-serif', 
    2239     'Verdana'       => 'Verdana,Geneva,sans-serif', 
    2240   ); 
    2241  
    2242   if ($font) 
    2243     return $fonts[$font]; 
    2244  
    2245   return $fonts; 
    2246 } 
     315    return rcube_ui::font_defs($font); 
     316} 
     317 
     318function send_nocacheing_headers() 
     319{ 
     320    return rcmail::get_instance()->output->nocacheing_headers(); 
     321} 
     322 
     323function show_bytes($bytes) 
     324{ 
     325    return rcube_ui::show_bytes($bytes); 
     326} 
     327 
     328function rc_wordwrap($string, $width=75, $break="\n", $cut=false) 
     329{ 
     330    return rcube_mime::wordwrap($string, $width, $break, $cut); 
     331} 
     332 
     333function rc_request_header($name) 
     334{ 
     335    return rcube_request_header($name); 
     336} 
     337 
     338function rc_mime_content_type($path, $name, $failover = 'application/octet-stream', $is_stream=false) 
     339{ 
     340    return rcube_mime::file_content_type($path, $name, $failover, $is_stream); 
     341} 
     342 
     343function rc_image_content_type($data) 
     344{ 
     345    return rcube_mime::image_content_type($data); 
     346} 
  • trunk/roundcubemail/program/include/rcmail.php

    r6030 r6073  
    66 |                                                                       | 
    77 | This file is part of the Roundcube Webmail client                     | 
    8  | Copyright (C) 2008-2011, The Roundcube Dev Team                       | 
    9  | Copyright (C) 2011, Kolab Systems AG                                  | 
     8 | Copyright (C) 2008-2012, The Roundcube Dev Team                       | 
     9 | Copyright (C) 2011-2012, Kolab Systems AG                             | 
    1010 |                                                                       | 
    1111 | Licensed under the GNU General Public License version 3 or            | 
     
    3131 * @package Core 
    3232 */ 
    33 class rcmail 
     33class rcmail extends rcube 
    3434{ 
    3535  /** 
     
    3939   */ 
    4040  static public $main_tasks = array('mail','settings','addressbook','login','logout','utils','dummy'); 
    41  
    42   /** 
    43    * Singleton instace of rcmail 
    44    * 
    45    * @var rcmail 
    46    */ 
    47   static private $instance; 
    48  
    49   /** 
    50    * Stores instance of rcube_config. 
    51    * 
    52    * @var rcube_config 
    53    */ 
    54   public $config; 
    55  
    56   /** 
    57    * Stores rcube_user instance. 
    58    * 
    59    * @var rcube_user 
    60    */ 
    61   public $user; 
    62  
    63   /** 
    64    * Instace of database class. 
    65    * 
    66    * @var rcube_mdb2 
    67    */ 
    68   public $db; 
    69  
    70   /** 
    71    * Instace of Memcache class. 
    72    * 
    73    * @var rcube_mdb2 
    74    */ 
    75   public $memcache; 
    76  
    77   /** 
    78    * Instace of rcube_session class. 
    79    * 
    80    * @var rcube_session 
    81    */ 
    82   public $session; 
    83  
    84   /** 
    85    * Instance of rcube_smtp class. 
    86    * 
    87    * @var rcube_smtp 
    88    */ 
    89   public $smtp; 
    90  
    91   /** 
    92    * Instance of rcube_storage class. 
    93    * 
    94    * @var rcube_storage 
    95    */ 
    96   public $storage; 
    97  
    98   /** 
    99    * Instance of rcube_template class. 
    100    * 
    101    * @var rcube_template 
    102    */ 
    103   public $output; 
    104  
    105   /** 
    106    * Instance of rcube_plugin_api. 
    107    * 
    108    * @var rcube_plugin_api 
    109    */ 
    110   public $plugins; 
    11141 
    11242  /** 
     
    12555  public $comm_path = './'; 
    12656 
    127   private $texts; 
    12857  private $address_books = array(); 
    129   private $caches = array(); 
    13058  private $action_map = array(); 
    131   private $shutdown_functions = array(); 
    132   private $expunge_cache = false; 
    13359 
    13460 
     
    14066  static function get_instance() 
    14167  { 
    142     if (!self::$instance) { 
     68    if (!self::$instance || !is_a(self::$instance, 'rcmail')) { 
    14369      self::$instance = new rcmail(); 
    14470      self::$instance->startup();  // init AFTER object was linked with self::$instance 
     
    15076 
    15177  /** 
    152    * Private constructor 
    153    */ 
    154   private function __construct() 
    155   { 
    156     // load configuration 
    157     $this->config = new rcube_config(); 
    158  
    159     register_shutdown_function(array($this, 'shutdown')); 
    160   } 
    161  
    162  
    163   /** 
    16478   * Initial startup function 
    16579   * to register session, create database and imap connections 
    16680   */ 
    167   private function startup() 
    168   { 
    169     // initialize syslog 
    170     if ($this->config->get('log_driver') == 'syslog') { 
    171       $syslog_id = $this->config->get('syslog_id', 'roundcube'); 
    172       $syslog_facility = $this->config->get('syslog_facility', LOG_USER); 
    173       openlog($syslog_id, LOG_ODELAY, $syslog_facility); 
    174     } 
    175  
    176     // connect to database 
    177     $this->get_dbh(); 
     81  protected function startup() 
     82  { 
     83    $this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS); 
    17884 
    17985    // start session 
     
    18793 
    18894    // set task and action properties 
    189     $this->set_task(get_input_value('_task', RCUBE_INPUT_GPC)); 
    190     $this->action = asciiwords(get_input_value('_action', RCUBE_INPUT_GPC)); 
     95    $this->set_task(rcube_ui::get_input_value('_task', rcube_ui::INPUT_GPC)); 
     96    $this->action = asciiwords(rcube_ui::get_input_value('_action', rcube_ui::INPUT_GPC)); 
    19197 
    19298    // reset some session parameters when changing task 
     
    204110      $GLOBALS['OUTPUT'] = $this->load_gui(!empty($_REQUEST['_framed'])); 
    205111 
    206     // create plugin API and load plugins 
    207     $this->plugins = rcube_plugin_api::get_instance(); 
    208  
    209     // init plugins 
    210     $this->plugins->init(); 
     112    // load plugins 
     113    $this->plugins->init($this, $this->task); 
     114    $this->plugins->load_plugins((array)$this->config->get('plugins', array()), array('filesystem_attachments', 'jqueryui')); 
    211115  } 
    212116 
     
    256160    if (in_array($_SESSION['language'], array('tr_TR', 'ku', 'az_AZ'))) 
    257161      setlocale(LC_CTYPE, 'en_US' . '.utf8'); 
    258   } 
    259  
    260  
    261   /** 
    262    * Check the given string and return a valid language code 
    263    * 
    264    * @param string Language code 
    265    * @return string Valid language code 
    266    */ 
    267   private function language_prop($lang) 
    268   { 
    269     static $rcube_languages, $rcube_language_aliases; 
    270  
    271     // user HTTP_ACCEPT_LANGUAGE if no language is specified 
    272     if (empty($lang) || $lang == 'auto') { 
    273        $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); 
    274        $lang = str_replace('-', '_', $accept_langs[0]); 
    275      } 
    276  
    277     if (empty($rcube_languages)) { 
    278       @include(INSTALL_PATH . 'program/localization/index.inc'); 
    279     } 
    280  
    281     // check if we have an alias for that language 
    282     if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) { 
    283       $lang = $rcube_language_aliases[$lang]; 
    284     } 
    285     // try the first two chars 
    286     else if (!isset($rcube_languages[$lang])) { 
    287       $short = substr($lang, 0, 2); 
    288  
    289       // check if we have an alias for the short language code 
    290       if (!isset($rcube_languages[$short]) && isset($rcube_language_aliases[$short])) { 
    291         $lang = $rcube_language_aliases[$short]; 
    292       } 
    293       // expand 'nn' to 'nn_NN' 
    294       else if (!isset($rcube_languages[$short])) { 
    295         $lang = $short.'_'.strtoupper($short); 
    296       } 
    297     } 
    298  
    299     if (!isset($rcube_languages[$lang]) || !is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { 
    300       $lang = 'en_US'; 
    301     } 
    302  
    303     return $lang; 
    304   } 
    305  
    306  
    307   /** 
    308    * Get the current database connection 
    309    * 
    310    * @return rcube_mdb2  Database connection object 
    311    */ 
    312   public function get_dbh() 
    313   { 
    314     if (!$this->db) { 
    315       $config_all = $this->config->all(); 
    316  
    317       $this->db = new rcube_mdb2($config_all['db_dsnw'], $config_all['db_dsnr'], $config_all['db_persistent']); 
    318       $this->db->sqlite_initials = INSTALL_PATH . 'SQL/sqlite.initial.sql'; 
    319       $this->db->set_debug((bool)$config_all['sql_debug']); 
    320     } 
    321  
    322     return $this->db; 
    323   } 
    324  
    325  
    326   /** 
    327    * Get global handle for memcache access 
    328    * 
    329    * @return object Memcache 
    330    */ 
    331   public function get_memcache() 
    332   { 
    333     if (!isset($this->memcache)) { 
    334       // no memcache support in PHP 
    335       if (!class_exists('Memcache')) { 
    336         $this->memcache = false; 
    337         return false; 
    338       } 
    339  
    340       $this->memcache = new Memcache; 
    341       $this->mc_available = 0; 
    342        
    343       // add alll configured hosts to pool 
    344       $pconnect = $this->config->get('memcache_pconnect', true); 
    345       foreach ($this->config->get('memcache_hosts', array()) as $host) { 
    346         list($host, $port) = explode(':', $host); 
    347         if (!$port) $port = 11211; 
    348         $this->mc_available += intval($this->memcache->addServer($host, $port, $pconnect, 1, 1, 15, false, array($this, 'memcache_failure'))); 
    349       } 
    350        
    351       // test connection and failover (will result in $this->mc_available == 0 on complete failure) 
    352       $this->memcache->increment('__CONNECTIONTEST__', 1);  // NOP if key doesn't exist 
    353  
    354       if (!$this->mc_available) 
    355         $this->memcache = false; 
    356     } 
    357  
    358     return $this->memcache; 
    359   } 
    360    
    361   /** 
    362    * Callback for memcache failure 
    363    */ 
    364   public function memcache_failure($host, $port) 
    365   { 
    366     static $seen = array(); 
    367      
    368     // only report once 
    369     if (!$seen["$host:$port"]++) { 
    370       $this->mc_available--; 
    371       raise_error(array('code' => 604, 'type' => 'db', 
    372         'line' => __LINE__, 'file' => __FILE__, 
    373         'message' => "Memcache failure on host $host:$port"), 
    374         true, false); 
    375     } 
    376   } 
    377  
    378  
    379   /** 
    380    * Initialize and get cache object 
    381    * 
    382    * @param string $name   Cache identifier 
    383    * @param string $type   Cache type ('db', 'apc' or 'memcache') 
    384    * @param int    $ttl    Expiration time for cache items in seconds 
    385    * @param bool   $packed Enables/disables data serialization 
    386    * 
    387    * @return rcube_cache Cache object 
    388    */ 
    389   public function get_cache($name, $type='db', $ttl=0, $packed=true) 
    390   { 
    391     if (!isset($this->caches[$name])) { 
    392       $this->caches[$name] = new rcube_cache($type, $_SESSION['user_id'], $name, $ttl, $packed); 
    393     } 
    394  
    395     return $this->caches[$name]; 
    396162  } 
    397163 
     
    426192    } 
    427193    else if ($id === '0') { 
    428       $contacts = new rcube_contacts($this->db, $this->user->ID); 
     194      $contacts = new rcube_contacts($this->db, $this->get_user_id()); 
    429195    } 
    430196    else { 
     
    447213 
    448214    if (!$contacts) { 
    449       raise_error(array( 
     215      self::raise_error(array( 
    450216        'code' => 700, 'type' => 'php', 
    451217        'file' => __FILE__, 'line' => __LINE__, 
     
    482248    if ($abook_type != 'ldap') { 
    483249      if (!isset($this->address_books['0'])) 
    484         $this->address_books['0'] = new rcube_contacts($this->db, $this->user->ID); 
     250        $this->address_books['0'] = new rcube_contacts($this->db, $this->get_user_id()); 
    485251      $list['0'] = array( 
    486252        'id'       => '0', 
    487         'name'     => rcube_label('personaladrbook'), 
     253        'name'     => $this->gettext('personaladrbook'), 
    488254        'groups'   => $this->address_books['0']->groups, 
    489255        'readonly' => $this->address_books['0']->readonly, 
     
    533299   * 
    534300   * @param boolean True if this request is loaded in a (i)frame 
    535    * @return rcube_template Reference to HTML output object 
     301   * @return rcube_output_html Reference to HTML output object 
    536302   */ 
    537303  public function load_gui($framed = false) 
    538304  { 
    539305    // init output page 
    540     if (!($this->output instanceof rcube_template)) 
    541       $this->output = new rcube_template($this->task, $framed); 
     306    if (!($this->output instanceof rcube_output_html)) 
     307      $this->output = new rcube_output_html($this->task, $framed); 
    542308 
    543309    // set keep-alive/check-recent interval 
     
    566332   * Create an output object for JSON responses 
    567333   * 
    568    * @return rcube_json_output Reference to JSON output object 
     334   * @return rcube_output_json Reference to JSON output object 
    569335   */ 
    570336  public function json_init() 
    571337  { 
    572     if (!($this->output instanceof rcube_json_output)) 
    573       $this->output = new rcube_json_output($this->task); 
     338    if (!($this->output instanceof rcube_output_json)) 
     339      $this->output = new rcube_output_json($this->task); 
    574340 
    575341    return $this->output; 
    576   } 
    577  
    578  
    579   /** 
    580    * Create SMTP object and connect to server 
    581    * 
    582    * @param boolean True if connection should be established 
    583    */ 
    584   public function smtp_init($connect = false) 
    585   { 
    586     $this->smtp = new rcube_smtp(); 
    587  
    588     if ($connect) 
    589       $this->smtp->connect(); 
    590   } 
    591  
    592  
    593   /** 
    594    * Initialize and get storage object 
    595    * 
    596    * @return rcube_storage Storage object 
    597    */ 
    598   public function get_storage() 
    599   { 
    600     // already initialized 
    601     if (!is_object($this->storage)) { 
    602       $this->storage_init(); 
    603     } 
    604  
    605     return $this->storage; 
    606   } 
    607  
    608  
    609   /** 
    610    * Connect to the IMAP server with stored session data. 
    611    * 
    612    * @return bool True on success, False on error 
    613    * @deprecated 
    614    */ 
    615   public function imap_connect() 
    616   { 
    617     return $this->storage_connect(); 
    618   } 
    619  
    620  
    621   /** 
    622    * Initialize IMAP object. 
    623    * 
    624    * @deprecated 
    625    */ 
    626   public function imap_init() 
    627   { 
    628     $this->storage_init(); 
    629   } 
    630  
    631  
    632   /** 
    633    * Initialize storage object 
    634    */ 
    635   public function storage_init() 
    636   { 
    637     // already initialized 
    638     if (is_object($this->storage)) { 
    639       return; 
    640     } 
    641  
    642     $driver = $this->config->get('storage_driver', 'imap'); 
    643     $driver_class = "rcube_{$driver}"; 
    644  
    645     if (!class_exists($driver_class)) { 
    646       raise_error(array( 
    647         'code' => 700, 'type' => 'php', 
    648         'file' => __FILE__, 'line' => __LINE__, 
    649         'message' => "Storage driver class ($driver) not found!"), 
    650         true, true); 
    651     } 
    652  
    653     // Initialize storage object 
    654     $this->storage = new $driver_class; 
    655  
    656     // for backward compat. (deprecated, will be removed) 
    657     $this->imap = $this->storage; 
    658  
    659     // enable caching of mail data 
    660     $storage_cache  = $this->config->get("{$driver}_cache"); 
    661     $messages_cache = $this->config->get('messages_cache'); 
    662     // for backward compatybility 
    663     if ($storage_cache === null && $messages_cache === null && $this->config->get('enable_caching')) { 
    664         $storage_cache  = 'db'; 
    665         $messages_cache = true; 
    666     } 
    667  
    668     if ($storage_cache) 
    669         $this->storage->set_caching($storage_cache); 
    670     if ($messages_cache) 
    671         $this->storage->set_messages_caching(true); 
    672  
    673     // set pagesize from config 
    674     $pagesize = $this->config->get('mail_pagesize'); 
    675     if (!$pagesize) { 
    676         $pagesize = $this->config->get('pagesize', 50); 
    677     } 
    678     $this->storage->set_pagesize($pagesize); 
    679  
    680     // set class options 
    681     $options = array( 
    682       'auth_type'   => $this->config->get("{$driver}_auth_type", 'check'), 
    683       'auth_cid'    => $this->config->get("{$driver}_auth_cid"), 
    684       'auth_pw'     => $this->config->get("{$driver}_auth_pw"), 
    685       'debug'       => (bool) $this->config->get("{$driver}_debug"), 
    686       'force_caps'  => (bool) $this->config->get("{$driver}_force_caps"), 
    687       'timeout'     => (int) $this->config->get("{$driver}_timeout"), 
    688       'skip_deleted' => (bool) $this->config->get('skip_deleted'), 
    689       'driver'      => $driver, 
    690     ); 
    691  
    692     if (!empty($_SESSION['storage_host'])) { 
    693       $options['host']     = $_SESSION['storage_host']; 
    694       $options['user']     = $_SESSION['username']; 
    695       $options['port']     = $_SESSION['storage_port']; 
    696       $options['ssl']      = $_SESSION['storage_ssl']; 
    697       $options['password'] = $this->decrypt($_SESSION['password']); 
    698       // set 'imap_host' for backwards compatibility 
    699       $_SESSION[$driver.'_host'] = &$_SESSION['storage_host']; 
    700     } 
    701  
    702     $options = $this->plugins->exec_hook("storage_init", $options); 
    703  
    704     $this->storage->set_options($options); 
    705     $this->set_storage_prop(); 
    706   } 
    707  
    708  
    709   /** 
    710    * Connect to the mail storage server with stored session data 
    711    * 
    712    * @return bool True on success, False on error 
    713    */ 
    714   public function storage_connect() 
    715   { 
    716     $storage = $this->get_storage(); 
    717  
    718     if ($_SESSION['storage_host'] && !$storage->is_connected()) { 
    719       $host = $_SESSION['storage_host']; 
    720       $user = $_SESSION['username']; 
    721       $port = $_SESSION['storage_port']; 
    722       $ssl  = $_SESSION['storage_ssl']; 
    723       $pass = $this->decrypt($_SESSION['password']); 
    724  
    725       if (!$storage->connect($host, $user, $pass, $port, $ssl)) { 
    726         if ($this->output) 
    727           $this->output->show_message($storage->get_error_code() == -1 ? 'storageerror' : 'sessionerror', 'error'); 
    728       } 
    729       else { 
    730         $this->set_storage_prop(); 
    731       } 
    732     } 
    733  
    734     return $storage->is_connected(); 
    735342  } 
    736343 
     
    758365    } 
    759366 
    760     ini_set('session.cookie_secure', rcube_https_check()); 
     367    ini_set('session.cookie_secure', rcube_ui::https_check()); 
    761368    ini_set('session.name', $sess_name ? $sess_name : 'roundcube_sessid'); 
    762369    ini_set('session.use_cookies', 1); 
     
    767374    $this->session = new rcube_session($this->get_dbh(), $this->config); 
    768375 
    769     $this->session->register_gc_handler('rcmail_temp_gc'); 
     376    $this->session->register_gc_handler(array($this, 'temp_gc')); 
    770377    $this->session->register_gc_handler(array($this, 'cache_gc')); 
    771378 
     
    843450        return false; 
    844451      } 
    845     else if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host'])) 
     452    else if (!empty($config['default_host']) && $host != self::parse_host($config['default_host'])) 
    846453      return false; 
    847454 
     
    867474    if (!empty($config['username_domain']) && strpos($username, '@') === false) { 
    868475      if (is_array($config['username_domain']) && isset($config['username_domain'][$host])) 
    869         $username .= '@'.rcube_parse_host($config['username_domain'][$host], $host); 
     476        $username .= '@'.self::parse_host($config['username_domain'][$host], $host); 
    870477      else if (is_string($config['username_domain'])) 
    871         $username .= '@'.rcube_parse_host($config['username_domain'], $host); 
     478        $username .= '@'.self::parse_host($config['username_domain'], $host); 
    872479    } 
    873480 
     
    930537      } 
    931538      else { 
    932         raise_error(array( 
     539        self::raise_error(array( 
    933540          'code' => 620, 'type' => 'php', 
    934541          'file' => __FILE__, 'line' => __LINE__, 
     
    938545    } 
    939546    else { 
    940       raise_error(array( 
     547      self::raise_error(array( 
    941548        'code' => 621, 'type' => 'php', 
    942549        'file' => __FILE__, 'line' => __LINE__, 
     
    985592 
    986593  /** 
    987    * Set storage parameters. 
    988    * This must be done AFTER connecting to the server! 
    989    */ 
    990   private function set_storage_prop() 
    991   { 
    992     $storage = $this->get_storage(); 
    993  
    994     $storage->set_charset($this->config->get('default_charset', RCMAIL_CHARSET)); 
    995  
    996     if ($default_folders = $this->config->get('default_folders')) { 
    997       $storage->set_default_folders($default_folders); 
    998     } 
    999     if (isset($_SESSION['mbox'])) { 
    1000       $storage->set_folder($_SESSION['mbox']); 
    1001     } 
    1002     if (isset($_SESSION['page'])) { 
    1003       $storage->set_page($_SESSION['page']); 
    1004     } 
    1005   } 
    1006  
    1007  
    1008   /** 
    1009594   * Auto-select IMAP host based on the posted login information 
    1010595   * 
     
    1017602 
    1018603    if (is_array($default_host)) { 
    1019       $post_host = get_input_value('_host', RCUBE_INPUT_POST); 
     604      $post_host = rcube_ui::get_input_value('_host', rcube_ui::INPUT_POST); 
    1020605 
    1021606      // direct match in default_host array 
     
    1025610 
    1026611      // try to select host by mail domain 
    1027       list($user, $domain) = explode('@', get_input_value('_user', RCUBE_INPUT_POST)); 
     612      list($user, $domain) = explode('@', rcube_ui::get_input_value('_user', rcube_ui::INPUT_POST)); 
    1028613      if (!empty($domain)) { 
    1029614        foreach ($default_host as $storage_host => $mail_domains) { 
     
    1046631    } 
    1047632    else if (empty($default_host)) { 
    1048       $host = get_input_value('_host', RCUBE_INPUT_POST); 
     633      $host = rcube_ui::get_input_value('_host', rcube_ui::INPUT_POST); 
    1049634    } 
    1050635    else 
    1051       $host = rcube_parse_host($default_host); 
     636      $host = self::parse_host($default_host); 
    1052637 
    1053638    return $host; 
    1054   } 
    1055  
    1056  
    1057   /** 
    1058    * Get localized text in the desired language 
    1059    * 
    1060    * @param mixed   $attrib  Named parameters array or label name 
    1061    * @param string  $domain  Label domain (plugin) name 
    1062    * 
    1063    * @return string Localized text 
    1064    */ 
    1065   public function gettext($attrib, $domain=null) 
    1066   { 
    1067     // load localization files if not done yet 
    1068     if (empty($this->texts)) 
    1069       $this->load_language(); 
    1070  
    1071     // extract attributes 
    1072     if (is_string($attrib)) 
    1073       $attrib = array('name' => $attrib); 
    1074  
    1075     $name = $attrib['name'] ? $attrib['name'] : ''; 
    1076  
    1077     // attrib contain text values: use them from now 
    1078     if (($setval = $attrib[strtolower($_SESSION['language'])]) || ($setval = $attrib['en_us'])) 
    1079         $this->texts[$name] = $setval; 
    1080  
    1081     // check for text with domain 
    1082     if ($domain && ($text = $this->texts[$domain.'.'.$name])) 
    1083       ; 
    1084     // text does not exist 
    1085     else if (!($text = $this->texts[$name])) { 
    1086       return "[$name]"; 
    1087     } 
    1088  
    1089     // replace vars in text 
    1090     if (is_array($attrib['vars'])) { 
    1091       foreach ($attrib['vars'] as $var_key => $var_value) 
    1092         $text = str_replace($var_key[0]!='$' ? '$'.$var_key : $var_key, $var_value, $text); 
    1093     } 
    1094  
    1095     // format output 
    1096     if (($attrib['uppercase'] && strtolower($attrib['uppercase']=='first')) || $attrib['ucfirst']) 
    1097       return ucfirst($text); 
    1098     else if ($attrib['uppercase']) 
    1099       return mb_strtoupper($text); 
    1100     else if ($attrib['lowercase']) 
    1101       return mb_strtolower($text); 
    1102  
    1103     return strtr($text, array('\n' => "\n")); 
    1104   } 
    1105  
    1106  
    1107   /** 
    1108    * Check if the given text label exists 
    1109    * 
    1110    * @param string  $name       Label name 
    1111    * @param string  $domain     Label domain (plugin) name or '*' for all domains 
    1112    * @param string  $ref_domain Sets domain name if label is found 
    1113    * 
    1114    * @return boolean True if text exists (either in the current language or in en_US) 
    1115    */ 
    1116   public function text_exists($name, $domain = null, &$ref_domain = null) 
    1117   { 
    1118     // load localization files if not done yet 
    1119     if (empty($this->texts)) 
    1120       $this->load_language(); 
    1121  
    1122     if (isset($this->texts[$name])) { 
    1123         $ref_domain = ''; 
    1124         return true; 
    1125     } 
    1126  
    1127     // any of loaded domains (plugins) 
    1128     if ($domain == '*') { 
    1129       foreach ($this->plugins->loaded_plugins() as $domain) 
    1130         if (isset($this->texts[$domain.'.'.$name])) { 
    1131           $ref_domain = $domain; 
    1132           return true; 
    1133         } 
    1134     } 
    1135     // specified domain 
    1136     else if ($domain) { 
    1137       $ref_domain = $domain; 
    1138       return isset($this->texts[$domain.'.'.$name]); 
    1139     } 
    1140  
    1141     return false; 
    1142   } 
    1143  
    1144   /** 
    1145    * Load a localization package 
    1146    * 
    1147    * @param string Language ID 
    1148    */ 
    1149   public function load_language($lang = null, $add = array()) 
    1150   { 
    1151     $lang = $this->language_prop(($lang ? $lang : $_SESSION['language'])); 
    1152  
    1153     // load localized texts 
    1154     if (empty($this->texts) || $lang != $_SESSION['language']) { 
    1155       $this->texts = array(); 
    1156  
    1157       // handle empty lines after closing PHP tag in localization files 
    1158       ob_start(); 
    1159  
    1160       // get english labels (these should be complete) 
    1161       @include(INSTALL_PATH . 'program/localization/en_US/labels.inc'); 
    1162       @include(INSTALL_PATH . 'program/localization/en_US/messages.inc'); 
    1163  
    1164       if (is_array($labels)) 
    1165         $this->texts = $labels; 
    1166       if (is_array($messages)) 
    1167         $this->texts = array_merge($this->texts, $messages); 
    1168  
    1169       // include user language files 
    1170       if ($lang != 'en' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { 
    1171         include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc'); 
    1172         include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc'); 
    1173  
    1174         if (is_array($labels)) 
    1175           $this->texts = array_merge($this->texts, $labels); 
    1176         if (is_array($messages)) 
    1177           $this->texts = array_merge($this->texts, $messages); 
    1178       } 
    1179  
    1180       ob_end_clean(); 
    1181  
    1182       $_SESSION['language'] = $lang; 
    1183     } 
    1184  
    1185     // append additional texts (from plugin) 
    1186     if (is_array($add) && !empty($add)) 
    1187       $this->texts += $add; 
    1188   } 
    1189  
    1190  
    1191   /** 
    1192    * Read directory program/localization and return a list of available languages 
    1193    * 
    1194    * @return array List of available localizations 
    1195    */ 
    1196   public function list_languages() 
    1197   { 
    1198     static $sa_languages = array(); 
    1199  
    1200     if (!sizeof($sa_languages)) { 
    1201       @include(INSTALL_PATH . 'program/localization/index.inc'); 
    1202  
    1203       if ($dh = @opendir(INSTALL_PATH . 'program/localization')) { 
    1204         while (($name = readdir($dh)) !== false) { 
    1205           if ($name[0] == '.' || !is_dir(INSTALL_PATH . 'program/localization/' . $name)) 
    1206             continue; 
    1207  
    1208           if ($label = $rcube_languages[$name]) 
    1209             $sa_languages[$name] = $label; 
    1210         } 
    1211         closedir($dh); 
    1212       } 
    1213     } 
    1214  
    1215     return $sa_languages; 
    1216639  } 
    1217640 
     
    1261684 
    1262685  /** 
    1263    * Function to be executed in script shutdown 
    1264    * Registered with register_shutdown_function() 
    1265    */ 
    1266   public function shutdown() 
    1267   { 
    1268     foreach ($this->shutdown_functions as $function) 
    1269       call_user_func($function); 
    1270  
    1271     if (is_object($this->smtp)) 
    1272       $this->smtp->disconnect(); 
    1273  
    1274     foreach ($this->address_books as $book) { 
    1275       if (is_object($book) && is_a($book, 'rcube_addressbook')) 
    1276         $book->close(); 
    1277     } 
    1278  
    1279     foreach ($this->caches as $cache) { 
    1280         if (is_object($cache)) 
    1281             $cache->close(); 
    1282     } 
    1283  
    1284     if (is_object($this->storage)) { 
    1285         if ($this->expunge_cache) 
    1286             $this->storage->expunge_cache(); 
    1287       $this->storage->close(); 
    1288   } 
    1289  
    1290     // before closing the database connection, write session data 
    1291     if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) { 
    1292       session_write_close(); 
    1293     } 
    1294  
    1295     // write performance stats to logs/console 
    1296     if ($this->config->get('devel_mode')) { 
    1297       if (function_exists('memory_get_usage')) 
    1298         $mem = show_bytes(memory_get_usage()); 
    1299       if (function_exists('memory_get_peak_usage')) 
    1300         $mem .= '/'.show_bytes(memory_get_peak_usage()); 
    1301  
    1302       $log = $this->task . ($this->action ? '/'.$this->action : '') . ($mem ? " [$mem]" : ''); 
    1303       if (defined('RCMAIL_START')) 
    1304         rcube_print_time(RCMAIL_START, $log); 
    1305       else 
    1306         console($log); 
    1307     } 
    1308   } 
    1309  
    1310  
    1311   /** 
    1312    * Registers shutdown function to be executed on shutdown. 
    1313    * The functions will be executed before destroying any 
    1314    * objects like smtp, imap, session, etc. 
    1315    * 
    1316    * @param callback Function callback 
    1317    */ 
    1318   public function add_shutdown_function($function) 
    1319   { 
    1320     $this->shutdown_functions[] = $function; 
    1321   } 
    1322  
    1323  
    1324   /** 
    1325686   * Garbage collector for cache entries. 
    1326687   * Set flag to expunge caches on shutdown 
     
    1343704    $sess_id = $_COOKIE[ini_get('session.name')]; 
    1344705    if (!$sess_id) $sess_id = session_id(); 
    1345     $plugin = $this->plugins->exec_hook('request_token', array('value' => md5('RT' . $this->user->ID . $this->config->get('des_key') . $sess_id))); 
     706    $plugin = $this->plugins->exec_hook('request_token', array('value' => md5('RT' . $this->get_user_id() . $this->config->get('des_key') . $sess_id))); 
    1346707    return $plugin['value']; 
    1347708  } 
     
    1354715   * @return boolean True if request token is valid false if not 
    1355716   */ 
    1356   public function check_request($mode = RCUBE_INPUT_POST) 
    1357   { 
    1358     $token = get_input_value('_token', $mode); 
     717  public function check_request($mode = rcube_ui::INPUT_POST) 
     718  { 
     719    $token = rcube_ui::get_input_value('_token', $mode); 
    1359720    $sess_id = $_COOKIE[ini_get('session.name')]; 
    1360721    return !empty($sess_id) && $token == $this->get_request_token(); 
     
    1383744  } 
    1384745 
    1385  
    1386   /** 
    1387    * Encrypt using 3DES 
    1388    * 
    1389    * @param string $clear clear text input 
    1390    * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' 
    1391    * @param boolean $base64 whether or not to base64_encode() the result before returning 
    1392    * 
    1393    * @return string encrypted text 
    1394    */ 
    1395   public function encrypt($clear, $key = 'des_key', $base64 = true) 
    1396   { 
    1397     if (!$clear) 
    1398       return ''; 
    1399     /*- 
    1400      * Add a single canary byte to the end of the clear text, which 
    1401      * will help find out how much of padding will need to be removed 
    1402      * upon decryption; see http://php.net/mcrypt_generic#68082 
    1403      */ 
    1404     $clear = pack("a*H2", $clear, "80"); 
    1405  
    1406     if (function_exists('mcrypt_module_open') && 
    1407         ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) 
    1408     { 
    1409       $iv = $this->create_iv(mcrypt_enc_get_iv_size($td)); 
    1410       mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); 
    1411       $cipher = $iv . mcrypt_generic($td, $clear); 
    1412       mcrypt_generic_deinit($td); 
    1413       mcrypt_module_close($td); 
    1414     } 
    1415     else { 
    1416       @include_once 'des.inc'; 
    1417  
    1418       if (function_exists('des')) { 
    1419         $des_iv_size = 8; 
    1420         $iv = $this->create_iv($des_iv_size); 
    1421         $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv); 
    1422       } 
    1423       else { 
    1424         raise_error(array( 
    1425           'code' => 500, 'type' => 'php', 
    1426           'file' => __FILE__, 'line' => __LINE__, 
    1427           'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available" 
    1428         ), true, true); 
    1429       } 
    1430     } 
    1431  
    1432     return $base64 ? base64_encode($cipher) : $cipher; 
    1433   } 
    1434  
    1435   /** 
    1436    * Decrypt 3DES-encrypted string 
    1437    * 
    1438    * @param string $cipher encrypted text 
    1439    * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key' 
    1440    * @param boolean $base64 whether or not input is base64-encoded 
    1441    * 
    1442    * @return string decrypted text 
    1443    */ 
    1444   public function decrypt($cipher, $key = 'des_key', $base64 = true) 
    1445   { 
    1446     if (!$cipher) 
    1447       return ''; 
    1448  
    1449     $cipher = $base64 ? base64_decode($cipher) : $cipher; 
    1450  
    1451     if (function_exists('mcrypt_module_open') && 
    1452         ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, ""))) 
    1453     { 
    1454       $iv_size = mcrypt_enc_get_iv_size($td); 
    1455       $iv = substr($cipher, 0, $iv_size); 
    1456  
    1457       // session corruption? (#1485970) 
    1458       if (strlen($iv) < $iv_size) 
    1459         return ''; 
    1460  
    1461       $cipher = substr($cipher, $iv_size); 
    1462       mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); 
    1463       $clear = mdecrypt_generic($td, $cipher); 
    1464       mcrypt_generic_deinit($td); 
    1465       mcrypt_module_close($td); 
    1466     } 
    1467     else { 
    1468       @include_once 'des.inc'; 
    1469  
    1470       if (function_exists('des')) { 
    1471         $des_iv_size = 8; 
    1472         $iv = substr($cipher, 0, $des_iv_size); 
    1473         $cipher = substr($cipher, $des_iv_size); 
    1474         $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv); 
    1475       } 
    1476       else { 
    1477         raise_error(array( 
    1478           'code' => 500, 'type' => 'php', 
    1479           'file' => __FILE__, 'line' => __LINE__, 
    1480           'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available" 
    1481         ), true, true); 
    1482       } 
    1483     } 
    1484  
    1485     /*- 
    1486      * Trim PHP's padding and the canary byte; see note in 
    1487      * rcmail::encrypt() and http://php.net/mcrypt_generic#68082 
    1488      */ 
    1489     $clear = substr(rtrim($clear, "\0"), 0, -1); 
    1490  
    1491     return $clear; 
    1492   } 
    1493  
    1494   /** 
    1495    * Generates encryption initialization vector (IV) 
    1496    * 
    1497    * @param int Vector size 
    1498    * @return string Vector string 
    1499    */ 
    1500   private function create_iv($size) 
    1501   { 
    1502     // mcrypt_create_iv() can be slow when system lacks entrophy 
    1503     // we'll generate IV vector manually 
    1504     $iv = ''; 
    1505     for ($i = 0; $i < $size; $i++) 
    1506         $iv .= chr(mt_rand(0, 255)); 
    1507     return $iv; 
    1508   } 
    1509746 
    1510747  /** 
     
    1537774 
    1538775  /** 
    1539    * Construct shell command, execute it and return output as string. 
    1540    * Keywords {keyword} are replaced with arguments 
    1541    * 
    1542    * @param $cmd Format string with {keywords} to be replaced 
    1543    * @param $values (zero, one or more arrays can be passed) 
    1544    * @return output of command. shell errors not detectable 
    1545    */ 
    1546   public static function exec(/* $cmd, $values1 = array(), ... */) 
    1547   { 
    1548     $args = func_get_args(); 
    1549     $cmd = array_shift($args); 
    1550     $values = $replacements = array(); 
    1551  
    1552     // merge values into one array 
    1553     foreach ($args as $arg) 
    1554       $values += (array)$arg; 
    1555  
    1556     preg_match_all('/({(-?)([a-z]\w*)})/', $cmd, $matches, PREG_SET_ORDER); 
    1557     foreach ($matches as $tags) { 
    1558       list(, $tag, $option, $key) = $tags; 
    1559       $parts = array(); 
    1560  
    1561       if ($option) { 
    1562         foreach ((array)$values["-$key"] as $key => $value) { 
    1563           if ($value === true || $value === false || $value === null) 
    1564             $parts[] = $value ? $key : ""; 
    1565           else foreach ((array)$value as $val) 
    1566             $parts[] = "$key " . escapeshellarg($val); 
    1567         } 
    1568       } 
    1569       else { 
    1570         foreach ((array)$values[$key] as $value) 
    1571           $parts[] = escapeshellarg($value); 
    1572       } 
    1573  
    1574       $replacements[$tag] = join(" ", $parts); 
    1575     } 
    1576  
    1577     // use strtr behaviour of going through source string once 
    1578     $cmd = strtr($cmd, $replacements); 
    1579  
    1580     return (string)shell_exec($cmd); 
    1581   } 
    1582  
     776   * Function to be executed in script shutdown 
     777   */ 
     778  public function shutdown() 
     779  { 
     780    parent::shutdown(); 
     781 
     782    foreach ($this->address_books as $book) { 
     783      if (is_object($book) && is_a($book, 'rcube_addressbook')) 
     784        $book->close(); 
     785    } 
     786 
     787    // before closing the database connection, write session data 
     788    if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) { 
     789      session_write_close(); 
     790    } 
     791 
     792    // write performance stats to logs/console 
     793    if ($this->config->get('devel_mode')) { 
     794      if (function_exists('memory_get_usage')) 
     795        $mem = rcube_ui::show_bytes(memory_get_usage()); 
     796      if (function_exists('memory_get_peak_usage')) 
     797        $mem .= '/'.rcube_ui::show_bytes(memory_get_peak_usage()); 
     798 
     799      $log = $this->task . ($this->action ? '/'.$this->action : '') . ($mem ? " [$mem]" : ''); 
     800      if (defined('RCMAIL_START')) 
     801        self::print_timer(RCMAIL_START, $log); 
     802      else 
     803        self::console($log); 
     804    } 
     805  } 
    1583806 
    1584807  /** 
     
    1597820 
    1598821    setcookie($name, $value, $exp, $cookie['path'], $cookie['domain'], 
    1599       rcube_https_check(), true); 
     822      rcube_ui::https_check(), true); 
    1600823  } 
    1601824 
     
    1728951  } 
    1729952 
     953 
     954    /** 
     955     * Overwrite action variable 
     956     * 
     957     * @param string New action value 
     958     */ 
     959    public function overwrite_action($action) 
     960    { 
     961        $this->action = $action; 
     962        $this->output->set_env('action', $action); 
     963    } 
     964 
     965 
     966    /** 
     967     * Send the given message using the configured method. 
     968     * 
     969     * @param object $message    Reference to Mail_MIME object 
     970     * @param string $from       Sender address string 
     971     * @param array  $mailto     Array of recipient address strings 
     972     * @param array  $smtp_error SMTP error array (reference) 
     973     * @param string $body_file  Location of file with saved message body (reference), 
     974     *                           used when delay_file_io is enabled 
     975     * @param array  $smtp_opts  SMTP options (e.g. DSN request) 
     976     * 
     977     * @return boolean Send status. 
     978     */ 
     979    public function deliver_message(&$message, $from, $mailto, &$smtp_error, &$body_file = null, $smtp_opts = null) 
     980    { 
     981        $headers = $message->headers(); 
     982 
     983        // send thru SMTP server using custom SMTP library 
     984        if ($this->config->get('smtp_server')) { 
     985            // generate list of recipients 
     986            $a_recipients = array($mailto); 
     987 
     988            if (strlen($headers['Cc'])) 
     989                $a_recipients[] = $headers['Cc']; 
     990            if (strlen($headers['Bcc'])) 
     991                $a_recipients[] = $headers['Bcc']; 
     992 
     993            // clean Bcc from header for recipients 
     994            $send_headers = $headers; 
     995            unset($send_headers['Bcc']); 
     996            // here too, it because txtHeaders() below use $message->_headers not only $send_headers 
     997            unset($message->_headers['Bcc']); 
     998 
     999            $smtp_headers = $message->txtHeaders($send_headers, true); 
     1000 
     1001            if ($message->getParam('delay_file_io')) { 
     1002                // use common temp dir 
     1003                $temp_dir = $this->config->get('temp_dir'); 
     1004                $body_file = tempnam($temp_dir, 'rcmMsg'); 
     1005                if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) { 
     1006                    self::raise_error(array('code' => 650, 'type' => 'php', 
     1007                        'file' => __FILE__, 'line' => __LINE__, 
     1008                        'message' => "Could not create message: ".$mime_result->getMessage()), 
     1009                        TRUE, FALSE); 
     1010                    return false; 
     1011                } 
     1012                $msg_body = fopen($body_file, 'r'); 
     1013            } 
     1014            else { 
     1015                $msg_body = $message->get(); 
     1016            } 
     1017 
     1018            // send message 
     1019            if (!is_object($this->smtp)) { 
     1020                $this->smtp_init(true); 
     1021            } 
     1022 
     1023            $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $smtp_opts); 
     1024            $smtp_response = $this->smtp->get_response(); 
     1025            $smtp_error = $this->smtp->get_error(); 
     1026 
     1027            // log error 
     1028            if (!$sent) { 
     1029                self::raise_error(array('code' => 800, 'type' => 'smtp', 
     1030                    'line' => __LINE__, 'file' => __FILE__, 
     1031                    'message' => "SMTP error: ".join("\n", $smtp_response)), TRUE, FALSE); 
     1032            } 
     1033        } 
     1034        // send mail using PHP's mail() function 
     1035        else { 
     1036            // unset some headers because they will be added by the mail() function 
     1037            $headers_enc = $message->headers($headers); 
     1038            $headers_php = $message->_headers; 
     1039            unset($headers_php['To'], $headers_php['Subject']); 
     1040 
     1041            // reset stored headers and overwrite 
     1042            $message->_headers = array(); 
     1043            $header_str = $message->txtHeaders($headers_php); 
     1044 
     1045            // #1485779 
     1046            if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 
     1047                if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) { 
     1048                    $headers_enc['To'] = implode(', ', $m[1]); 
     1049                } 
     1050            } 
     1051 
     1052            $msg_body = $message->get(); 
     1053 
     1054            if (PEAR::isError($msg_body)) { 
     1055                self::raise_error(array('code' => 650, 'type' => 'php', 
     1056                    'file' => __FILE__, 'line' => __LINE__, 
     1057                    'message' => "Could not create message: ".$msg_body->getMessage()), 
     1058                    TRUE, FALSE); 
     1059            } 
     1060            else { 
     1061                $delim   = $this->config->header_delimiter(); 
     1062                $to      = $headers_enc['To']; 
     1063                $subject = $headers_enc['Subject']; 
     1064                $header_str = rtrim($header_str); 
     1065 
     1066                if ($delim != "\r\n") { 
     1067                    $header_str = str_replace("\r\n", $delim, $header_str); 
     1068                    $msg_body   = str_replace("\r\n", $delim, $msg_body); 
     1069                    $to         = str_replace("\r\n", $delim, $to); 
     1070                    $subject    = str_replace("\r\n", $delim, $subject); 
     1071                } 
     1072 
     1073                if (ini_get('safe_mode')) 
     1074                    $sent = mail($to, $subject, $msg_body, $header_str); 
     1075                else 
     1076                    $sent = mail($to, $subject, $msg_body, $header_str, "-f$from"); 
     1077            } 
     1078        } 
     1079 
     1080        if ($sent) { 
     1081            $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body)); 
     1082 
     1083            // remove MDN headers after sending 
     1084            unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']); 
     1085 
     1086            // get all recipients 
     1087            if ($headers['Cc']) 
     1088                $mailto .= $headers['Cc']; 
     1089            if ($headers['Bcc']) 
     1090                $mailto .= $headers['Bcc']; 
     1091            if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m)) 
     1092                $mailto = implode(', ', array_unique($m[1])); 
     1093 
     1094            if ($this->config->get('smtp_log')) { 
     1095                self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", 
     1096                    $this->user->get_username(), 
     1097                    $_SERVER['REMOTE_ADDR'], 
     1098                    $mailto, 
     1099                    !empty($smtp_response) ? join('; ', $smtp_response) : '')); 
     1100            } 
     1101        } 
     1102 
     1103        if (is_resource($msg_body)) { 
     1104            fclose($msg_body); 
     1105        } 
     1106 
     1107        $message->_headers = array(); 
     1108        $message->headers($headers); 
     1109 
     1110        return $sent; 
     1111    } 
     1112 
     1113 
     1114    /** 
     1115     * Unique Message-ID generator. 
     1116     * 
     1117     * @return string Message-ID 
     1118     */ 
     1119    public function gen_message_id() 
     1120    { 
     1121        $local_part  = md5(uniqid('rcmail'.mt_rand(),true)); 
     1122        $domain_part = $this->user->get_username('domain'); 
     1123 
     1124        // Try to find FQDN, some spamfilters doesn't like 'localhost' (#1486924) 
     1125        if (!preg_match('/\.[a-z]+$/i', $domain_part)) { 
     1126            foreach (array($_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME']) as $host) { 
     1127                $host = preg_replace('/:[0-9]+$/', '', $host); 
     1128                if ($host && preg_match('/\.[a-z]+$/i', $host)) { 
     1129                    $domain_part = $host; 
     1130                } 
     1131            } 
     1132        } 
     1133 
     1134        return sprintf('<%s@%s>', $local_part, $domain_part); 
     1135    } 
     1136 
     1137 
     1138    /** 
     1139     * Returns RFC2822 formatted current date in user's timezone 
     1140     * 
     1141     * @return string Date 
     1142     */ 
     1143    public function user_date() 
     1144    { 
     1145        // get user's timezone 
     1146        try { 
     1147            $tz   = new DateTimeZone($this->config->get('timezone')); 
     1148            $date = new DateTime('now', $tz); 
     1149        } 
     1150        catch (Exception $e) { 
     1151            $date = new DateTime(); 
     1152        } 
     1153 
     1154        return $date->format('r'); 
     1155    } 
     1156 
     1157 
     1158    /** 
     1159     * E-mail address validation. 
     1160     * 
     1161     * @param string $email Email address 
     1162     * @param boolean $dns_check True to check dns 
     1163     * 
     1164     * @return boolean True on success, False if address is invalid 
     1165     */ 
     1166    public function check_email($email, $dns_check=true) 
     1167    { 
     1168        // Check for invalid characters 
     1169        if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email)) { 
     1170            return false; 
     1171        } 
     1172 
     1173        // Check for length limit specified by RFC 5321 (#1486453) 
     1174        if (strlen($email) > 254) { 
     1175            return false; 
     1176        } 
     1177 
     1178        $email_array = explode('@', $email); 
     1179 
     1180        // Check that there's one @ symbol 
     1181        if (count($email_array) < 2) { 
     1182            return false; 
     1183        } 
     1184 
     1185        $domain_part = array_pop($email_array); 
     1186        $local_part  = implode('@', $email_array); 
     1187 
     1188        // from PEAR::Validate 
     1189        $regexp = '&^(?: 
     1190                ("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+")|                                         #1 quoted name 
     1191                ([-\w!\#\$%\&\'*+~/^`|{}=]+(?:\.[-\w!\#\$%\&\'*+~/^`|{}=]+)*))  #2 OR dot-atom (RFC5322) 
     1192                $&xi'; 
     1193 
     1194        if (!preg_match($regexp, $local_part)) { 
     1195            return false; 
     1196        } 
     1197 
     1198        // Check domain part 
     1199        if (preg_match('/^\[*(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]*$/', $domain_part)) { 
     1200            return true; // IP address 
     1201        } 
     1202        else { 
     1203            // If not an IP address 
     1204            $domain_array = explode('.', $domain_part); 
     1205            // Not enough parts to be a valid domain 
     1206            if (sizeof($domain_array) < 2) { 
     1207                return false; 
     1208            } 
     1209 
     1210            foreach ($domain_array as $part) { 
     1211                if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $part)) { 
     1212                    return false; 
     1213                } 
     1214            } 
     1215 
     1216            if (!$dns_check || !$this->config->get('email_dns_check')) { 
     1217                return true; 
     1218            } 
     1219 
     1220            if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' && version_compare(PHP_VERSION, '5.3.0', '<')) { 
     1221                $lookup = array(); 
     1222                @exec("nslookup -type=MX " . escapeshellarg($domain_part) . " 2>&1", $lookup); 
     1223                foreach ($lookup as $line) { 
     1224                    if (strpos($line, 'MX preference')) { 
     1225                        return true; 
     1226                    } 
     1227                } 
     1228                return false; 
     1229            } 
     1230 
     1231            // find MX record(s) 
     1232            if (getmxrr($domain_part, $mx_records)) { 
     1233                return true; 
     1234            } 
     1235 
     1236            // find any DNS record 
     1237            if (checkdnsrr($domain_part, 'ANY')) { 
     1238                return true; 
     1239            } 
     1240        } 
     1241 
     1242        return false; 
     1243    } 
     1244 
     1245 
     1246    /** 
     1247     * Write login data (name, ID, IP address) to the 'userlogins' log file. 
     1248     */ 
     1249    public function log_login() 
     1250    { 
     1251        if (!$this->config->get('log_logins')) { 
     1252            return; 
     1253        } 
     1254 
     1255        $user_name = $this->get_user_name(); 
     1256        $user_id   = $this->get_user_id(); 
     1257 
     1258        if (!$user_id) { 
     1259            return; 
     1260        } 
     1261 
     1262        self::write_log('userlogins', 
     1263            sprintf('Successful login for %s (ID: %d) from %s in session %s', 
     1264                $user_name, $user_id, self::remote_ip(), session_id())); 
     1265    } 
     1266 
     1267 
     1268    /** 
     1269     * Check whether the HTTP referer matches the current request 
     1270     * 
     1271     * @return boolean True if referer is the same host+path, false if not 
     1272     */ 
     1273    public static function check_referer() 
     1274    { 
     1275        $uri = parse_url($_SERVER['REQUEST_URI']); 
     1276        $referer = parse_url(rcube_request_header('Referer')); 
     1277        return $referer['host'] == rcube_request_header('Host') && $referer['path'] == $uri['path']; 
     1278    } 
     1279 
     1280 
     1281    /** 
     1282     * Garbage collector function for temp files. 
     1283     * Remove temp files older than two days 
     1284     */ 
     1285    public function temp_gc() 
     1286    { 
     1287        $tmp = unslashify($this->config->get('temp_dir')); 
     1288        $expire = mktime() - 172800;  // expire in 48 hours 
     1289 
     1290        if ($dir = opendir($tmp)) { 
     1291            while (($fname = readdir($dir)) !== false) { 
     1292                if ($fname{0} == '.') { 
     1293                    continue; 
     1294                } 
     1295 
     1296                if (filemtime($tmp.'/'.$fname) < $expire) { 
     1297                    @unlink($tmp.'/'.$fname); 
     1298                } 
     1299            } 
     1300 
     1301            closedir($dir); 
     1302        } 
     1303    } 
     1304 
    17301305} 
  • trunk/roundcubemail/program/include/rcube.php

    r5994 r6073  
    66 |                                                                       | 
    77 | This file is part of the Roundcube Webmail client                     | 
    8  | Copyright (C) 2008-2011, The Roundcube Dev Team                       | 
    9  | Copyright (C) 2011, Kolab Systems AG                                  | 
    10  | Licensed under the GNU GPL                                            | 
     8 | Copyright (C) 2008-2012, The Roundcube Dev Team                       | 
     9 | Copyright (C) 2011-2012, Kolab Systems AG                             | 
     10 |                                                                       | 
     11 | Licensed under the GNU General Public License version 3 or            | 
     12 | any later version with exceptions for skins & plugins.                | 
     13 | See the README file for a full license statement.                     | 
    1114 |                                                                       | 
    1215 | PURPOSE:                                                              | 
     
    101104  protected $caches = array(); 
    102105  protected $shutdown_functions = array(); 
     106  protected $expunge_cache = false; 
    103107 
    104108 
     
    769773    } 
    770774 
    771     if (is_object($this->storage)) 
     775    if (is_object($this->storage)) { 
     776      if ($this->expunge_cache) 
     777        $this->storage->expunge_cache(); 
    772778      $this->storage->close(); 
     779    } 
    773780  } 
    774781 
  • trunk/roundcubemail/program/include/rcube_addressbook.php

    r5871 r6073  
    212212    public function validate(&$save_data, $autofix = false) 
    213213    { 
     214        $rcmail = rcmail::get_instance(); 
     215 
    214216        // check validity of email addresses 
    215217        foreach ($this->get_col_values('email', $save_data, true) as $email) { 
    216218            if (strlen($email)) { 
    217                 if (!check_email(rcube_idn_to_ascii($email))) { 
    218                     $this->set_error(self::ERROR_VALIDATE, rcube_label(array('name' => 'emailformaterror', 'vars' => array('email' => $email)))); 
     219                if (!$rcmail->check_email(rcube_idn_to_ascii($email))) { 
     220                    $error = $rcmail->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email))); 
     221                    $this->set_error(self::ERROR_VALIDATE, $error); 
    219222                    return false; 
    220223                } 
  • trunk/roundcubemail/program/include/rcube_base_replacer.php

    r5994 r6073  
    77 | This file is part of the Roundcube Webmail client                     | 
    88 | Copyright (C) 2005-2012, The Roundcube Dev Team                       | 
    9  | Licensed under the GNU GPL                                            | 
     9 |                                                                       | 
     10 | Licensed under the GNU General Public License version 3 or            | 
     11 | any later version with exceptions for skins & plugins.                | 
     12 | See the README file for a full license statement.                     | 
    1013 |                                                                       | 
    1114 | PURPOSE:                                                              | 
  • trunk/roundcubemail/program/include/rcube_cache.php

    r5787 r6073  
    6767    function __construct($type, $userid, $prefix='', $ttl=0, $packed=true) 
    6868    { 
    69         $rcmail = rcmail::get_instance(); 
     69        $rcmail = rcube::get_instance(); 
    7070        $type   = strtolower($type); 
    7171 
     
    198198        if ($this->type == 'db' && $this->db) { 
    199199            $this->db->query( 
    200                 "DELETE FROM ".get_table_name('cache'). 
     200                "DELETE FROM ".$this->db->table_name('cache'). 
    201201                " WHERE user_id = ?". 
    202202                " AND cache_key LIKE ?". 
     
    275275            $sql_result = $this->db->limitquery( 
    276276                "SELECT cache_id, data, cache_key". 
    277                 " FROM ".get_table_name('cache'). 
     277                " FROM ".$this->db->table_name('cache'). 
    278278                " WHERE user_id = ?". 
    279279                " AND cache_key = ?". 
     
    331331        if ($data == 'N;') { 
    332332            $this->db->query( 
    333                 "DELETE FROM ".get_table_name('cache'). 
     333                "DELETE FROM ".$this->db->table_name('cache'). 
    334334                " WHERE user_id = ?". 
    335335                " AND cache_key = ?", 
     
    342342        if ($key_exists) { 
    343343            $result = $this->db->query( 
    344                 "UPDATE ".get_table_name('cache'). 
     344                "UPDATE ".$this->db->table_name('cache'). 
    345345                " SET created = ". $this->db->now().", data = ?". 
    346346                " WHERE user_id = ?". 
     
    353353            // so, no need to check if record exist (see rcube_cache::read_record()) 
    354354            $result = $this->db->query( 
    355                 "INSERT INTO ".get_table_name('cache'). 
     355                "INSERT INTO ".$this->db->table_name('cache'). 
    356356                " (created, user_id, cache_key, data)". 
    357357                " VALUES (".$this->db->now().", ?, ?, ?)", 
     
    417417 
    418418        $this->db->query( 
    419             "DELETE FROM ".get_table_name('cache'). 
     419            "DELETE FROM ".$this->db->table_name('cache'). 
    420420            " WHERE user_id = ?" . $where, 
    421421            $this->userid); 
  • trunk/roundcubemail/program/include/rcube_config.php

    r5815 r6073  
    8686        // fix default imap folders encoding 
    8787        foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder) 
    88             $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP'); 
     88            $this->prop[$folder] = rcube_charset::convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP'); 
    8989 
    9090        if (!empty($this->prop['default_folders'])) 
    9191            foreach ($this->prop['default_folders'] as $n => $folder) 
    92                 $this->prop['default_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP'); 
     92                $this->prop['default_folders'][$n] = rcube_charset::convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP'); 
    9393 
    9494        // set PHP error logging according to config 
     
    187187        } 
    188188 
    189         $rcmail = rcmail::get_instance(); 
     189        $rcmail = rcube::get_instance(); 
    190190 
    191191        if ($name == 'timezone' && isset($this->prop['_timezone_value'])) 
     
    301301        // Bomb out if the requested key does not exist 
    302302        if (!array_key_exists($key, $this->prop)) { 
    303             raise_error(array( 
     303            rcube::raise_error(array( 
    304304                'code' => 500, 'type' => 'php', 
    305305                'file' => __FILE__, 'line' => __LINE__, 
     
    312312        // Bomb out if the configured key is not exactly 24 bytes long 
    313313        if (strlen($key) != 24) { 
    314             raise_error(array( 
     314            rcube::raise_error(array( 
    315315                'code' => 500, 'type' => 'php', 
    316316                    'file' => __FILE__, 'line' => __LINE__, 
     
    336336                return $delim; 
    337337            else 
    338                 raise_error(array( 
     338                rcube::raise_error(array( 
    339339                    'code' => 500, 'type' => 'php', 
    340340                        'file' => __FILE__, 'line' => __LINE__, 
     
    371371        } 
    372372        else if (!empty($this->prop['mail_domain'])) 
    373             $domain = rcube_parse_host($this->prop['mail_domain']); 
     373            $domain = rcmail::parse_host($this->prop['mail_domain']); 
    374374 
    375375        if ($encode) 
  • trunk/roundcubemail/program/include/rcube_contacts.php

    r5958 r6073  
    154154 
    155155        $sql_result = $this->db->query( 
    156             "SELECT * FROM ".get_table_name($this->db_groups). 
     156            "SELECT * FROM ".$this->db->table_name($this->db_groups). 
    157157            " WHERE del<>1". 
    158158            " AND user_id=?". 
     
    179179    { 
    180180        $sql_result = $this->db->query( 
    181             "SELECT * FROM ".get_table_name($this->db_groups). 
     181            "SELECT * FROM ".$this->db->table_name($this->db_groups). 
    182182            " WHERE del<>1". 
    183183            " AND contactgroup_id=?". 
     
    215215 
    216216        if ($this->group_id) 
    217             $join = " LEFT JOIN ".get_table_name($this->db_groupmembers)." AS m". 
     217            $join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m". 
    218218                " ON (m.contact_id = c.".$this->primary_key.")"; 
    219219 
     
    229229 
    230230        $sql_result = $this->db->limitquery( 
    231             "SELECT * FROM ".get_table_name($this->db_name)." AS c" . 
     231            "SELECT * FROM ".$this->db->table_name($this->db_name)." AS c" . 
    232232            $join . 
    233233            " WHERE c.del<>1" . 
     
    489489    { 
    490490        if ($this->group_id) 
    491             $join = " LEFT JOIN ".get_table_name($this->db_groupmembers)." AS m". 
     491            $join = " LEFT JOIN ".$this->db->table_name($this->db_groupmembers)." AS m". 
    492492                " ON (m.contact_id=c.".$this->primary_key.")"; 
    493493 
     
    495495        $sql_result = $this->db->query( 
    496496            "SELECT COUNT(c.contact_id) AS rows". 
    497             " FROM ".get_table_name($this->db_name)." AS c". 
     497            " FROM ".$this->db->table_name($this->db_name)." AS c". 
    498498                $join. 
    499499            " WHERE c.del<>1". 
     
    537537 
    538538        $this->db->query( 
    539             "SELECT * FROM ".get_table_name($this->db_name). 
     539            "SELECT * FROM ".$this->db->table_name($this->db_name). 
    540540            " WHERE contact_id=?". 
    541541                " AND user_id=?". 
     
    569569 
    570570      $sql_result = $this->db->query( 
    571         "SELECT cgm.contactgroup_id, cg.name FROM " . get_table_name($this->db_groupmembers) . " AS cgm" . 
    572         " LEFT JOIN " . get_table_name($this->db_groups) . " AS cg ON (cgm.contactgroup_id = cg.contactgroup_id AND cg.del<>1)" . 
     571        "SELECT cgm.contactgroup_id, cg.name FROM " . $this->db->table_name($this->db_groupmembers) . " AS cgm" . 
     572        " LEFT JOIN " . $this->db->table_name($this->db_groups) . " AS cg ON (cgm.contactgroup_id = cg.contactgroup_id AND cg.del<>1)" . 
    573573        " WHERE cgm.contact_id=?", 
    574574        $id 
     
    639639        if (!$existing->count && !empty($a_insert_cols)) { 
    640640            $this->db->query( 
    641                 "INSERT INTO ".get_table_name($this->db_name). 
     641                "INSERT INTO ".$this->db->table_name($this->db_name). 
    642642                " (user_id, changed, del, ".join(', ', $a_insert_cols).")". 
    643643                " VALUES (".intval($this->user_id).", ".$this->db->now().", 0, ".join(', ', $a_insert_values).")" 
     
    677677        if (!empty($write_sql)) { 
    678678            $this->db->query( 
    679                 "UPDATE ".get_table_name($this->db_name). 
     679                "UPDATE ".$this->db->table_name($this->db_name). 
    680680                " SET changed=".$this->db->now().", ".join(', ', $write_sql). 
    681681                " WHERE contact_id=?". 
     
    773773        // flag record as deleted (always) 
    774774        $this->db->query( 
    775             "UPDATE ".get_table_name($this->db_name). 
     775            "UPDATE ".$this->db->table_name($this->db_name). 
    776776            " SET del=1, changed=".$this->db->now(). 
    777777            " WHERE user_id=?". 
     
    800800        // clear deleted flag 
    801801        $this->db->query( 
    802             "UPDATE ".get_table_name($this->db_name). 
     802            "UPDATE ".$this->db->table_name($this->db_name). 
    803803            " SET del=0, changed=".$this->db->now(). 
    804804            " WHERE user_id=?". 
     
    820820        $this->cache = null; 
    821821 
    822         $this->db->query("UPDATE ".get_table_name($this->db_name). 
     822        $this->db->query("UPDATE ".$this->db->table_name($this->db_name). 
    823823            " SET del=1, changed=".$this->db->now(). 
    824824            " WHERE user_id = ?", $this->user_id); 
     
    842842 
    843843        $this->db->query( 
    844             "INSERT INTO ".get_table_name($this->db_groups). 
     844            "INSERT INTO ".$this->db->table_name($this->db_groups). 
    845845            " (user_id, changed, name)". 
    846846            " VALUES (".intval($this->user_id).", ".$this->db->now().", ".$this->db->quote($name).")" 
     
    864864        // flag group record as deleted 
    865865        $sql_result = $this->db->query( 
    866             "UPDATE ".get_table_name($this->db_groups). 
     866            "UPDATE ".$this->db->table_name($this->db_groups). 
    867867            " SET del=1, changed=".$this->db->now(). 
    868868            " WHERE contactgroup_id=?". 
     
    890890 
    891891        $sql_result = $this->db->query( 
    892             "UPDATE ".get_table_name($this->db_groups). 
     892            "UPDATE ".$this->db->table_name($this->db_groups). 
    893893            " SET name=?, changed=".$this->db->now(). 
    894894            " WHERE contactgroup_id=?". 
     
    918918        // get existing assignments ... 
    919919        $sql_result = $this->db->query( 
    920             "SELECT contact_id FROM ".get_table_name($this->db_groupmembers). 
     920            "SELECT contact_id FROM ".$this->db->table_name($this->db_groupmembers). 
    921921            " WHERE contactgroup_id=?". 
    922922                " AND contact_id IN (".$this->db->array2list($ids, 'integer').")", 
     
    931931        foreach ($ids as $contact_id) { 
    932932            $this->db->query( 
    933                 "INSERT INTO ".get_table_name($this->db_groupmembers). 
     933                "INSERT INTO ".$this->db->table_name($this->db_groupmembers). 
    934934                " (contactgroup_id, contact_id, created)". 
    935935                " VALUES (?, ?, ".$this->db->now().")", 
     
    961961 
    962962        $sql_result = $this->db->query( 
    963             "DELETE FROM ".get_table_name($this->db_groupmembers). 
     963            "DELETE FROM ".$this->db->table_name($this->db_groupmembers). 
    964964            " WHERE contactgroup_id=?". 
    965965                " AND contact_id IN ($ids)", 
     
    984984        do { 
    985985            $sql_result = $this->db->query( 
    986                 "SELECT 1 FROM ".get_table_name($this->db_groups). 
     986                "SELECT 1 FROM ".$this->db->table_name($this->db_groups). 
    987987                " WHERE del<>1". 
    988988                    " AND user_id=?". 
  • trunk/roundcubemail/program/include/rcube_imap.php

    r6023 r6073  
    133133        } 
    134134        else if ($use_ssl) { 
    135             raise_error(array('code' => 403, 'type' => 'imap', 
     135            rcube::raise_error(array('code' => 403, 'type' => 'imap', 
    136136                'file' => __FILE__, 'line' => __LINE__, 
    137137                'message' => "OpenSSL not available"), true, false); 
     
    155155        $attempt = 0; 
    156156        do { 
    157             $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', 
     157            $data = rcube::get_instance()->plugins->exec_hook('imap_connect', 
    158158                array_merge($this->options, array('host' => $host, 'user' => $user, 
    159159                    'attempt' => ++$attempt))); 
     
    186186            if ($pass && $user) { 
    187187                $message = sprintf("Login failed for %s from %s. %s", 
    188                     $user, rcmail_remote_ip(), $this->conn->error); 
    189  
    190                 raise_error(array('code' => 403, 'type' => 'imap', 
     188                    $user, rcmail::remote_ip(), $this->conn->error); 
     189 
     190                rcube::raise_error(array('code' => 403, 'type' => 'imap', 
    191191                    'file' => __FILE__, 'line' => __LINE__, 
    192192                    'message' => $message), true, false); 
     
    458458        } 
    459459 
    460         $config = rcmail::get_instance()->config; 
     460        $config = rcube::get_instance()->config; 
    461461        $imap_personal  = $config->get('imap_ns_personal'); 
    462462        $imap_other     = $config->get('imap_ns_other'); 
     
    547547        } 
    548548 
    549         return $this->messagecount($folder, $mode, $force, $status); 
     549        return $this->countmessages($folder, $mode, $force, $status); 
    550550    } 
    551551 
     
    563563     * @see rcube_imap::count() 
    564564     */ 
    565     protected function messagecount($folder, $mode='ALL', $force=false, $status=true) 
     565    protected function countmessages($folder, $mode='ALL', $force=false, $status=true) 
    566566    { 
    567567        $mode = strtoupper($mode); 
     
    835835     * depth, has_children and unread_children 
    836836     * 
    837      * @param  array             $headers Reference to headers array indexed by message UID 
    838      * @param  rcube_imap_result $threads Threads data object 
     837     * @param  array               $headers Reference to headers array indexed by message UID 
     838     * @param  rcube_result_thread $threads Threads data object 
    839839     * 
    840840     * @return array Message headers array indexed by message UID 
     
    10491049        if ($sort) { 
    10501050            // use this class for message sorting 
    1051             $sorter = new rcube_header_sorter(); 
     1051            $sorter = new rcube_message_header_sorter(); 
    10521052            $sorter->set_index($msgs); 
    10531053            $sorter->sort_headers($a_msg_headers); 
     
    10761076 
    10771077        // refresh message count -> will update 
    1078         $this->messagecount($folder, 'ALL', true); 
     1078        $this->countmessages($folder, 'ALL', true); 
    10791079 
    10801080        $result = 0; 
     
    14571457                $string_offset = $m[1] + strlen($m[0]) + 4; // {}\r\n 
    14581458                $string = substr($str, $string_offset - 1, $m[0]); 
    1459                 $string = rcube_charset_convert($string, $charset, $dest_charset); 
     1459                $string = rcube_charset::convert($string, $charset, $dest_charset); 
    14601460                if ($string === false) { 
    14611461                    continue; 
     
    14991499     * @param bool    $force    True to skip cache 
    15001500     * 
    1501      * @return rcube_mail_header Message headers 
     1501     * @return rcube_message_header Message headers 
    15021502     */ 
    15031503    public function get_message_headers($uid, $folder = null, $force = false) 
     
    15301530     * @param string  $folder   Folder to read from 
    15311531     * 
    1532      * @return object rcube_mail_header Message data 
     1532     * @return object rcube_message_header Message data 
    15331533     */ 
    15341534    public function get_message($uid, $folder = null) 
     
    19491949            } 
    19501950            else { 
    1951                 $charset = rc_detect_encoding($filename_mime, $this->default_charset); 
     1951                $charset = rcube_charset::detect($filename_mime, $this->default_charset); 
    19521952            } 
    19531953 
     
    19611961            } 
    19621962 
    1963             $part->filename = rcube_charset_convert(urldecode($filename_encoded), $filename_charset); 
     1963            $part->filename = rcube_charset::convert(urldecode($filename_encoded), $filename_charset); 
    19641964        } 
    19651965    } 
     
    20402040                    } 
    20412041                } 
    2042                 $body = rcube_charset_convert($body, $o_part->charset); 
     2042                $body = rcube_charset::convert($body, $o_part->charset); 
    20432043            } 
    20442044        } 
     
    22282228        } 
    22292229 
    2230         $config = rcmail::get_instance()->config; 
     2230        $config = rcube::get_instance()->config; 
    22312231        $to_trash = $to_mbox == $config->get('trash_mbox'); 
    22322232 
     
    25112511 
    25122512        // Give plugins a chance to provide a list of folders 
    2513         $data = rcmail::get_instance()->plugins->exec_hook('storage_folders', 
     2513        $data = rcube::get_instance()->plugins->exec_hook('storage_folders', 
    25142514            array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB')); 
    25152515 
     
    25222522        else { 
    25232523            // Server supports LIST-EXTENDED, we can use selection options 
    2524             $config = rcmail::get_instance()->config; 
     2524            $config = rcube::get_instance()->config; 
    25252525            // #1486225: Some dovecot versions returns wrong result using LIST-EXTENDED 
    25262526            if (!$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED')) { 
     
    35313531    { 
    35323532        if ($this->caching && !$this->cache) { 
    3533             $rcmail = rcmail::get_instance(); 
     3533            $rcmail = rcube::get_instance(); 
    35343534            $ttl = $rcmail->config->get('message_cache_lifetime', '10d') - mktime(); 
    35353535            $this->cache = $rcmail->get_cache('IMAP', $this->caching, $ttl); 
     
    35903590        } 
    35913591 
    3592         if ($this->cache) 
     3592        if ($this->cache) { 
    35933593            $this->cache->expunge(); 
     3594        } 
    35943595    } 
    35953596 
     
    36253626    { 
    36263627        if ($this->messages_caching && !$this->mcache) { 
    3627             $rcmail = rcmail::get_instance(); 
     3628            $rcmail = rcube::get_instance(); 
    36283629            if ($dbh = $rcmail->get_dbh()) { 
    36293630                $this->mcache = new rcube_imap_cache( 
    3630                     $dbh, $this, $rcmail->user->ID, $this->options['skip_deleted']); 
     3631                    $dbh, $this, $rcmail->get_user_id(), $this->options['skip_deleted']); 
    36313632            } 
    36323633        } 
     
    36923693            } 
    36933694            else { 
    3694                 $folders[$folder] = rcube_charset_convert($folder, 'UTF7-IMAP'); 
     3695                $folders[$folder] = rcube_charset::convert($folder, 'UTF7-IMAP'); 
    36953696            } 
    36963697        } 
     
    38523853    public function debug_handler(&$imap, $message) 
    38533854    { 
    3854         write_log('imap', $message); 
     3855        rcmail::write_log('imap', $message); 
    38553856    } 
    38563857 
  • trunk/roundcubemail/program/include/rcube_imap_cache.php

    r6020 r6073  
    9696        $this->db           = $db; 
    9797        $this->imap         = $imap; 
    98         $this->userid       = (int)$userid; 
     98        $this->userid       = $userid; 
    9999        $this->skip_deleted = $skip_deleted; 
    100100    } 
     
    291291     * @param array  $msgs     Message UIDs 
    292292     * 
    293      * @return array The list of messages (rcube_mail_header) indexed by UID 
     293     * @return array The list of messages (rcube_message_header) indexed by UID 
    294294     */ 
    295295    function get_messages($mailbox, $msgs = array()) 
     
    302302        $sql_result = $this->db->query( 
    303303            "SELECT uid, data, flags" 
    304             ." FROM ".get_table_name('cache_messages') 
     304            ." FROM ".$this->db->table_name('cache_messages') 
    305305            ." WHERE user_id = ?" 
    306306                ." AND mailbox = ?" 
     
    349349     * @param bool   $no_cache Enables internal cache usage 
    350350     * 
    351      * @return rcube_mail_header Message data 
     351     * @return rcube_message_header Message data 
    352352     */ 
    353353    function get_message($mailbox, $uid, $update = true, $cache = true) 
     
    363363        $sql_result = $this->db->query( 
    364364            "SELECT flags, data" 
    365             ." FROM ".get_table_name('cache_messages') 
     365            ." FROM ".$this->db->table_name('cache_messages') 
    366366            ." WHERE user_id = ?" 
    367367                ." AND mailbox = ?" 
     
    405405     * Saves the message in cache. 
    406406     * 
    407      * @param string            $mailbox  Folder name 
    408      * @param rcube_mail_header $message  Message data 
    409      * @param bool              $force    Skips message in-cache existance check 
     407     * @param string               $mailbox  Folder name 
     408     * @param rcube_message_header $message  Message data 
     409     * @param bool                 $force    Skips message in-cache existance check 
    410410     */ 
    411411    function add_message($mailbox, $message, $force = false) 
     
    431431        if (!$force) { 
    432432            $res = $this->db->query( 
    433                 "UPDATE ".get_table_name('cache_messages') 
     433                "UPDATE ".$this->db->table_name('cache_messages') 
    434434                ." SET flags = ?, data = ?, changed = ".$this->db->now() 
    435435                ." WHERE user_id = ?" 
     
    445445        // insert new record 
    446446        $this->db->query( 
    447             "INSERT INTO ".get_table_name('cache_messages') 
     447            "INSERT INTO ".$this->db->table_name('cache_messages') 
    448448            ." (user_id, mailbox, uid, flags, changed, data)" 
    449449            ." VALUES (?, ?, ?, ?, ".$this->db->now().", ?)", 
     
    480480 
    481481        $this->db->query( 
    482             "UPDATE ".get_table_name('cache_messages') 
     482            "UPDATE ".$this->db->table_name('cache_messages') 
    483483            ." SET changed = ".$this->db->now() 
    484484            .", flags = flags ".($enabled ? "+ $idx" : "- $idx") 
     
    501501        if (!strlen($mailbox)) { 
    502502            $this->db->query( 
    503                 "DELETE FROM ".get_table_name('cache_messages') 
     503                "DELETE FROM ".$this->db->table_name('cache_messages') 
    504504                ." WHERE user_id = ?", 
    505505                $this->userid); 
     
    514514 
    515515            $this->db->query( 
    516                 "DELETE FROM ".get_table_name('cache_messages') 
     516                "DELETE FROM ".$this->db->table_name('cache_messages') 
    517517                ." WHERE user_id = ?" 
    518                     ." AND mailbox = ".$this->db->quote($mailbox) 
     518                    ." AND mailbox = ?" 
    519519                    .($uids !== null ? " AND uid IN (".$this->db->array2list((array)$uids, 'integer').")" : ""), 
    520                 $this->userid); 
     520                $this->userid, $mailbox); 
    521521        } 
    522522 
     
    537537        if ($remove) { 
    538538            $this->db->query( 
    539                 "DELETE FROM ".get_table_name('cache_index') 
    540                 ." WHERE user_id = ".intval($this->userid) 
    541                     .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "") 
     539                "DELETE FROM ".$this->db->table_name('cache_index') 
     540                ." WHERE user_id = ?" 
     541                    .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), 
     542                $this->userid 
    542543            ); 
    543544        } 
    544545        else { 
    545546            $this->db->query( 
    546                 "UPDATE ".get_table_name('cache_index') 
     547                "UPDATE ".$this->db->table_name('cache_index') 
    547548                ." SET valid = 0" 
    548                 ." WHERE user_id = ".intval($this->userid) 
    549                     .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "") 
     549                ." WHERE user_id = ?" 
     550                    .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), 
     551                $this->userid 
    550552            ); 
    551553        } 
     
    570572    { 
    571573        $this->db->query( 
    572             "DELETE FROM ".get_table_name('cache_thread') 
    573             ." WHERE user_id = ".intval($this->userid) 
    574                 .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : "") 
     574            "DELETE FROM ".$this->db->table_name('cache_thread') 
     575            ." WHERE user_id = ?" 
     576                .(strlen($mailbox) ? " AND mailbox = ".$this->db->quote($mailbox) : ""), 
     577            $this->userid 
    575578        ); 
    576579 
     
    629632        $sql_result = $this->db->query( 
    630633            "SELECT data, valid" 
    631             ." FROM ".get_table_name('cache_index') 
     634            ." FROM ".$this->db->table_name('cache_index') 
    632635            ." WHERE user_id = ?" 
    633636                ." AND mailbox = ?", 
     
    666669        $sql_result = $this->db->query( 
    667670            "SELECT data" 
    668             ." FROM ".get_table_name('cache_thread') 
     671            ." FROM ".$this->db->table_name('cache_thread') 
    669672            ." WHERE user_id = ?" 
    670673                ." AND mailbox = ?", 
     
    710713        if ($exists) { 
    711714            $sql_result = $this->db->query( 
    712                 "UPDATE ".get_table_name('cache_index') 
     715                "UPDATE ".$this->db->table_name('cache_index') 
    713716                ." SET data = ?, valid = 1, changed = ".$this->db->now() 
    714717                ." WHERE user_id = ?" 
     
    718721        else { 
    719722            $sql_result = $this->db->query( 
    720                 "INSERT INTO ".get_table_name('cache_index') 
     723                "INSERT INTO ".$this->db->table_name('cache_index') 
    721724                ." (user_id, mailbox, data, valid, changed)" 
    722725                ." VALUES (?, ?, ?, 1, ".$this->db->now().")", 
     
    741744        if ($exists) { 
    742745            $sql_result = $this->db->query( 
    743                 "UPDATE ".get_table_name('cache_thread') 
     746                "UPDATE ".$this->db->table_name('cache_thread') 
    744747                ." SET data = ?, changed = ".$this->db->now() 
    745748                ." WHERE user_id = ?" 
     
    749752        else { 
    750753            $sql_result = $this->db->query( 
    751                 "INSERT INTO ".get_table_name('cache_thread') 
     754                "INSERT INTO ".$this->db->table_name('cache_thread') 
    752755                ." (user_id, mailbox, data, changed)" 
    753756                ." VALUES (?, ?, ?, ".$this->db->now().")", 
     
    957960        $sql_result = $this->db->query( 
    958961            "SELECT uid" 
    959             ." FROM ".get_table_name('cache_messages') 
     962            ." FROM ".$this->db->table_name('cache_messages') 
    960963            ." WHERE user_id = ?" 
    961964                ." AND mailbox = ?", 
     
    10041007 
    10051008                $this->db->query( 
    1006                     "UPDATE ".get_table_name('cache_messages') 
     1009                    "UPDATE ".$this->db->table_name('cache_messages') 
    10071010                    ." SET flags = ?, changed = ".$this->db->now() 
    10081011                    ." WHERE user_id = ?" 
     
    10591062     * @param array $sql_arr Message row data 
    10601063     * 
    1061      * @return rcube_mail_header Message object 
     1064     * @return rcube_message_header Message object 
    10621065     */ 
    10631066    private function build_message($sql_arr) 
  • trunk/roundcubemail/program/include/rcube_imap_generic.php

    r6027 r6073  
    3030*/ 
    3131 
    32 /** 
    33  * Struct representing an e-mail message header 
    34  * 
    35  * @package Mail 
    36  * @author  Aleksander Machniak <alec@alec.pl> 
    37  */ 
    38 class rcube_mail_header 
    39 { 
    40     public $id; 
    41     public $uid; 
    42     public $subject; 
    43     public $from; 
    44     public $to; 
    45     public $cc; 
    46     public $replyto; 
    47     public $in_reply_to; 
    48     public $date; 
    49     public $messageID; 
    50     public $size; 
    51     public $encoding; 
    52     public $charset; 
    53     public $ctype; 
    54     public $timestamp; 
    55     public $bodystructure; 
    56     public $internaldate; 
    57     public $references; 
    58     public $priority; 
    59     public $mdn_to; 
    60     public $others = array(); 
    61     public $flags = array(); 
    62 } 
    63  
    64 // For backward compatibility with cached messages (#1486602) 
    65 class iilBasicHeader extends rcube_mail_header 
    66 { 
    67 } 
     32// for backward copat. 
     33class rcube_mail_header extends rcube_message_header { } 
     34 
    6835 
    6936/** 
     
    15461513    function sort($mailbox, $field, $add='', $return_uid=false, $encoding = 'US-ASCII') 
    15471514    { 
    1548         require_once dirname(__FILE__) . '/rcube_result_index.php'; 
    1549  
    15501515        $field = strtoupper($field); 
    15511516        if ($field == 'INTERNALDATE') { 
     
    15961561    function thread($mailbox, $algorithm='REFERENCES', $criteria='', $return_uid=false, $encoding='US-ASCII') 
    15971562    { 
    1598         require_once dirname(__FILE__) . '/rcube_result_thread.php'; 
    1599  
    16001563        $old_sel = $this->selected; 
    16011564 
     
    16361599    function search($mailbox, $criteria, $return_uid=false, $items=array()) 
    16371600    { 
    1638         require_once dirname(__FILE__) . '/rcube_result_index.php'; 
    1639  
    16401601        $old_sel = $this->selected; 
    16411602 
     
    16971658        $uidfetch=false, $return_uid=false) 
    16981659    { 
    1699         require_once dirname(__FILE__) . '/rcube_result_index.php'; 
    1700  
    17011660        $msg_index = $this->fetchHeaderIndex($mailbox, $message_set, 
    17021661            $index_field, $skip_deleted, $uidfetch, $return_uid); 
     
    20351994     * @param bool   $vanished    Enables VANISHED parameter (RFC5162) for CHANGEDSINCE query 
    20361995     * 
    2037      * @return array List of rcube_mail_header elements, False on error 
     1996     * @return array List of rcube_message_header elements, False on error 
    20381997     * @since 0.6 
    20391998     */ 
     
    20752034                $id = intval($m[1]); 
    20762035 
    2077                 $result[$id]            = new rcube_mail_header; 
     2036                $result[$id]            = new rcube_message_header; 
    20782037                $result[$id]->id        = $id; 
    20792038                $result[$id]->subject   = ''; 
  • trunk/roundcubemail/program/include/rcube_ldap.php

    r6067 r6073  
    6464    * Object constructor 
    6565    * 
    66     * @param array          LDAP connection properties 
    67     * @param boolean    Enables debug mode 
    68     * @param string     Current user mail domain name 
    69     * @param integer User-ID 
     66    * @param array       $p            LDAP connection properties 
     67    * @param boolean $debug        Enables debug mode 
     68    * @param string  $mail_domain  Current user mail domain name 
    7069    */ 
    71     function __construct($p, $debug=false, $mail_domain=NULL) 
     70    function __construct($p, $debug = false, $mail_domain = null) 
    7271    { 
    7372        $this->prop = $p; 
     
    177176    private function _connect() 
    178177    { 
    179         global $RCMAIL; 
     178        $RCMAIL = rcmail::get_instance(); 
    180179 
    181180        if (!function_exists('ldap_connect')) 
    182             raise_error(array('code' => 100, 'type' => 'ldap', 
     181            rcube::raise_error(array('code' => 100, 'type' => 'ldap', 
    183182                'file' => __FILE__, 'line' => __LINE__, 
    184183                'message' => "No ldap support in this installation of PHP"), 
     
    196195        foreach ($this->prop['hosts'] as $host) 
    197196        { 
    198             $host     = idn_to_ascii(rcube_parse_host($host)); 
     197            $host     = idn_to_ascii(rcmail::parse_host($host)); 
    199198            $hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : ''); 
    200199 
     
    226225 
    227226        if (!is_resource($this->conn)) { 
    228             raise_error(array('code' => 100, 'type' => 'ldap', 
     227            rcube::raise_error(array('code' => 100, 'type' => 'ldap', 
    229228                'file' => __FILE__, 'line' => __LINE__, 
    230229                'message' => "Could not connect to any LDAP server, last tried $hostname"), true); 
     
    249248 
    250249            // Get the pieces needed for variable replacement. 
    251             if ($fu = $RCMAIL->user->get_username()) 
     250            if ($fu = $RCMAIL->get_user_name()) 
    252251                list($u, $d) = explode('@', $fu); 
    253252            else 
     
    288287                        $replaces['%dn'] = $this->prop['search_dn_default']; 
    289288                    else { 
    290                         raise_error(array( 
     289                        rcube::raise_error(array( 
    291290                            'code' => 100, 'type' => 'ldap', 
    292291                            'file' => __FILE__, 'line' => __LINE__, 
     
    342341 
    343342        if (!function_exists('ldap_sasl_bind')) { 
    344             raise_error(array('code' => 100, 'type' => 'ldap', 
     343            rcube::raise_error(array('code' => 100, 'type' => 'ldap', 
    345344                'file' => __FILE__, 'line' => __LINE__, 
    346345                'message' => "Unable to bind: ldap_sasl_bind() not exists"), 
     
    368367        $this->_debug("S: ".ldap_error($this->conn)); 
    369368 
    370         raise_error(array( 
     369        rcube::raise_error(array( 
    371370            'code' => ldap_errno($this->conn), 'type' => 'ldap', 
    372371            'file' => __FILE__, 'line' => __LINE__, 
     
    401400        $this->_debug("S: ".ldap_error($this->conn)); 
    402401 
    403         raise_error(array( 
     402        rcube::raise_error(array( 
    404403            'code' => ldap_errno($this->conn), 'type' => 'ldap', 
    405404            'file' => __FILE__, 'line' => __LINE__, 
     
    15631562    private function _debug($str) 
    15641563    { 
    1565         if ($this->debug) 
    1566             write_log('ldap', $str); 
     1564        if ($this->debug) { 
     1565            rcmail::write_log('ldap', $str); 
     1566        } 
    15671567    } 
    15681568 
  • trunk/roundcubemail/program/include/rcube_mdb2.php

    r5850 r6073  
    6060     * @param  string $db_dsnr Optional DSN for read only operations 
    6161     */ 
    62     function __construct($db_dsnw, $db_dsnr='', $pconn=false) 
    63     { 
    64         if (empty($db_dsnr)) 
     62    public function __construct($db_dsnw, $db_dsnr='', $pconn=false) 
     63    { 
     64        if (empty($db_dsnr)) { 
    6565            $db_dsnr = $db_dsnw; 
     66        } 
    6667 
    6768        $this->db_dsnw = $db_dsnw; 
     
    8990            'debug'            => $this->debug_mode, 
    9091            'debug_handler'    => array($this, 'debug_handler'), 
    91             'portability'      => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL); 
     92            'portability'      => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL, 
     93        ); 
    9294 
    9395        if ($this->db_provider == 'pgsql') { 
     
    104106            $this->db_error_msg = $dbh->getMessage(); 
    105107 
    106             raise_error(array('code' => 500, 'type' => 'db', 
     108            rcube::raise_error(array('code' => 500, 'type' => 'db', 
    107109                'line' => __LINE__, 'file' => __FILE__, 
    108110                'message' => $dbh->getUserInfo()), true, false); 
     
    110112        else if ($this->db_provider == 'sqlite') { 
    111113            $dsn_array = MDB2::parseDSN($dsn); 
    112             if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials)) 
    113                 $this->_sqlite_create_database($dbh, $this->sqlite_initials); 
    114         } 
    115         else if ($this->db_provider!='mssql' && $this->db_provider!='sqlsrv') 
     114            if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials)) { 
     115                $this->sqlite_create_database($dbh, $this->sqlite_initials); 
     116            } 
     117        } 
     118        else if ($this->db_provider != 'mssql' && $this->db_provider != 'sqlsrv') { 
    116119            $dbh->setCharset('utf8'); 
     120        } 
    117121 
    118122        return $dbh; 
     
    124128     * 
    125129     * @param  string $mode Connection mode (r|w) 
    126      * @access public 
    127      */ 
    128     function db_connect($mode) 
     130     */ 
     131    public function db_connect($mode) 
    129132    { 
    130133        // previous connection failed, don't attempt to connect again 
     
    158161        } 
    159162 
    160         if ($this->db_connected) 
     163        if ($this->db_connected) { 
    161164            $this->db_mode = $mode; 
    162         else 
     165        } 
     166        else { 
    163167            $this->conn_failure = true; 
     168        } 
    164169    } 
    165170 
     
    169174     * 
    170175     * @param boolean $dbg True if SQL queries should be logged 
    171      * @access public 
    172      */ 
    173     function set_debug($dbg = true) 
     176     */ 
     177    public function set_debug($dbg = true) 
    174178    { 
    175179        $this->debug_mode = $dbg; 
     
    185189     * 
    186190     * @param  boolean  True on error 
    187      * @access public 
    188      */ 
    189     function is_error() 
     191     */ 
     192    public function is_error() 
    190193    { 
    191194        return $this->db_error ? $this->db_error_msg : false; 
     
    197200     * 
    198201     * @param  boolean  True if in connected state 
    199      * @access public 
    200      */ 
    201     function is_connected() 
     202     */ 
     203    public function is_connected() 
    202204    { 
    203205        return PEAR::isError($this->db_handle) ? false : $this->db_connected; 
     
    209211     * This returns true if dsnw != dsnr 
    210212     */ 
    211     function is_replicated() 
     213    public function is_replicated() 
    212214    { 
    213215      return !empty($this->db_dsnr) && $this->db_dsnw != $this->db_dsnr; 
     
    220222     * @param  string  SQL query to execute 
    221223     * @param  mixed   Values to be inserted in query 
     224     * 
    222225     * @return number  Query handle identifier 
    223      * @access public 
    224      */ 
    225     function query() 
     226     */ 
     227    public function query() 
    226228    { 
    227229        $params = func_get_args(); 
     
    229231 
    230232        // Support one argument of type array, instead of n arguments 
    231         if (count($params) == 1 && is_array($params[0])) 
     233        if (count($params) == 1 && is_array($params[0])) { 
    232234            $params = $params[0]; 
     235        } 
    233236 
    234237        return $this->_query($query, 0, 0, $params); 
     
    243246     * @param  number  Number of rows for LIMIT statement 
    244247     * @param  mixed   Values to be inserted in query 
     248     * 
    245249     * @return number  Query handle identifier 
    246      * @access public 
    247      */ 
    248     function limitquery() 
     250     */ 
     251    public function limitquery() 
    249252    { 
    250253        $params  = func_get_args(); 
     
    275278 
    276279        // check connection before proceeding 
    277         if (!$this->is_connected()) 
     280        if (!$this->is_connected()) { 
    278281            return null; 
    279  
    280         if ($this->db_provider == 'sqlite') 
    281             $this->_sqlite_prepare(); 
    282  
    283         if ($numrows || $offset) 
     282        } 
     283 
     284        if ($this->db_provider == 'sqlite') { 
     285            $this->sqlite_prepare(); 
     286        } 
     287 
     288        if ($numrows || $offset) { 
    284289            $result = $this->db_handle->setLimit($numrows,$offset); 
    285  
    286         if (empty($params)) 
     290        } 
     291 
     292        if (empty($params)) { 
    287293            $result = $mode == 'r' ? $this->db_handle->query($query) : $this->db_handle->exec($query); 
     294        } 
    288295        else { 
    289296            $params = (array)$params; 
     
    293300                $this->db_error_msg = $q->userinfo; 
    294301 
    295                 raise_error(array('code' => 500, 'type' => 'db', 
     302                rcube::raise_error(array('code' => 500, 'type' => 'db', 
    296303                    'line' => __LINE__, 'file' => __FILE__, 
    297304                    'message' => $this->db_error_msg), true, false); 
     
    316323     * @param  number $res_id  Optional query handle identifier 
    317324     * @return mixed   Number of rows or false on failure 
    318      * @access public 
    319      */ 
    320     function num_rows($res_id=null) 
    321     { 
    322         if (!$this->db_connected) 
     325     */ 
     326    public function num_rows($res_id=null) 
     327    { 
     328        if (!$this->db_connected) { 
    323329            return false; 
    324  
    325         if ($result = $this->_get_result($res_id)) 
     330        } 
     331 
     332        if ($result = $this->_get_result($res_id)) { 
    326333            return $result->numRows(); 
    327         else 
    328             return false; 
     334        } 
     335 
     336        return false; 
    329337    } 
    330338 
     
    335343     * @param  number $res_id Optional query handle identifier 
    336344     * @return mixed   Number of rows or false on failure 
    337      * @access public 
    338      */ 
    339     function affected_rows($res_id = null) 
    340     { 
    341         if (!$this->db_connected) 
     345     */ 
     346    public function affected_rows($res_id = null) 
     347    { 
     348        if (!$this->db_connected) { 
    342349            return false; 
     350        } 
    343351 
    344352        return $this->_get_result($res_id); 
     
    351359     * 
    352360     * @param  string $table  Table name (to find the incremented sequence) 
     361     * 
    353362     * @return mixed   ID or false on failure 
    354      * @access public 
    355      */ 
    356     function insert_id($table = '') 
    357     { 
    358         if (!$this->db_connected || $this->db_mode == 'r') 
     363     */ 
     364    public function insert_id($table = '') 
     365    { 
     366        if (!$this->db_connected || $this->db_mode == 'r') { 
    359367            return false; 
     368        } 
    360369 
    361370        if ($table) { 
    362             if ($this->db_provider == 'pgsql') 
     371            if ($this->db_provider == 'pgsql') { 
    363372                // find sequence name 
    364                 $table = get_sequence_name($table); 
    365             else 
     373                $table = $this->sequence_name($table); 
     374            } 
     375            else { 
    366376                // resolve table name 
    367                 $table = get_table_name($table); 
     377                $table = $this->table_name($table); 
     378            } 
    368379        } 
    369380 
     
    379390     * 
    380391     * @param  number $res_id Optional query handle identifier 
     392     * 
    381393     * @return mixed   Array with col values or false on failure 
    382      * @access public 
    383      */ 
    384     function fetch_assoc($res_id=null) 
     394     */ 
     395    public function fetch_assoc($res_id = null) 
    385396    { 
    386397        $result = $this->_get_result($res_id); 
     
    394405     * 
    395406     * @param  number $res_id  Optional query handle identifier 
     407     * 
    396408     * @return mixed   Array with col values or false on failure 
    397      * @access public 
    398      */ 
    399     function fetch_array($res_id=null) 
     409     */ 
     410    public function fetch_array($res_id = null) 
    400411    { 
    401412        $result = $this->_get_result($res_id); 
     
    409420     * @param  MDB2_Result_Common Query $result result handle 
    410421     * @param  number                   $mode   Fetch mode identifier 
    411      * @return mixed   Array with col values or false on failure 
    412      * @access private 
     422     * 
     423     * @return mixed  Array with col values or false on failure 
    413424     */ 
    414425    private function _fetch_row($result, $mode) 
    415426    { 
    416         if ($result === false || PEAR::isError($result) || !$this->is_connected()) 
     427        if ($result === false || PEAR::isError($result) || !$this->is_connected()) { 
    417428            return false; 
     429        } 
    418430 
    419431        return $result->fetchRow($mode); 
     
    425437     * 
    426438     * @return array List of all tables of the current database 
    427      * @access public 
    428439     * @since 0.4-beta 
    429440     */ 
    430     function list_tables() 
     441    public function list_tables() 
    431442    { 
    432443        // get tables if not cached 
    433444        if (!$this->tables) { 
    434445            $this->db_handle->loadModule('Manager'); 
    435             if (!PEAR::isError($result = $this->db_handle->listTables())) 
     446            if (!PEAR::isError($result = $this->db_handle->listTables())) { 
    436447                $this->tables = $result; 
    437             else 
     448            } 
     449            else { 
    438450                $this->tables = array(); 
     451            } 
    439452        } 
    440453 
     
    447460     * 
    448461     * @param string Table name 
     462     * 
    449463     * @return array List of table cols 
    450464     */ 
    451     function list_cols($table) 
     465    public function list_cols($table) 
    452466    { 
    453467        $this->db_handle->loadModule('Manager'); 
     
    465479     * @param  mixed  $input  Value to quote 
    466480     * @param  string $type   Type of data 
     481     * 
    467482     * @return string  Quoted/converted string for use in query 
    468      * @access public 
    469      */ 
    470     function quote($input, $type = null) 
     483     */ 
     484    public function quote($input, $type = null) 
    471485    { 
    472486        // handle int directly for better performance 
    473         if ($type == 'integer') 
     487        if ($type == 'integer') { 
    474488            return intval($input); 
     489        } 
    475490 
    476491        // create DB handle if not available 
    477         if (!$this->db_handle) 
     492        if (!$this->db_handle) { 
    478493            $this->db_connect('r'); 
     494        } 
    479495 
    480496        return $this->db_connected ? $this->db_handle->quote($input, $type) : addslashes($input); 
     
    486502     * 
    487503     * @param  string $str Value to quote 
     504     * 
    488505     * @return string  Quoted string for use in query 
    489506     * @deprecated     Replaced by rcube_MDB2::quote_identifier 
    490507     * @see            rcube_mdb2::quote_identifier 
    491      * @access public 
    492      */ 
    493     function quoteIdentifier($str) 
     508     */ 
     509    public function quoteIdentifier($str) 
    494510    { 
    495511        return $this->quote_identifier($str); 
     
    501517     * 
    502518     * @param  string $str Value to quote 
     519     * 
    503520     * @return string  Quoted string for use in query 
    504      * @access public 
    505      */ 
    506     function quote_identifier($str) 
    507     { 
    508         if (!$this->db_handle) 
     521     */ 
     522    public function quote_identifier($str) 
     523    { 
     524        if (!$this->db_handle) { 
    509525            $this->db_connect('r'); 
     526        } 
    510527 
    511528        return $this->db_connected ? $this->db_handle->quoteIdentifier($str) : $str; 
     
    517534     * 
    518535     * @param  string $str The string to be escaped 
     536     * 
    519537     * @return string  The escaped string 
    520      * @access public 
    521538     * @since  0.1.1 
    522539     */ 
    523     function escapeSimple($str) 
    524     { 
    525         if (!$this->db_handle) 
     540    public function escapeSimple($str) 
     541    { 
     542        if (!$this->db_handle) { 
    526543            $this->db_connect('r'); 
     544        } 
    527545 
    528546        return $this->db_handle->escape($str); 
     
    534552     * 
    535553     * @return string SQL function to use in query 
    536      * @access public 
    537      */ 
    538     function now() 
     554     */ 
     555    public function now() 
    539556    { 
    540557        switch ($this->db_provider) { 
     
    554571     * @param  array  $arr  Input array 
    555572     * @param  string $type Type of data 
     573     * 
    556574     * @return string Comma-separated list of quoted values for use in query 
    557      * @access public 
    558      */ 
    559     function array2list($arr, $type = null) 
    560     { 
    561         if (!is_array($arr)) 
     575     */ 
     576    public function array2list($arr, $type = null) 
     577    { 
     578        if (!is_array($arr)) { 
    562579            return $this->quote($arr, $type); 
    563  
    564         foreach ($arr as $idx => $item) 
     580        } 
     581 
     582        foreach ($arr as $idx => $item) { 
    565583            $arr[$idx] = $this->quote($item, $type); 
     584        } 
    566585 
    567586        return implode(',', $arr); 
     
    576595     * 
    577596     * @param  string $field Field name 
     597     * 
    578598     * @return string  SQL statement to use in query 
    579599     * @deprecated 
    580600     */ 
    581     function unixtimestamp($field) 
     601    public function unixtimestamp($field) 
    582602    { 
    583603        switch($this->db_provider) { 
     
    599619     * 
    600620     * @param  string $timestamp Field name 
     621     * 
    601622     * @return string  SQL statement to use in query 
    602      * @access public 
    603      */ 
    604     function fromunixtime($timestamp) 
     623     */ 
     624    public function fromunixtime($timestamp) 
    605625    { 
    606626        return date("'Y-m-d H:i:s'", $timestamp); 
     
    613633     * @param  string $column  Field name 
    614634     * @param  string $value   Search value 
     635     * 
    615636     * @return string  SQL statement to use in query 
    616      * @access public 
    617      */ 
    618     function ilike($column, $value) 
     637     */ 
     638    public function ilike($column, $value) 
    619639    { 
    620640        // TODO: use MDB2's matchPattern() function 
    621         switch($this->db_provider) { 
     641        switch ($this->db_provider) { 
    622642            case 'pgsql': 
    623643                return $this->quote_identifier($column).' ILIKE '.$this->quote($value); 
     
    627647    } 
    628648 
     649 
    629650    /** 
    630651     * Abstract SQL statement for value concatenation 
    631652     * 
    632653     * @return string SQL statement to be used in query 
    633      * @access public 
    634      */ 
    635     function concat(/* col1, col2, ... */) 
     654     */ 
     655    public function concat(/* col1, col2, ... */) 
    636656    { 
    637657        $func = ''; 
     
    640660            $args = $args[0]; 
    641661 
    642         switch($this->db_provider) { 
     662        switch ($this->db_provider) { 
    643663            case 'mysql': 
    644664            case 'mysqli': 
     
    662682     * 
    663683     * @param  mixed  $input Data to fix 
     684     * 
    664685     * @return mixed  Properly UTF-8 encoded data 
    665      * @access public 
    666      */ 
    667     function encode($input) 
     686     */ 
     687    public static function encode($input) 
    668688    { 
    669689        if (is_object($input)) { 
    670             foreach (get_object_vars($input) as $idx => $value) 
    671                 $input->$idx = $this->encode($value); 
     690            foreach (get_object_vars($input) as $idx => $value) { 
     691                $input->$idx = self::encode($value); 
     692            } 
    672693            return $input; 
    673694        } 
    674695        else if (is_array($input)) { 
    675             foreach ($input as $idx => $value) 
    676                 $input[$idx] = $this->encode($value); 
    677             return $input;       
     696            foreach ($input as $idx => $value) { 
     697                $input[$idx] = self::encode($value); 
     698            } 
     699            return $input; 
    678700        } 
    679701 
     
    686708     * 
    687709     * @param  mixed $input Input data 
     710     * 
    688711     * @return mixed  Decoded data 
    689      * @access public 
    690      */ 
    691     function decode($input) 
     712     */ 
     713    public static function decode($input) 
    692714    { 
    693715        if (is_object($input)) { 
    694             foreach (get_object_vars($input) as $idx => $value) 
    695                 $input->$idx = $this->decode($value); 
     716            foreach (get_object_vars($input) as $idx => $value) { 
     717                $input->$idx = self::decode($value); 
     718            } 
    696719            return $input; 
    697720        } 
    698721        else if (is_array($input)) { 
    699             foreach ($input as $idx => $value) 
    700                 $input[$idx] = $this->decode($value); 
    701             return $input;       
     722            foreach ($input as $idx => $value) { 
     723                $input[$idx] = self::decode($value); 
     724            } 
     725            return $input; 
    702726        } 
    703727 
     
    710734     * 
    711735     * @param  object $res Query handle 
     736     * 
    712737     * @return mixed   Handle ID 
    713      * @access private