summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
Diffstat (limited to 'program')
-rw-r--r--program/include/main.inc31
-rw-r--r--program/include/rcmail.php11
-rw-r--r--program/include/rcube_imap.php79
-rw-r--r--program/js/common.js11
-rw-r--r--program/steps/mail/autocomplete.inc34
5 files changed, 118 insertions, 48 deletions
diff --git a/program/include/main.inc b/program/include/main.inc
index 95d422d6a..c84e5ad6b 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -1281,11 +1281,6 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')
$path .= $prefix.$currentFolder;
if (!isset($arrFolders[$currentFolder])) {
- // Check \Noselect attribute (if attributes are in cache)
- if (!$virtual && ($attrs = $RCMAIL->imap->mailbox_attributes($path))) {
- $virtual = in_array('\\Noselect', $attrs);
- }
-
$arrFolders[$currentFolder] = array(
'id' => $path,
'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'),
@@ -1313,12 +1308,14 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $at
$realnames = (bool)$attrib['realnames'];
$msgcounts = $RCMAIL->imap->get_cache('messagecount');
- $idx = 0;
$out = '';
foreach ($arrFolders as $key => $folder) {
- $title = null;
+ $title = null;
+ $folder_class = rcmail_folder_classname($folder['id']);
+ $collapsed = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false;
+ $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0;
- if (($folder_class = rcmail_folder_classname($folder['id'])) && !$realnames) {
+ if ($folder_class && !$realnames) {
$foldername = rcube_label($folder_class);
}
else {
@@ -1338,25 +1335,12 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $at
$classes = array('mailbox');
// set special class for Sent, Drafts, Trash and Junk
- if ($folder['id'] == $CONFIG['sent_mbox'])
- $classes[] = 'sent';
- else if ($folder['id'] == $CONFIG['drafts_mbox'])
- $classes[] = 'drafts';
- else if ($folder['id'] == $CONFIG['trash_mbox'])
- $classes[] = 'trash';
- else if ($folder['id'] == $CONFIG['junk_mbox'])
- $classes[] = 'junk';
- else if ($folder['id'] == 'INBOX')
- $classes[] = 'inbox';
- else
- $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
+ if ($folder_class)
+ $classes[] = $folder_class;
if ($folder['id'] == $mbox_name)
$classes[] = 'selected';
- $collapsed = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false;
- $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0;
-
if ($folder['virtual'])
$classes[] = 'virtual';
else if ($unread)
@@ -1390,7 +1374,6 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $at
}
$out .= "</li>\n";
- $idx++;
}
return $out;
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 969e101f7..e06594fcd 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -678,18 +678,21 @@ class rcmail
if (session_id())
return;
+ $sess_name = $this->config->get('session_name');
+ $sess_domain = $this->config->get('session_domain');
+ $lifetime = $this->config->get('session_lifetime', 0) * 60;
+
// set session domain
- if ($domain = $this->config->get('session_domain')) {
- ini_set('session.cookie_domain', $domain);
+ if ($sess_domain) {
+ ini_set('session.cookie_domain', $sess_domain);
}
// set session garbage collecting time according to session_lifetime
- $lifetime = $this->config->get('session_lifetime', 0) * 60;
if ($lifetime) {
ini_set('session.gc_maxlifetime', $lifetime * 2);
}
ini_set('session.cookie_secure', rcube_https_check());
- ini_set('session.name', 'roundcube_sessid');
+ ini_set('session.name', $sess_name ? $sess_name : 'roundcube_sessid');
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.serialize_handler', 'php');
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 8c1fab8cf..d56da3d26 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -1373,6 +1373,11 @@ class rcube_imap
$this->_messagecount($mailbox, 'ALL', true);
$result = 0;
+
+ if (empty($old)) {
+ return $result;
+ }
+
$new = $this->get_folder_stats($mailbox);
// got new messages
@@ -2999,14 +3004,14 @@ class rcube_imap
/**
- * Private method for mailbox listing
+ * Private method for mailbox listing (LSUB)
*
* @param string $root Optional root folder
* @param string $name Optional name pattern
* @param mixed $filter Optional filter
* @param string $rights Optional ACL requirements
*
- * @return array List of mailboxes/folders
+ * @return array List of subscribed folders
* @see rcube_imap::list_mailboxes()
* @access private
*/
@@ -3109,7 +3114,7 @@ class rcube_imap
}
else {
// retrieve list of folders from IMAP server
- $a_mboxes = $this->conn->listMailboxes($root, $name);
+ $a_mboxes = $this->_list_unsubscribed($root, $name);
}
if (!is_array($a_mboxes)) {
@@ -3144,6 +3149,70 @@ class rcube_imap
/**
+ * Private method for mailbox listing (LIST)
+ *
+ * @param string $root Optional root folder
+ * @param string $name Optional name pattern
+ *
+ * @return array List of folders
+ * @see rcube_imap::list_unsubscribed()
+ */
+ private function _list_unsubscribed($root='', $name='*')
+ {
+ $result = $this->conn->listMailboxes($root, $name);
+
+ if (!is_array($result)) {
+ return array();
+ }
+
+ // #1486796: some server configurations doesn't
+ // return folders in all namespaces, we'll try to detect that situation
+ // and ask for these namespaces separately
+ if ($root == '' && $name = '*') {
+ $delim = $this->get_hierarchy_delimiter();
+ $namespace = $this->get_namespace();
+ $search = array();
+
+ // build list of namespace prefixes
+ foreach ((array)$namespace as $ns) {
+ if (is_array($ns)) {
+ foreach ($ns as $ns_data) {
+ if (strlen($ns_data[0])) {
+ $search = $ns_data[0];
+ }
+ }
+ }
+ }
+
+ if (!empty($search)) {
+ // go through all folders detecting namespace usage
+ foreach ($result as $folder) {
+ foreach ($search as $idx => $prefix) {
+ if (strpos($folder, $prefix) === 0) {
+ unset($search[$idx]);
+ }
+ }
+ if (empty($search)) {
+ break;
+ }
+ }
+
+ // get folders in hidden namespaces and add to the result
+ foreach ($search as $prefix) {
+ $list = $this->conn->listMailboxes($prefix, $name);
+
+ if (!empty($list)) {
+ $result = array_merge($result, $list);
+ }
+ }
+ }
+ }
+
+ return $result;
+ }
+
+
+ /**
* Filter the given list of folders according to access rights
*/
private function filter_rights($a_folders, $rights)
@@ -3415,8 +3484,8 @@ class rcube_imap
foreach ($this->namespace as $type => $namespace) {
if (is_array($namespace)) {
foreach ($namespace as $ns) {
- if (strlen($ns[0])) {
- if ((strlen($ns[0])>1 && $mailbox == substr($ns[0], 0, -1))
+ if ($len = strlen($ns[0])) {
+ if (($len > 1 && $mailbox == substr($ns[0], 0, -1))
|| strpos($mailbox, $ns[0]) === 0
) {
return $type;
diff --git a/program/js/common.js b/program/js/common.js
index 831e44a21..c13d95e3d 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -542,10 +542,17 @@ function rcube_clone_object(obj)
return out;
};
-// make a string URL safe
+// make a string URL safe (and compatible with PHP's rawurlencode())
function urlencode(str)
{
- return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
+ if (window.encodeURIComponent)
+ return encodeURIComponent(str).replace('*', '%2A');
+
+ return escape(str)
+ .replace('+', '%2B')
+ .replace('*', '%2A')
+ .replace('/', '%2F')
+ .replace('@', '%40');
};
diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc
index e40bb76c3..281a4e9f7 100644
--- a/program/steps/mail/autocomplete.inc
+++ b/program/steps/mail/autocomplete.inc
@@ -54,6 +54,7 @@ else
if (!empty($book_types) && strlen($search)) {
$contacts = array();
+ $sort_keys = array();
$books_num = count($book_types);
$search_lc = mb_strtolower($search);
@@ -66,6 +67,7 @@ if (!empty($book_types) && strlen($search)) {
// Contact can have more than one e-mail address
$email_arr = (array)$abook->get_col_values('email', $sql_arr, true);
$email_cnt = count($email_arr);
+ $idx = 0;
foreach ($email_arr as $email) {
if (empty($email)) {
continue;
@@ -80,7 +82,9 @@ if (!empty($book_types) && strlen($search)) {
// skip duplicates
if (!in_array($contact, $contacts)) {
- $contacts[] = $contact;
+ $contacts[] = $contact;
+ $sort_keys[] = sprintf('%s %03d', $sql_arr['name'] , $idx++);
+
if (count($contacts) >= $MAXNUM)
break 2;
}
@@ -102,15 +106,20 @@ if (!empty($book_types) && strlen($search)) {
// group (distribution list) with email address(es)
if ($group_prop['email']) {
+ $idx = 0;
foreach ((array)$group_prop['email'] as $email) {
- $contacts[] = format_email_recipient($email, $group['name']);
+ $contacts[] = format_email_recipient($email, $group['name']);
+ $sort_keys[] = sprintf('%s %03d', $group['name'] , $idx++);
+
if (count($contacts) >= $MAXNUM)
break 2;
}
}
// show group with count
else if (($result = $abook->count()) && $result->count) {
- $contacts[] = array('name' => $group['name'] . ' (' . intval($result->count) . ')', 'id' => $group['ID'], 'source' => $id);
+ $contacts[] = array('name' => $group['name'] . ' (' . intval($result->count) . ')', 'id' => $group['ID'], 'source' => $id);
+ $sort_keys[] = $group['name'];
+
if (count($contacts) >= $MAXNUM)
break;
}
@@ -118,17 +127,16 @@ if (!empty($book_types) && strlen($search)) {
}
}
- usort($contacts, 'contact_results_sort');
+ if (count($contacts)) {
+ // sort contacts index
+ asort($sort_keys, SORT_LOCALE_STRING);
+ // re-sort contacts according to index
+ foreach ($sort_keys as $idx => $val) {
+ $sort_keys[$idx] = $contacts[$idx];
+ }
+ $contacts = array_values($sort_keys);
+ }
}
$OUTPUT->command('ksearch_query_results', $contacts, $search, $sid);
$OUTPUT->send();
-
-
-function contact_results_sort($a, $b)
-{
- $name_a = is_array($a) ? $a['name'] : $a;
- $name_b = is_array($b) ? $b['name'] : $b;
- return strcoll(trim($name_a, '" '), trim($name_b, '" '));
-}
-