Changeset 15a9d1c in github


Ignore:
Timestamp:
Jan 4, 2006 7:37:10 PM (7 years ago)
Author:
thomascube <thomas@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
3baec23
Parents:
977a295e
Message:

Optimized loading time; added periodic mail check; added EXPUNGE command

Files:
3 added
21 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r977a295e r15a9d1c  
    11CHANGELOG RoundCube Webmail 
    22--------------------------- 
     3 
     42006/01/04 
     5---------- 
     6- Fixed bug when inserting signatures with !?& 
     7- Chopping message headers before inserting into the message cache table (to avoid bugs in Postgres) 
     8- Allow one-char domains in e-mail addresses 
     9- Make product name in page title configurable 
     10- Make username available as skin object 
     11- Added session_write_close() in rcube_db class destructor to avoid problems in PHP 5.0.5 
     12- Use move_uploaded_file() instead of copy() for a more secure handling of uploaded attachments 
     13- Additional config parameter to show/hide deleted messages 
     14- Added periodic request for checking new mails (Request #1307821) 
     15- Added EXPUNGE command 
     16- Optimized loading time for mail interface 
    317 
    418 
  • INSTALL

    r1cded85 r15a9d1c  
    7777* .htaccess support allowing overrides for DirectoryIndex 
    7878* PHP Version 4.3.1 or greater 
     79* PCRE (perl compatible regular expression) installed with PHP 
    7980* php.ini options: 
    8081   - error_reporting E_ALL & ~E_NOTICE (or lower) 
  • SQL/mysql.initial.sql

    r1cded85 r15a9d1c  
    9292  `last_login` datetime NOT NULL default '0000-00-00 00:00:00', 
    9393  `language` varchar(5) NOT NULL default 'en', 
    94   `preferences` text NOT NULL, 
     94  `preferences` text NOT NULL default '', 
    9595  PRIMARY KEY  (`user_id`) 
    9696) TYPE=MyISAM; 
  • SQL/mysql.update.sql

    r1cded85 r15a9d1c  
    33 
    44 
    5 ALTER TABLE session ADD ip VARCHAR(15) NOT NULL AFTER changed; 
    6 ALTER TABLE users ADD alias VARCHAR(128) NOT NULL AFTER mail_host; 
     5ALTER TABLE `session` ADD `ip` VARCHAR(15) NOT NULL AFTER changed; 
     6ALTER TABLE `users` ADD `alias` VARCHAR(128) NOT NULL AFTER mail_host; 
    77 
    88 
  • SQL/postgres.initial.sql

    r977a295e r15a9d1c  
    6969 
    7070CREATE TABLE users ( 
    71     user_id integer DEFAULT nextval('user_ids'::text) NOT NULL, 
     71    user_id integer DEFAULT nextval('user_ids'::text) PRIMARY KEY, 
    7272    username character varying(128) DEFAULT ''::character varying NOT NULL, 
    7373    mail_host character varying(128) DEFAULT ''::character varying NOT NULL, 
     
    8787 
    8888CREATE TABLE "session" ( 
    89     sess_id character varying(40) DEFAULT ''::character varying NOT NULL, 
     89    sess_id character varying(40) DEFAULT ''::character varying PRIMARY KEY, 
    9090    created timestamp with time zone DEFAULT now() NOT NULL, 
    9191    changed timestamp with time zone DEFAULT now() NOT NULL, 
     
    102102 
    103103CREATE TABLE identities ( 
    104     identity_id integer DEFAULT nextval('identity_ids'::text) NOT NULL, 
    105     user_id integer DEFAULT 0 NOT NULL, 
     104    identity_id integer DEFAULT nextval('identity_ids'::text) PRIMARY KEY, 
     105    user_id integer NOT NULL REFERENCES users (user_id), 
    106106    del integer DEFAULT 0 NOT NULL, 
    107107    standard integer DEFAULT 0 NOT NULL, 
     
    121121 
    122122CREATE TABLE contacts ( 
    123     contact_id integer DEFAULT nextval('contact_ids'::text) NOT NULL, 
    124     user_id integer DEFAULT 0 NOT NULL, 
     123    contact_id integer DEFAULT nextval('contact_ids'::text) PRIMARY KEY, 
     124    user_id integer NOT NULL REFERENCES users (user_id), 
    125125    changed timestamp with time zone DEFAULT now() NOT NULL, 
    126126    del integer DEFAULT 0 NOT NULL, 
     
    140140 
    141141CREATE TABLE "cache" ( 
    142     cache_id integer DEFAULT nextval('cache_ids'::text) NOT NULL, 
    143     user_id integer DEFAULT 0 NOT NULL, 
    144     session_id character varying(40), 
     142    cache_id integer DEFAULT nextval('cache_ids'::text) PRIMARY KEY, 
     143    user_id integer NOT NULL REFERENCES users (user_id), 
     144    session_id character varying(40) REFERENCES "session" (session_id), 
    145145    cache_key character varying(128) DEFAULT ''::character varying NOT NULL, 
    146146    created timestamp with time zone DEFAULT now() NOT NULL, 
     
    156156 
    157157CREATE TABLE "messages" ( 
    158     message_id integer DEFAULT nextval('message_ids'::text) NOT NULL, 
    159     user_id integer DEFAULT 0 NOT NULL, 
     158    message_id integer DEFAULT nextval('message_ids'::text) PRIMARY KEY, 
     159    user_id integer NOT NULL REFERENCES users (user_id), 
    160160    del integer DEFAULT 0 NOT NULL, 
    161161    cache_key character varying(128) DEFAULT ''::character varying NOT NULL, 
     
    172172); 
    173173 
    174  
    175  
    176 -- 
    177 -- Add primary keys 
    178 -- 
    179  
    180 ALTER TABLE ONLY "cache" 
    181     ADD CONSTRAINT cache_pkey PRIMARY KEY (cache_id); 
    182  
    183  
    184 ALTER TABLE ONLY "contacts" 
    185     ADD CONSTRAINT contacts_pkey PRIMARY KEY (contact_id); 
    186  
    187  
    188 ALTER TABLE ONLY identities 
    189     ADD CONSTRAINT identities_pkey PRIMARY KEY (identity_id); 
    190  
    191  
    192 ALTER TABLE ONLY "session" 
    193     ADD CONSTRAINT session_pkey PRIMARY KEY (sess_id); 
    194  
    195  
    196 ALTER TABLE ONLY "users" 
    197     ADD CONSTRAINT users_pkey PRIMARY KEY (user_id); 
    198  
    199  
    200 ALTER TABLE ONLY "messages" 
    201     ADD CONSTRAINT messages_pkey PRIMARY KEY (message_id); 
    202  
    203  
    204 -- 
    205 -- Reference keys 
    206 -- 
    207  
    208 ALTER TABLE ONLY "cache" 
    209     ADD CONSTRAINT "$1" FOREIGN KEY (user_id) REFERENCES users(user_id); 
    210  
    211 ALTER TABLE ONLY "cache" 
    212     ADD CONSTRAINT "$2" FOREIGN KEY (session_id) REFERENCES "session"(sess_id); 
    213  
    214  
    215 ALTER TABLE ONLY "contacts" 
    216     ADD CONSTRAINT "$1" FOREIGN KEY (user_id) REFERENCES users(user_id); 
    217  
    218  
    219 ALTER TABLE ONLY "identities" 
    220     ADD CONSTRAINT "$1" FOREIGN KEY (user_id) REFERENCES users(user_id); 
    221  
    222  
    223 ALTER TABLE ONLY "messages" 
    224     ADD CONSTRAINT "$1" FOREIGN KEY (user_id) REFERENCES users(user_id); 
    225  
  • UPGRADING

    r1cded85 r15a9d1c  
    2020  $rcmail_config['default_port'] = 143; 
    2121  $rcmail_config['session_lifetime'] = 20; 
     22  $rcmail_config['skip_deleted'] = FALSE; 
    2223  $rcmail_config['message_sort_col'] = 'date'; 
    2324  $rcmail_config['message_sort_order'] = 'DESC'; 
     
    4243  $rcmail_config['default_port'] = 143; 
    4344  $rcmail_config['session_lifetime'] = 20; 
     45  $rcmail_config['skip_deleted'] = FALSE; 
    4446  $rcmail_config['message_sort_col'] = 'date'; 
    4547  $rcmail_config['message_sort_order'] = 'DESC'; 
     
    6264  $rcmail_config['smtp_auth_type'] = '';  // if you need to specify an auth method for SMTP 
    6365  $rcmail_config['session_lifetime'] = 20;  // to specify the session lifetime in minutes 
     66  $rcmail_config['skip_deleted'] = FALSE; 
    6467  $rcmail_config['message_sort_col'] = 'date'; 
    6568  $rcmail_config['message_sort_order'] = 'DESC'; 
     
    8285- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql 
    8386- add these lines to /config/main.inc.php 
     87  $rcmail_config['skip_deleted'] = FALSE; 
    8488  $rcmail_config['message_sort_col'] = 'date'; 
    8589  $rcmail_config['message_sort_order'] = 'DESC'; 
     
    9296  $rcmail_config['db_sequence_contact_ids'] = 'contact_ids'; 
    9397  $rcmail_config['db_sequence_cache_ids'] = 'cache_ids'; 
    94   $rcmail_config['db_sequence_message_ids'] = 'message_ids';   
     98  $rcmail_config['db_sequence_message_ids'] = 'message_ids'; 
     99   
  • config/main.inc.php.dist

    r977a295e r15a9d1c  
    9898$rcmail_config['useragent'] = 'RoundCube Webmail/0.1b'; 
    9999 
     100// use this name to compose page titles 
     101$rcmail_config['product_name'] = 'RoundCube Webmail'; 
     102 
    100103// only list folders within this path 
    101104$rcmail_config['imap_root'] = ''; 
  • index.php

    r977a295e r15a9d1c  
    44 +-----------------------------------------------------------------------+ 
    55 | RoundCube Webmail IMAP Client                                         | 
    6  | Version 0.1-20051214                                                  | 
     6 | Version 0.1-20060104                                                  | 
    77 |                                                                       | 
    88 | Copyright (C) 2005, RoundCube Dev. - Switzerland                      | 
     
    4242*/ 
    4343 
     44define('RCMAIL_VERSION', '0.1-20060104'); 
     45 
     46 
    4447// define global vars 
    4548$INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']); 
     
    241244  if ($_action=='addcontact') 
    242245    include('program/steps/mail/addcontact.inc'); 
     246 
     247  if ($_action=='expunge') 
     248    include('program/steps/mail/folders.inc'); 
     249 
     250  if ($_action=='check-recent') 
     251    include('program/steps/mail/check_recent.inc'); 
     252 
     253  if ($_action=='getunread') 
     254    include('program/steps/mail/getunread.inc'); 
    243255     
    244256  if ($_action=='list' && $_GET['_remote']) 
  • program/include/main.inc

    r977a295e r15a9d1c  
    147147 
    148148  $IMAP = new rcube_imap($DB); 
     149  $IMAP->debug_level = $CONFIG['debug_level']; 
     150  $IMAP->skip_deleted = $CONFIG['skip_deleted']; 
     151 
    149152 
    150153  // connect with stored session data 
     
    592595 
    593596// send correct response on a remote request 
    594 function rcube_remote_response($js_code) 
    595   { 
    596   send_nocacheing_headers(); 
    597   header('Content-Type: application/x-javascript'); 
    598  
    599   print '/** remote response ['.date('d/M/Y h:i:s O')."] **/\n"; 
     597function rcube_remote_response($js_code, $flush=FALSE) 
     598  { 
     599  static $s_header_sent = FALSE; 
     600   
     601  if (!$s_header_sent) 
     602    { 
     603    $s_header_sent = TRUE; 
     604    send_nocacheing_headers(); 
     605    header('Content-Type: application/x-javascript'); 
     606    print '/** remote response ['.date('d/M/Y h:i:s O')."] **/\n"; 
     607    } 
     608 
     609  // send response code 
    600610  print $js_code; 
    601   exit; 
     611 
     612  if ($flush)  // flush the output buffer 
     613    flush(); 
     614  else         // terminate script 
     615    exit; 
    602616  } 
    603617 
     
    880894 
    881895      $object_handlers = array( 
     896        // GENERAL 
     897        'loginform' => 'rcmail_login_form', 
     898        'username'  => 'rcmail_current_username', 
     899         
    882900        // MAIL 
    883901        'mailboxlist' => 'rcmail_mailbox_list', 
     902        'message' => 'rcmail_message_container', 
    884903        'messages' => 'rcmail_message_list', 
    885904        'messagecountdisplay' => 'rcmail_messagecount_display', 
     
    917936      ); 
    918937 
    919       if ($object=='loginform') 
    920         return rcmail_login_form($attrib); 
    921  
    922       else if ($object=='message') 
    923         return rcmail_message_container($attrib); 
    924938       
    925939      // execute object handler function 
    926       else if ($object_handlers[$object] && function_exists($object_handlers[$object])) 
     940      if ($object_handlers[$object] && function_exists($object_handlers[$object])) 
    927941        return call_user_func($object_handlers[$object], $attrib); 
    928942 
     
    930944        { 
    931945        $task = $GLOBALS['_task']; 
     946        $title = !empty($CONFIG['product_name']) ? $CONFIG['product_name'].' :: ' : ''; 
     947         
    932948        if ($task=='mail' && isset($GLOBALS['MESSAGE']['subject'])) 
    933           return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['MESSAGE']['subject']); 
     949          $title .= $GLOBALS['MESSAGE']['subject']; 
    934950        else if (isset($GLOBALS['PAGE_TITLE'])) 
    935           return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['PAGE_TITLE']); 
     951          $title .= $GLOBALS['PAGE_TITLE']; 
    936952        else if ($task=='mail' && ($mbox_name = $IMAP->get_mailbox_name())) 
    937           return "RoundCube|Mail :: ".rep_specialchars_output(UTF7DecodeString($mbox_name), 'html', 'all'); 
     953          $title .= UTF7DecodeString($mbox_name); 
    938954        else 
    939           return "RoundCube|Mail :: $task"; 
     955          $title .= $task; 
     956           
     957        return rep_specialchars_output($title, 'html', 'all'); 
    940958        } 
    941  
    942       else if ($object=='about') 
    943         return ''; 
    944959 
    945960      break; 
     
    12641279   
    12651280  return $out; 
     1281  } 
     1282 
     1283 
     1284// return the IMAP username of the current session 
     1285function rcmail_current_username($attrib) 
     1286  { 
     1287  global $DB; 
     1288  static $s_username; 
     1289 
     1290  // alread fetched   
     1291  if (!empty($s_username)) 
     1292    return $s_username; 
     1293 
     1294  // get e-mail address form default identity 
     1295  $sql_result = $DB->query("SELECT email AS mailto 
     1296                            FROM ".get_table_name('identities')." 
     1297                            WHERE  user_id=? 
     1298                            AND    standard=1 
     1299                            AND    del<>1", 
     1300                            $_SESSION['user_id']); 
     1301                                    
     1302  if ($DB->num_rows($sql_result)) 
     1303    { 
     1304    $sql_arr = $DB->fetch_assoc($sql_result); 
     1305    $s_username = $sql_arr['mailto']; 
     1306    } 
     1307  else if (strstr($_SESSION['username'], '@')) 
     1308    $s_username = $_SESSION['username']; 
     1309  else 
     1310    $s_username = $_SESSION['username'].'@'.$_SESSION['imap_host']; 
     1311 
     1312  return $s_username; 
    12661313  } 
    12671314 
     
    13741421 
    13751422 
     1423 
     1424function rcube_timer() 
     1425  { 
     1426  list($usec, $sec) = explode(" ", microtime()); 
     1427  return ((float)$usec + (float)$sec); 
     1428  } 
     1429   
     1430 
     1431function rcube_print_time($timer, $label='Timer') 
     1432  { 
     1433  static $print_count = 0; 
     1434   
     1435  $print_count++; 
     1436  $now = rcube_timer(); 
     1437  $diff = $now-$timer; 
     1438   
     1439  if (empty($label)) 
     1440    $label = 'Timer '.$print_count; 
     1441   
     1442  console(sprintf("%s: %0.4f sec", $label, $diff)); 
     1443  } 
     1444 
     1445 
    13761446?> 
  • program/include/rcube_db.inc

    r1cded85 r15a9d1c  
    2121*/ 
    2222 
     23 
     24/** 
     25 * Obtain the PEAR::DB class that is used for abstraction 
     26 */ 
    2327require_once('DB.php'); 
    2428 
     29 
     30/** 
     31 * Database independent query interface 
     32 * 
     33 * This is a wrapper for the PEAR::DB class 
     34 * 
     35 * @package    RoundCube Webmail 
     36 * @author     David Saez Padros <david@ols.es> 
     37 * @author     Thomas Bruederli <roundcube@gmail.com> 
     38 * @version    1.14 
     39 * @link       http://pear.php.net/package/DB 
     40 */ 
    2541class rcube_db 
    2642  { 
     
    3551 
    3652 
    37   // PHP 5 constructor 
    38   function __construct($db_dsnw,$db_dsnr='') 
     53  /** 
     54   * Object constructor 
     55   * 
     56   * @param  string  DSN for read/write operations 
     57   * @param  string  Optional DSN for read only operations 
     58   */ 
     59  function __construct($db_dsnw, $db_dsnr='') 
    3960    { 
    4061    if ($db_dsnr=='') 
     
    4970 
    5071 
    51   // PHP 4 compatibility 
     72  /** 
     73   * PHP 4 object constructor 
     74   * 
     75   * @see  rcube_db::__construct 
     76   */ 
    5277  function rcube_db($db_dsnw,$db_dsnr='') 
    5378    { 
     
    5681 
    5782 
    58   // Connect to specific database  
     83  /** 
     84   * Object destructor 
     85   */ 
     86  function __destruct() 
     87    { 
     88    // before closing the database connection, write session data 
     89    session_write_close(); 
     90    }  
     91 
     92 
     93  /** 
     94   * Connect to specific database 
     95   * 
     96   * @param  string  DSN for DB connections 
     97   * @return object  PEAR database handle 
     98   * @access private 
     99   */ 
    59100  function dsn_connect($dsn) 
    60101    { 
     
    63104         
    64105    if (DB::isError($dbh)) 
    65       raise_error(array('code' => 500, 
    66                         'type' => 'db', 
    67                         'line' => __LINE__, 
    68                         'file' => __FILE__, 
     106      { 
     107      raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, 
    69108                        'message' => $dbh->getMessage()), TRUE, FALSE); 
     109      } 
    70110 
    71111    else if ($this->db_provider=='sqlite') 
     
    80120 
    81121 
    82   // Connect to appropiate databse     
    83   function db_connect ($mode) 
     122  /** 
     123   * Connect to appropiate databse 
     124   * depending on the operation 
     125   * 
     126   * @param  string  Connection mode (r|w) 
     127   * @access public 
     128   */ 
     129  function db_connect($mode) 
    84130    { 
    85131    $this->db_mode = $mode; 
     
    100146        return; 
    101147      } 
    102              
     148      
    103149    if ($mode=='r') 
    104150      $dsn = $this->db_dsnr; 
     
    111157 
    112158 
    113   // Query database 
     159  /** 
     160   * Execute a SQL query 
     161   * 
     162   * @param  string  SQL query to execute 
     163   * @param  mixed   Values to be inserted in query 
     164   * @return number  Query handle identifier 
     165   * @access public 
     166   */ 
    114167  function query() 
    115168    { 
     
    121174 
    122175 
    123   // Query with limits 
     176  /** 
     177   * Execute a SQL query with limits 
     178   * 
     179   * @param  string  SQL query to execute 
     180   * @param  number  Offset for LIMIT statement 
     181   * @param  number  Number of rows for LIMIT statement 
     182   * @param  mixed   Values to be inserted in query 
     183   * @return number  Query handle identifier 
     184   * @access public 
     185   */ 
    124186  function limitquery() 
    125187    { 
     
    133195 
    134196 
     197  /** 
     198   * Execute a SQL query with limits 
     199   * 
     200   * @param  string  SQL query to execute 
     201   * @param  number  Offset for LIMIT statement 
     202   * @param  number  Number of rows for LIMIT statement 
     203   * @param  array   Values to be inserted in query 
     204   * @return number  Query handle identifier 
     205   * @access private 
     206   */ 
    135207  function _query($query, $offset, $numrows, $params) 
    136208    { 
     
    156228 
    157229 
     230  /** 
     231   * Get number of rows for a SQL query 
     232   * If no query handle is specified, the last query will be taken as reference 
     233   * 
     234   * @param  number  Optional query handle identifier 
     235   * @return mixed   Number of rows or FALSE on failure 
     236   * @access public 
     237   */ 
    158238  function num_rows($res_id=NULL) 
    159239    { 
     
    168248 
    169249 
    170   function affected_rows($res_id=NULL) 
     250  /** 
     251   * Get number of affected rows fort he last query 
     252   * 
     253   * @return mixed   Number of rows or FALSE on failure 
     254   * @access public 
     255   */ 
     256  function affected_rows() 
    171257    { 
    172258    if (!$this->db_handle) 
     
    177263 
    178264 
     265  /** 
     266   * Get last inserted record ID 
     267   * For Postgres databases, a sequence name is required 
     268   * 
     269   * @param  string  Sequence name for increment 
     270   * @return mixed   ID or FALSE on failure 
     271   * @access public 
     272   */ 
    179273  function insert_id($sequence = '') 
    180274    { 
     
    186280      case 'pgsql': 
    187281        // PostgreSQL uses sequences 
    188         $result =& $this->db_handle->getOne("SELECT CURRVAL('$sequence')");     
     282        $result = &$this->db_handle->getOne("SELECT CURRVAL('$sequence')"); 
    189283        if (DB::isError($result)) 
     284          { 
    190285          raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,  
    191286                            'message' => $result->getMessage()), TRUE, FALSE); 
     287          } 
    192288 
    193289        return $result; 
     
    208304 
    209305 
     306  /** 
     307   * Get an associative array for one row 
     308   * If no query handle is specified, the last query will be taken as reference 
     309   * 
     310   * @param  number  Optional query handle identifier 
     311   * @return mixed   Array with col values or FALSE on failure 
     312   * @access public 
     313   */ 
    210314  function fetch_assoc($res_id=NULL) 
    211315    { 
     
    223327 
    224328 
    225   function quote($input, $type=null) 
    226     { 
     329  /** 
     330   * Formats input so it can be safely used in a query 
     331   * 
     332   * @param  mixed   Value to quote 
     333   * @return string  Quoted/converted string for use in query 
     334   * @access public 
     335   */ 
     336  function quote($input) 
     337    { 
     338    // create DB handle if not available 
    227339    if (!$this->db_handle) 
    228340      $this->db_connect('r'); 
    229  
    230     return $this->db_handle->quote($input); 
     341       
     342    // escape pear identifier chars 
     343    $rep_chars = array('?' => '\?', 
     344                       '!' => '\!', 
     345                       '&' => '\&'); 
     346       
     347    return $this->db_handle->quoteSmart(strtr($input, $rep_chars)); 
    231348    } 
    232349     
    233350 
     351  /** 
     352   * Quotes a string so it can be safely used as a table or column name 
     353   * 
     354   * @param  string  Value to quote 
     355   * @return string  Quoted string for use in query 
     356   * @deprecated     Replaced by rcube_db::quote_identifier 
     357   * @see            rcube_db::quote_identifier 
     358   * @access public 
     359   */ 
    234360  function quoteIdentifier($str) 
    235361        { 
     362    return $this->quote_identifier($str); 
     363        } 
     364 
     365 
     366  /** 
     367   * Quotes a string so it can be safely used as a table or column name 
     368   * 
     369   * @param  string  Value to quote 
     370   * @return string  Quoted string for use in query 
     371   * @access public 
     372   */ 
     373  function quote_identifier($str) 
     374    { 
    236375    if (!$this->db_handle) 
    237376      $this->db_connect('r'); 
    238377                         
    239378    return $this->db_handle->quoteIdentifier($str); 
    240         } 
    241  
    242  
    243   function quote_identifier($str) 
    244     { 
    245     return $this->quoteIdentifier($str); 
    246     } 
    247  
    248  
     379    } 
     380 
     381 
     382  /** 
     383   * Return SQL statement to convert a field value into a unix timestamp 
     384   * 
     385   * @param  string  Field name 
     386   * @return string  SQL statement to use in query 
     387   * @access public 
     388   */ 
    249389  function unixtimestamp($field) 
    250390    { 
     
    261401 
    262402 
     403  /** 
     404   * Return SQL statement to convert from a unix timestamp 
     405   * 
     406   * @param  string  Field name 
     407   * @return string  SQL statement to use in query 
     408   * @access public 
     409   */ 
    263410  function fromunixtime($timestamp) 
    264411    { 
     
    276423 
    277424 
     425  /** 
     426   * Adds a query result and returns a handle ID 
     427   * 
     428   * @param  object  Query handle 
     429   * @return mixed   Handle ID or FALE on failure 
     430   * @access private 
     431   */ 
    278432  function _add_result($res) 
    279433    { 
     
    282436      { 
    283437      raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, 
    284                         'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 1024)), TRUE, FALSE); 
     438                        'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 512)), TRUE, FALSE); 
    285439      return FALSE; 
    286440      } 
     
    295449 
    296450 
    297   function _get_result($res_id) 
     451  /** 
     452   * Resolves a given handle ID and returns the according query handle 
     453   * If no ID is specified, the last ressource handle will be returned 
     454   * 
     455   * @param  number  Handle ID 
     456   * @return mixed   Ressource handle or FALE on failure 
     457   * @access private 
     458   */ 
     459  function _get_result($res_id=NULL) 
    298460    { 
    299461    if ($res_id==NULL) 
     
    307469 
    308470 
    309   // create a sqlite database from a file 
    310   function _sqlite_create_database($dbh, $fileName) 
    311     { 
    312     if (empty($fileName) || !is_string($fileName)) 
    313       return ; 
     471  /** 
     472   * Create a sqlite database from a file 
     473   * 
     474   * @param  object  SQLite database handle 
     475   * @param  string  File path to use for DB creation 
     476   * @access private 
     477   */ 
     478  function _sqlite_create_database($dbh, $file_name) 
     479    { 
     480    if (empty($file_name) || !is_string($file_name)) 
     481      return; 
    314482 
    315483    $data = ''; 
    316     if ($fd = fopen($fileName, 'r')) 
    317       { 
    318       $data = fread($fd, filesize($fileName)); 
     484    if ($fd = fopen($file_name, 'r')) 
     485      { 
     486      $data = fread($fd, filesize($file_name)); 
    319487      fclose($fd); 
    320488      } 
     
    324492    } 
    325493 
     494 
     495  /** 
     496   * Add some proprietary database functions to the current SQLite handle 
     497   * in order to make it MySQL compatible 
     498   * 
     499   * @access private 
     500   */ 
    326501  function _sqlite_prepare() 
    327502    { 
     
    335510    } 
    336511 
    337 /* 
    338   // transform a query so that it is sqlite2 compliant 
    339   function _sqlite_prepare_query($query) 
    340     { 
    341     if (!is_string($query)) 
    342       return ($query); 
    343  
    344  
    345     $search = array('/NOW\(\)/i', '/`/'); 
    346     $replace = array("datetime('now')", '"'); 
    347     $query = preg_replace($search, $replace, $query); 
    348  
    349     return ($query); 
    350     } 
    351 */ 
     512 
    352513  }  // end class rcube_db 
    353514 
  • program/include/rcube_imap.inc

    r749b07c r15a9d1c  
    2222 
    2323 
     24/** 
     25 * Obtain classes from the Iloha IMAP library 
     26 */ 
    2427require_once('lib/imap.inc'); 
    2528require_once('lib/mime.inc'); 
     
    2730 
    2831 
     32/** 
     33 * Interface class for accessing an IMAP server 
     34 * 
     35 * This is a wrapper that implements the Iloha IMAP Library (IIL) 
     36 * 
     37 * @package    RoundCube Webmail 
     38 * @author     Thomas Bruederli <roundcube@gmail.com> 
     39 * @version    1.22 
     40 * @link       http://ilohamail.org 
     41 */ 
    2942class rcube_imap 
    3043  { 
     
    4760  var $msg_headers = array(); 
    4861  var $capabilities = array(); 
    49  
    50  
    51   // PHP 5 constructor 
     62  var $skip_deleted = FALSE; 
     63  var $debug_level = 1; 
     64 
     65 
     66  /** 
     67   * Object constructor 
     68   * 
     69   * @param  object  Database connection 
     70   */ 
    5271  function __construct($db_conn) 
    5372    { 
     
    5574    } 
    5675 
    57   // PHP 4 compatibility 
     76 
     77  /** 
     78   * PHP 4 object constructor 
     79   * 
     80   * @see  rcube_imap::__construct 
     81   */ 
    5882  function rcube_imap($db_conn) 
    5983    { 
     
    6286 
    6387 
     88  /** 
     89   * Connect to an IMAP server 
     90   * 
     91   * @param  string   Host to connect 
     92   * @param  string   Username for IMAP account 
     93   * @param  string   Password for IMAP account 
     94   * @param  number   Port to connect to 
     95   * @param  boolean  Use SSL connection 
     96   * @return boolean  TRUE on success, FALSE on failure 
     97   * @access public 
     98   */ 
    6499  function connect($host, $user, $pass, $port=143, $use_ssl=FALSE) 
    65100    { 
    66     global $ICL_SSL, $ICL_PORT, $CONFIG; 
     101    global $ICL_SSL, $ICL_PORT; 
    67102     
    68103    // check for Open-SSL support in PHP build 
     
    71106    else if ($use_ssl) 
    72107      { 
    73       raise_error(array('code' => 403, 
    74                         'type' => 'imap', 
    75                         'file' => __FILE__, 
     108      raise_error(array('code' => 403, 'type' => 'imap', 'file' => __FILE__, 
    76109                        'message' => 'Open SSL not available;'), TRUE, FALSE); 
    77110      $port = 143; 
     
    87120     
    88121    // print trace mesages 
    89     if ($this->conn && ($CONFIG['debug_level'] & 8)) 
     122    if ($this->conn && ($this->debug_level & 8)) 
    90123      console($this->conn->message); 
    91124     
     
    117150 
    118151 
     152  /** 
     153   * Close IMAP connection 
     154   * Usually done on script shutdown 
     155   * 
     156   * @access public 
     157   */ 
    119158  function close() 
    120159    {     
     
    124163 
    125164 
     165  /** 
     166   * Close IMAP connection and re-connect 
     167   * This is used to avoid some strange socket errors when talking to Courier IMAP 
     168   * 
     169   * @access public 
     170   */ 
    126171  function reconnect() 
    127172    { 
     
    131176 
    132177 
     178  /** 
     179   * Set a root folder for the IMAP connection. 
     180   * 
     181   * Only folders within this root folder will be displayed 
     182   * and all folder paths will be translated using this folder name 
     183   * 
     184   * @param  string   Root folder 
     185   * @access public 
     186   */ 
    133187  function set_rootdir($root) 
    134188    { 
     
    143197 
    144198 
     199  /** 
     200   * This list of folders will be listed above all other folders 
     201   * 
     202   * @param  array  Indexed list of folder names 
     203   * @access public 
     204   */ 
    145205  function set_default_mailboxes($arr) 
    146206    { 
     
    160220 
    161221 
     222  /** 
     223   * Set internal mailbox reference. 
     224   * 
     225   * All operations will be perfomed on this mailbox/folder 
     226   * 
     227   * @param  string  Mailbox/Folder name 
     228   * @access public 
     229   */ 
    162230  function set_mailbox($mbox) 
    163231    { 
     
    174242 
    175243 
     244  /** 
     245   * Set internal list page 
     246   * 
     247   * @param  number  Page number to list 
     248   * @access public 
     249   */ 
    176250  function set_page($page) 
    177251    { 
     
    180254 
    181255 
     256  /** 
     257   * Set internal page size 
     258   * 
     259   * @param  number  Number of messages to display on one page 
     260   * @access public 
     261   */ 
    182262  function set_pagesize($size) 
    183263    { 
     
    186266 
    187267 
     268  /** 
     269   * Returns the currently used mailbox name 
     270   * 
     271   * @return  string Name of the mailbox/folder 
     272   * @access  public 
     273   */ 
    188274  function get_mailbox_name() 
    189275    { 
     
    192278 
    193279 
     280  /** 
     281   * Returns the IMAP server's capability 
     282   * 
     283   * @param   string  Capability name 
     284   * @return  mixed   Capability value or TRUE if supported, FALSE if not 
     285   * @access  public 
     286   */ 
    194287  function get_capability($cap) 
    195288    { 
     
    199292 
    200293 
     294  /** 
     295   * Returns the delimiter that is used by the IMAP server for folder separation 
     296   * 
     297   * @return  string  Delimiter string 
     298   * @access  public 
     299   */ 
    201300  function get_hierarchy_delimiter() 
    202301    { 
     
    210309    } 
    211310 
    212   // public method for mailbox listing 
    213   // convert mailbox name with root dir first 
     311 
     312  /** 
     313   * Public method for mailbox listing. 
     314   * 
     315   * Converts mailbox name with root dir first 
     316   * 
     317   * @param   string  Optional root folder 
     318   * @param   string  Optional filter for mailbox listing 
     319   * @return  array   List of mailboxes/folders 
     320   * @access  public 
     321   */ 
    214322  function list_mailboxes($root='', $filter='*') 
    215323    { 
     
    230338    } 
    231339 
    232   // private method for mailbox listing 
     340 
     341  /** 
     342   * Private method for mailbox listing 
     343   * 
     344   * @return  array   List of mailboxes/folders 
     345   * @access  private 
     346   * @see     rcube_imap::list_mailboxes 
     347   */ 
    233348  function _list_mailboxes($root='', $filter='*') 
    234349    { 
     
    262377 
    263378 
    264   // get message count for a specific mailbox; acceptes modes are: ALL, UNSEEN 
     379  // get message count for a specific mailbox; acceptes modes are: ALL, UNSEEN, RECENT 
    265380  function messagecount($mbox='', $mode='ALL', $force=FALSE) 
    266381    { 
     
    275390    $mode = strtoupper($mode); 
    276391 
    277     if (!$mailbox) 
     392    if (empty($mailbox)) 
    278393      $mailbox = $this->mailbox; 
    279394 
     
    283398    if (!$force && is_array($a_mailbox_cache[$mailbox]) && isset($a_mailbox_cache[$mailbox][$mode])) 
    284399      return $a_mailbox_cache[$mailbox][$mode]; 
    285        
    286     $search_str = "ALL UNDELETED"; 
    287  
    288     // get message count and store in cache 
    289     if ($mode == 'UNSEEN') 
    290       $search_str .= " UNSEEN"; 
    291  
    292     // get message count using SEARCH 
    293     // not very performant but more precise (using UNDELETED) 
    294     $count = 0; 
    295     $index = $this->_search_index($mailbox, $search_str); 
    296     if (is_array($index)) 
    297       { 
    298       $str = implode(",", $index); 
    299       if (!empty($str)) 
    300         $count = count($index); 
     400 
     401    // RECENT count is fetched abit different       
     402    if ($mode == 'RECENT') 
     403       $count = iil_C_CheckForRecent($this->conn, $mailbox); 
     404 
     405    // use SEARCH for message counting 
     406    else if ($this->skip_deleted) 
     407      { 
     408      $search_str = "ALL UNDELETED"; 
     409 
     410      // get message count and store in cache 
     411      if ($mode == 'UNSEEN') 
     412        $search_str .= " UNSEEN"; 
     413 
     414      // get message count using SEARCH 
     415      // not very performant but more precise (using UNDELETED) 
     416      $count = 0; 
     417      $index = $this->_search_index($mailbox, $search_str); 
     418      if (is_array($index)) 
     419        { 
     420        $str = implode(",", $index); 
     421        if (!empty($str)) 
     422          $count = count($index); 
     423        } 
     424      } 
     425    else 
     426      { 
     427      if ($mode == 'UNSEEN') 
     428        $count = iil_C_CountUnseen($this->conn, $mailbox); 
     429      else 
     430        $count = iil_C_CountMessages($this->conn, $mailbox); 
    301431      } 
    302432 
     
    349479      { 
    350480      $begin = $start_msg; 
    351       $end $start_msg + $this->page_size; 
     481      $end   = $start_msg + $this->page_size; 
    352482      } 
    353483 
     
    373503      { 
    374504      // retrieve headers from IMAP 
    375       if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field))) 
    376         { 
    377 //console("$mailbox: ".count($msg_index)); 
     505      if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : ''))) 
     506        { 
     507//console("$mailbox: ".join(',', $msg_index)); 
    378508         
    379509        $msgs = $msg_index[$begin]; 
    380         for ($i=$begin; $i < $end; $i++) 
     510        for ($i=$begin+1; $i < $end; $i++) 
    381511          { 
    382           if ($this->sort_order == 'DESC') 
    383             $msgs = $msg_index[$i].','.$msgs; 
    384           else 
     512          //if ($this->sort_order == 'DESC') 
     513          //  $msgs = $msg_index[$i].','.$msgs; 
     514          //else 
    385515            $msgs = $msgs.','.$msg_index[$i]; 
    386516          } 
     
    402532        }       
    403533 
    404  
    405       // cache is incomplete 
    406       $cache_index = $this->get_message_cache_index($cache_key); 
    407534         
    408535      // fetch reuested headers from server 
    409536      $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs); 
    410537      $a_msg_headers = array(); 
    411       $deleted_count = 0; 
    412        
    413       if (!empty($a_header_index)) 
    414         { 
    415         foreach ($a_header_index as $i => $headers) 
    416           { 
    417           if ($headers->deleted) 
    418             { 
    419             // delete from cache 
    420             if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid) 
    421               $this->remove_message_cache($cache_key, $headers->id); 
    422  
    423             $deleted_count++; 
    424             continue; 
    425             } 
    426  
    427           // add message to cache 
    428           if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid) 
    429             $this->add_message_cache($cache_key, $headers->id, $headers); 
    430  
    431           $a_msg_headers[$headers->uid] = $headers; 
    432           } 
    433         } 
     538      $deleted_count = $this->_fetch_headers($mailbox, $msgs, $a_msg_headers, $cache_key); 
    434539 
    435540      // delete cached messages with a higher index than $max 
    436541      $this->clear_message_cache($cache_key, $max); 
    437542 
    438  
    439       // fetch more headers of there were any deleted messages 
    440       // ... 
    441  
     543         
    442544      // kick child process to sync cache 
    443545      // ... 
     
    457559    return array_values($a_msg_headers); 
    458560    } 
     561 
     562 
     563  /** 
     564   * Fetches message headers 
     565   * Used for loop 
     566   * 
     567   * @param  string  Mailbox name 
     568   * @param  string  Message indey to fetch 
     569   * @param  array   Reference to message headers array 
     570   * @param  array   Array with cache index 
     571   * @return number  Number of deleted messages 
     572   * @access private 
     573   */ 
     574  function _fetch_headers($mailbox, $msgs, &$a_msg_headers, $cache_key) 
     575    { 
     576    // cache is incomplete 
     577    $cache_index = $this->get_message_cache_index($cache_key); 
     578 
     579    // fetch reuested headers from server 
     580    $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs); 
     581    $deleted_count = 0; 
     582     
     583    if (!empty($a_header_index)) 
     584      { 
     585      foreach ($a_header_index as $i => $headers) 
     586        { 
     587        if ($headers->deleted && $this->skip_deleted) 
     588          { 
     589          // delete from cache 
     590          if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid) 
     591            $this->remove_message_cache($cache_key, $headers->id); 
     592 
     593          $deleted_count++; 
     594          continue; 
     595          } 
     596 
     597        // add message to cache 
     598        if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid) 
     599          $this->add_message_cache($cache_key, $headers->id, $headers); 
     600 
     601        $a_msg_headers[$headers->uid] = $headers; 
     602        } 
     603      } 
     604         
     605    return $deleted_count; 
     606    } 
     607     
    459608 
    460609 
     
    585734 
    586735 
    587   function get_headers($uid, $mbox=NULL) 
     736  function get_headers($id, $mbox=NULL, $is_uid=TRUE) 
    588737    { 
    589738    $mailbox = $mbox ? $this->_mod_mailbox($mbox) : $this->mailbox; 
     
    593742      return $headers; 
    594743 
    595     $msg_id = $this->_uid2id($uid); 
     744    $msg_id = $is_uid ? $this->_uid2id($id) : $id; 
    596745    $headers = iil_C_FetchHeader($this->conn, $mailbox, $msg_id); 
    597746 
     
    803952 
    804953  // clear all messages in a specific mailbox 
    805   function clear_mailbox($mbox) 
    806     { 
    807     $mailbox = $mbox ? $this->_mod_mailbox($mbox) : $this->mailbox; 
     954  function clear_mailbox($mbox=NULL) 
     955    { 
     956    $mailbox = !empty($mbox) ? $this->_mod_mailbox($mbox) : $this->mailbox; 
    808957    $msg_count = $this->_messagecount($mailbox, 'ALL'); 
    809958     
     
    12711420      $index, 
    12721421      $headers->uid, 
    1273       $this->decode_header($headers->subject, TRUE), 
    1274       $this->decode_header($headers->from, TRUE), 
    1275       $this->decode_header($headers->to, TRUE), 
    1276       $this->decode_header($headers->cc, TRUE), 
     1422      substr($this->decode_header($headers->subject, TRUE), 0, 128), 
     1423      substr($this->decode_header($headers->from, TRUE), 0, 128), 
     1424      substr($this->decode_header($headers->to, TRUE), 0, 128), 
     1425      substr($this->decode_header($headers->cc, TRUE), 0, 128), 
    12771426      (int)$headers->size, 
    12781427      serialize($headers)); 
  • program/js/app.js

    r977a295e r15a9d1c  
    77 | Licensed under the GNU GPL                                            | 
    88 |                                                                       | 
    9  | Modified: 2005/12/16 (roundcube)                                      | 
    10  |                                                                       | 
    119 +-----------------------------------------------------------------------+ 
    1210 | Author: Thomas Bruederli <roundcube@gmail.com>                        | 
    1311 +-----------------------------------------------------------------------+ 
     12  
     13  $Id$ 
    1414*/ 
    1515 
     
    138138           
    139139        if (this.env.messagecount) 
    140           this.enable_command('select-all', 'select-none', 'sort', true); 
     140          this.enable_command('select-all', 'select-none', 'sort', 'expunge', true); 
    141141 
    142142        this.set_page_buttons(); 
     
    152152        if (this.env.action=='print') 
    153153          window.print(); 
     154           
     155        // get unread count for each mailbox 
     156        if (this.gui_objects.mailboxlist) 
     157          this.http_request('getunread', ''); 
    154158 
    155159        break; 
     
    220224      this.display_message(this.pending_message[0], this.pending_message[1]); 
    221225       
    222     // start interval for keep-alive siganl 
     226    // start interval for keep-alive/recent_check signal 
    223227    if (this.kepp_alive_interval) 
    224       this.kepp_alive_int = setInterval(this.ref+'.send_keep_alive()', this.kepp_alive_interval); 
     228      this.kepp_alive_int = setInterval(this.ref+'.'+(this.task=='mail'?'check_for_recent()':'send_keep_alive()'), this.kepp_alive_interval); 
    225229    }; 
    226230 
     
    437441      return false; 
    438442      } 
     443       
     444       
     445   // check input before leaving compose step 
     446   if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings')) 
     447     { 
     448     if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) 
     449        return false; 
     450     } 
     451 
    439452 
    440453    // process command 
     
    461474      case 'list': 
    462475        if (this.task=='mail') 
    463           { 
    464           // check input before leaving compose step 
    465           if (this.env.action=='compose' && this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning'))) 
    466               break; 
    467  
    468476          this.list_mailbox(props); 
    469           } 
    470477        else if (this.task=='addressbook') 
    471478          this.list_contacts(); 
     
    511518      case 'previouspage': 
    512519        this.list_page('prev'); 
     520        break; 
     521 
     522      case 'expunge': 
     523        if (this.env.messagecount) 
     524          this.expunge_mailbox(this.env.mailbox); 
     525        break; 
     526 
     527      case 'clear-mailbox': 
     528        //if (this.env.messagecount) 
     529          //this.clear_mailbox(this.env.mailbox); 
    513530        break; 
    514531 
     
    11691186  this.list_mailbox_remote = function(mbox, page, add_url) 
    11701187    { 
    1171     // clear message list 
     1188    // clear message list first 
     1189    this.clear_message_list(); 
     1190 
     1191    // send request to server 
     1192    var url = '_mbox='+escape(mbox)+(page ? '&_page='+page : ''); 
     1193    this.set_busy(true, 'loading'); 
     1194    this.http_request('list', url+add_url, true); 
     1195    }; 
     1196 
     1197 
     1198  this.clear_message_list = function() 
     1199    { 
    11721200    var table = this.gui_objects.messagelist; 
    11731201    var tbody = document.createElement('TBODY'); 
     
    11771205    this.message_rows = new Array(); 
    11781206    this.list_rows = this.message_rows; 
     1207     
     1208    }; 
     1209 
     1210 
     1211  this.expunge_mailbox = function(mbox) 
     1212    { 
     1213    var lock = false; 
     1214    var add_url = ''; 
     1215     
     1216    // lock interface if it's the active mailbox 
     1217    if (mbox == this.env.mailbox) 
     1218       { 
     1219       lock = true; 
     1220       this.set_busy(true, 'loading'); 
     1221       add_url = '&_reload=1'; 
     1222       } 
    11791223 
    11801224    // send request to server 
    1181     var url = '_mbox='+escape(mbox)+(page ? '&_page='+page : ''); 
    1182     this.set_busy(true, 'loading'); 
    1183     this.http_request('list', url+add_url, true); 
     1225    var url = '_mbox='+escape(mbox); 
     1226    this.http_request('expunge', url+add_url, lock); 
    11841227    }; 
    11851228 
     
    22642307 
    22652308  // create a table row in the message list 
    2266   this.add_message_row = function(uid, cols, flags, attachment) 
     2309  this.add_message_row = function(uid, cols, flags, attachment, attop) 
    22672310    { 
    22682311    if (!this.gui_objects.messagelist || !this.gui_objects.messagelist.tBodies[0]) 
     
    22782321    var row = document.createElement('TR'); 
    22792322    row.id = 'rcmrow'+uid; 
    2280     row.className = 'message '+(even ? 'even' : 'odd')+(flags.unread ? ' unread' : ''); 
    2281  
     2323    row.className = 'message '+(even ? 'even' : 'odd')+(flags.unread ? ' unread' : '')+(flags.deleted ? ' deleted' : ''); 
     2324     
    22822325    if (this.in_selection(uid)) 
    22832326      row.className += ' selected'; 
     
    23052348    row.appendChild(col); 
    23062349     
    2307     tbody.appendChild(row); 
     2350    if (attop && tbody.rows.length) 
     2351      tbody.insertBefore(row, tbody.firstChild); 
     2352    else 
     2353      tbody.appendChild(row); 
     2354       
    23082355    this.init_message_row(row); 
    23092356    }; 
     
    23222369 
    23232370  // update the mailboxlist 
    2324   this.set_unread_count = function(mbox, count) 
     2371  this.set_unread_count = function(mbox, count, set_title) 
    23252372    { 
    23262373    if (!this.gui_objects.mailboxlist) 
    23272374      return false; 
    23282375       
     2376    var item, reg, text_obj; 
    23292377    mbox = String(mbox).toLowerCase().replace(this.mbox_expression, ''); 
    2330      
    2331     var item, reg, text_obj; 
    2332     for (var n=0; n<this.gui_objects.mailboxlist.childNodes.length; n++) 
    2333       { 
    2334       item = this.gui_objects.mailboxlist.childNodes[n]; 
    2335  
    2336       if (item.className && item.className.indexOf('mailbox '+mbox)>=0) 
    2337         { 
    2338         // set new text 
    2339         text_obj = item.firstChild; 
    2340         reg = /\s+\([0-9]+\)$/i; 
    2341  
    2342         if (count && text_obj.innerHTML.match(reg)) 
    2343           text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+count+')'); 
    2344         else if (count) 
    2345           text_obj.innerHTML += ' ('+count+')'; 
    2346         else 
    2347           text_obj.innerHTML = text_obj.innerHTML.replace(reg, ''); 
     2378    item = document.getElementById('rcmbx'+mbox); 
     2379 
     2380    if (item && item.className && item.className.indexOf('mailbox '+mbox)>=0) 
     2381      { 
     2382      // set new text 
     2383      text_obj = item.firstChild; 
     2384      reg = /\s+\([0-9]+\)$/i; 
     2385 
     2386      if (count && text_obj.innerHTML.match(reg)) 
     2387        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+count+')'); 
     2388      else if (count) 
     2389        text_obj.innerHTML += ' ('+count+')'; 
     2390      else 
     2391        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ''); 
    23482392           
    2349         // set the right classes 
    2350         this.set_classname(item, 'unread', count>0 ? true : false);         
    2351         break; 
    2352         } 
     2393      // set the right classes 
     2394      this.set_classname(item, 'unread', count>0 ? true : false); 
     2395      } 
     2396 
     2397    // set unread count to window title 
     2398    if (set_title && document.title) 
     2399      { 
     2400      var doc_title = String(document.title); 
     2401      reg = /^\([0-9]+\)\s+/i; 
     2402 
     2403      if (count && doc_title.match(reg)) 
     2404        document.title = doc_title.replace(reg, '('+count+') '); 
     2405      else if (count) 
     2406        document.title = '('+count+') '+doc_title; 
     2407      else 
     2408        document.title = doc_title.replace(reg, ''); 
    23532409      } 
    23542410    }; 
     
    25282584          this.command('list'); 
    25292585        break; 
    2530            
     2586 
    25312587      case 'list': 
    2532         this.enable_command('select-all', 'select-none', this.env.messagecount ? true : false); 
     2588      case 'expunge': 
     2589        this.enable_command('select-all', 'select-none', 'expunge', this.env.messagecount ? true : false); 
    25332590        break; 
    25342591      } 
     
    25572614    this.http_request('keep-alive', '_t='+d.getTime()); 
    25582615    }; 
    2559      
     2616 
     2617     
     2618  // send periodic request to check for recent messages 
     2619  this.check_for_recent = function() 
     2620    { 
     2621    var d = new Date(); 
     2622    this.http_request('check-recent', '_t='+d.getTime()); 
     2623    }; 
    25602624 
    25612625 
  • program/js/common.js

    r10a69975 r15a9d1c  
    270270  if (input && window.RegExp) 
    271271    { 
    272     var reg_str = '([a-z0-9][-a-z0-9\.\+_]*)\@([a-z0-9]([-a-z0-9][\.]?)*[a-z0-9]\.[a-z]{2,9})'; 
     272    var reg_str = '([a-z0-9][-a-z0-9\.\+_]*)\@(([-a-z0-9][\.]?)*[a-z0-9]\.[a-z]{2,9})'; 
    273273    var reg1 = inline ? new RegExp(reg_str, 'i') : new RegExp('^'+reg_str+'$', 'i'); 
    274274    var reg2 = /[\._\-\@]{2}/; 
  • program/lib/imap.inc

    r31b2cee r15a9d1c  
    608608} 
    609609 
    610 function iil_C_Sort(&$conn, $mailbox, $field){ 
     610function iil_C_Sort(&$conn, $mailbox, $field, $add=''){ 
    611611        /*  Do "SELECT" command */ 
    612612        if (!iil_C_Select($conn, $mailbox)) return false; 
     
    619619         
    620620        $fp = $conn->fp; 
    621         $command = 's SORT ('.$field.') US-ASCII ALL UNDELETED'."\r\n"; 
     621        $command = 's SORT ('.$field.') US-ASCII ALL '."$add\r\n"; 
     622        //$command = 's SORT ('.$field.') US-ASCII ALL UNDELETED'."\r\n"; 
    622623        $line = $data = ''; 
    623624         
  • program/localization/de/labels.inc

    r1cded85 r15a9d1c  
    106106$labels['unread'] = 'Ungelesene'; 
    107107 
     108$labels['compact'] = 'Packen'; 
     109 
     110 
    108111// message compose // Nachrichten erstellen 
    109112$labels['compose']  = 'Neue Nachricht verfassen'; 
     
    168171$labels['signature'] = 'Signatur'; 
    169172 
     173$labels['folder']  = 'Ordner'; 
    170174$labels['folders']  = 'Ordner'; 
    171175$labels['foldername']  = 'Ordnername'; 
  • program/localization/en/labels.inc

    r1cded85 r15a9d1c  
    106106$labels['unread'] = 'Unread'; 
    107107 
     108$labels['compact'] = 'Compact'; 
     109 
     110 
    108111// message compose 
    109112$labels['compose']  = 'Compose a message'; 
     
    168171$labels['signature'] = 'Signature'; 
    169172 
     173$labels['folder']  = 'Folder'; 
    170174$labels['folders']  = 'Folders'; 
    171175$labels['foldername']  = 'Folder name'; 
  • program/steps/mail/func.inc

    r749b07c r15a9d1c  
    7070  static $a_mailboxes; 
    7171   
     72// $mboxlist_start = rcube_timer(); 
     73   
    7274  $type = $attrib['type'] ? $attrib['type'] : 'ul'; 
    7375  $add_attrib = $type=='select' ? array('style', 'class', 'id', 'name', 'onchange') : 
     
    101103    $delimiter = $IMAP->get_hierarchy_delimiter(); 
    102104    $a_mailboxes = array(); 
    103      
     105 
     106// rcube_print_time($mboxlist_start, 'list_mailboxes()'); 
     107 
    104108    foreach ($a_folders as $folder) 
    105109      rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); 
     
    112116   else 
    113117    $out .= rcmail_render_folder_tree_html($a_mailboxes, $special_mailboxes, $mbox, $attrib['maxlength']); 
     118 
     119// rcube_print_time($mboxlist_start, 'render_folder_tree()'); 
    114120 
    115121 
     
    182188 
    183189    // add unread message count display 
    184     if ($unread_count = $IMAP->messagecount($folder['id'], 'UNSEEN', ($folder['id']==$mbox))) 
     190    if ($unread_count = $IMAP->messagecount($folder['id'], 'RECENT', ($folder['id']==$mbox))) 
    185191      $foldername .= sprintf(' (%d)', $unread_count); 
    186192       
     
    398404      $attach_icon = $attrib['attachmenticon']; 
    399405         
    400     $out .= sprintf('<tr id="rcmrow%d" class="message'.($header->seen ? '' : ' unread').' '.$zebra_class.'">'."\n", $header->uid); 
     406    $out .= sprintf('<tr id="rcmrow%d" class="message%s%s %s">'."\n", 
     407                    $header->uid, 
     408                    $header->seen ? '' : ' unread', 
     409                    $header->deleted ? ' deleted' : '', 
     410                    $zebra_class);     
     411     
    401412    $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : ''); 
    402413         
     
    496507    $a_msg_flags['unread'] = $header->seen ? 0 : 1; 
    497508    $a_msg_flags['replied'] = $header->answered ? 1 : 0; 
    498    
    499     $commands .= sprintf("this.add_message_row(%s, %s, %s, %b);\n", 
     509     
     510    if ($header->deleted) 
     511      $a_msg_flags['deleted'] = 1; 
     512   
     513    $commands .= sprintf("this.add_message_row(%s, %s, %s, %b, %b);\n", 
    500514                         $header->uid, 
    501515                         array2js($a_msg_cols), 
    502516                         array2js($a_msg_flags), 
    503                          preg_match("/multipart\/m/i", $header->ctype)); 
     517                         preg_match("/multipart\/m/i", $header->ctype), 
     518                         $insert_top); 
    504519    } 
    505520 
     
    13781393  if (is_array($_SESSION['compose']['attachments'])) 
    13791394    foreach ($_SESSION['compose']['attachments'] as $attachment) 
    1380       unlink($attachment['path']); 
     1395      @unlink($attachment['path']); 
    13811396 
    13821397  // kill temp dir 
    13831398  if ($_SESSION['compose']['temp_dir']) 
    1384     rmdir($_SESSION['compose']['temp_dir']); 
     1399    @rmdir($_SESSION['compose']['temp_dir']); 
    13851400   
    13861401  unset($_SESSION['compose']); 
  • program/steps/mail/sendmail.inc

    r749b07c r15a9d1c  
    225225  // unset some headers because they will be added by the mail() function 
    226226  $headers_php = $headers; 
     227  $headers_enc = $MAIL_MIME->headers($headers); 
    227228  unset($headers_php['To'], $headers_php['Subject']); 
    228229 
     230  // reset stored headers and overwrite 
     231  $MAIL_MIME->_headers = array(); 
    229232  $header_str = $MAIL_MIME->txtHeaders($headers_php); 
    230233   
    231234  if(ini_get('safe_mode')) 
    232     $sent = mail($mailto, $msg_subject, $msg_body, $header_str); 
    233   else   
    234     $sent = mail($mailto, $msg_subject, $msg_body, $header_str, "-f$from"); 
     235    $sent = mail($headers_enc['To'], $headers_enc['Subject'], $msg_body, $header_str); 
     236  else 
     237    $sent = mail($headers_enc['To'], $headers_enc['Subject'], $msg_body, $header_str, "-f$from"); 
    235238  } 
    236239 
  • program/steps/mail/upload.inc

    r597170f r15a9d1c  
    4040  { 
    4141  $tmpfname = tempnam($temp_dir, 'rcmAttmnt'); 
    42   if (copy($filepath, $tmpfname)) 
     42  if (move_uploaded_file($filepath, $tmpfname)) 
    4343    { 
    4444    $_SESSION['compose']['attachments'][] = array('name' => $_FILES['_attachments']['name'][$i], 
  • skins/default/mail.css

    r1cded85 r15a9d1c  
    5252#listcontrols a, 
    5353#listcontrols a:active, 
    54 #listcontrols a:visited 
     54#listcontrols a:visited, 
     55#mailboxcontrols a, 
     56#mailboxcontrols a:active, 
     57#mailboxcontrols a:visited 
    5558{ 
    5659  color: #999999; 
     
    6164#listcontrols a.active, 
    6265#listcontrols a.active:active, 
    63 #listcontrols a.active:visited 
     66#listcontrols a.active:visited, 
     67#mailboxcontrols a.active, 
     68#mailboxcontrols a.active:active, 
     69#mailboxcontrols a.active:visited 
    6470{ 
    6571  color: #CC0000; 
    6672} 
    6773 
    68 #listcontrols a.active:hover 
     74#listcontrols a.active:hover, 
     75#mailboxcontrols a.active:hover 
    6976{ 
    7077  text-decoration: underline; 
     
    295302 
    296303 
     304#mailboxcontrols 
     305{ 
     306  position: absolute; 
     307  left: 20px; 
     308  width: 160px; 
     309  bottom: 20px; 
     310  height: 16px; 
     311  overflow: hidden; 
     312} 
     313 
     314 
    297315/** message list styles */ 
    298316 
     
    429447{ 
    430448  color: #FFFFFF; 
     449} 
     450 
     451#messagelist tr.deleted td, 
     452#messagelist tr.deleted td a 
     453{ 
     454  color: #CCCCCC; 
    431455} 
    432456 
  • skins/default/templates/mail.html

    r1cded85 r15a9d1c  
    2929<div id="mailboxlist-container"><roundcube:object name="mailboxlist" id="mailboxlist" maxlength="16" /></div> 
    3030 
     31<div id="mailboxcontrols"> 
     32<roundcube:label name="folder" />:&nbsp; 
     33<roundcube:button command="expunge" label="compact" classAct="active" />&nbsp; 
     34</div> 
     35 
    3136 
    3237<div id="mailcontframe"> 
Note: See TracChangeset for help on using the changeset viewer.