From 075e9d5ba25ece5b7fed5470efb38272d519fa27 Mon Sep 17 00:00:00 2001 From: alecpl Date: Wed, 21 Sep 2011 12:22:40 +0000 Subject: - Applied fixes from trunk up to r5259 --- config/main.inc.php.dist | 4 ++- program/include/rcube_imap.php | 23 ++++++------ program/include/rcube_ldap.php | 75 ++++++++++++++++++--------------------- program/include/rcube_message.php | 2 ++ program/include/rcube_session.php | 26 +++++++++----- program/js/app.js | 17 ++++++--- 6 files changed, 82 insertions(+), 65 deletions(-) diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index d68fd1a54..824085c14 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -570,9 +570,11 @@ $rcmail_config['ldap_public']['Verisign'] = array( // if the groups base_dn is empty, the contact base_dn is used for the groups as well // -> in this case, assure that groups and contacts are separated due to the concernig filters! 'groups' => array( - 'base_dn' => '', + 'base_dn' => '', 'filter' => '(objectClass=groupOfNames)', 'object_classes' => array("top", "groupOfNames"), + // name of the member attribute, e.g. uniqueMember + 'member_attr' => 'member', ), ); */ diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 7147c14d5..5f476aba4 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -1505,7 +1505,10 @@ class rcube_imap // use message index sort as default sorting if (!$this->sort_field) { if ($this->skip_deleted) { - $a_index = $this->_search_index($mailbox, 'ALL'); + $a_index = $this->conn->search($mailbox, 'ALL UNDELETED'); + // I didn't found that SEARCH should return sorted IDs + if (is_array($a_index)) + sort($a_index); } else if ($max = $this->_messagecount($mailbox)) { $a_index = range(1, $max); } @@ -2491,17 +2494,17 @@ class rcube_imap return true; } - // Remove NULL characters (#1486189) - $body = str_replace("\x00", '', $body); - // convert charset (if text or message part) - if ($body && !$skip_charset_conv && - preg_match('/^(text|message)$/', $o_part->ctype_primary) - ) { - if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') { - $o_part->charset = $this->default_charset; + if ($body && preg_match('/^(text|message)$/', $o_part->ctype_primary)) { + // Remove NULL characters (#1486189) + $body = str_replace("\x00", '', $body); + + if (!$skip_charset_conv) { + if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') { + $o_part->charset = $this->default_charset; + } + $body = rcube_charset_convert($body, $o_part->charset); } - $body = rcube_charset_convert($body, $o_part->charset); } return $body; diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php index 48920d9fa..69ae8f8d7 100644 --- a/program/include/rcube_ldap.php +++ b/program/include/rcube_ldap.php @@ -73,8 +73,14 @@ class rcube_ldap extends rcube_addressbook $this->prop = $p; // check if groups are configured - if (is_array($p['groups']) and count($p['groups'])) + if (is_array($p['groups']) && count($p['groups'])) { $this->groups = true; + // set member field + if (!empty($p['groups']['member_attr'])) + $this->prop['member_attr'] = strtolower($p['groups']['member_attr']); + else if (empty($p['member_attr'])) + $this->prop['member_attr'] = 'member'; + } // fieldmap property is given if (is_array($p['fieldmap'])) { @@ -115,8 +121,8 @@ class rcube_ldap extends rcube_addressbook foreach ($this->prop['required_fields'] as $key => $val) $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val)); - $this->sort_col = is_array($p['sort']) ? $p['sort'][0] : $p['sort']; - $this->debug = $debug; + $this->sort_col = is_array($p['sort']) ? $p['sort'][0] : $p['sort']; + $this->debug = $debug; $this->mail_domain = $mail_domain; $this->_connect(); @@ -173,7 +179,10 @@ class rcube_ldap extends rcube_addressbook $bind_pass = $this->prop['bind_pass']; $bind_user = $this->prop['bind_user']; $bind_dn = $this->prop['bind_dn']; - $this->base_dn = $this->prop['base_dn']; + + $this->base_dn = $this->prop['base_dn']; + $this->groups_base_dn = ($this->prop['groups']['base_dn']) ? + $this->prop['groups']['base_dn'] : $this->base_dn; // User specific access, generate the proper values to use. if ($this->prop['user_specific']) { @@ -199,7 +208,7 @@ class rcube_ldap extends rcube_addressbook $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}"); - $res = ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid')); + $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid')); if ($res && ($entry = ldap_first_entry($this->conn, $res))) { $bind_dn = ldap_get_dn($this->conn, $entry); @@ -212,8 +221,9 @@ class rcube_ldap extends rcube_addressbook } } // Replace the bind_dn and base_dn variables. - $bind_dn = strtr($bind_dn, $replaces); - $this->base_dn = strtr($this->base_dn, $replaces); + $bind_dn = strtr($bind_dn, $replaces); + $this->base_dn = strtr($this->base_dn, $replaces); + $this->groups_base_dn = strtr($this->groups_base_dn, $replaces); if (empty($bind_user)) { $bind_user = $u; @@ -1091,35 +1101,18 @@ class rcube_ldap extends rcube_addressbook */ function list_groups($search = null) { - global $RCMAIL; - if (!$this->groups) return array(); - $this->groups_base_dn = ($this->prop['groups']['base_dn']) ? - $this->prop['groups']['base_dn'] : $this->base_dn; - - // replace user specific dn - if ($this->prop['user_specific']) - { - $fu = $RCMAIL->user->get_username(); - list($u, $d) = explode('@', $fu); - $dc = 'dc='.strtr($d, array('.' => ',dc=')); - $replaces = array('%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u); - - $this->groups_base_dn = strtr($this->groups_base_dn, $replaces); - } - $base_dn = $this->groups_base_dn; $filter = $this->prop['groups']['filter']; $this->_debug("C: Search [$filter][dn: $base_dn]"); - $res = ldap_search($this->conn, $base_dn, $filter, array('cn','member')); + $res = @ldap_search($this->conn, $base_dn, $filter, array('cn', $this->prop['member_attr'])); if ($res === false) { $this->_debug("S: ".ldap_error($this->conn)); - $this->set_error(self::ERROR_SAVING, 'errorsaving'); return array(); } @@ -1136,7 +1129,7 @@ class rcube_ldap extends rcube_addressbook $group_id = self::dn_encode($group_name); $groups[$group_id]['ID'] = $group_id; $groups[$group_id]['name'] = $group_name; - $groups[$group_id]['members'] = $ldap_data[$i]['member']; + $groups[$group_id]['members'] = $ldap_data[$i][$this->prop['member_attr']]; $group_sortnames[] = strtolower($group_name); } } @@ -1164,7 +1157,7 @@ class rcube_ldap extends rcube_addressbook $new_entry = array( 'objectClass' => $this->prop['groups']['object_classes'], 'cn' => $group_name, - 'member' => '', + $this->prop['member_attr'] => '', ); $this->_debug("C: Add [dn: $new_dn]: ".print_r($new_entry, true)); @@ -1258,13 +1251,14 @@ class rcube_ldap extends rcube_addressbook if (!$this->group_cache) $this->list_groups(); - $base_dn = $this->groups_base_dn; - $group_name = $this->group_cache[$group_id]['name']; - $group_dn = "cn=$group_name,$base_dn"; + $base_dn = $this->groups_base_dn; + $group_name = $this->group_cache[$group_id]['name']; + $member_attr = $this->prop['member_attr']; + $group_dn = "cn=$group_name,$base_dn"; $new_attrs = array(); foreach (explode(",", $contact_ids) as $id) - $new_attrs['member'][] = self::dn_decode($id); + $new_attrs[$member_attr][] = self::dn_decode($id); $this->_debug("C: Add [dn: $group_dn]: ".print_r($new_attrs, true)); @@ -1293,13 +1287,14 @@ class rcube_ldap extends rcube_addressbook if (!$this->group_cache) $this->list_groups(); - $base_dn = $this->groups_base_dn; - $group_name = $this->group_cache[$group_id]['name']; - $group_dn = "cn=$group_name,$base_dn"; + $base_dn = $this->groups_base_dn; + $group_name = $this->group_cache[$group_id]['name']; + $member_attr = $this->prop['member_attr']; + $group_dn = "cn=$group_name,$base_dn"; $del_attrs = array(); foreach (explode(",", $contact_ids) as $id) - $del_attrs['member'][] = self::dn_decode($id); + $del_attrs[$member_attr][] = self::dn_decode($id); $this->_debug("C: Delete [dn: $group_dn]: ".print_r($del_attrs, true)); @@ -1329,17 +1324,17 @@ class rcube_ldap extends rcube_addressbook if (!$this->groups) return array(); - $base_dn = $this->groups_base_dn; - $contact_dn = self::dn_decode($contact_id); - $filter = strtr("(member=$contact_dn)", array('\\' => '\\\\')); + $base_dn = $this->groups_base_dn; + $contact_dn = self::dn_decode($contact_id); + $member_attr = $this->prop['member_attr']; + $filter = strtr("($member_attr=$contact_dn)", array('\\' => '\\\\')); $this->_debug("C: Search [$filter][dn: $base_dn]"); - $res = ldap_search($this->conn, $base_dn, $filter, array('cn')); + $res = @ldap_search($this->conn, $base_dn, $filter, array('cn')); if ($res === false) { $this->_debug("S: ".ldap_error($this->conn)); - $this->set_error(self::ERROR_SAVING, 'errorsaving'); return array(); } $ldap_data = ldap_get_entries($this->conn, $res); diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php index 4e2595550..20cecf117 100644 --- a/program/include/rcube_message.php +++ b/program/include/rcube_message.php @@ -373,6 +373,8 @@ class rcube_message $p->ctype_secondary = 'plain'; $p->body = rcube_label('encryptedmessage'); $p->size = strlen($p->body); + + $this->parts[] = $p; } // message contains multiple parts else if (is_array($structure->parts) && !empty($structure->parts)) { diff --git a/program/include/rcube_session.php b/program/include/rcube_session.php index 1a83a7db1..01b93670c 100644 --- a/program/include/rcube_session.php +++ b/program/include/rcube_session.php @@ -51,9 +51,9 @@ class rcube_session */ public function __construct($db, $config) { - $this->db = $db; - $this->start = microtime(true); - $this->ip = $_SERVER['REMOTE_ADDR']; + $this->db = $db; + $this->start = microtime(true); + $this->ip = $_SERVER['REMOTE_ADDR']; $this->logging = $config->get('log_session', false); $this->mc_debug = $config->get('memcache_debug', false); @@ -126,10 +126,10 @@ class rcube_session public function db_read($key) { $sql_result = $this->db->query( - "SELECT vars, ip, changed FROM ".get_table_name('session')." WHERE sess_id = ?", - $key); + "SELECT vars, ip, changed FROM ".get_table_name('session') + ." WHERE sess_id = ?", $key); - if ($sql_arr = $this->db->fetch_assoc($sql_result)) { + if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) { $this->changed = strtotime($sql_arr['changed']); $this->ip = $sql_arr['ip']; $this->vars = base64_decode($sql_arr['vars']); @@ -156,10 +156,15 @@ class rcube_session $ts = microtime(true); $now = $this->db->fromunixtime((int)$ts); + // no session row in DB (db_read() returns false) + if (!$this->key) { + $oldvars = false; + } // use internal data from read() for fast requests (up to 0.5 sec.) - if ($key == $this->key && (!$this->vars || $ts - $this->start < 0.5)) { + else if ($key == $this->key && (!$this->vars || $ts - $this->start < 0.5)) { $oldvars = $this->vars; - } else { // else read data again from DB + } + else { // else read data again from DB $oldvars = $this->db_read($key); } @@ -281,8 +286,11 @@ class rcube_session { $ts = microtime(true); + // no session data in cache (mc_read() returns false) + if (!$this->key) + $oldvars = false; // use internal data for fast requests (up to 0.5 sec.) - if ($key == $this->key && (!$this->vars || $ts - $this->start < 0.5)) + else if ($key == $this->key && (!$this->vars || $ts - $this->start < 0.5)) $oldvars = $this->vars; else // else read data again $oldvars = $this->mc_read($key); diff --git a/program/js/app.js b/program/js/app.js index bc16b8607..be42cc8b3 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -3489,13 +3489,15 @@ function rcube_webmail() return rcube_event.cancel(e); - case 9: // tab - if (mod == SHIFT_KEY) - break; + case 9: // tab + if (mod == SHIFT_KEY || !this.ksearch_visible()) { + this.ksearch_hide(); + return; + } case 13: // enter - if (this.ksearch_selected === null || !this.ksearch_value) - break; + if (!this.ksearch_visible()) + return false; // insert selected address and hide ksearch pane this.insert_recipient(this.ksearch_selected); @@ -3520,6 +3522,11 @@ function rcube_webmail() return true; }; + this.ksearch_visible = function() + { + return (this.ksearch_selected !== null && this.ksearch_selected !== undefined && this.ksearch_value); + }; + this.ksearch_select = function(node) { var current = $('#rcmksearchSelected'); -- cgit v1.2.3