Changeset 15a9d1c in github
- Timestamp:
- Jan 4, 2006 7:37:10 PM (7 years ago)
- Branches:
- master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
- Children:
- 3baec23
- Parents:
- 977a295e
- Files:
-
- 3 added
- 21 edited
-
CHANGELOG (modified) (1 diff)
-
INSTALL (modified) (1 diff)
-
SQL/mysql.initial.sql (modified) (1 diff)
-
SQL/mysql.update.sql (modified) (1 diff)
-
SQL/postgres.initial.sql (modified) (7 diffs)
-
UPGRADING (modified) (5 diffs)
-
config/main.inc.php.dist (modified) (1 diff)
-
index.php (modified) (3 diffs)
-
program/include/main.inc (modified) (7 diffs)
-
program/include/rcube_db.inc (modified) (23 diffs)
-
program/include/rcube_imap.inc (modified) (30 diffs)
-
program/js/app.js (modified) (15 diffs)
-
program/js/common.js (modified) (1 diff)
-
program/lib/imap.inc (modified) (2 diffs)
-
program/localization/de/labels.inc (modified) (2 diffs)
-
program/localization/en/labels.inc (modified) (2 diffs)
-
program/steps/mail/check_recent.inc (added)
-
program/steps/mail/folders.inc (added)
-
program/steps/mail/func.inc (modified) (7 diffs)
-
program/steps/mail/getunread.inc (added)
-
program/steps/mail/sendmail.inc (modified) (1 diff)
-
program/steps/mail/upload.inc (modified) (1 diff)
-
skins/default/mail.css (modified) (4 diffs)
-
skins/default/templates/mail.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
CHANGELOG
r977a295e r15a9d1c 1 1 CHANGELOG RoundCube Webmail 2 2 --------------------------- 3 4 2006/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 3 17 4 18 -
INSTALL
r1cded85 r15a9d1c 77 77 * .htaccess support allowing overrides for DirectoryIndex 78 78 * PHP Version 4.3.1 or greater 79 * PCRE (perl compatible regular expression) installed with PHP 79 80 * php.ini options: 80 81 - error_reporting E_ALL & ~E_NOTICE (or lower) -
SQL/mysql.initial.sql
r1cded85 r15a9d1c 92 92 `last_login` datetime NOT NULL default '0000-00-00 00:00:00', 93 93 `language` varchar(5) NOT NULL default 'en', 94 `preferences` text NOT NULL ,94 `preferences` text NOT NULL default '', 95 95 PRIMARY KEY (`user_id`) 96 96 ) TYPE=MyISAM; -
SQL/mysql.update.sql
r1cded85 r15a9d1c 3 3 4 4 5 ALTER TABLE session ADD ipVARCHAR(15) NOT NULL AFTER changed;6 ALTER TABLE users ADD aliasVARCHAR(128) NOT NULL AFTER mail_host;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; 7 7 8 8 -
SQL/postgres.initial.sql
r977a295e r15a9d1c 69 69 70 70 CREATE TABLE users ( 71 user_id integer DEFAULT nextval('user_ids'::text) NOT NULL,71 user_id integer DEFAULT nextval('user_ids'::text) PRIMARY KEY, 72 72 username character varying(128) DEFAULT ''::character varying NOT NULL, 73 73 mail_host character varying(128) DEFAULT ''::character varying NOT NULL, … … 87 87 88 88 CREATE TABLE "session" ( 89 sess_id character varying(40) DEFAULT ''::character varying NOT NULL,89 sess_id character varying(40) DEFAULT ''::character varying PRIMARY KEY, 90 90 created timestamp with time zone DEFAULT now() NOT NULL, 91 91 changed timestamp with time zone DEFAULT now() NOT NULL, … … 102 102 103 103 CREATE 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), 106 106 del integer DEFAULT 0 NOT NULL, 107 107 standard integer DEFAULT 0 NOT NULL, … … 121 121 122 122 CREATE 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), 125 125 changed timestamp with time zone DEFAULT now() NOT NULL, 126 126 del integer DEFAULT 0 NOT NULL, … … 140 140 141 141 CREATE 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), 145 145 cache_key character varying(128) DEFAULT ''::character varying NOT NULL, 146 146 created timestamp with time zone DEFAULT now() NOT NULL, … … 156 156 157 157 CREATE 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), 160 160 del integer DEFAULT 0 NOT NULL, 161 161 cache_key character varying(128) DEFAULT ''::character varying NOT NULL, … … 172 172 ); 173 173 174 175 176 --177 -- Add primary keys178 --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 identities189 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 keys206 --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 20 20 $rcmail_config['default_port'] = 143; 21 21 $rcmail_config['session_lifetime'] = 20; 22 $rcmail_config['skip_deleted'] = FALSE; 22 23 $rcmail_config['message_sort_col'] = 'date'; 23 24 $rcmail_config['message_sort_order'] = 'DESC'; … … 42 43 $rcmail_config['default_port'] = 143; 43 44 $rcmail_config['session_lifetime'] = 20; 45 $rcmail_config['skip_deleted'] = FALSE; 44 46 $rcmail_config['message_sort_col'] = 'date'; 45 47 $rcmail_config['message_sort_order'] = 'DESC'; … … 62 64 $rcmail_config['smtp_auth_type'] = ''; // if you need to specify an auth method for SMTP 63 65 $rcmail_config['session_lifetime'] = 20; // to specify the session lifetime in minutes 66 $rcmail_config['skip_deleted'] = FALSE; 64 67 $rcmail_config['message_sort_col'] = 'date'; 65 68 $rcmail_config['message_sort_order'] = 'DESC'; … … 82 85 - run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql 83 86 - add these lines to /config/main.inc.php 87 $rcmail_config['skip_deleted'] = FALSE; 84 88 $rcmail_config['message_sort_col'] = 'date'; 85 89 $rcmail_config['message_sort_order'] = 'DESC'; … … 92 96 $rcmail_config['db_sequence_contact_ids'] = 'contact_ids'; 93 97 $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 98 98 $rcmail_config['useragent'] = 'RoundCube Webmail/0.1b'; 99 99 100 // use this name to compose page titles 101 $rcmail_config['product_name'] = 'RoundCube Webmail'; 102 100 103 // only list folders within this path 101 104 $rcmail_config['imap_root'] = ''; -
index.php
r977a295e r15a9d1c 4 4 +-----------------------------------------------------------------------+ 5 5 | RoundCube Webmail IMAP Client | 6 | Version 0.1-200 51214 |6 | Version 0.1-20060104 | 7 7 | | 8 8 | Copyright (C) 2005, RoundCube Dev. - Switzerland | … … 42 42 */ 43 43 44 define('RCMAIL_VERSION', '0.1-20060104'); 45 46 44 47 // define global vars 45 48 $INSTALL_PATH = dirname($_SERVER['SCRIPT_FILENAME']); … … 241 244 if ($_action=='addcontact') 242 245 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'); 243 255 244 256 if ($_action=='list' && $_GET['_remote']) -
program/include/main.inc
r977a295e r15a9d1c 147 147 148 148 $IMAP = new rcube_imap($DB); 149 $IMAP->debug_level = $CONFIG['debug_level']; 150 $IMAP->skip_deleted = $CONFIG['skip_deleted']; 151 149 152 150 153 // connect with stored session data … … 592 595 593 596 // 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"; 597 function 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 600 610 print $js_code; 601 exit; 611 612 if ($flush) // flush the output buffer 613 flush(); 614 else // terminate script 615 exit; 602 616 } 603 617 … … 880 894 881 895 $object_handlers = array( 896 // GENERAL 897 'loginform' => 'rcmail_login_form', 898 'username' => 'rcmail_current_username', 899 882 900 // MAIL 883 901 'mailboxlist' => 'rcmail_mailbox_list', 902 'message' => 'rcmail_message_container', 884 903 'messages' => 'rcmail_message_list', 885 904 'messagecountdisplay' => 'rcmail_messagecount_display', … … 917 936 ); 918 937 919 if ($object=='loginform')920 return rcmail_login_form($attrib);921 922 else if ($object=='message')923 return rcmail_message_container($attrib);924 938 925 939 // execute object handler function 926 elseif ($object_handlers[$object] && function_exists($object_handlers[$object]))940 if ($object_handlers[$object] && function_exists($object_handlers[$object])) 927 941 return call_user_func($object_handlers[$object], $attrib); 928 942 … … 930 944 { 931 945 $task = $GLOBALS['_task']; 946 $title = !empty($CONFIG['product_name']) ? $CONFIG['product_name'].' :: ' : ''; 947 932 948 if ($task=='mail' && isset($GLOBALS['MESSAGE']['subject'])) 933 return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['MESSAGE']['subject']);949 $title .= $GLOBALS['MESSAGE']['subject']; 934 950 else if (isset($GLOBALS['PAGE_TITLE'])) 935 return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['PAGE_TITLE']);951 $title .= $GLOBALS['PAGE_TITLE']; 936 952 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); 938 954 else 939 return "RoundCube|Mail :: $task"; 955 $title .= $task; 956 957 return rep_specialchars_output($title, 'html', 'all'); 940 958 } 941 942 else if ($object=='about')943 return '';944 959 945 960 break; … … 1264 1279 1265 1280 return $out; 1281 } 1282 1283 1284 // return the IMAP username of the current session 1285 function 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; 1266 1313 } 1267 1314 … … 1374 1421 1375 1422 1423 1424 function rcube_timer() 1425 { 1426 list($usec, $sec) = explode(" ", microtime()); 1427 return ((float)$usec + (float)$sec); 1428 } 1429 1430 1431 function 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 1376 1446 ?> -
program/include/rcube_db.inc
r1cded85 r15a9d1c 21 21 */ 22 22 23 24 /** 25 * Obtain the PEAR::DB class that is used for abstraction 26 */ 23 27 require_once('DB.php'); 24 28 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 */ 25 41 class rcube_db 26 42 { … … 35 51 36 52 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='') 39 60 { 40 61 if ($db_dsnr=='') … … 49 70 50 71 51 // PHP 4 compatibility 72 /** 73 * PHP 4 object constructor 74 * 75 * @see rcube_db::__construct 76 */ 52 77 function rcube_db($db_dsnw,$db_dsnr='') 53 78 { … … 56 81 57 82 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 */ 59 100 function dsn_connect($dsn) 60 101 { … … 63 104 64 105 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__, 69 108 'message' => $dbh->getMessage()), TRUE, FALSE); 109 } 70 110 71 111 else if ($this->db_provider=='sqlite') … … 80 120 81 121 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) 84 130 { 85 131 $this->db_mode = $mode; … … 100 146 return; 101 147 } 102 148 103 149 if ($mode=='r') 104 150 $dsn = $this->db_dsnr; … … 111 157 112 158 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 */ 114 167 function query() 115 168 { … … 121 174 122 175 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 */ 124 186 function limitquery() 125 187 { … … 133 195 134 196 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 */ 135 207 function _query($query, $offset, $numrows, $params) 136 208 { … … 156 228 157 229 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 */ 158 238 function num_rows($res_id=NULL) 159 239 { … … 168 248 169 249 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() 171 257 { 172 258 if (!$this->db_handle) … … 177 263 178 264 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 */ 179 273 function insert_id($sequence = '') 180 274 { … … 186 280 case 'pgsql': 187 281 // PostgreSQL uses sequences 188 $result = & $this->db_handle->getOne("SELECT CURRVAL('$sequence')");282 $result = &$this->db_handle->getOne("SELECT CURRVAL('$sequence')"); 189 283 if (DB::isError($result)) 284 { 190 285 raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, 191 286 'message' => $result->getMessage()), TRUE, FALSE); 287 } 192 288 193 289 return $result; … … 208 304 209 305 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 */ 210 314 function fetch_assoc($res_id=NULL) 211 315 { … … 223 327 224 328 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 227 339 if (!$this->db_handle) 228 340 $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)); 231 348 } 232 349 233 350 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 */ 234 360 function quoteIdentifier($str) 235 361 { 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 { 236 375 if (!$this->db_handle) 237 376 $this->db_connect('r'); 238 377 239 378 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 */ 249 389 function unixtimestamp($field) 250 390 { … … 261 401 262 402 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 */ 263 410 function fromunixtime($timestamp) 264 411 { … … 276 423 277 424 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 */ 278 432 function _add_result($res) 279 433 { … … 282 436 { 283 437 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); 285 439 return FALSE; 286 440 } … … 295 449 296 450 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) 298 460 { 299 461 if ($res_id==NULL) … … 307 469 308 470 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; 314 482 315 483 $data = ''; 316 if ($fd = fopen($file Name, 'r'))317 { 318 $data = fread($fd, filesize($file Name));484 if ($fd = fopen($file_name, 'r')) 485 { 486 $data = fread($fd, filesize($file_name)); 319 487 fclose($fd); 320 488 } … … 324 492 } 325 493 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 */ 326 501 function _sqlite_prepare() 327 502 { … … 335 510 } 336 511 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 352 513 } // end class rcube_db 353 514 -
program/include/rcube_imap.inc
r749b07c r15a9d1c 22 22 23 23 24 /** 25 * Obtain classes from the Iloha IMAP library 26 */ 24 27 require_once('lib/imap.inc'); 25 28 require_once('lib/mime.inc'); … … 27 30 28 31 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 */ 29 42 class rcube_imap 30 43 { … … 47 60 var $msg_headers = array(); 48 61 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 */ 52 71 function __construct($db_conn) 53 72 { … … 55 74 } 56 75 57 // PHP 4 compatibility 76 77 /** 78 * PHP 4 object constructor 79 * 80 * @see rcube_imap::__construct 81 */ 58 82 function rcube_imap($db_conn) 59 83 { … … 62 86 63 87 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 */ 64 99 function connect($host, $user, $pass, $port=143, $use_ssl=FALSE) 65 100 { 66 global $ICL_SSL, $ICL_PORT , $CONFIG;101 global $ICL_SSL, $ICL_PORT; 67 102 68 103 // check for Open-SSL support in PHP build … … 71 106 else if ($use_ssl) 72 107 { 73 raise_error(array('code' => 403, 74 'type' => 'imap', 75 'file' => __FILE__, 108 raise_error(array('code' => 403, 'type' => 'imap', 'file' => __FILE__, 76 109 'message' => 'Open SSL not available;'), TRUE, FALSE); 77 110 $port = 143; … … 87 120 88 121 // print trace mesages 89 if ($this->conn && ($ CONFIG['debug_level']& 8))122 if ($this->conn && ($this->debug_level & 8)) 90 123 console($this->conn->message); 91 124 … … 117 150 118 151 152 /** 153 * Close IMAP connection 154 * Usually done on script shutdown 155 * 156 * @access public 157 */ 119 158 function close() 120 159 { … … 124 163 125 164 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 */ 126 171 function reconnect() 127 172 { … … 131 176 132 177 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 */ 133 187 function set_rootdir($root) 134 188 { … … 143 197 144 198 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 */ 145 205 function set_default_mailboxes($arr) 146 206 { … … 160 220 161 221 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 */ 162 230 function set_mailbox($mbox) 163 231 { … … 174 242 175 243 244 /** 245 * Set internal list page 246 * 247 * @param number Page number to list 248 * @access public 249 */ 176 250 function set_page($page) 177 251 { … … 180 254 181 255 256 /** 257 * Set internal page size 258 * 259 * @param number Number of messages to display on one page 260 * @access public 261 */ 182 262 function set_pagesize($size) 183 263 { … … 186 266 187 267 268 /** 269 * Returns the currently used mailbox name 270 * 271 * @return string Name of the mailbox/folder 272 * @access public 273 */ 188 274 function get_mailbox_name() 189 275 { … … 192 278 193 279 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 */ 194 287 function get_capability($cap) 195 288 { … … 199 292 200 293 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 */ 201 300 function get_hierarchy_delimiter() 202 301 { … … 210 309 } 211 310 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 */ 214 322 function list_mailboxes($root='', $filter='*') 215 323 { … … 230 338 } 231 339 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 */ 233 348 function _list_mailboxes($root='', $filter='*') 234 349 { … … 262 377 263 378 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 265 380 function messagecount($mbox='', $mode='ALL', $force=FALSE) 266 381 { … … 275 390 $mode = strtoupper($mode); 276 391 277 if ( !$mailbox)392 if (empty($mailbox)) 278 393 $mailbox = $this->mailbox; 279 394 … … 283 398 if (!$force && is_array($a_mailbox_cache[$mailbox]) && isset($a_mailbox_cache[$mailbox][$mode])) 284 399 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); 301 431 } 302 432 … … 349 479 { 350 480 $begin = $start_msg; 351 $end =$start_msg + $this->page_size;481 $end = $start_msg + $this->page_size; 352 482 } 353 483 … … 373 503 { 374 504 // 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)); 378 508 379 509 $msgs = $msg_index[$begin]; 380 for ($i=$begin ; $i < $end; $i++)510 for ($i=$begin+1; $i < $end; $i++) 381 511 { 382 if ($this->sort_order == 'DESC')383 $msgs = $msg_index[$i].','.$msgs;384 else512 //if ($this->sort_order == 'DESC') 513 // $msgs = $msg_index[$i].','.$msgs; 514 //else 385 515 $msgs = $msgs.','.$msg_index[$i]; 386 516 } … … 402 532 } 403 533 404 405 // cache is incomplete406 $cache_index = $this->get_message_cache_index($cache_key);407 534 408 535 // fetch reuested headers from server 409 536 $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs); 410 537 $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); 434 539 435 540 // delete cached messages with a higher index than $max 436 541 $this->clear_message_cache($cache_key, $max); 437 542 438 439 // fetch more headers of there were any deleted messages 440 // ... 441 543 442 544 // kick child process to sync cache 443 545 // ... … … 457 559 return array_values($a_msg_headers); 458 560 } 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 459 608 460 609 … … 585 734 586 735 587 function get_headers($ uid, $mbox=NULL)736 function get_headers($id, $mbox=NULL, $is_uid=TRUE) 588 737 { 589 738 $mailbox = $mbox ? $this->_mod_mailbox($mbox) : $this->mailbox; … … 593 742 return $headers; 594 743 595 $msg_id = $ this->_uid2id($uid);744 $msg_id = $is_uid ? $this->_uid2id($id) : $id; 596 745 $headers = iil_C_FetchHeader($this->conn, $mailbox, $msg_id); 597 746 … … 803 952 804 953 // 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; 808 957 $msg_count = $this->_messagecount($mailbox, 'ALL'); 809 958 … … 1271 1420 $index, 1272 1421 $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), 1277 1426 (int)$headers->size, 1278 1427 serialize($headers)); -
program/js/app.js
r977a295e r15a9d1c 7 7 | Licensed under the GNU GPL | 8 8 | | 9 | Modified: 2005/12/16 (roundcube) |10 | |11 9 +-----------------------------------------------------------------------+ 12 10 | Author: Thomas Bruederli <roundcube@gmail.com> | 13 11 +-----------------------------------------------------------------------+ 12 13 $Id$ 14 14 */ 15 15 … … 138 138 139 139 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); 141 141 142 142 this.set_page_buttons(); … … 152 152 if (this.env.action=='print') 153 153 window.print(); 154 155 // get unread count for each mailbox 156 if (this.gui_objects.mailboxlist) 157 this.http_request('getunread', ''); 154 158 155 159 break; … … 220 224 this.display_message(this.pending_message[0], this.pending_message[1]); 221 225 222 // start interval for keep-alive siganl226 // start interval for keep-alive/recent_check signal 223 227 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); 225 229 }; 226 230 … … 437 441 return false; 438 442 } 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 439 452 440 453 // process command … … 461 474 case 'list': 462 475 if (this.task=='mail') 463 {464 // check input before leaving compose step465 if (this.env.action=='compose' && this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))466 break;467 468 476 this.list_mailbox(props); 469 }470 477 else if (this.task=='addressbook') 471 478 this.list_contacts(); … … 511 518 case 'previouspage': 512 519 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); 513 530 break; 514 531 … … 1169 1186 this.list_mailbox_remote = function(mbox, page, add_url) 1170 1187 { 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 { 1172 1200 var table = this.gui_objects.messagelist; 1173 1201 var tbody = document.createElement('TBODY'); … … 1177 1205 this.message_rows = new Array(); 1178 1206 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 } 1179 1223 1180 1224 // 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); 1184 1227 }; 1185 1228 … … 2264 2307 2265 2308 // 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) 2267 2310 { 2268 2311 if (!this.gui_objects.messagelist || !this.gui_objects.messagelist.tBodies[0]) … … 2278 2321 var row = document.createElement('TR'); 2279 2322 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 2282 2325 if (this.in_selection(uid)) 2283 2326 row.className += ' selected'; … … 2305 2348 row.appendChild(col); 2306 2349 2307 tbody.appendChild(row); 2350 if (attop && tbody.rows.length) 2351 tbody.insertBefore(row, tbody.firstChild); 2352 else 2353 tbody.appendChild(row); 2354 2308 2355 this.init_message_row(row); 2309 2356 }; … … 2322 2369 2323 2370 // update the mailboxlist 2324 this.set_unread_count = function(mbox, count )2371 this.set_unread_count = function(mbox, count, set_title) 2325 2372 { 2326 2373 if (!this.gui_objects.mailboxlist) 2327 2374 return false; 2328 2375 2376 var item, reg, text_obj; 2329 2377 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, ''); 2348 2392 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, ''); 2353 2409 } 2354 2410 }; … … 2528 2584 this.command('list'); 2529 2585 break; 2530 2586 2531 2587 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); 2533 2590 break; 2534 2591 } … … 2557 2614 this.http_request('keep-alive', '_t='+d.getTime()); 2558 2615 }; 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 }; 2560 2624 2561 2625 -
program/js/common.js
r10a69975 r15a9d1c 270 270 if (input && window.RegExp) 271 271 { 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})'; 273 273 var reg1 = inline ? new RegExp(reg_str, 'i') : new RegExp('^'+reg_str+'$', 'i'); 274 274 var reg2 = /[\._\-\@]{2}/; -
program/lib/imap.inc
r31b2cee r15a9d1c 608 608 } 609 609 610 function iil_C_Sort(&$conn, $mailbox, $field ){610 function iil_C_Sort(&$conn, $mailbox, $field, $add=''){ 611 611 /* Do "SELECT" command */ 612 612 if (!iil_C_Select($conn, $mailbox)) return false; … … 619 619 620 620 $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"; 622 623 $line = $data = ''; 623 624 -
program/localization/de/labels.inc
r1cded85 r15a9d1c 106 106 $labels['unread'] = 'Ungelesene'; 107 107 108 $labels['compact'] = 'Packen'; 109 110 108 111 // message compose // Nachrichten erstellen 109 112 $labels['compose'] = 'Neue Nachricht verfassen'; … … 168 171 $labels['signature'] = 'Signatur'; 169 172 173 $labels['folder'] = 'Ordner'; 170 174 $labels['folders'] = 'Ordner'; 171 175 $labels['foldername'] = 'Ordnername'; -
program/localization/en/labels.inc
r1cded85 r15a9d1c 106 106 $labels['unread'] = 'Unread'; 107 107 108 $labels['compact'] = 'Compact'; 109 110 108 111 // message compose 109 112 $labels['compose'] = 'Compose a message'; … … 168 171 $labels['signature'] = 'Signature'; 169 172 173 $labels['folder'] = 'Folder'; 170 174 $labels['folders'] = 'Folders'; 171 175 $labels['foldername'] = 'Folder name'; -
program/steps/mail/func.inc
r749b07c r15a9d1c 70 70 static $a_mailboxes; 71 71 72 // $mboxlist_start = rcube_timer(); 73 72 74 $type = $attrib['type'] ? $attrib['type'] : 'ul'; 73 75 $add_attrib = $type=='select' ? array('style', 'class', 'id', 'name', 'onchange') : … … 101 103 $delimiter = $IMAP->get_hierarchy_delimiter(); 102 104 $a_mailboxes = array(); 103 105 106 // rcube_print_time($mboxlist_start, 'list_mailboxes()'); 107 104 108 foreach ($a_folders as $folder) 105 109 rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter); … … 112 116 else 113 117 $out .= rcmail_render_folder_tree_html($a_mailboxes, $special_mailboxes, $mbox, $attrib['maxlength']); 118 119 // rcube_print_time($mboxlist_start, 'render_folder_tree()'); 114 120 115 121 … … 182 188 183 189 // 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))) 185 191 $foldername .= sprintf(' (%d)', $unread_count); 186 192 … … 398 404 $attach_icon = $attrib['attachmenticon']; 399 405 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 401 412 $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : ''); 402 413 … … 496 507 $a_msg_flags['unread'] = $header->seen ? 0 : 1; 497 508 $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", 500 514 $header->uid, 501 515 array2js($a_msg_cols), 502 516 array2js($a_msg_flags), 503 preg_match("/multipart\/m/i", $header->ctype)); 517 preg_match("/multipart\/m/i", $header->ctype), 518 $insert_top); 504 519 } 505 520 … … 1378 1393 if (is_array($_SESSION['compose']['attachments'])) 1379 1394 foreach ($_SESSION['compose']['attachments'] as $attachment) 1380 unlink($attachment['path']);1395 @unlink($attachment['path']); 1381 1396 1382 1397 // kill temp dir 1383 1398 if ($_SESSION['compose']['temp_dir']) 1384 rmdir($_SESSION['compose']['temp_dir']);1399 @rmdir($_SESSION['compose']['temp_dir']); 1385 1400 1386 1401 unset($_SESSION['compose']); -
program/steps/mail/sendmail.inc
r749b07c r15a9d1c 225 225 // unset some headers because they will be added by the mail() function 226 226 $headers_php = $headers; 227 $headers_enc = $MAIL_MIME->headers($headers); 227 228 unset($headers_php['To'], $headers_php['Subject']); 228 229 230 // reset stored headers and overwrite 231 $MAIL_MIME->_headers = array(); 229 232 $header_str = $MAIL_MIME->txtHeaders($headers_php); 230 233 231 234 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"); 235 238 } 236 239 -
program/steps/mail/upload.inc
r597170f r15a9d1c 40 40 { 41 41 $tmpfname = tempnam($temp_dir, 'rcmAttmnt'); 42 if ( copy($filepath, $tmpfname))42 if (move_uploaded_file($filepath, $tmpfname)) 43 43 { 44 44 $_SESSION['compose']['attachments'][] = array('name' => $_FILES['_attachments']['name'][$i], -
skins/default/mail.css
r1cded85 r15a9d1c 52 52 #listcontrols a, 53 53 #listcontrols a:active, 54 #listcontrols a:visited 54 #listcontrols a:visited, 55 #mailboxcontrols a, 56 #mailboxcontrols a:active, 57 #mailboxcontrols a:visited 55 58 { 56 59 color: #999999; … … 61 64 #listcontrols a.active, 62 65 #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 64 70 { 65 71 color: #CC0000; 66 72 } 67 73 68 #listcontrols a.active:hover 74 #listcontrols a.active:hover, 75 #mailboxcontrols a.active:hover 69 76 { 70 77 text-decoration: underline; … … 295 302 296 303 304 #mailboxcontrols 305 { 306 position: absolute; 307 left: 20px; 308 width: 160px; 309 bottom: 20px; 310 height: 16px; 311 overflow: hidden; 312 } 313 314 297 315 /** message list styles */ 298 316 … … 429 447 { 430 448 color: #FFFFFF; 449 } 450 451 #messagelist tr.deleted td, 452 #messagelist tr.deleted td a 453 { 454 color: #CCCCCC; 431 455 } 432 456 -
skins/default/templates/mail.html
r1cded85 r15a9d1c 29 29 <div id="mailboxlist-container"><roundcube:object name="mailboxlist" id="mailboxlist" maxlength="16" /></div> 30 30 31 <div id="mailboxcontrols"> 32 <roundcube:label name="folder" />: 33 <roundcube:button command="expunge" label="compact" classAct="active" /> 34 </div> 35 31 36 32 37 <div id="mailcontframe">
Note: See TracChangeset
for help on using the changeset viewer.
