summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authorthomascube <thomas@roundcube.net>2005-12-03 16:54:12 +0000
committerthomascube <thomas@roundcube.net>2005-12-03 16:54:12 +0000
commit1cded85790206afe084e1baff371c543711b2b18 (patch)
treeb050fb89707e048df5f30f500faad792962a1e81 /program
parent5bc8cb662fc3bcda9aa641b7a5e88c0b81dd63d6 (diff)
Re-design of caching (new database table added\!); some bugfixes; Postgres support
Diffstat (limited to 'program')
-rw-r--r--program/include/cache.inc5
-rw-r--r--program/include/main.inc312
-rwxr-xr-xprogram/include/rcube_db.inc465
-rw-r--r--program/include/rcube_imap.inc748
-rwxr-xr-xprogram/include/rcube_mdb2.inc16
-rw-r--r--program/include/rcube_shared.inc109
-rw-r--r--program/include/rcube_sqlite.inc71
-rw-r--r--program/include/session.inc16
-rw-r--r--program/js/app.js99
-rw-r--r--program/localization/de/labels.inc4
-rw-r--r--program/localization/de/messages.inc2
-rw-r--r--program/localization/ee/labels.inc182
-rw-r--r--program/localization/ee/messages.inc80
-rw-r--r--program/localization/en/labels.inc4
-rw-r--r--program/localization/en/messages.inc8
-rw-r--r--program/localization/en_GB/labels.inc3
-rw-r--r--program/localization/index.inc1
-rw-r--r--program/steps/addressbook/delete.inc6
-rw-r--r--program/steps/addressbook/edit.inc2
-rw-r--r--program/steps/addressbook/func.inc6
-rw-r--r--program/steps/addressbook/list.inc4
-rw-r--r--program/steps/addressbook/save.inc12
-rw-r--r--program/steps/addressbook/show.inc2
-rw-r--r--program/steps/mail/addcontact.inc8
-rw-r--r--program/steps/mail/compose.inc182
-rw-r--r--program/steps/mail/func.inc121
-rw-r--r--program/steps/mail/sendmail.inc15
-rw-r--r--program/steps/settings/delete_identity.inc2
-rw-r--r--program/steps/settings/edit_identity.inc5
-rw-r--r--program/steps/settings/func.inc4
-rw-r--r--program/steps/settings/manage_folders.inc15
-rw-r--r--program/steps/settings/save_identity.inc12
32 files changed, 1703 insertions, 818 deletions
diff --git a/program/include/cache.inc b/program/include/cache.inc
index 8d088e57b..06e0681ce 100644
--- a/program/include/cache.inc
+++ b/program/include/cache.inc
@@ -43,8 +43,8 @@ function rcube_read_cache($key)
return $data;
}
-
-
+
+
function rcube_write_cache($key, $data, $session_cache=FALSE)
{
global $DB, $CACHE_KEYS, $sess_id;
@@ -91,7 +91,6 @@ function rcube_write_cache($key, $data, $session_cache=FALSE)
}
-
function rcube_clear_cache($key)
{
global $DB;
diff --git a/program/include/main.inc b/program/include/main.inc
index ddb42181a..40ca1d4d7 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -69,7 +69,7 @@ function rcmail_startup($task='mail')
// we can use the database for storing session data
// session queries do not work with MDB2
- if ($CONFIG['db_backend']!='mdb2' && is_object($DB) && $DB->db_provider!='sqlite')
+ if ($CONFIG['db_backend']!='mdb2' && is_object($DB) /* && $DB->db_provider!='sqlite' */)
include_once('include/session.inc');
@@ -143,9 +143,9 @@ function rcmail_auth_hash($sess_id, $ts)
// create IMAP object and connect to server
function rcmail_imap_init($connect=FALSE)
{
- global $CONFIG, $IMAP;
+ global $CONFIG, $DB, $IMAP;
- $IMAP = new rcube_imap();
+ $IMAP = new rcube_imap($DB);
// connect with stored session data
if ($connect)
@@ -227,6 +227,22 @@ function get_table_name($table)
}
+// return correct name for a specific database sequence
+// (used for Postres only)
+function get_sequence_name($sequence)
+ {
+ global $CONFIG;
+
+ // return table name if configured
+ $config_key = 'db_sequence_'.$sequence;
+
+ if (strlen($CONFIG[$config_key]))
+ return $CONFIG[$config_key];
+
+ return $table;
+ }
+
+
// init output object for GUI and add common scripts
function load_gui()
@@ -380,15 +396,15 @@ function rcmail_create_user($user, $host)
$host,
$_SESSION['user_lang']);
- if ($user_id = $DB->insert_id('user_ids'))
+ if ($user_id = $DB->insert_id(get_sequence_name('users')))
{
$user_email = strstr($user, '@') ? $user : sprintf('%s@%s', $user, $host);
$user_name = $user!=$user_email ? $user : '';
// also create a new identity record
$DB->query("INSERT INTO ".get_table_name('identities')."
- (user_id, `default`, name, email)
- VALUES (?, '1', ?, ?)",
+ (user_id, del, standard, name, email)
+ VALUES (?, 0, 1, ?, ?)",
$user_id,
$user_name,
$user_email);
@@ -479,7 +495,6 @@ function decrypt_passwd($cypher)
function rcube_remote_response($js_code)
{
send_nocacheing_headers();
- //header('Content-Type: text/javascript');
header('Content-Type: application/x-javascript');
print '/** remote response ['.date('d/M/Y h:i:s O')."] **/\n";
@@ -530,6 +545,117 @@ function rcube_add_label()
}
+// remove temp files of a session
+function rcmail_clear_session_temp($sess_id)
+ {
+ global $CONFIG;
+
+ $temp_dir = $CONFIG['temp_dir'].(!eregi('\/$', $CONFIG['temp_dir']) ? '/' : '');
+ $cache_dir = $temp_dir.$sess_id;
+
+ if (is_dir($cache_dir))
+ {
+ clear_directory($cache_dir);
+ rmdir($cache_dir);
+ }
+ }
+
+
+
+// replace specials characters to a specific encoding type
+function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
+ {
+ global $OUTPUT_TYPE, $CHARSET;
+ static $html_encode_arr, $js_rep_table, $rtf_rep_table, $xml_rep_table;
+
+ if (!$enctype)
+ $enctype = $GLOBALS['OUTPUT_TYPE'];
+
+ // convert nbsps back to normal spaces if not html
+ if ($enctype!='html')
+ $str = str_replace(chr(160), ' ', $str);
+
+
+ // encode for plaintext
+ if ($enctype=='text')
+ return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
+
+ // encode for HTML output
+ if ($enctype=='html')
+ {
+ if (!$html_encode_arr)
+ {
+ if ($CHARSET=='ISO-8859-1')
+ {
+ $html_encode_arr = get_html_translation_table(HTML_ENTITIES);
+ $html_encode_arr[chr(128)] = '&euro;';
+ }
+ else
+ $html_encode_arr = get_html_translation_table(HTML_SPECIALCHARS);
+
+ unset($html_encode_arr['?']);
+ unset($html_encode_arr['&']);
+ }
+
+ $ltpos = strpos($str, '<');
+ $encode_arr = $html_encode_arr;
+
+ // don't replace quotes and html tags
+ if (($mode=='show' || $mode=='') && $ltpos!==false && strpos($str, '>', $ltpos)!==false)
+ {
+ unset($encode_arr['"']);
+ unset($encode_arr['<']);
+ unset($encode_arr['>']);
+ }
+ else if ($mode=='remove')
+ $str = strip_tags($str);
+
+ $out = strtr($str, $encode_arr);
+
+ return $newlines ? nl2br($out) : $out;
+ }
+
+
+ if ($enctype=='url')
+ return rawurlencode($str);
+
+
+ // if the replace tables for RTF, XML and JS are not yet defined
+ if (!$js_rep_table)
+ {
+ $js_rep_table = $rtf_rep_table = $xml_rep_table = array();
+
+ for ($c=160; $c<256; $c++) // can be increased to support more charsets
+ {
+ $hex = dechex($c);
+ $rtf_rep_table[Chr($c)] = "\\'$hex";
+ $xml_rep_table[Chr($c)] = "&#$c;";
+
+ if ($CHARSET=='ISO-8859-1')
+ $js_rep_table[Chr($c)] = sprintf("\u%s%s", str_repeat('0', 4-strlen($hex)), $hex);
+ }
+
+ $js_rep_table['"'] = sprintf("\u%s%s", str_repeat('0', 4-strlen(dechex(34))), dechex(34));
+ $xml_rep_table['"'] = '&quot;';
+ }
+
+ // encode for RTF
+ if ($enctype=='xml')
+ return strtr($str, $xml_rep_table);
+
+ // encode for javascript use
+ if ($enctype=='js')
+ return preg_replace(array("/\r\n/", '/"/', "/([^\\\])'/"), array('\n', '\"', "$1\'"), strtr($str, $js_rep_table));
+
+ // encode for RTF
+ if ($enctype=='rtf')
+ return preg_replace("/\r\n/", "\par ", strtr($str, $rtf_rep_table));
+
+ // no encoding given -> return original string
+ return $str;
+ }
+
+
// ************** template parsing and gui functions **************
@@ -653,104 +779,53 @@ function rcube_xml_command($command, $str_attrib, $a_attrib=NULL)
case 'object':
$object = strtolower($attrib['name']);
+ $object_handlers = array(
+ // MAIL
+ 'mailboxlist' => 'rcmail_mailbox_list',
+ 'messages' => 'rcmail_message_list',
+ 'messagecountdisplay' => 'rcmail_messagecount_display',
+ 'messageheaders' => 'rcmail_message_headers',
+ 'messagebody' => 'rcmail_message_body',
+ 'messageattachments' => 'rcmail_message_attachments',
+ 'blockedobjects' => 'rcmail_remote_objects_msg',
+ 'messagecontentframe' => 'rcmail_messagecontent_frame',
+ 'messagepartframe' => 'rcmail_message_part_frame',
+ 'messagepartcontrols' => 'rcmail_message_part_controls',
+ 'composeheaders' => 'rcmail_compose_headers',
+ 'composesubject' => 'rcmail_compose_subject',
+ 'composebody' => 'rcmail_compose_body',
+ 'composeattachmentlist' => 'rcmail_compose_attachment_list',
+ 'composeattachmentform' => 'rcmail_compose_attachment_form',
+ 'composeattachment' => 'rcmail_compose_attachment_field',
+ 'priorityselector' => 'rcmail_priority_selector',
+ 'charsetselector' => 'rcmail_charset_selector',
+
+ // ADDRESS BOOK
+ 'addresslist' => 'rcmail_contacts_list',
+ 'addressframe' => 'rcmail_contact_frame',
+ 'recordscountdisplay' => 'rcmail_rowcount_display',
+ 'contactdetails' => 'rcmail_contact_details',
+ 'contacteditform' => 'rcmail_contact_editform',
+
+ // USER SETTINGS
+ 'userprefs' => 'rcmail_user_prefs_form',
+ 'itentitieslist' => 'rcmail_identities_list',
+ 'identityframe' => 'rcmail_identity_frame',
+ 'identityform' => 'rcube_identity_form',
+ 'foldersubscription' => 'rcube_subscription_form',
+ 'createfolder' => 'rcube_create_folder_form',
+ 'composebody' => 'rcmail_compose_body'
+ );
+
if ($object=='loginform')
return rcmail_login_form($attrib);
else if ($object=='message')
return rcmail_message_container($attrib);
-
- // MAIL
- else if ($object=='mailboxlist' && function_exists('rcmail_mailbox_list'))
- return rcmail_mailbox_list($attrib);
-
- else if ($object=='messages' && function_exists('rcmail_message_list'))
- return rcmail_message_list($attrib);
-
- else if ($object=='messagecountdisplay' && function_exists('rcmail_messagecount_display'))
- return rcmail_messagecount_display($attrib);
-
- else if ($object=='messageheaders' && function_exists('rcmail_message_headers'))
- return rcmail_message_headers($attrib);
-
- else if ($object=='messageattachments' && function_exists('rcmail_message_attachments'))
- return rcmail_message_attachments($attrib);
-
- else if ($object=='messagebody' && function_exists('rcmail_message_body'))
- return rcmail_message_body($attrib);
-
- else if ($object=='blockedobjects' && function_exists('rcmail_remote_objects_msg'))
- return rcmail_remote_objects_msg($attrib);
-
- else if ($object=='messagecontentframe' && function_exists('rcmail_messagecontent_frame'))
- return rcmail_messagecontent_frame($attrib);
-
- else if ($object=='messagepartframe' && function_exists('rcmail_message_part_frame'))
- return rcmail_message_part_frame($attrib);
-
- else if ($object=='messagepartcontrols' && function_exists('rcmail_message_part_controls'))
- return rcmail_message_part_controls($attrib);
-
- else if ($object=='composeheaders' && function_exists('rcmail_compose_headers'))
- return rcmail_compose_headers($attrib);
-
- else if ($object=='composesubject' && function_exists('rcmail_compose_subject'))
- return rcmail_compose_subject($attrib);
-
- else if ($object=='composebody' && function_exists('rcmail_compose_body'))
- return rcmail_compose_body($attrib);
-
- else if ($object=='composeattachmentlist' && function_exists('rcmail_compose_attachment_list'))
- return rcmail_compose_attachment_list($attrib);
-
- else if ($object=='composeattachmentform' && function_exists('rcmail_compose_attachment_form'))
- return rcmail_compose_attachment_form($attrib);
-
- else if ($object=='composeattachment' && function_exists('rcmail_compose_attachment_field'))
- return rcmail_compose_attachment_field($attrib);
-
- else if ($object=='priorityselector' && function_exists('rcmail_priority_selector'))
- return rcmail_priority_selector($attrib);
-
- else if ($object=='priorityselector' && function_exists('rcmail_priority_selector'))
- return rcmail_priority_selector($attrib);
-
-
- // ADDRESS BOOK
- else if ($object=='addresslist' && function_exists('rcmail_contacts_list'))
- return rcmail_contacts_list($attrib);
-
- else if ($object=='addressframe' && function_exists('rcmail_contact_frame'))
- return rcmail_contact_frame($attrib);
-
- else if ($object=='recordscountdisplay' && function_exists('rcmail_rowcount_display'))
- return rcmail_rowcount_display($attrib);
-
- else if ($object=='contactdetails' && function_exists('rcmail_contact_details'))
- return rcmail_contact_details($attrib);
-
- else if ($object=='contacteditform' && function_exists('rcmail_contact_editform'))
- return rcmail_contact_editform($attrib);
-
-
- // USER SETTINGS
- else if ($object=='userprefs' && function_exists('rcmail_user_prefs_form'))
- return rcmail_user_prefs_form($attrib);
-
- else if ($object=='itentitieslist' && function_exists('rcmail_identities_list'))
- return rcmail_identities_list($attrib);
-
- else if ($object=='identityframe' && function_exists('rcmail_identity_frame'))
- return rcmail_identity_frame($attrib);
-
- else if ($object=='identityform' && function_exists('rcube_identity_form'))
- return rcube_identity_form($attrib);
-
- else if ($object=='foldersubscription' && function_exists('rcube_subscription_form'))
- return rcube_subscription_form($attrib);
-
- else if ($object=='createfolder' && function_exists('rcube_create_folder_form'))
- return rcube_create_folder_form($attrib);
-
+
+ // execute object handler function
+ else if ($object_handlers[$object] && function_exists($object_handlers[$object]))
+ return call_user_func($object_handlers[$object], $attrib);
else if ($object=='pagetitle')
{
@@ -878,7 +953,7 @@ function rcube_button($attrib)
// generate image tag
if ($attrib['type']=='image')
{
- $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'width', 'height', 'border', 'hspace', 'vspace', 'alt'));
+ $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'width', 'height', 'border', 'hspace', 'vspace', 'align', 'alt'));
$img_tag = sprintf('<img src="%%s"%s />', $attrib_str);
$btn_content = sprintf($img_tag, $skin_path.$attrib['image']);
if ($attrib['label'])
@@ -1161,4 +1236,39 @@ EOF;
}
+
+function rcmail_charset_selector($attrib)
+ {
+ // pass the following attributes to the form class
+ $field_attrib = array('name' => '_charset');
+ foreach ($attrib as $attr => $value)
+ if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
+ $field_attrib[$attr] = $value;
+
+ $charsets = array(
+ 'US-ASCII' => 'ASCII (English)',
+ 'X-EUC-JP' => 'EUC-JP (Japanese)',
+ 'EUC-KR' => 'EUC-KR (Korean)',
+ 'BIG5' => 'BIG5 (Chinese)',
+ 'GB2312' => 'GB2312 (Chinese)',
+ 'ISO-8859-1' => 'ISO-8859-1 (Latin-1)',
+ 'ISO-8859-2' => 'ISO-8895-2 (Central European)',
+ 'ISO-8859-7' => 'ISO-8859-7 (Greek)',
+ 'ISO-8859-9' => 'ISO-8859-9 (Turkish)',
+ 'Windows-1251' => 'Windows-1251 (Cyrillic)',
+ 'Windows-1252' => 'Windows-1252 (Western)',
+ 'Windows-1255' => 'Windows-1255 (Hebrew)',
+ 'Windows-1256' => 'Windows-1256 (Arabic)',
+ 'Windows-1257' => 'Windows-1257 (Baltic)',
+ 'UTF-8' => 'UTF-8'
+ );
+
+ $select = new select($field_attrib);
+ $select->add(array_values($charsets), array_keys($charsets));
+
+ $set = $_POST['_charset'] ? $_POST['_charset'] : $GLOBALS['CHARSET'];
+ return $select->show($set);
+ }
+
+
?> \ No newline at end of file
diff --git a/program/include/rcube_db.inc b/program/include/rcube_db.inc
index f13ab55c0..acb13ce37 100755
--- a/program/include/rcube_db.inc
+++ b/program/include/rcube_db.inc
@@ -23,299 +23,332 @@
require_once('DB.php');
class rcube_db
-{
- var $db_dsnw; // DSN for write operations
- var $db_dsnr; // DSN for read operations
- var $db_connected=false; // Already connected ?
- var $db_mode=''; // Connection mode
- var $db_handle=0; // Connection handle
-
- var $a_query_results = array('dummy');
- var $last_res_id = 0;
-
- // PHP 5 constructor
- function __construct($db_dsnw,$db_dsnr='')
+ {
+ var $db_dsnw; // DSN for write operations
+ var $db_dsnr; // DSN for read operations
+ var $db_connected = false; // Already connected ?
+ var $db_mode = ''; // Connection mode
+ var $db_handle = 0; // Connection handle
+
+ var $a_query_results = array('dummy');
+ var $last_res_id = 0;
+
+
+ // PHP 5 constructor
+ function __construct($db_dsnw,$db_dsnr='')
{
- if ($db_dsnr=='') $db_dsnr=$db_dsnw;
+ if ($db_dsnr=='')
+ $db_dsnr=$db_dsnw;
- $this->db_dsnw = $db_dsnw;
- $this->db_dsnr = $db_dsnr;
+ $this->db_dsnw = $db_dsnw;
+ $this->db_dsnr = $db_dsnr;
- $dsn_array = DB::parseDSN($db_dsnw);
- $this->db_provider = $dsn_array['phptype'];
+ $dsn_array = DB::parseDSN($db_dsnw);
+ $this->db_provider = $dsn_array['phptype'];
}
- // PHP 4 compatibility
- function rcube_db($db_dsnw,$db_dsnr='')
+
+ // PHP 4 compatibility
+ function rcube_db($db_dsnw,$db_dsnr='')
{
- $this->__construct($db_dsnw,$db_dsnr);
+ $this->__construct($db_dsnw,$db_dsnr);
}
- // Connect to specific database
- function dsn_connect($dsn)
+
+ // Connect to specific database
+ function dsn_connect($dsn)
{
- // Use persistent connections if available
- $dbh = DB::connect($dsn, array('persistent' => $true));
+ // Use persistent connections if available
+ $dbh = DB::connect($dsn, array('persistent' => TRUE));
- if (DB::isError($dbh))
- raise_error(array('code' => 500,
+ if (DB::isError($dbh))
+ raise_error(array('code' => 500,
'type' => 'db',
'line' => __LINE__,
'file' => __FILE__,
'message' => $dbh->getMessage()), TRUE, FALSE);
- else if ($this->db_provider=='sqlite')
- {
- $dsn_array = DB::parseDSN($dsn);
- if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials))
- $this->_sqlite_create_database($dbh, $this->sqlite_initials);
- }
+ else if ($this->db_provider=='sqlite')
+ {
+ $dsn_array = DB::parseDSN($dsn);
+ if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials))
+ $this->_sqlite_create_database($dbh, $this->sqlite_initials);
+ }
- return $dbh;
+ return $dbh;
}
- // Connect to appropiate databse
- function db_connect ($mode)
- {
- $this->db_mode = $mode;
- // Already connected
- if ($this->db_connected)
- {
- // no replication, current connection is ok
- if ($this->db_dsnw==$this->db_dsnr) return;
+ // Connect to appropiate databse
+ function db_connect ($mode)
+ {
+ $this->db_mode = $mode;
+
+ // Already connected
+ if ($this->db_connected)
+ {
+ // no replication, current connection is ok
+ if ($this->db_dsnw==$this->db_dsnr)
+ return;
- // connected to master, current connection is ok
- if ($this->db_mode=='w') return;
-
- // Same mode, current connection is ok
- if ($this->db_mode==$mode) return;
- }
+ // connected to master, current connection is ok
+ if ($this->db_mode=='w')
+ return;
+
+ // Same mode, current connection is ok
+ if ($this->db_mode==$mode)
+ return;
+ }
- if ($mode=='r')
- $dsn=$this->db_dsnr;
- else
- $dsn=$this->db_dsnw;
+ if ($mode=='r')
+ $dsn = $this->db_dsnr;
+ else
+ $dsn = $this->db_dsnw;
- $this->db_handle = $this->dsn_connect($dsn);
- $this->db_connected = true;
+ $this->db_handle = $this->dsn_connect($dsn);
+ $this->db_connected = true;
}
- // Query database
-
- function query()
+
+ // Query database
+ function query()
{
- $params = func_get_args();
- $query = array_shift($params);
-
- return $this->_query($query, 0, 0, $params);
+ $params = func_get_args();
+ $query = array_shift($params);
+
+ return $this->_query($query, 0, 0, $params);
}
-
- function limitquery()
+
+
+ // Query with limits
+ function limitquery()
{
- $params = func_get_args();
- $query = array_shift($params);
- $offset = array_shift($params);
- $numrows = array_shift($params);
+ $params = func_get_args();
+ $query = array_shift($params);
+ $offset = array_shift($params);
+ $numrows = array_shift($params);
- return $this->_query($query, $offset, $numrows, $params);
+ return $this->_query($query, $offset, $numrows, $params);
}
-
- function _query($query, $offset, $numrows, $params)
+
+
+ function _query($query, $offset, $numrows, $params)
{
- // Read or write ?
- if (strtolower(trim(substr($query,0,6)))=='select')
- $mode='r';
- else
- $mode='w';
+ // Read or write ?
+ if (strtolower(trim(substr($query,0,6)))=='select')
+ $mode='r';
+ else
+ $mode='w';
- $this->db_connect($mode);
+ $this->db_connect($mode);
- if ($this->db_provider == 'sqlite')
- $query = $this->_sqlite_prepare_query($query);
-
- if ($numrows || $offset)
- {
- $result = $this->db_handle->limitQuery($query,$offset,$numrows,$params);
- }
- else
- $result = $this->db_handle->query($query, $params);
+ if ($this->db_provider == 'sqlite')
+ $this->_sqlite_prepare();
- if (DB::isError($result))
- {
- raise_error(array('code' => 500,
- 'type' => 'db',
- 'line' => __LINE__,
- 'file' => __FILE__,
- 'message' => $result->getMessage().'; QUERY: '.$query), TRUE, FALSE);
- return false;
- }
-
- return $this->_add_result($result, $query);
+ if ($numrows || $offset)
+ $result = $this->db_handle->limitQuery($query,$offset,$numrows,$params);
+ else
+ $result = $this->db_handle->query($query, $params);
+
+ // add result, even if it's an error
+ return $this->_add_result($result);
}
-
- function num_rows($res_id=NULL)
+
+
+ function num_rows($res_id=NULL)
{
- if (!$this->db_handle)
- return FALSE;
+ if (!$this->db_handle)
+ return FALSE;
- $result = $this->_get_result($res_id);
-
- if ($result)
- return $result->numRows();
- else
- return FALSE;
+ if ($result = $this->_get_result($res_id))
+ return $result->numRows();
+ else
+ return FALSE;
}
- function affected_rows($res_id=NULL)
+
+ function affected_rows($res_id=NULL)
{
- if (!$this->db_handle)
- return FALSE;
-
- return $this->db_handle->affectedRows();
+ if (!$this->db_handle)
+ return FALSE;
+
+ return $this->db_handle->affectedRows();
}
- function insert_id($sequence = '')
+
+ function insert_id($sequence = '')
{
- if (!$this->db_handle || $this->db_mode=='r')
- return FALSE;
-
- switch($this->db_provider)
- {
- case 'pgsql':
- // PostgreSQL uses sequences
- $result =& $this->db_handle->getOne("SELECT CURRVAL('$sequence')");
- if (DB::isError($result)) {
- raise_error( array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
- 'message' => $result->getMessage()), TRUE, TRUE);
- }
- return $result;
+ if (!$this->db_handle || $this->db_mode=='r')
+ return FALSE;
+
+ switch($this->db_provider)
+ {
+ case 'pgsql':
+ // PostgreSQL uses sequences
+ $result =& $this->db_handle->getOne("SELECT CURRVAL('$sequence')");
+ if (DB::isError($result))
+ raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $result->getMessage()), TRUE, FALSE);
+
+ return $result;
- case 'mysql': // This is unfortuneate
- return mysql_insert_id($this->db_handle->connection);
+ case 'mysql': // This is unfortuneate
+ return mysql_insert_id($this->db_handle->connection);
- case 'mysqli':
- return mysqli_insert_id($this->db_handle->connection);
+ case 'mysqli':
+ return mysqli_insert_id($this->db_handle->connection);
- case 'sqlite':
- return sqlite_last_insert_rowid($this->db_handle->connection);
+ case 'sqlite':
+ return sqlite_last_insert_rowid($this->db_handle->connection);
- default:
- die("portability issue with this database, please have the developer fix");
- }
+ default:
+ die("portability issue with this database, please have the developer fix");
+ }
}
- function fetch_assoc($res_id=NULL)
+ function fetch_assoc($res_id=NULL)
{
- $result = $this->_get_result($res_id);
-
- if (DB::isError($result))
- {
- raise_error( array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
- 'message' => $this->db_link->getMessage()), TRUE, FALSE);
- return FALSE;
- }
+ $result = $this->_get_result($res_id);
+
+ if (DB::isError($result))
+ {
+ raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $this->db_link->getMessage()), TRUE, FALSE);
+ return FALSE;
+ }
- return $result->fetchRow(DB_FETCHMODE_ASSOC);
+ return $result->fetchRow(DB_FETCHMODE_ASSOC);
}
- function quote($input, $type=null)
+ function quote($input, $type=null)
{
- if (!$this->db_handle)
- $this->db_connect('r');
+ if (!$this->db_handle)
+ $this->db_connect('r');
- return $this->db_handle->quote($input);
+ return $this->db_handle->quote($input);
}
- function quoteIdentifier($str)
+ function quoteIdentifier($str)
{
- if (!$this->db_handle)
- $this->db_connect('r');
+ if (!$this->db_handle)
+ $this->db_connect('r');
- return $this->db_handle->quoteIdentifier($str);
- }
-
- function quote_identifier($str)
- {
- return $this->quoteIdentifier($str);
+ return $this->db_handle->quoteIdentifier($str);
}
-
- function unixtimestamp($field)
- {
- switch($this->db_provider)
- {
- case 'pgsql':
- return "EXTRACT (EPOCH FROM $field)";
- break;
- default:
- return "UNIX_TIMESTAMP($field)";
- }
- }
-
- function _add_result($res, $query)
+
+ function quote_identifier($str)
+ {
+ return $this->quoteIdentifier($str);
+ }
+
+
+ function unixtimestamp($field)
{
- // sql error occured
- if (DB::isError($res))
- {
- raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__, 'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $query), 0, 1024)), TRUE, FALSE);
- return FALSE;
- }
- else
- {
- $res_id = sizeof($this->a_query_results);
- $this->a_query_results[$res_id] = $res;
- $this->last_res_id = $res_id;
- return $res_id;
- }
+ switch($this->db_provider)
+ {
+ case 'pgsql':
+ return "EXTRACT (EPOCH FROM $field)";
+ break;
+
+ default:
+ return "UNIX_TIMESTAMP($field)";
+ }
}
- function _get_result($res_id)
+ function fromunixtime($timestamp)
{
- if ($res_id==NULL)
- $res_id = $this->last_res_id;
+ switch($this->db_provider)
+ {
+ case 'mysqli':
+ case 'mysql':
+ case 'sqlite':
+ return "FROM_UNIXTIME($timestamp)";
+
+ default:
+ return date("'Y-m-d H:i:s'", $timestamp);
+ }
+ }
+
+
+ function _add_result($res)
+ {
+ // sql error occured
+ if (DB::isError($res))
+ {
+ raise_error(array('code' => 500, 'type' => 'db', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $res->getMessage() . " Query: " . substr(preg_replace('/[\r\n]+\s*/', ' ', $res->userinfo), 0, 1024)), TRUE, FALSE);
+ return FALSE;
+ }
+ else
+ {
+ $res_id = sizeof($this->a_query_results);
+ $this->a_query_results[$res_id] = $res;
+ $this->last_res_id = $res_id;
+ return $res_id;
+ }
+ }
+
+
+ function _get_result($res_id)
+ {
+ if ($res_id==NULL)
+ $res_id = $this->last_res_id;
- if ($res_id && isset($this->a_query_results[$res_id]))
- return $this->a_query_results[$res_id];
- else
- return FALSE;
+ if ($res_id && isset($this->a_query_results[$res_id]))
+ return $this->a_query_results[$res_id];
+ else
+ return FALSE;
}
- // create a sqlite database from a file
- function _sqlite_create_database($dbh, $fileName)
+ // create a sqlite database from a file
+ function _sqlite_create_database($dbh, $fileName)
{
- if (empty($fileName) || !is_string($fileName))
- return ;
-
- $data = '';
- if ($fd = fopen($fileName, 'r'))
- {
- $data = fread($fd, filesize($fileName));
- fclose($fd);
- }
-
- if (strlen($data))
- sqlite_exec($dbh->connection, $data);
+ if (empty($fileName) || !is_string($fileName))
+ return ;
+
+ $data = '';
+ if ($fd = fopen($fileName, 'r'))
+ {
+ $data = fread($fd, filesize($fileName));
+ fclose($fd);
+ }
+
+ if (strlen($data))
+ sqlite_exec($dbh->connection, $data);
}
- // transform a query so that it is sqlite2 compliant
- function _sqlite_prepare_query($query)
+ function _sqlite_prepare()
{
- if (!is_string($query))
- return ($query);
-
- $search = array('/NOW\(\)/i', '/`/');
- $replace = array("datetime('now')", '"');
- $query = preg_replace($search, $replace, $query);
+ include_once('include/rcube_sqlite.inc');
- return ($query);
+ // we emulate via callback some missing MySQL function
+ sqlite_create_function($this->db_handle->connection, "from_unixtime", "rcube_sqlite_from_unixtime");
+ sqlite_create_function($this->db_handle->connection, "unix_timestamp", "rcube_sqlite_unix_timestamp");
+ sqlite_create_function($this->db_handle->connection, "now", "rcube_sqlite_now");
+ sqlite_create_function($this->db_handle->connection, "md5", "rcube_sqlite_md5");
}
-
-}
+
+/*
+ // transform a query so that it is sqlite2 compliant
+ function _sqlite_prepare_query($query)
+ {
+ if (!is_string($query))
+ return ($query);
+
+
+ $search = array('/NOW\(\)/i', '/`/');
+ $replace = array("datetime('now')", '"');
+ $query = preg_replace($search, $replace, $query);
+
+ return ($query);
+ }
+*/
+ } // end class rcube_db
?> \ No newline at end of file
diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc
index 2237b38f3..ed7c3edcd 100644
--- a/program/include/rcube_imap.inc
+++ b/program/include/rcube_imap.inc
@@ -28,6 +28,7 @@ require_once('lib/utf7.inc');
class rcube_imap
{
+ var $db;
var $conn;
var $root_ns = '';
var $root_dir = '';
@@ -38,21 +39,23 @@ class rcube_imap
var $caching_enabled = FALSE;
var $default_folders = array('inbox', 'drafts', 'sent', 'junk', 'trash');
var $cache = array();
+ var $cache_keys = array();
var $cache_changes = array();
var $uid_id_map = array();
var $msg_headers = array();
+ var $capabilities = array();
// PHP 5 constructor
- function __construct()
+ function __construct($db_conn)
{
-
+ $this->db = $db_conn;
}
// PHP 4 compatibility
- function rcube_imap()
+ function rcube_imap($db_conn)
{
- $this->__construct();
+ $this->__construct($db_conn);
}
@@ -95,6 +98,7 @@ class rcube_imap
// get account namespace
if ($this->conn)
{
+ $this->_parse_capability($this->conn->capability);
iil_C_NameSpace($this->conn);
if (!empty($this->conn->delimiter))
@@ -185,6 +189,13 @@ class rcube_imap
}
+ function get_capability($cap)
+ {
+ $cap = strtoupper($cap);
+ return $this->capabilities[$cap];
+ }
+
+
function get_hierarchy_delimiter()
{
if ($this->conn && empty($this->delimiter))
@@ -298,200 +309,131 @@ class rcube_imap
// private method for listing message header
- // by DrSlump <drslump@drslump.biz>
- function __list_headers($mailbox='', $page=NULL, $sort_field='date', $sort_order='DESC')
+ function _list_headers($mailbox='', $page=NULL, $sort_field='date', $sort_order='DESC')
{
- $a_out = array();
- $cached_count = 0;
-
if (!strlen($mailbox))
- return $a_out;
+ return array();
+
+ $max = $this->_messagecount($mailbox);
+ $start_msg = ($this->list_page-1) * $this->page_size;
+
+ if ($page=='all')
+ {
+ $begin = 0;
+ $end = $max;
+ }
+ else if ($sort_order=='DESC')
+ {
+ $begin = $max - $this->page_size - $start_msg;
+ $end = $max - $start_msg;
+ }
+ else
+ {
+ $begin = $start_msg;
+ $end = $start_msg + $this->page_size;
+ }
- $mbox_count = $this->_messagecount($mailbox /*, 'ALL', TRUE*/);
+ if ($begin < 0) $begin = 0;
+ if ($end < 0) $end = $max;
+ if ($end > $max) $end = $max;
- $revalidate = false;
- if ($mbox_count)
+//console("fetch headers $start_msg to ".($start_msg+$this->page_size)." (msg $begin to $end)");
+
+ $headers_sorted = FALSE;
+ $cache_key = $mailbox.'.msg';
+ $cache_status = $this->check_cache_status($mailbox, $cache_key);
+
+//console("Cache status = $cache_status");
+
+ // cache is OK, we can get all messages from local cache
+ if ($cache_status>0)
+ {
+ $a_msg_headers = $this->get_message_cache($cache_key, $start_msg, $start_msg+$this->page_size, $sort_field, $sort_order);
+ $headers_sorted = TRUE;
+ }
+ else
{
- // get cached headers
- $a_out = $this->get_cache($mailbox.'.msg');
- $a_out = is_array($a_out) ? $a_out : array(); // make sure we get an array
-
- $cached_count = count($a_out);
- $a_new = array();
- $revalidate = true; // revalidate by default
-
- // if the cache count is greater then there have been changes for sure
- if ($cached_count <= $mbox_count)
+ // retrieve headers from IMAP
+ if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $sort_field)))
{
- $from = $cached_count?$cached_count:1;
-
- //get new headers (at least one is returned)
- $a_temp = iil_C_FetchHeaders($this->conn, $mailbox, $from . ':' . $mbox_count);
- $duplicated = $cached_count?true:false;
-
- foreach ($a_temp as $hdr)
+//console("$mailbox: ".count($msg_index));
+
+ $msgs = $msg_index[$begin];
+ for ($i=$begin; $i < $end; $i++)
{
- //skip the first one if duplicated
- if ($duplicated)
- {
- //check for changes using the UID
- $lastCacheHdr = end($a_out);
- if ($hdr->uid === $lastCacheHdr->uid)
- $revalidate = false;
-
- $duplicated = false;
- continue;
- }
-
- //skip deleted ones
- if (! $hdr->deleted)
- $a_new[ $hdr->uid ] = $hdr;
+ if ($sort_order == 'DESC')
+ $msgs = $msg_index[$i].','.$msgs;
+ else
+ $msgs = $msgs.','.$msg_index[$i];
}
- }
- //revalidate cache if needed
- $to = $mbox_count - count($a_new);
- if ($revalidate && $to !== 0) //we'll need to reindex the array so we have to make a copy
+ $sorted = TRUE;
+ }
+ else
{
- $a_dirty = $a_out;
- $a_out = array();
- $a_buffers = array();
+ $msgs = sprintf("%d:%d", $begin+1, $end);
+ $sorted = FALSE;
+ }
- //fetch chunks of 20 headers
- $step = 20;
- $found = false;
-
- //fetch headers in blocks starting from new to old
- do {
- $from = $to-$step;
- if ($from < 1) $from = 1;
- //store the block in a temporal buffer
- $a_buffers[$from] = iil_C_FetchHeaders($this->conn, $mailbox, $from . ':' . $to);
+ // cache is dirty, sync it
+ if ($this->caching_enabled && $cache_status==-1)
+ {
+ $this->sync_header_index($mailbox);
+ return $this->_list_headers($mailbox, $page, $sort_field, $sort_order);
+ }
+
- //compare the fetched headers with the ones in the cache
- $idx = 0;
- foreach ($a_buffers[$from] as $k=>$hdr)
+ // cache is incomplete
+ $cache_index = $this->get_message_cache_index($cache_key);
+
+ // fetch reuested headers from server
+ $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs);
+ $a_msg_headers = array();
+
+
+ if (!empty($a_header_index))
+ {
+ foreach ($a_header_index as $i => $headers)
+ {
+ if ($headers->deleted)
{
- //if it's different the comparison ends
- if (!isset($a_dirty[$hdr->uid]) || $a_dirty[$hdr->uid]->id !== $hdr->id)
- break;
+ // delete from cache
+ if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid)
+ $this->remove_message_cache($cache_key, $headers->id);
- //if we arrive here then we know that the older messages in cache are ok
- $found = $hdr->id;
- $idx++;
+ continue;
}
- //remove from the buffer the headers which are already cached
- if ($found)
- $a_buffers[$from] = array_splice($a_buffers[$from], 0, $idx );
-
- $to = $from-1;
- }
- while ($found===false && $from > 1);
+ // add message to cache
+ if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid)
+ $this->add_message_cache($cache_key, $headers->id, $headers);
- //just keep the headers we are certain that didn't change in the cache
- if ($found !== false)
- {
- foreach ($a_dirty as $hdr)
- {
- if ($hdr->id > $found) break;
- $a_out[$hdr->uid] = $hdr;
- }
- }
-
- //we builded the block buffers from new to older, we process them in reverse order
- ksort($a_buffers, SORT_NUMERIC);
- foreach ($a_buffers as $a_buff)
- {
- foreach ($a_buff as $hdr)
- {
- if (! $hdr->deleted)
- $a_out[$hdr->uid] = $hdr;
- }
+ $a_msg_headers[$headers->uid] = $headers;
}
}
-
- //array_merge() would reindex the keys, so we use this 'hack'
- $a_out += $a_new;
- }
-
- //write headers list to cache if needed
- if ($revalidate || count($a_out)!=$cached_count) {
- $this->update_cache($mailbox.'.msg', $a_out);
- }
-
- //sort headers by a specific col
- $a_out = iil_SortHeaders( $a_out, $sort_field, $sort_order );
-
- // return complete list of messages
- if (strtolower($page)=='all')
- return $a_out;
- $start_msg = ($this->list_page-1) * $this->page_size;
- return array_slice($a_out, $start_msg, $this->page_size);
- }
+ // delete cached messages with a higher index than $max
+ $this->clear_message_cache($cache_key, $max);
- // original function; replaced 2005/10/18
- // private method for listing message header
- function _list_headers($mailbox='', $page=NULL, $sort_field='date', $sort_order='DESC')
- {
- $max = $this->_messagecount($mailbox);
-
- if (!strlen($mailbox))
- return array();
-
- // get cached headers
- $a_msg_headers = $this->get_cache($mailbox.'.msg');
-
- // retrieve headers from IMAP
- if (!is_array($a_msg_headers) || sizeof($a_msg_headers) != $max)
- {
- $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, "1:$max");
- $a_msg_headers = array();
-
- if (!empty($a_header_index))
- foreach ($a_header_index as $i => $headers)
- if (!$headers->deleted)
- $a_msg_headers[$headers->uid] = $headers;
- }
- else
- $headers_cached = TRUE;
-
- if (!is_array($a_msg_headers))
- return array();
-
- // sort headers by a specific col
- $a_headers = iil_SortHeaders($a_msg_headers, $sort_field, $sort_order);
- $headers_count = count($a_headers);
-
- // free memory
- unset($a_msg_headers);
-
- // write headers list to cache
- if (!$headers_cached)
- $this->update_cache($mailbox.'.msg', $a_headers);
+ // kick child process to sync cache
- // update message count cache
- $a_mailbox_cache = $this->get_cache('messagecount');
- if (isset($a_mailbox_cache[$mailbox]['ALL']) && $a_mailbox_cache[$mailbox]['ALL'] != $headers_count)
- {
- $a_mailbox_cache[$mailbox]['ALL'] = (int)$headers_count;
- $this->update_cache('messagecount', $a_mailbox_cache);
}
- if (empty($a_headers))
+
+ // return empty array if no messages found
+ if (!is_array($a_msg_headers) || empty($a_msg_headers))
return array();
-
- // return complete list of messages
- if (strtolower($page)=='all')
- return $a_headers;
- $start_msg = ($this->list_page-1) * $this->page_size;
- return array_slice($a_headers, $start_msg, $this->page_size);
+
+ // if not already sorted
+ if (!$headers_sorted)
+ $a_msg_headers = iil_SortHeaders($a_msg_headers, $sort_field, $sort_order);
+
+ return array_values($a_msg_headers);
}
-
+
// return sorted array of message UIDs
function message_index($mbox='', $sort_field='date', $sort_order='DESC')
@@ -510,9 +452,54 @@ class rcube_imap
}
- function sync_header_index($mbox=NULL)
+ function sync_header_index($mailbox)
{
-
+ $cache_key = $mailbox.'.msg';
+ $cache_index = $this->get_message_cache_index($cache_key);
+ $msg_count = $this->_messagecount($mailbox);
+
+ // fetch complete message index
+ $a_message_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", 'UID');
+
+ foreach ($a_message_index as $id => $uid)
+ {
+ // message in cache at correct position
+ if ($cache_index[$id] == $uid)
+ {
+// console("$id / $uid: OK");
+ unset($cache_index[$id]);
+ continue;
+ }
+
+ // message in cache but in wrong position
+ if (in_array((string)$uid, $cache_index, TRUE))
+ {
+// console("$id / $uid: Moved");
+ unset($cache_index[$id]);
+ }
+
+ // other message at this position
+ if (isset($cache_index[$id]))
+ {
+// console("$id / $uid: Delete");
+ $this->remove_message_cache($cache_key, $id);
+ unset($cache_index[$id]);
+ }
+
+
+// console("$id / $uid: Add");
+
+ // fetch complete headers and add to cache
+ $headers = iil_C_FetchHeader($this->conn, $mailbox, $id);
+ $this->add_message_cache($cache_key, $headers->id, $headers);
+ }
+
+ // those ids that are still in cache_index have been deleted
+ if (!empty($cache_index))
+ {
+ foreach ($cache_index as $id => $uid)
+ $this->remove_message_cache($cache_key, $id);
+ }
}
@@ -527,22 +514,19 @@ class rcube_imap
function get_headers($uid, $mbox=NULL)
{
$mailbox = $mbox ? $this->_mod_mailbox($mbox) : $this->mailbox;
-
+
// get cached headers
- $a_msg_headers = $this->get_cache($mailbox.'.msg');
-
- // return cached header
- if ($a_msg_headers[$uid])
- return $a_msg_headers[$uid];
+ if ($headers = $this->get_cached_message($mailbox.'.msg', $uid))
+ return $headers;
$msg_id = $this->_uid2id($uid);
- $header = iil_C_FetchHeader($this->conn, $mailbox, $msg_id);
+ $headers = iil_C_FetchHeader($this->conn, $mailbox, $msg_id);
// write headers cache
- $a_msg_headers[$uid] = $header;
- $this->update_cache($mailbox.'.msg', $a_msg_headers);
+ if ($headers)
+ $this->add_message_cache($mailbox.'.msg', $msg_id, $headers);
- return $header;
+ return $headers;
}
@@ -595,19 +579,20 @@ class rcube_imap
// reload message headers if cached
$cache_key = $this->mailbox.'.msg';
- if ($this->caching_enabled && $result && ($a_cached_headers = $this->get_cache($cache_key)))
+ if ($this->caching_enabled)
{
- // close and re-open connection
- $this->reconnect();
-
- foreach ($uids as $uid)
+ foreach ($msg_ids as $id)
{
- if (isset($a_cached_headers[$uid]))
+ if ($cached_headers = $this->get_cached_message($cache_key, $id))
{
- unset($this->cache[$cache_key][$uid]);
- $this->get_headers($uid);
+ $this->remove_message_cache($cache_key, $id);
+ //$this->get_headers($uid);
}
}
+
+ // close and re-open connection
+ // this prevents connection problems with Courier
+ $this->reconnect();
}
// set nr of messages that were flaged
@@ -633,7 +618,7 @@ class rcube_imap
// make shure mailbox exists
if (in_array($mailbox, $this->_list_mailboxes()))
$saved = iil_C_Append($this->conn, $mailbox, $message);
-
+
if ($saved)
{
// increase messagecount of the target mailbox
@@ -672,20 +657,24 @@ class rcube_imap
// really deleted from the source mailbox
if ($moved)
{
- $this->expunge($from_mbox, FALSE);
- $this->clear_cache($to_mbox.'.msg');
+ $this->_expunge($from_mbox, FALSE);
$this->_clear_messagecount($from_mbox);
$this->_clear_messagecount($to_mbox);
}
// update cached message headers
$cache_key = $from_mbox.'.msg';
- if ($moved && ($a_cached_headers = $this->get_cache($cache_key)))
+ if ($moved && ($a_cache_index = $this->get_message_cache_index($cache_key)))
{
+ $start_index = 100000;
foreach ($a_uids as $uid)
- unset($a_cached_headers[$uid]);
+ {
+ $index = array_search($uid, $a_cache_index);
+ $start_index = min($index, $start_index);
+ }
- $this->update_cache($cache_key, $a_cached_headers);
+ // clear cache from the lowest index on
+ $this->clear_message_cache($cache_key, $start_index);
}
return $moved;
@@ -716,17 +705,23 @@ class rcube_imap
// really deleted from the mailbox
if ($deleted)
{
- $this->expunge($mailbox, FALSE);
+ $this->_expunge($mailbox, FALSE);
$this->_clear_messagecount($mailbox);
}
// remove deleted messages from cache
- if ($deleted && ($a_cached_headers = $this->get_cache($mailbox.'.msg')))
+ $cache_key = $mailbox.'.msg';
+ if ($deleted && ($a_cache_index = $this->get_message_cache_index($cache_key)))
{
+ $start_index = 100000;
foreach ($a_uids as $uid)
- unset($a_cached_headers[$uid]);
+ {
+ $index = array_search($uid, $a_cache_index);
+ $start_index = min($index, $start_index);
+ }
- $this->update_cache($mailbox.'.msg', $a_cached_headers);
+ // clear cache from the lowest index on
+ $this->clear_message_cache($cache_key, $start_index);
}
return $deleted;
@@ -740,7 +735,10 @@ class rcube_imap
$msg_count = $this->_messagecount($mailbox, 'ALL');
if ($msg_count>0)
+ {
+ $this->clear_message_cache($mailbox.'.msg');
return iil_C_ClearFolder($this->conn, $mailbox);
+ }
else
return 0;
}
@@ -750,12 +748,18 @@ class rcube_imap
function expunge($mbox='', $clear_cache=TRUE)
{
$mailbox = $mbox ? $this->_mod_mailbox($mbox) : $this->mailbox;
-
+ return $this->_expunge($mailbox, $clear_cache);
+ }
+
+
+ // send IMAP expunge command and clear cache
+ function _expunge($mailbox, $clear_cache=TRUE)
+ {
$result = iil_C_Expunge($this->conn, $mailbox);
if ($result>=0 && $clear_cache)
{
- $this->clear_cache($mailbox.'.msg');
+ //$this->clear_message_cache($mailbox.'.msg');
$this->_clear_messagecount($mailbox);
}
@@ -763,7 +767,6 @@ class rcube_imap
}
-
/* --------------------------------
* folder managment
* --------------------------------*/
@@ -824,13 +827,18 @@ class rcube_imap
function create_mailbox($name, $subscribe=FALSE)
{
$result = FALSE;
+
+ // replace backslashes
+ $name = preg_replace('/[\\\]+/', '-', $name);
+
$name_enc = UTF7EncodeString($name);
+
+ // reduce mailbox name to 100 chars
+ $name_enc = substr($name_enc, 0, 100);
+
$abs_name = $this->_mod_mailbox($name_enc);
$a_mailbox_cache = $this->get_cache('mailboxes');
-
- //if (strlen($this->root_ns))
- // $abs_name = $this->root_ns.$abs_name;
-
+
if (strlen($abs_name) && (!is_array($a_mailbox_cache) || !in_array($abs_name, $a_mailbox_cache)))
$result = iil_C_CreateFolder($this->conn, $abs_name);
@@ -875,37 +883,41 @@ class rcube_imap
// clear mailboxlist cache
if ($deleted)
+ {
+ $this->clear_message_cache($mailbox.'.msg');
$this->clear_cache('mailboxes');
+ }
- return $updated;
+ return $deleted;
}
/* --------------------------------
- * internal caching functions
+ * internal caching methods
* --------------------------------*/
function set_caching($set)
{
- if ($set && function_exists('rcube_read_cache'))
+ if ($set && is_object($this->db))
$this->caching_enabled = TRUE;
else
$this->caching_enabled = FALSE;
}
+
function get_cache($key)
{
// read cache
if (!isset($this->cache[$key]) && $this->caching_enabled)
{
- $cache_data = rcube_read_cache('IMAP.'.$key);
+ $cache_data = $this->_read_cache_record('IMAP.'.$key);
$this->cache[$key] = strlen($cache_data) ? unserialize($cache_data) : FALSE;
}
- return $this->cache[$key];
+ return $this->cache[$key];
}
@@ -924,7 +936,7 @@ class rcube_imap
foreach ($this->cache as $key => $data)
{
if ($this->cache_changes[$key])
- rcube_write_cache('IMAP.'.$key, serialize($data));
+ $this->_write_cache_record('IMAP.'.$key, serialize($data));
}
}
}
@@ -935,7 +947,7 @@ class rcube_imap
if ($key===NULL)
{
foreach ($this->cache as $key => $data)
- rcube_clear_cache('IMAP.'.$key);
+ $this->_clear_cache_record('IMAP.'.$key);
$this->cache = array();
$this->cache_changed = FALSE;
@@ -943,7 +955,7 @@ class rcube_imap
}
else
{
- rcube_clear_cache('IMAP.'.$key);
+ $this->_clear_cache_record('IMAP.'.$key);
$this->cache_changes[$key] = FALSE;
unset($this->cache[$key]);
}
@@ -951,8 +963,276 @@ class rcube_imap
+ function _read_cache_record($key)
+ {
+ $cache_data = FALSE;
+
+ if ($this->db)
+ {
+ // get cached data from DB
+ $sql_result = $this->db->query(
+ "SELECT cache_id, data
+ FROM ".get_table_name('cache')."
+ WHERE user_id=?
+ AND cache_key=?",
+ $_SESSION['user_id'],
+ $key);
+
+ if ($sql_arr = $this->db->fetch_assoc($sql_result))
+ {
+ $cache_data = $sql_arr['data'];
+ $this->cache_keys[$key] = $sql_arr['cache_id'];
+ }
+ }
+
+ return $cache_data;
+ }
+
+
+ function _write_cache_record($key, $data)
+ {
+ if (!$this->db)
+ return FALSE;
+
+ // check if we already have a cache entry for this key
+ if (!isset($this->cache_keys[$key]))
+ {
+ $sql_result = $this->db->query(
+ "SELECT cache_id
+ FROM ".get_table_name('cache')."
+ WHERE user_id=?
+ AND cache_key=?",
+ $_SESSION['user_id'],
+ $key);
+
+ if ($sql_arr = $this->db->fetch_assoc($sql_result))
+ $this->cache_keys[$key] = $sql_arr['cache_id'];
+ else
+ $this->cache_keys[$key] = FALSE;
+ }
+
+ // update existing cache record
+ if ($this->cache_keys[$key])
+ {
+ $this->db->query(
+ "UPDATE ".get_table_name('cache')."
+ SET created=now(),
+ data=?
+ WHERE user_id=?
+ AND cache_key=?",
+ $data,
+ $_SESSION['user_id'],
+ $key);
+ }
+ // add new cache record
+ else
+ {
+ $this->db->query(
+ "INSERT INTO ".get_table_name('cache')."
+ (created, user_id, cache_key, data)
+ VALUES (now(), ?, ?, ?)",
+ $_SESSION['user_id'],
+ $key,
+ $data);
+ }
+ }
+
+
+ function _clear_cache_record($key)
+ {
+ $this->db->query(
+ "DELETE FROM ".get_table_name('cache')."
+ WHERE user_id=?
+ AND cache_key=?",
+ $_SESSION['user_id'],
+ $key);
+ }
+
+
+
+ /* --------------------------------
+ * message caching methods
+ * --------------------------------*/
+
+
+ // checks if the cache is up-to-date
+ // return: -3 = off, -2 = incomplete, -1 = dirty
+ function check_cache_status($mailbox, $cache_key)
+ {
+ if (!$this->caching_enabled)
+ return -3;
+
+ $cache_index = $this->get_message_cache_index($cache_key, TRUE);
+ $msg_count = $this->_messagecount($mailbox);
+ $cache_count = count($cache_index);
+
+ // console("Cache check: $msg_count !== ".count($cache_index));
+
+ if ($cache_count==$msg_count)
+ {
+ // get highest index
+ $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
+ $cache_uid = array_pop($cache_index);
+
+ // uids of highes message matches -> cache seems OK
+ if ($cache_uid == $header->uid)
+ return 1;
+
+ // cache is dirty
+ return -1;
+ }
+ // if cache count differs less that 10% report as dirty
+ else if (abs($msg_count - $cache_count) < $msg_count/10)
+ return -1;
+ else
+ return -2;
+ }
+
+
+
+ function get_message_cache($key, $from, $to, $sort_field, $sort_order)
+ {
+ $cache_key = "$key:$from:$to:$sort_field:$sort_order";
+ $db_header_fields = array('idx', 'uid', 'subject', 'from', 'to', 'cc', 'date', 'size');
+
+ if (!in_array($sort_field, $db_header_fields))
+ $sort_field = 'idx';
+
+ if ($this->caching_enabled && !isset($this->cache[$cache_key]))
+ {
+ $this->cache[$cache_key] = array();
+ $sql_result = $this->db->limitquery(
+ "SELECT idx, uid, headers
+ FROM ".get_table_name('messages')."
+ WHERE user_id=?
+ AND cache_key=?
+ ORDER BY ".$this->db->quoteIdentifier($sort_field)." ".
+ strtoupper($sort_order),
+ $from,
+ $to-$from,
+ $_SESSION['user_id'],
+ $key);
+
+ while ($sql_arr = $this->db->fetch_assoc($sql_result))
+ {
+ $uid = $sql_arr['uid'];
+ $this->cache[$cache_key][$uid] = unserialize($sql_arr['headers']);
+ }
+ }
+
+ return $this->cache[$cache_key];
+ }
+
+
+ function get_cached_message($key, $uid, $body=FALSE)
+ {
+ if (!$this->caching_enabled)
+ return FALSE;
+
+ $internal_key = '__single_msg';
+ if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) || $body))
+ {
+ $sql_select = "idx, uid, headers";
+ if ($body)
+ $sql_select .= ", body";
+
+ $sql_result = $this->db->query(
+ "SELECT $sql_select
+ FROM ".get_table_name('messages')."
+ WHERE user_id=?
+ AND cache_key=?
+ AND uid=?",
+ $_SESSION['user_id'],
+ $key,
+ $uid);
+
+ if ($sql_arr = $this->db->fetch_assoc($sql_result))
+ {
+ $headers = unserialize($sql_arr['headers']);
+ if (is_object($headers) && !empty($sql_arr['body']))
+ $headers->body = $sql_arr['body'];
+
+ $this->cache[$internal_key][$uid] = $headers;
+ }
+ }
+
+ return $this->cache[$internal_key][$uid];
+ }
+
+
+ function get_message_cache_index($key, $force=FALSE)
+ {
+ static $sa_message_index = array();
+
+ if (!empty($sa_message_index[$key]) && !$force)
+ return $sa_message_index[$key];
+
+ $sa_message_index[$key] = array();
+ $sql_result = $this->db->query(
+ "SELECT idx, uid
+ FROM ".get_table_name('messages')."
+ WHERE user_id=?
+ AND cache_key=?
+ ORDER BY idx ASC",
+ $_SESSION['user_id'],
+ $key);
+
+ while ($sql_arr = $this->db->fetch_assoc($sql_result))
+ $sa_message_index[$key][$sql_arr['idx']] = $sql_arr['uid'];
+
+ return $sa_message_index[$key];
+ }
+
+
+ function add_message_cache($key, $index, $headers)
+ {
+ $this->db->query(
+ "INSERT INTO ".get_table_name('messages')."
+ (user_id, del, cache_key, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers)
+ VALUES (?, 0, ?, ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?)",
+ $_SESSION['user_id'],
+ $key,
+ $index,
+ $headers->uid,
+ $this->decode_header($headers->subject, TRUE),
+ $this->decode_header($headers->from, TRUE),
+ $this->decode_header($headers->to, TRUE),
+ $this->decode_header($headers->cc, TRUE),
+ $headers->size,
+ serialize($headers));
+ }
+
+
+ function remove_message_cache($key, $index)
+ {
+ $this->db->query(
+ "DELETE FROM ".get_table_name('messages')."
+ WHERE user_id=?
+ AND cache_key=?
+ AND idx=?",
+ $_SESSION['user_id'],
+ $key,
+ $index);
+ }
+
+
+ function clear_message_cache($key, $start_index=1)
+ {
+ $this->db->query(
+ "DELETE FROM ".get_table_name('messages')."
+ WHERE user_id=?
+ AND cache_key=?
+ AND idx>=?",
+ $_SESSION['user_id'],
+ $key,
+ $start_index);
+ }
+
+
+
+
/* --------------------------------
- * encoding/decoding functions
+ * encoding/decoding methods
* --------------------------------*/
@@ -986,9 +1266,15 @@ class rcube_imap
}
- function decode_header($input)
+ function decode_header($input, $remove_quotes=FALSE)
{
- return $this->decode_mime_string($input);
+ $str = $this->decode_mime_string($input);
+ if ($str{0}=='"' && $remove_quotes)
+ {
+ $str = str_replace('"', '', $str);
+ }
+
+ return $str;
}
@@ -1094,6 +1380,7 @@ class rcube_imap
}
+
/* --------------------------------
* private methods
* --------------------------------*/
@@ -1149,6 +1436,33 @@ class rcube_imap
}
+ // parse string or array of server capabilities and put them in internal array
+ function _parse_capability($caps)
+ {
+ if (!is_array($caps))
+ $cap_arr = explode(' ', $caps);
+ else
+ $cap_arr = $caps;
+
+ foreach ($cap_arr as $cap)
+ {
+ if ($cap=='CAPABILITY')
+ continue;
+
+ if (strpos($cap, '=')>0)
+ {
+ list($key, $value) = explode('=', $cap);
+ if (!is_array($this->capabilities[$key]))
+ $this->capabilities[$key] = array();
+
+ $this->capabilities[$key][] = $value;
+ }
+ else
+ $this->capabilities[$cap] = TRUE;
+ }
+ }
+
+
// subscribe/unsubscribe a list of mailboxes and update local cache
function _change_subscription($a_mboxes, $mode)
{
diff --git a/program/include/rcube_mdb2.inc b/program/include/rcube_mdb2.inc
index 35973ad5d..54a40e796 100755
--- a/program/include/rcube_mdb2.inc
+++ b/program/include/rcube_mdb2.inc
@@ -238,6 +238,22 @@ class rcube_db
}
+ function format_date($timestamp)
+ {
+ switch($this->db_provider)
+ {
+ case 'mysqli':
+ case 'mysql':
+ return "FROM_UNIXTIME($timestamp)";
+ break;
+ case 'sqlite':
+ return "datetime('$timestamp')";
+ break;
+ default:
+ return date("Y-m-d H:i:s", $timestamp);
+ }
+ }
+
function _add_result($res, $query)
{
// sql error occured
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index 400e345c0..75db7603f 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -1185,99 +1185,6 @@ function send_future_expire_header()
}
-// replace specials characters to a specific encoding type
-function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
- {
- global $OUTPUT_TYPE, $CHARSET;
- static $html_encode_arr, $js_rep_table, $rtf_rep_table, $xml_rep_table;
-
- if (!$enctype)
- $enctype = $GLOBALS['OUTPUT_TYPE'];
-
- // convert nbsps back to normal spaces if not html
- if ($enctype!='html')
- $str = str_replace(chr(160), ' ', $str);
-
-
- // encode for plaintext
- if ($enctype=='text')
- return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
-
- // encode for HTML output
- if ($enctype=='html')
- {
- if (!$html_encode_arr)
- {
- if ($CHARSET=='ISO-8859-1')
- {
- $html_encode_arr = get_html_translation_table(HTML_ENTITIES);
- $html_encode_arr[chr(128)] = '&euro;';
- }
- else
- $html_encode_arr = get_html_translation_table(HTML_SPECIALCHARS);
-
- unset($html_encode_arr['?']);
- unset($html_encode_arr['&']);
- }
-
- $ltpos = strpos($str, '<');
- $encode_arr = $html_encode_arr;
-
- // don't replace quotes and html tags
- if (($mode=='show' || $mode=='') && $ltpos!==false && strpos($str, '>', $ltpos)!==false)
- {
- unset($encode_arr['"']);
- unset($encode_arr['<']);
- unset($encode_arr['>']);
- }
- else if ($mode=='remove')
- $str = strip_tags($str);
-
- $out = strtr($str, $encode_arr);
-
- return $newlines ? nl2br($out) : $out;
- }
-
-
- if ($enctype=='url')
- return rawurlencode($str);
-
-
- // if the replace tables for RTF, XML and JS are not yet defined
- if (!$js_rep_table)
- {
- $js_rep_table = $rtf_rep_table = $xml_rep_table = array();
-
- for ($c=160; $c<256; $c++) // can be increased to support more charsets
- {
- $hex = dechex($c);
- $rtf_rep_table[Chr($c)] = "\\'$hex";
- $xml_rep_table[Chr($c)] = "&#$c;";
-
- if ($CHARSET=='ISO-8859-1')
- $js_rep_table[Chr($c)] = sprintf("\u%s%s", str_repeat('0', 4-strlen($hex)), $hex);
- }
-
- $js_rep_table['"'] = sprintf("\u%s%s", str_repeat('0', 4-strlen(dechex(34))), dechex(34));
- $xml_rep_table['"'] = '&quot;';
- }
-
- // encode for RTF
- if ($enctype=='xml')
- return strtr($str, $xml_rep_table);
-
- // encode for javascript use
- if ($enctype=='js')
- return preg_replace(array("/\r\n/", '/"/', "/([^\\\])'/"), array('\n', '\"', "$1\'"), strtr($str, $js_rep_table));
-
- // encode for RTF
- if ($enctype=='rtf')
- return preg_replace("/\r\n/", "\par ", strtr($str, $rtf_rep_table));
-
- // no encoding given -> return original string
- return $str;
- }
-
function decode_specialchars($input, $charset='')
{
@@ -1462,7 +1369,21 @@ function abbrevate_string($str, $maxlength, $place_holder='...')
return $str;
}
-
+
+
+// delete all files within a folder
+function clear_directory($dir_path)
+ {
+ $dir = @opendir($dir_path);
+ if(!$dir) return FALSE;
+
+ while ($file = readdir($dir))
+ if (strlen($file)>2)
+ unlink("$dir_path/$file");
+
+ closedir($dir);
+ return TRUE;
+ }
?> \ No newline at end of file
diff --git a/program/include/rcube_sqlite.inc b/program/include/rcube_sqlite.inc
new file mode 100644
index 000000000..78c671d38
--- /dev/null
+++ b/program/include/rcube_sqlite.inc
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_sqlite.inc |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2005, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Provide callback functions for sqlite that will emulate |
+ | sone MySQL functions |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+
+function rcube_sqlite_from_unixtime($timestamp)
+ {
+ $timestamp = trim($timestamp);
+ if (!preg_match("/^[0-9]+$/is", $timestamp))
+ $ret = strtotime($timestamp);
+ else
+ $ret = $timestamp;
+
+ $ret = date("Y-m-d H:i:s", $ret);
+ rcube_sqlite_debug("FROM_UNIXTIME ($timestamp) = $ret");
+ return $ret;
+ }
+
+
+function rcube_sqlite_unix_timestamp($timestamp="")
+ {
+ $timestamp = trim($timestamp);
+ if (!$timestamp)
+ $ret = time();
+ else if (!preg_match("/^[0-9]+$/is", $timestamp))
+ $ret = strtotime($timestamp);
+ else
+ $ret = $timestamp;
+
+ rcube_sqlite_debug("UNIX_TIMESTAMP ($timestamp) = $ret");
+ return $ret;
+ }
+
+
+function rcube_sqlite_now()
+ {
+ rcube_sqlite_debug("NOW() = ".date("Y-m-d H:i:s"));
+ return date("Y-m-d H:i:s");
+ }
+
+
+function rcube_sqlite_md5($str)
+ {
+ return md5($str);
+ }
+
+
+function rcube_sqlite_debug($str)
+ {
+ //console($str);
+ }
+
+?> \ No newline at end of file
diff --git a/program/include/session.inc b/program/include/session.inc
index 54ed798fc..f10a2b37e 100644
--- a/program/include/session.inc
+++ b/program/include/session.inc
@@ -45,7 +45,7 @@ function sess_read($key)
if ($sql_arr = $DB->fetch_assoc($sql_result))
{
- $SESS_CHANGED = $sql_arr['changed'];
+ $SESS_CHANGED = mktime(); //$sql_arr['changed'];
if (strlen($sql_arr['vars']))
return $sql_arr['vars'];
@@ -59,7 +59,7 @@ function sess_read($key)
function sess_write($key, $vars)
{
global $DB;
-
+
$sql_result = $DB->query("SELECT 1
FROM ".get_table_name('session')."
WHERE sess_id=?",
@@ -83,6 +83,8 @@ function sess_write($key, $vars)
$key,
$vars,
$_SERVER['REMOTE_ADDR']);
+
+
}
return TRUE;
@@ -102,7 +104,9 @@ function sess_destroy($key)
$DB->query("DELETE FROM ".get_table_name('session')."
WHERE sess_id=?",
$key);
-
+
+ rcmail_clear_session_temp($key);
+
return TRUE;
}
@@ -115,7 +119,7 @@ function sess_gc($maxlifetime)
// get all expired sessions
$sql_result = $DB->query("SELECT sess_id
FROM ".get_table_name('session')."
- WHERE ".$DB->unixtimestamp('now()')."-".$DB->unixtimestamp('created')." > ?",
+ WHERE ".$DB->unixtimestamp('now()')."-".$DB->unixtimestamp('changed')." > ?",
$maxlifetime);
$a_exp_sessions = array();
@@ -134,6 +138,10 @@ function sess_gc($maxlifetime)
WHERE sess_id IN ('".join("','", $a_exp_sessions)."')");
}
+ // remove session specific temp dirs
+ foreach ($a_exp_sessions as $key)
+ rcmail_clear_session_temp($key);
+
return TRUE;
}
diff --git a/program/js/app.js b/program/js/app.js
index 095c89d3a..d65af420e 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -210,7 +210,7 @@ function rcube_webmail()
this.enable_command('logout', true);
// disable browser's contextmenus
- //document.oncontextmenu = function(){ return false; }
+ // document.oncontextmenu = function(){ return false; }
// flag object as complete
this.loaded = true;
@@ -286,6 +286,7 @@ function rcube_webmail()
return false;
//this.messageform = this.gui_objects.messageform;
+ var input_from = rcube_find_object('_from');
var input_to = rcube_find_object('_to');
var input_cc = rcube_find_object('_cc');
var input_bcc = rcube_find_object('_bcc');
@@ -300,6 +301,10 @@ function rcube_webmail()
this.init_address_input_events(input_cc);
if (input_bcc)
this.init_address_input_events(input_bcc);
+
+ // add signature according to selected identity
+ if (input_from && input_from.type=='select-one')
+ this.change_identity(input_from);
if (input_to && input_to.value=='')
input_to.focus();
@@ -461,9 +466,18 @@ function rcube_webmail()
// get the type of sorting
var a_sort = props.split('_');
var sort_col = a_sort[0];
- var sort_order = a_sort[1].toUpperCase();
+ var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null;
var header;
+ // no sort order specified: toggle
+ if (sort_order==null)
+ {
+ if (this.env.sort_col==sort_col)
+ sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
+ else
+ sort_order = this.env.sort_order;
+ }
+
if (this.env.sort_col==sort_col && this.env.sort_order==sort_order)
break;
@@ -478,7 +492,7 @@ function rcube_webmail()
this.env.sort_order = sort_order;
// reload message list
- this.list_mailbox('', '', props);
+ this.list_mailbox('', '', sort_col+'_'+sort_order);
break;
case 'nextpage':
@@ -805,7 +819,7 @@ function rcube_webmail()
break;
case 'delete-folder':
- if (confirm('Do you really want to delete this folder?'))
+ if (confirm(this.get_label('deletefolderconfirm')))
this.delete_folder(props);
break;
@@ -933,8 +947,8 @@ function rcube_webmail()
if (!this.in_selection_before)
{
- var shift = this.check_shiftkey(e);
- this.select(id, shift);
+ var ctrl = this.check_ctrlkey(e);
+ this.select(id, ctrl);
}
if (this.selection.length)
@@ -951,7 +965,7 @@ function rcube_webmail()
// onmouseup-handler of message list row
this.click_row = function(e, id)
{
- var shift = this.check_shiftkey(e);
+ var ctrl = this.check_ctrlkey(e);
// don't do anything (another action processed before)
if (this.dont_select)
@@ -961,13 +975,13 @@ function rcube_webmail()
}
if (!this.drag_active && this.in_selection_before==id)
- this.select(id, (shift && this.task!='settings'));
+ this.select(id, (ctrl && this.task!='settings'));
this.drag_start = false;
this.in_selection_before = false;
// row was double clicked
- if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked && !shift)
+ if (this.task=='mail' && this.list_rows && this.list_rows[id].clicked && !ctrl)
{
this.show_message(id);
return false;
@@ -1332,6 +1346,38 @@ function rcube_webmail()
/*********************************************************/
/********* message compose methods *********/
/*********************************************************/
+
+
+ this.change_identity = function(obj)
+ {
+ if (!obj || !obj.options)
+ return false;
+
+ var id = obj.options[obj.selectedIndex].value;
+ var input_message = rcube_find_object('_message');
+ var message = input_message ? input_message.value : '';
+
+ // remove the 'old' signature
+ if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
+ {
+ var sig = this.env.signatures[this.env.identity];
+
+ if (p = message.lastIndexOf(sig))
+ message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
+ }
+
+ // add the new signature string
+ if (this.env.signatures && this.env.signatures[id])
+ {
+ var sig = this.env.signatures[id];
+ message += '\n'+sig;
+ }
+
+ if (input_message && message)
+ input_message.value = message;
+
+ this.env.identity = id;
+ };
this.show_attachment_form = function(a)
@@ -1854,19 +1900,23 @@ function rcube_webmail()
{
if (folder)
{
- for (var id in this.env.subscriptionrows)
- if (this.env.subscriptionrows[id]==folder)
- break;
-
- var row;
- if (id && (row = document.getElementById(id)))
- row.style.display = 'none';
-
this.http_request('delete-folder', '_mboxes='+escape(folder));
}
};
+ this.remove_folder_row = function(folder)
+ {
+ for (var id in this.env.subscriptionrows)
+ if (this.env.subscriptionrows[id]==folder)
+ break;
+
+ var row;
+ if (id && (row = document.getElementById(id)))
+ row.style.display = 'none';
+ };
+
+
this.subscribe_folder = function(folder)
{
var form;
@@ -2491,6 +2541,21 @@ function rcube_webmail()
return false;
}
+ // check if Shift-key is pressed on event
+ this.check_ctrlkey = function(e)
+ {
+ if(!e && window.event)
+ e = window.event;
+
+ if(bw.linux && bw.ns4 && e.modifiers)
+ return true;
+ else if (bw.mac)
+ return this.check_shiftkey(e);
+ else if((bw.ns4 && e.modifiers & Event.CTRL_MASK) || (e && e.ctrlKey))
+ return true;
+ else
+ return false;
+ }
this.get_mouse_pos = function(e)
{
diff --git a/program/localization/de/labels.inc b/program/localization/de/labels.inc
index 4bbb14c95..12ec06e8c 100644
--- a/program/localization/de/labels.inc
+++ b/program/localization/de/labels.inc
@@ -109,6 +109,7 @@ $labels['unread'] = 'Ungelesene';
$labels['compose'] = 'Neue Nachricht verfassen';
$labels['sendmessage'] = 'Nachricht jetzt senden';
$labels['addattachment'] = 'Datei anfügen';
+$labels['charset'] = 'Zeichensatz';
$labels['attachments'] = 'Anhänge';
$labels['upload'] = 'Hochladen';
@@ -121,7 +122,6 @@ $labels['high'] = 'Hoch';
$labels['highest'] = 'Höchste';
$labels['nosubject'] = '(kein Betreff)';
-
$labels['showimages'] = 'Bilder anzeigen';
@@ -165,7 +165,7 @@ $labels['setdefault'] = 'Als Standard';
$labels['language'] = 'Sprache';
$labels['timezone'] = 'Zeitzone';
$labels['pagesize'] = 'Einträge pro Seite';
-
+$labels['signature'] = 'Signatur';
$labels['folders'] = 'Ordner';
$labels['foldername'] = 'Ordnername';
diff --git a/program/localization/de/messages.inc b/program/localization/de/messages.inc
index e8eabe10a..145c7b4a7 100644
--- a/program/localization/de/messages.inc
+++ b/program/localization/de/messages.inc
@@ -54,6 +54,8 @@ $messages['sendingfailed'] = 'Versand der Nachricht fehlgeschlagen';
$messages['errorsaving'] = 'Beim Speichern ist ein Fehler aufgetreten';
+$messages['deletefolderconfirm'] = 'Wollen Sie diesen Ordner wirklich löschen?';
+
$messages['formincomplete'] = 'Das Formular wurde nicht vollständig ausgefüllt';
$messages['noemailwarning'] = 'Bitte geben Sie eine gültige E-Mail-Adresse ein';
diff --git a/program/localization/ee/labels.inc b/program/localization/ee/labels.inc
new file mode 100644
index 000000000..76050726f
--- /dev/null
+++ b/program/localization/ee/labels.inc
@@ -0,0 +1,182 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | language/ee/labels.inc |
+ | |
+ | Language file of the RoundCube Webmail client |
+ | Copyright (C) 2005, RoundQube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Üllar Pajus <yllar.pajus@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+$labels = array();
+
+// login page
+$labels['username'] = 'Kasutajanimi';
+$labels['password'] = 'Parool';
+$labels['server'] = 'Server';
+$labels['login'] = 'Logi sisse';
+
+// taskbar
+$labels['logout'] = 'Logi välja';
+$labels['mail'] = 'Postkast';
+$labels['settings'] = 'Seaded';
+$labels['addressbook'] = 'Aadressiraamat';
+
+// mailbox names
+$labels['inbox'] = 'Sissetulevad';
+$labels['sent'] = 'Saadetud';
+$labels['trash'] = 'Prügikast';
+$labels['drafts'] = 'Ootel';
+$labels['junk'] = 'Rämps';
+
+// message listing
+$labels['subject'] = 'Pealkiri';
+$labels['from'] = 'Saatja';
+$labels['to'] = 'Saaja';
+$labels['cc'] = 'Koopia';
+$labels['bcc'] = 'Bcc';
+$labels['replyto'] = 'Vastus aadressile';
+$labels['date'] = 'Kuupäev';
+$labels['size'] = 'Suurus';
+$labels['priority'] = 'Tähtsus';
+$labels['organization'] = 'Organisatsioon';
+
+// aliases
+$labels['reply-to'] = $labels['replyto'];
+
+$labels['mailboxlist'] = 'Kaustad';
+$labels['messagesfromto'] = 'Kirjed $from kuni $to, kokku $count';
+$labels['messagenrof'] = 'Kiri $nr, kokku $count';
+
+$labels['moveto'] = 'liiguta kausta...';
+$labels['download'] = 'lae arvutisse';
+
+$labels['filename'] = 'Faili nimi';
+$labels['filesize'] = 'Faili suurus';
+
+$labels['preferhtml'] = 'Eelista HTMLi';
+$labels['htmlmessage'] = 'HTML kirjad';
+$labels['prettydate'] = 'Kenad kuupäevad';
+
+$labels['addtoaddressbook'] = 'Lisa aadressiraamatusse';
+
+// weekdays short
+$labels['sun'] = 'P';
+$labels['mon'] = 'E';
+$labels['tue'] = 'T';
+$labels['wed'] = 'K';
+$labels['thu'] = 'N';
+$labels['fri'] = 'R';
+$labels['sat'] = 'L';
+
+// weekdays long
+$labels['sunday'] = 'Pühapäev';
+$labels['monday'] = 'Esmaspäev';
+$labels['tuesday'] = 'Teisipäev';
+$labels['wednesday'] = 'Kolmapäev';
+$labels['thursday'] = 'Neljapäev';
+$labels['friday'] = 'Reede';
+$labels['saturday'] = 'Laupäev';
+
+$labels['today'] = 'Täna';
+
+// toolbar buttons
+$labels['writenewmessage'] = 'Kirjuta uus kiri';
+$labels['replytomessage'] = 'Vasta kirjale';
+$labels['replytoallmessage'] = 'Vasta saatjale ja teistele kirja saanutele';
+$labels['forwardmessage'] = 'Edasta see kiri';
+$labels['deletemessage'] = 'Liiguta kiri prügikasti';
+$labels['printmessage'] = 'Trüki kiri';
+$labels['previousmessages'] = 'Näita eelmisi kirju';
+$labels['nextmessages'] = 'Näita järgmisi kirju';
+$labels['backtolist'] = 'Tagasi kirjade nimekirja';
+$labels['viewsource'] = 'Näita lähtekoodi';
+
+$labels['select'] = 'Vali';
+$labels['all'] = 'kõik';
+$labels['none'] = 'mitte midagi';
+$labels['unread'] = 'mitte loetud';
+
+// message compose
+$labels['compose'] = 'Koosta kiri';
+$labels['sendmessage'] = 'Saada kiri kohe';
+$labels['addattachment'] = 'Lisa fail';
+
+$labels['attachments'] = 'Manused';
+$labels['upload'] = 'Kinnita manus';
+$labels['close'] = 'Sulge';
+
+$labels['low'] = 'Madal';
+$labels['lowest'] = 'Madalaim';
+$labels['normal'] = 'Tavaline';
+$labels['high'] = 'Kõrge';
+$labels['highest'] = 'Kõrgeim';
+
+$labels['nosubject'] = '(teema puudub)';
+
+$labels['showimages'] = 'Näita pilte';
+
+
+// address boook
+$labels['name'] = 'Näidatav nimi';
+$labels['firstname'] = 'Eesnimi';
+$labels['surname'] = 'Perekonnanimi';
+$labels['email'] = 'E-Mail';
+
+$labels['addcontact'] = 'Lisa uus kontakt';
+$labels['editcontact'] = 'Muuda kontakti';
+
+$labels['edit'] = 'Muuda';
+$labels['cancel'] = 'Katkesta';
+$labels['save'] = 'Salvesta';
+$labels['delete'] = 'Kustuta';
+
+$labels['newcontact'] = 'Loo uus sissekanne';
+$labels['deletecontact'] = 'Kustuta märgistatud kontaktid';
+$labels['composeto'] = 'Kirjuta kiri';
+$labels['contactsfromto'] = 'Kirjed $from kuni $to, kokku $count';
+$labels['print'] = 'Trüki';
+$labels['export'] = 'Ekspordi';
+
+
+// settings
+$labels['settingsfor'] = 'Kasutajaeelistused kontole';
+
+$labels['preferences'] = 'Eelistused';
+$labels['userpreferences'] = 'Kasutaja eelistused';
+$labels['editpreferences'] = 'Muuda kasutaja eelistusi';
+
+$labels['identities'] = 'Identiteedid';
+$labels['manageidentities'] = 'Halda selle konto identiteete';
+$labels['newidentity'] = 'Uus identiteet';
+
+$labels['newitem'] = 'Uus sissekanne';
+$labels['edititem'] = 'Muuda sissekannet';
+
+$labels['setdefault'] = 'Muuda vaikeseadeks';
+$labels['language'] = 'Keel';
+$labels['timezone'] = 'Ajatsoon';
+$labels['pagesize'] = 'Ridu lehe kohta';
+
+
+$labels['folders'] = 'Kaustad';
+$labels['foldername'] = 'Kausta nimi';
+$labels['subscribed'] = 'Näitan';
+$labels['create'] = 'Loo';
+$labels['createfolder'] = 'Loo uus kaust';
+$labels['deletefolder'] = 'Kustuta kaust';
+$labels['managefolders'] = 'Manage folders';
+
+$labels['sortby'] = 'Järjesta';
+$labels['sortasc'] = 'Järjesta kasvavalt';
+$labels['sortdesc'] = 'Järjesta kahanevalt';
+
+?>
diff --git a/program/localization/ee/messages.inc b/program/localization/ee/messages.inc
new file mode 100644
index 000000000..6aeff2834
--- /dev/null
+++ b/program/localization/ee/messages.inc
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | language/ee/messages.inc |
+ | |
+ | Language file of the RoundCube Webmail client |
+ | Copyright (C) 2005, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Üllar Pajus <yllar.pajus@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+$messages = array();
+
+$messages['loginfailed'] = 'Sisselogimine ebaõnnestus';
+
+$messages['cookiesdisabled'] = 'Sinu veebilehitseja ei võta präänikuid vastu';
+
+$messages['sessionerror'] = 'Sinu sessioon on aegunud või vigane';
+
+$messages['imaperror'] = 'Ei õnnestunud IMAP serveriga ühendust luua';
+
+$messages['nomessagesfound'] = 'Postkast paistab tühi olevat';
+
+$messages['loggedout'] = 'Sinu sessioon on edukalt lõpetatud. Nägemiseni!';
+
+$messages['mailboxempty'] = 'Postkast on tühi';
+
+$messages['loading'] = 'Laen...';
+
+$messages['loadingdata'] = 'Laen andmeid...';
+
+$messages['sendingmessage'] = 'Saadan kirja...';
+
+$messages['messagesent'] = 'Kiri edukalt saadetud';
+
+$messages['successfullysaved'] = 'Edukalt salvestatud';
+
+$messages['addedsuccessfully'] = 'Kontakt lisati edukalt aadressiraamatusse';
+
+$messages['contactexists'] = 'Sama e-maili aadressiga kontakt on juba olemas';
+
+$messages['blockedimages'] = 'Sinu privaatsuse kaitsmiseks on selles kirjas välised pildid blokeeritud.';
+
+$messages['encryptedmessage'] = 'See on krüpteeritud kiri ja kahjuks pole seda võimalik näidata. Andestust!';
+
+$messages['nocontactsfound'] = 'Ei leidnud ühtegi kontakti';
+
+$messages['sendingfailed'] = 'Kirja saatmine ebaõnnestus';
+
+$messages['errorsaving'] = 'Salvestamie ajal ilmnes viga';
+
+$messages['errormoving'] = 'Ei suutnud seda kirja liigutada';
+
+$messages['errordeleting'] = 'Ei suutnud seda kirja kustutada';
+
+$messages['errordeleting'] = 'Ei suutnud seda kirja kustutada';
+
+$messages['formincomplete'] = 'Vormi kõik väljad ei ole täidetud';
+
+$messages['noemailwarning'] = 'Palun sisesta toimiv e-maili aadress';
+
+$messages['nonamewarning'] = 'Palun sisesta nimi';
+
+$messages['nopagesizewarning'] = 'Palun sisesta lehekülje suurus';
+
+$messages['norecipientwarning'] = 'Palun sisesta vähemalt üks kirjasaaja';
+
+$messages['nosubjectwarning'] = 'Väli "Pealkiri" on tühi. Soovid selle ära täita ?';
+
+$messages['nobodywarning'] = 'Saadan selle kirja ilma tekstita ?';
+
+
+?>
diff --git a/program/localization/en/labels.inc b/program/localization/en/labels.inc
index 35813cdb0..b37b48140 100644
--- a/program/localization/en/labels.inc
+++ b/program/localization/en/labels.inc
@@ -109,6 +109,7 @@ $labels['unread'] = 'Unread';
$labels['compose'] = 'Compose a message';
$labels['sendmessage'] = 'Send the message now';
$labels['addattachment'] = 'Attach a file';
+$labels['charset'] = 'Charset';
$labels['attachments'] = 'Attachments';
$labels['upload'] = 'Upload';
@@ -121,7 +122,6 @@ $labels['high'] = 'High';
$labels['highest'] = 'Highest';
$labels['nosubject'] = '(no subject)';
-
$labels['showimages'] = 'Display images';
@@ -165,7 +165,7 @@ $labels['setdefault'] = 'Set default';
$labels['language'] = 'Language';
$labels['timezone'] = 'Time zone';
$labels['pagesize'] = 'Rows per page';
-
+$labels['signature'] = 'Signature';
$labels['folders'] = 'Folders';
$labels['foldername'] = 'Folder name';
diff --git a/program/localization/en/messages.inc b/program/localization/en/messages.inc
index 1ce6bba6d..d0286e229 100644
--- a/program/localization/en/messages.inc
+++ b/program/localization/en/messages.inc
@@ -60,13 +60,13 @@ $messages['errormoving'] = 'Could not move the message';
$messages['errordeleting'] = 'Could not delete the message';
-$messages['errordeleting'] = 'Could not delete the message';
+$messages['deletefolderconfirm'] = 'Do you really want to delete this folder?';
-$messages['formincomplete'] = 'The form was not completely filled out';
+$messages['formincomplete'] = 'The form was not completely filled out';
-$messages['noemailwarning'] = 'Please enter a valid email address';
+$messages['noemailwarning'] = 'Please enter a valid email address';
-$messages['nonamewarning'] = 'Please enter a name';
+$messages['nonamewarning'] = 'Please enter a name';
$messages['nopagesizewarning'] = 'Please enter a page size';
diff --git a/program/localization/en_GB/labels.inc b/program/localization/en_GB/labels.inc
index d1a274971..cd9b5032d 100644
--- a/program/localization/en_GB/labels.inc
+++ b/program/localization/en_GB/labels.inc
@@ -120,6 +120,7 @@ $labels['normal'] = 'Normal';
$labels['high'] = 'High';
$labels['highest'] = 'Highest';
+$labels['nosubject'] = '(no subject)';
$labels['showimages'] = 'Display images';
@@ -163,7 +164,7 @@ $labels['setdefault'] = 'Set default';
$labels['language'] = 'Language';
$labels['timezone'] = 'Time zone';
$labels['pagesize'] = 'Rows per page';
-
+$labels['signature'] = 'Signature';
$labels['folders'] = 'Folders';
$labels['foldername'] = 'Folder name';
diff --git a/program/localization/index.inc b/program/localization/index.inc
index 3386ebd68..82424e602 100644
--- a/program/localization/index.inc
+++ b/program/localization/index.inc
@@ -32,6 +32,7 @@
'da' => 'Dansk',
'de' => 'Deutsch',
'es' => 'Espa&ntilde;ol',
+ 'ee' => 'Estonian',
'fr' => 'Fran&ccedil;ais',
'ga' => 'Galician',
'el' => 'Greek',
diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc
index a3fcefbf7..b95988d12 100644
--- a/program/steps/addressbook/delete.inc
+++ b/program/steps/addressbook/delete.inc
@@ -24,7 +24,7 @@ $REMOTE_REQUEST = TRUE;
if ($_GET['_cid'])
{
$DB->query("UPDATE ".get_table_name('contacts')."
- SET del='1'
+ SET del=1
WHERE user_id=?
AND contact_id IN (".$_GET['_cid'].")",
$_SESSION['user_id']);
@@ -40,7 +40,7 @@ if ($_GET['_cid'])
// count contacts for this user
$sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?",
$_SESSION['user_id']);
@@ -60,7 +60,7 @@ if ($_GET['_cid'])
// get contacts from DB
$sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?
ORDER BY name",
$start_row,
diff --git a/program/steps/addressbook/edit.inc b/program/steps/addressbook/edit.inc
index feb794f4d..a129d0094 100644
--- a/program/steps/addressbook/edit.inc
+++ b/program/steps/addressbook/edit.inc
@@ -26,7 +26,7 @@ if (($_GET['_cid'] || $_POST['_cid']) && $_action=='edit')
$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE contact_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$cid,
$_SESSION['user_id']);
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index 4cc79bad6..8065219b0 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -43,7 +43,7 @@ function rcmail_contacts_list($attrib)
// count contacts for this user
$sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?",
$_SESSION['user_id']);
@@ -56,7 +56,7 @@ function rcmail_contacts_list($attrib)
// get contacts from DB
$sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id= ?
ORDER BY name",
$start_row,
@@ -173,7 +173,7 @@ function rcmail_get_rowcount_text($max=NULL)
if ($max===NULL)
{
$sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?",
$_SESSION['user_id']);
diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc
index ecb634b6f..0aa4873b3 100644
--- a/program/steps/addressbook/list.inc
+++ b/program/steps/addressbook/list.inc
@@ -24,7 +24,7 @@ $REMOTE_REQUEST = TRUE;
// count contacts for this user
$sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?",
$_SESSION['user_id']);
@@ -40,7 +40,7 @@ $start_row = ($CONTACTS_LIST['page']-1) * $CONFIG['pagesize'];
// get contacts from DB
$sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?
ORDER BY name",
$start_row,
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 2f54e435b..f5ba139b9 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -52,7 +52,7 @@ if ($_POST['_cid'])
SET changed=now(), ".join(', ', $a_write_sql)."
WHERE contact_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$_POST['_cid'],
$_SESSION['user_id']);
@@ -73,7 +73,7 @@ if ($_POST['_cid'])
$sql_result = $DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE contact_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$_POST['_cid'],
$_SESSION['user_id']);
@@ -109,7 +109,7 @@ else
$sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE user_id=?
AND email=?
- AND del<>'1'",
+ AND del<>1",
$_SESSION['user_id'],
$_POST['_email']);
@@ -134,11 +134,11 @@ else
if (sizeof($a_insert_cols))
{
$DB->query("INSERT INTO ".get_table_name('contacts')."
- (user_id, changed, ".join(', ', $a_insert_cols).")
- VALUES (?, now(), ".join(', ', $a_insert_values).")",
+ (user_id, changed, del, ".join(', ', $a_insert_cols).")
+ VALUES (?, now(), 0, ".join(', ', $a_insert_values).")",
$_SESSION['user_id']);
- $insert_id = $DB->insert_id();
+ $insert_id = $DB->insert_id(get_sequence_name('contacts'));
}
if ($insert_id)
diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc
index 83db486cc..960ea1c45 100644
--- a/program/steps/addressbook/show.inc
+++ b/program/steps/addressbook/show.inc
@@ -26,7 +26,7 @@ if ($_GET['_cid'] || $_POST['_cid'])
$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE contact_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$cid,
$_SESSION['user_id']);
diff --git a/program/steps/mail/addcontact.inc b/program/steps/mail/addcontact.inc
index ad1544e71..b1129ec9d 100644
--- a/program/steps/mail/addcontact.inc
+++ b/program/steps/mail/addcontact.inc
@@ -32,7 +32,7 @@ if ($_GET['_address'])
$sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE user_id=?
AND email=?
- AND del<>'1'",
+ AND del<>1",
$_SESSION['user_id'],$contact['mailto']);
// contact entry with this mail address exists
@@ -42,13 +42,13 @@ if ($_GET['_address'])
else if ($contact['mailto'])
{
$DB->query("INSERT INTO ".get_table_name('contacts')."
- (user_id, changed, name, email)
- VALUES (?, now(), ?, ?)",
+ (user_id, changed, del, name, email)
+ VALUES (?, now(), 0, ?, ?)",
$_SESSION['user_id'],
$contact['name'],
$contact['mailto']);
- $added = $DB->insert_id();
+ $added = $DB->insert_id(get_sequence_name('contacts'));
}
}
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 9509b492b..45f111263 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -88,50 +88,20 @@ function rcmail_compose_headers($attrib)
switch ($part)
{
case 'from':
- // pass the following attributes to the form class
- $field_attrib = array('name' => '_from');
- foreach ($attrib as $attr => $value)
- if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
- $field_attrib[$attr] = $value;
-
- // get this user's identities
- $sql_result = $DB->query("SELECT identity_id, name, email
- FROM ".get_table_name('identities')." WHERE user_id=?
- AND del<>'1'
- ORDER BY ".$DB->quoteIdentifier('default')." DESC, name ASC",
- $_SESSION['user_id']);
-
- if ($DB->num_rows($sql_result))
- {
- $select_from = new select($field_attrib);
- while ($sql_arr = $DB->fetch_assoc($sql_result))
- $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $sql_arr['identity_id']);
-
- $out = $select_from->show($_POST['_from']);
- }
- else
- {
- $input_from = new textfield($field_attrib);
- $out = $input_from->show($_POST['_from']);
- }
-
- if ($form_start)
- $out = $form_start.$out;
-
- return $out;
-
+ return rcmail_compose_header_from($attrib);
case 'to':
$fname = '_to';
$header = 'to';
-
+
// we have contact id's as get parameters
- if (!empty($_GET['_to']) && preg_match('/[0-9]+,?/', $_GET['_to']))
+ if (!empty($_GET['_to']) && preg_match('/^([0-9]+,?)+$/', $_GET['_to']))
{
$a_recipients = array();
$sql_result = $DB->query("SELECT name, email
- FROM ".get_table_name('contacts')." WHERE user_id=?
- AND del<>'1'
+ FROM ".get_table_name('contacts')."
+ WHERE user_id=?
+ AND del<>1
AND contact_id IN (".$_GET['_to'].")",
$_SESSION['user_id']);
@@ -229,71 +199,91 @@ function rcmail_compose_headers($attrib)
}
-/*function rcube_compose_headers($attrib)
- {
- global $CONFIG, $OUTPUT;
-
- list($form_start, $form_end) = get_form_tags($attrib);
-
- // allow the following attributes to be added to the headers table
- $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border'));
-
- $labels = array();
- $labels['from'] = rcube_label('from');
- $labels['to'] = rcube_label('to');
- $labels['cc'] = rcube_label('cc');
- $labels['bcc'] = rcube_label('bcc');
- $labels['replyto'] = rcube_label('replyto');
-
- $input_from = new textfield(array('name' => '_from', 'size' => 30));
- $input_to = new textfield(array('name' => '_to', 'size' => 30));
- $input_cc = new textfield(array('name' => '_cc', 'size' => 30));
- $input_bcc = new textfield(array('name' => '_bcc', 'size' => 30));
- $input_replyto = new textfield(array('name' => '_replyto', 'size' => 30));
-
- $fields = array();
- $fields['from'] = $input_from->show($_POST['_from']);
- $fields['to'] = $input_to->show($_POST['_to']);
- $fields['cc'] = $input_cc->show($_POST['_cc']);
- $fields['bcc'] = $input_bcc->show($_POST['_bcc']);
- $fields['replyto'] = $input_replyto->show($_POST['_replyto']);
-
-
- $out = <<<EOF
-$form_start
-<table$attrib_str><tr>
-
-<td class="title">$labels[from]</td>
-<td>$fields[from]</td>
-
-</tr><tr>
-
-<td class="title">$labels[to]</td>
-<td>$fields[to]</td>
-</tr><tr>
+function rcmail_compose_header_from($attrib)
+ {
+ global $IMAP, $REPLY_MESSAGE, $DB, $OUTPUT, $JS_OBJECT_NAME;
+
+ // pass the following attributes to the form class
+ $field_attrib = array('name' => '_from');
+ foreach ($attrib as $attr => $value)
+ if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
+ $field_attrib[$attr] = $value;
+
+ // extract all recipients of the reply-message
+ $a_recipients = array();
+ if ($REPLY_MESSAGE && is_object($REPLY_MESSAGE['headers']))
+ {
+ $a_to = $IMAP->decode_address_list($REPLY_MESSAGE['headers']->to);
+ foreach ($a_to as $addr)
+ {
+ if (!empty($addr['mailto']))
+ $a_recipients[] = $addr['mailto'];
+ }
-<td class="title">$labels[cc]</td>
-<td>$fields[cc]</td>
+ if (!empty($REPLY_MESSAGE['headers']->cc))
+ {
+ $a_cc = $IMAP->decode_address_list($REPLY_MESSAGE['headers']->cc);
+ foreach ($a_cc as $addr)
+ {
+ if (!empty($addr['mailto']))
+ $a_recipients[] = $addr['mailto'];
+ }
+ }
+ }
-</tr><tr>
+ // get this user's identities
+ $sql_result = $DB->query("SELECT identity_id, name, email, signature
+ FROM ".get_table_name('identities')."
+ WHERE user_id=?
+ AND del<>1
+ ORDER BY ".$DB->quoteIdentifier('standard')." DESC, name ASC",
+ $_SESSION['user_id']);
+
+ if ($DB->num_rows($sql_result))
+ {
+ $from_id = 0;
+ $a_signatures = array();
+
+ $field_attrib['onchange'] = "$JS_OBJECT_NAME.change_identity(this)";
+ $select_from = new select($field_attrib);
+
+ while ($sql_arr = $DB->fetch_assoc($sql_result))
+ {
+ $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $sql_arr['identity_id']);
-<td class="title">$labels[bcc]</td>
-<td>$fields[bcc]</td>
+ // add signature to array
+ if (!empty($sql_arr['signature']))
+ $a_signatures[$sql_arr['identity_id']] = $sql_arr['signature'];
+
+ // set identity if it's one of the reply-message recipients
+ if (in_array($sql_arr['email'], $a_recipients))
+ $from_id = $sql_arr['identity_id'];
+ }
-</tr><tr>
+ // overwrite identity selection with post parameter
+ if (isset($_POST['_from']))
+ $from_id = $_POST['_from'];
-<td class="title">$labels[replyto]</td>
-<td>$fields[replyto]</td>
+ $out = $select_from->show($from_id);
+
-</tr></table>
-$form_end
-EOF;
+ // add signatures to client
+ $OUTPUT->add_script(sprintf("%s.set_env('signatures', %s);", $JS_OBJECT_NAME, array2js($a_signatures)));
+ }
+ else
+ {
+ $input_from = new textfield($field_attrib);
+ $out = $input_from->show($_POST['_from']);
+ }
+
+ if ($form_start)
+ $out = $form_start.$out;
- return $out;
+ return $out;
}
-*/
+
function rcmail_compose_body($attrib)
{
@@ -360,6 +350,14 @@ function rcmail_create_reply_body($body)
$pefix = sprintf("\n\n\nOn %s, %s wrote:\n",
$REPLY_MESSAGE['headers']->date,
$IMAP->decode_header($REPLY_MESSAGE['headers']->from));
+
+
+ // try to remove the signature
+ if ($sp = strrpos($body, '--'))
+ {
+ if ($body{$sp+3}==' ' || $body{$sp+3}=="\n" || $body{$sp+3}=="\r")
+ $body = substr($body, 0, $sp-1);
+ }
return $pefix.$body;
}
@@ -596,7 +594,7 @@ function rcmail_charset_pulldown($selected='ISO-8859-1')
$sql_result = $DB->query("SELECT name, email
FROM ".get_table_name('contacts')." WHERE user_id=?
- AND del<>'1'",$_SESSION['user_id']);
+ AND del<>1",$_SESSION['user_id']);
if ($DB->num_rows($sql_result))
{
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index ca72f7437..c81dd2fd2 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -305,26 +305,41 @@ function rcmail_message_list($attrib)
// make sort links
$sort = '';
- if (in_array($col, $a_sort_cols) && (!empty($attrib['sortdescbutton']) || !empty($attrib['sortascbutton'])))
+ if ($IMAP->get_capability('sort') && in_array($col, $a_sort_cols))
{
- $sort = '&nbsp;&nbsp;';
-
- // asc link
- if (!empty($attrib['sortascbutton']))
+ // have buttons configured
+ if (!empty($attrib['sortdescbutton']) || !empty($attrib['sortascbutton']))
{
- $sort .= rcube_button(array('command' => 'sort',
- 'prop' => $col.'_ASC',
- 'image' => $attrib['sortascbutton'],
- 'title' => 'sortasc'));
- }
+ $sort = '&nbsp;&nbsp;';
+
+ // asc link
+ if (!empty($attrib['sortascbutton']))
+ {
+ $sort .= rcube_button(array('command' => 'sort',
+ 'prop' => $col.'_ASC',
+ 'image' => $attrib['sortascbutton'],
+ 'align' => 'absmiddle',
+ 'title' => 'sortasc'));
+ }
- // desc link
- if (!empty($attrib['sortdescbutton']))
+ // desc link
+ if (!empty($attrib['sortdescbutton']))
+ {
+ $sort .= rcube_button(array('command' => 'sort',
+ 'prop' => $col.'_DESC',
+ 'image' => $attrib['sortdescbutton'],
+ 'align' => 'absmiddle',
+ 'title' => 'sortdesc'));
+ }
+ }
+ // just add a link tag to the header
+ else
{
- $sort .= rcube_button(array('command' => 'sort',
- 'prop' => $col.'_DESC',
- 'image' => $attrib['sortdescbutton'],
- 'title' => 'sortdesc'));
+ $col_name = sprintf('<a href="./#sort" onclick="return %s.command(\'sort\',\'%s\',this)" title="%s">%s</a>',
+ $JS_OBJECT_NAME,
+ $col,
+ rcube_label('sortby'),
+ $col_name);
}
}
@@ -1128,20 +1143,76 @@ function rcmail_first_text_part($message_parts)
// get source code of a specific message and cache it
function rcmail_message_source($uid)
{
- global $IMAP, $DB;
+ global $IMAP, $DB, $CONFIG;
+
+ // get message ID if uid is given
+ $cache_key = $IMAP->mailbox.'.msg';
+ $cached = $IMAP->get_cached_message($cache_key, $uid, FALSE);
+
+ // message is cached in database
+ if ($cached && !empty($cached->body))
+ return $cached->body;
+
+ if (!$cached)
+ $headers = $IMAP->get_headers($uid);
+ else
+ $headers = &$cached;
+
- // get message ID if uid is given
- $headers = $IMAP->get_headers($uid);
$message_id = $headers->messageID;
- // get cached message source
- $msg_source = rcube_read_cache($message_id);
+ $temp_dir = $CONFIG['temp_dir'].(!eregi('\/$', $CONFIG['temp_dir']) ? '/' : '');
+ $cache_dir = $temp_dir.$_SESSION['client_id'];
+ $cache_path = $cache_dir.'/'.$message_id;
+
+ // message is cached in temp dir
+ if (is_dir($cache_dir) && is_file($cache_path))
+ {
+ if ($fp = fopen($cache_path, 'r'))
+ {
+ $msg_source = fread($fp, filesize($cache_path));
+ fclose($fp);
+ return $msg_source;
+ }
+ }
+
+
+ // get message from server
+ $msg_source = $IMAP->get_raw_body($uid);
+
+ // let's cache the message body within the database
+ if ($CONFIG['enable_caching'] && $cached && ($CONFIG['db_max_length'] -300) > $headers->size)
+ {
+ $DB->query("UPDATE ".get_table_name('messages')."
+ SET body=?
+ WHERE user_id=?
+ AND cache_key=?
+ AND uid=?",
+ $msg_source,
+ $_SESSION['user_id'],
+ $cache_key,
+ $uid);
+
+ return $msg_source;
+ }
+
+
+ // create dir for caching
+ if (!is_dir($cache_dir))
+ $dir = mkdir($cache_dir);
+ else
+ $dir = true;
- // get message from server and cache it
- if (!$msg_source)
+ // attempt to write a file with the message body
+ if ($dir && ($fp = fopen($cache_path, 'w')))
+ {
+ fwrite($fp, $msg_source);
+ fclose($fp);
+ }
+ else
{
- $msg_source = $IMAP->get_raw_body($uid);
- rcube_write_cache($message_id, $msg_source, TRUE);
+ raise_error(array('code' => 403, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => "Failed to write to temp dir"), TRUE, FALSE);
}
return $msg_source;
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 11fb559dd..8ec30b0a7 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -46,7 +46,7 @@ function rcmail_get_identity($id)
FROM ".get_table_name('identities')."
WHERE identity_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$id,$_SESSION['user_id']);
if ($DB->num_rows($sql_result))
@@ -78,8 +78,8 @@ if (empty($CHARSET))
$CHARSET = 'ISO-8859-1';
-$mailto_regexp = array('/,\s*[\r\n]+/', '/[\r\n]+/', '/,\s*$/m');
-$mailto_replace = array(' ', ', ', '');
+$mailto_regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m');
+$mailto_replace = array(', ', ', ', '');
// repalce new lines and strip ending ', '
$mailto = preg_replace($mailto_regexp, $mailto_replace, stripslashes($_POST['_to']));
@@ -175,13 +175,16 @@ if (is_array($_FILES['_attachments']['tmp_name']))
foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath)
$MAIL_MIME->addAttachment($filepath, $files['type'][$i], $files['name'][$i], TRUE);
+
+$message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $CHARSET;
+
// encoding settings for mail composing
$message_param = array('text_encoding' => '7bit',
'html_encoding' => 'quoted-printable',
'head_encoding' => 'quoted-printable',
- 'head_charset' => $CHARSET,
- 'html_charset' => $CHARSET,
- 'text_charset' => $CHARSET);
+ 'head_charset' => $message_charset,
+ 'html_charset' => $message_charset,
+ 'text_charset' => $message_charset);
// compose message body and get headers
$msg_body = $MAIL_MIME->get($message_param);
diff --git a/program/steps/settings/delete_identity.inc b/program/steps/settings/delete_identity.inc
index 3bca860b3..b8f9f526c 100644
--- a/program/steps/settings/delete_identity.inc
+++ b/program/steps/settings/delete_identity.inc
@@ -24,7 +24,7 @@ $REMOTE_REQUEST = $_GET['_remote'] ? TRUE : FALSE;
if ($_GET['_iid'])
{
$DB->query("UPDATE ".get_table_name('identities')."
- SET del='1'
+ SET del=1
WHERE user_id=?
AND identity_id IN (".$_GET['_iid'].")",
$_SESSION['user_id']);
diff --git a/program/steps/settings/edit_identity.inc b/program/steps/settings/edit_identity.inc
index 6649c209a..07cd8fa02 100644
--- a/program/steps/settings/edit_identity.inc
+++ b/program/steps/settings/edit_identity.inc
@@ -25,7 +25,7 @@ if (($_GET['_iid'] || $_POST['_iid']) && $_action=='edit-identity')
$DB->query("SELECT * FROM ".get_table_name('identities')."
WHERE identity_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$id,
$_SESSION['user_id']);
@@ -63,7 +63,8 @@ function rcube_identity_form($attrib)
'organization' => array('type' => 'text'),
'reply-to' => array('type' => 'text', 'label' => 'replyto'),
'bcc' => array('type' => 'text'),
- 'default' => array('type' => 'checkbox', 'label' => 'setdefault'));
+ 'signature' => array('type' => 'textarea'),
+ 'standard' => array('type' => 'checkbox', 'label' => 'setdefault'));
// a specific part is requested
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 01b692395..b33f8d434 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -146,9 +146,9 @@ function rcmail_identities_list($attrib)
// get contacts from DB
$sql_result = $DB->query("SELECT * FROM ".get_table_name('identities')."
- WHERE del<>'1'
+ WHERE del<>1
AND user_id=?
- ORDER BY ".$DB->quoteIdentifier('default')." DESC, name ASC",
+ ORDER BY standard DESC, name ASC",
$_SESSION['user_id']);
diff --git a/program/steps/settings/manage_folders.inc b/program/steps/settings/manage_folders.inc
index 04b2a461e..33d83dfff 100644
--- a/program/steps/settings/manage_folders.inc
+++ b/program/steps/settings/manage_folders.inc
@@ -69,10 +69,15 @@ else if ($_action=='create-folder')
else if ($_action=='delete-folder')
{
if (strlen($_GET['_mboxes']))
- $IMAP->delete_mailbox(explode(',', $_GET['_mboxes']));
+ $deleted = $IMAP->delete_mailbox(explode(',', $_GET['_mboxes']));
- if ($_GET['_remote'])
- rcube_remote_response('// deleted');
+ if ($_GET['_remote'] && $deleted)
+ rcube_remote_response(sprintf("this.remove_folder_row('%s')", rep_specialchars_output($_GET['_mboxes'], 'js')));
+ else if ($_GET['_remote'])
+ {
+ $commands = show_message('errorsaving', 'error');
+ rcube_remote_response($commands);
+ }
}
@@ -174,5 +179,9 @@ function rcube_create_folder_form($attrib)
}
+// add some labels to client
+rcube_add_label('deletefolderconfirm');
+
+
parse_template('managefolders');
?> \ No newline at end of file
diff --git a/program/steps/settings/save_identity.inc b/program/steps/settings/save_identity.inc
index 2e42987bf..dc61b7875 100644
--- a/program/steps/settings/save_identity.inc
+++ b/program/steps/settings/save_identity.inc
@@ -19,7 +19,7 @@
*/
-$a_save_cols = array('name', 'email', 'organization', 'reply-to', 'bcc', 'default');
+$a_save_cols = array('name', 'email', 'organization', 'reply-to', 'bcc', 'standard', 'signature');
// check input
@@ -51,7 +51,7 @@ if ($_POST['_iid'])
SET ".join(', ', $a_write_sql)."
WHERE identity_id=?
AND user_id=?
- AND del<>'1'",
+ AND del<>1",
$_POST['_iid'],
$_SESSION['user_id']);
@@ -64,10 +64,10 @@ if ($_POST['_iid'])
// mark all other identities as 'not-default'
$DB->query("UPDATE ".get_table_name('identities')."
- SET ".$DB->quoteIdentifier('default')."='0'
+ SET ".$DB->quoteIdentifier('standard')."='0'
WHERE user_id=?
AND identity_id<>?
- AND del<>'1'",
+ AND del<>1",
$_SESSION['user_id'],
$_POST['_iid']);
@@ -106,8 +106,8 @@ else
(user_id, ".join(', ', $a_insert_cols).")
VALUES (?, ".join(', ', $a_insert_values).")",
$_SESSION['user_id']);
-
- $insert_id = $DB->insert_id();
+
+ $insert_id = $DB->insert_id(get_sequence_name('identities'));
}
if ($insert_id)