| | |
| | | } |
| | | |
| | | // get server properties |
| | | if (!empty($this->conn->rootdir)) |
| | | $this->set_rootdir($this->conn->rootdir); |
| | | $rootdir = $this->conn->getRootDir(); |
| | | if (!empty($rootdir)) |
| | | $this->set_rootdir($rootdir); |
| | | if (empty($this->delimiter)) |
| | | $this->get_hierarchy_delimiter(); |
| | | |
| | |
| | | // use SEARCH for message counting |
| | | else if ($this->skip_deleted) { |
| | | $search_str = "ALL UNDELETED"; |
| | | $keys = array('COUNT'); |
| | | $need_uid = false; |
| | | |
| | | // get message count and store in cache |
| | | if ($mode == 'UNSEEN') |
| | | if ($mode == 'UNSEEN') { |
| | | $search_str .= " UNSEEN"; |
| | | // get message count using SEARCH |
| | | // not very performant but more precise (using UNDELETED) |
| | | $index = $this->conn->search($mailbox, $search_str); |
| | | } |
| | | else if ($status) { |
| | | $keys[] = 'MAX'; |
| | | $need_uid = true; |
| | | } |
| | | |
| | | $count = is_array($index) ? count($index) : 0; |
| | | // get message count using (E)SEARCH |
| | | // not very performant but more precise (using UNDELETED) |
| | | $index = $this->conn->search($mailbox, $search_str, $need_uid, $keys); |
| | | |
| | | $count = is_array($index) ? $index['COUNT'] : 0; |
| | | |
| | | if ($mode == 'ALL' && $status) { |
| | | $this->set_folder_stats($mailbox, 'cnt', $count); |
| | | $this->set_folder_stats($mailbox, 'maxuid', $index ? $this->_id2uid(max($index), $mailbox) : 0); |
| | | $this->set_folder_stats($mailbox, 'maxuid', is_array($index) ? $index['MAX'] : 0); |
| | | } |
| | | } |
| | | else { |
| | |
| | | $key = "{$mailbox}:{$this->sort_field}:{$this->sort_order}:{$this->search_string}.msgi"; |
| | | |
| | | // we have a saved search result, get index from there |
| | | if (!isset($this->cache[$key]) && $this->search_string |
| | | if (!isset($this->icache[$key]) && $this->search_string |
| | | && !$this->search_threads && $mailbox == $this->mailbox) { |
| | | // use message index sort as default sorting |
| | | if (!$this->sort_field) { |
| | |
| | | sort($msgs); |
| | | |
| | | if ($this->sort_order == 'DESC') |
| | | $this->cache[$key] = array_reverse($msgs); |
| | | $this->icache[$key] = array_reverse($msgs); |
| | | else |
| | | $this->cache[$key] = $msgs; |
| | | $this->icache[$key] = $msgs; |
| | | } |
| | | // sort with SORT command |
| | | else if ($this->search_sorted) { |
| | |
| | | $this->search('', $this->search_string, $this->search_charset, $this->sort_field); |
| | | |
| | | if ($this->sort_order == 'DESC') |
| | | $this->cache[$key] = array_reverse($this->search_set); |
| | | $this->icache[$key] = array_reverse($this->search_set); |
| | | else |
| | | $this->cache[$key] = $this->search_set; |
| | | $this->icache[$key] = $this->search_set; |
| | | } |
| | | else { |
| | | $a_index = $this->conn->fetchHeaderIndex($mailbox, |
| | |
| | | else if ($this->sort_order=="DESC") |
| | | arsort($a_index); |
| | | |
| | | $this->cache[$key] = array_keys($a_index); |
| | | $this->icache[$key] = array_keys($a_index); |
| | | } |
| | | else { |
| | | $this->cache[$key] = array(); |
| | | $this->icache[$key] = array(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // have stored it in RAM |
| | | if (isset($this->cache[$key])) |
| | | return $this->cache[$key]; |
| | | if (isset($this->icache[$key])) |
| | | return $this->icache[$key]; |
| | | |
| | | // check local cache |
| | | $cache_key = $mailbox.'.msg'; |
| | |
| | | if ($a_index !== false && $this->sort_order == 'DESC') |
| | | $a_index = array_reverse($a_index); |
| | | |
| | | $this->cache[$key] = $a_index; |
| | | $this->icache[$key] = $a_index; |
| | | } |
| | | // fetch complete message index |
| | | else if ($this->get_capability('SORT') && |
| | |
| | | if ($this->sort_order == 'DESC') |
| | | $a_index = array_reverse($a_index); |
| | | |
| | | $this->cache[$key] = $a_index; |
| | | $this->icache[$key] = $a_index; |
| | | } |
| | | else if ($a_index = $this->conn->fetchHeaderIndex( |
| | | $mailbox, "1:*", $this->sort_field, $this->skip_deleted)) { |
| | |
| | | else if ($this->sort_order=="DESC") |
| | | arsort($a_index); |
| | | |
| | | $this->cache[$key] = array_keys($a_index); |
| | | $this->icache[$key] = array_keys($a_index); |
| | | } |
| | | |
| | | return $this->cache[$key] !== false ? $this->cache[$key] : array(); |
| | | return $this->icache[$key] !== false ? $this->icache[$key] : array(); |
| | | } |
| | | |
| | | |
| | |
| | | $key = "{$mailbox}:{$this->sort_field}:{$this->sort_order}:{$this->search_string}.thi"; |
| | | |
| | | // we have a saved search result, get index from there |
| | | if (!isset($this->cache[$key]) && $this->search_string |
| | | if (!isset($this->icache[$key]) && $this->search_string |
| | | && $this->search_threads && $mailbox == $this->mailbox) { |
| | | // use message IDs for better performance |
| | | $ids = array_keys_recursive($this->search_set['tree']); |
| | | $this->cache[$key] = $this->_flatten_threads($mailbox, $this->search_set['tree'], $ids); |
| | | $this->icache[$key] = $this->_flatten_threads($mailbox, $this->search_set['tree'], $ids); |
| | | } |
| | | |
| | | // have stored it in RAM |
| | | if (isset($this->cache[$key])) |
| | | return $this->cache[$key]; |
| | | if (isset($this->icache[$key])) |
| | | return $this->icache[$key]; |
| | | /* |
| | | // check local cache |
| | | $cache_key = $mailbox.'.msg'; |
| | |
| | | // get all threads (default sort order) |
| | | list ($thread_tree) = $this->_fetch_threads($mailbox); |
| | | |
| | | $this->cache[$key] = $this->_flatten_threads($mailbox, $thread_tree); |
| | | $this->icache[$key] = $this->_flatten_threads($mailbox, $thread_tree); |
| | | |
| | | return $this->cache[$key]; |
| | | return $this->icache[$key]; |
| | | } |
| | | |
| | | |
| | |
| | | function clear_mailbox($mbox_name=NULL) |
| | | { |
| | | $mailbox = !empty($mbox_name) ? $this->mod_mailbox($mbox_name) : $this->mailbox; |
| | | $msg_count = $this->_messagecount($mailbox, 'ALL'); |
| | | |
| | | if (!$msg_count) { |
| | | return 0; |
| | | // SELECT will set messages count for clearFolder() |
| | | if ($this->conn->select($mailbox)) { |
| | | $cleared = $this->conn->clearFolder($mailbox); |
| | | } |
| | | |
| | | $cleared = $this->conn->clearFolder($mailbox); |
| | | |
| | | // make sure the message count cache is cleared as well |
| | | if ($cleared) { |
| | |
| | | $a_folders = $data['folders']; |
| | | } |
| | | else { |
| | | // retrieve list of folders from IMAP server |
| | | $a_folders = $this->conn->listSubscribed($this->mod_mailbox($root), $filter); |
| | | // Server supports LIST-EXTENDED, we can use selection options |
| | | if ($this->get_capability('LIST-EXTENDED')) { |
| | | // This will also set mailbox options, LSUB doesn't do that |
| | | $a_folders = $this->conn->listMailboxes($this->mod_mailbox($root), $filter, |
| | | NULL, array('SUBSCRIBED')); |
| | | |
| | | // remove non-existent folders |
| | | if (is_array($a_folders)) { |
| | | foreach ($a_folders as $idx => $folder) { |
| | | if ($this->conn->data['LIST'] && ($opts = $this->conn->data['LIST'][$folder]) |
| | | && in_array('\\NonExistent', $opts) |
| | | ) { |
| | | unset($a_folders[$idx]); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // retrieve list of folders from IMAP server using LSUB |
| | | else { |
| | | $a_folders = $this->conn->listSubscribed($this->mod_mailbox($root), $filter); |
| | | } |
| | | } |
| | | |
| | | if (!is_array($a_folders) || !sizeof($a_folders)) |
| | |
| | | } |
| | | |
| | | return $mbox_name; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Gets folder options from LIST response, e.g. \Noselect, \Noinferiors |
| | | * |
| | | * @param string $mbox_name Folder name |
| | | * @param bool $force Set to True if options should be refreshed |
| | | * Options are available after LIST command only |
| | | * |
| | | * @return array Options list |
| | | */ |
| | | function mailbox_options($mbox_name, $force=false) |
| | | { |
| | | $mbox = $this->mod_mailbox($mbox_name); |
| | | |
| | | if ($mbox == 'INBOX') { |
| | | return array(); |
| | | } |
| | | |
| | | if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mbox])) { |
| | | if ($force) { |
| | | $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); |
| | | } |
| | | else { |
| | | return array(); |
| | | } |
| | | } |
| | | |
| | | $opts = $this->conn->data['LIST'][$mbox]; |
| | | |
| | | return is_array($opts) ? $opts : array(); |
| | | } |
| | | |
| | | |
| | |
| | | foreach ($a as $val) { |
| | | $j++; |
| | | $address = trim($val['address']); |
| | | $name = trim($val['name']); |
| | | |
| | | if ($name && preg_match('/^[\'"]/', $name) && preg_match('/[\'"]$/', $name)) |
| | | $name = trim($name, '\'"'); |
| | | $name = trim($val['name']); |
| | | |
| | | if ($name && $address && $name != $address) |
| | | $string = sprintf('%s <%s>', preg_match("/$special_chars/", $name) ? '"'.addcslashes($name, '"').'"' : $name, $address); |
| | |
| | | $result = array(); |
| | | |
| | | foreach ($a as $key => $val) { |
| | | $val = preg_replace("/([\"\w])</", "$1 <", $val); |
| | | $sub_a = rcube_explode_quoted_string(' ', $decode ? $this->decode_header($val) : $val); |
| | | $result[$key]['name'] = ''; |
| | | $name = ''; |
| | | $address = ''; |
| | | $val = trim($val); |
| | | |
| | | foreach ($sub_a as $k => $v) { |
| | | // use angle brackets in regexp to not handle names with @ sign |
| | | if (preg_match('/^<\S+@\S+>$/', $v)) |
| | | $result[$key]['address'] = trim($v, '<>'); |
| | | else |
| | | $result[$key]['name'] .= (empty($result[$key]['name'])?'':' ').str_replace("\"",'',stripslashes($v)); |
| | | if (preg_match('/(.*)<(\S+@\S+)>$/', $val, $m)) { |
| | | $address = $m[2]; |
| | | $name = trim($m[1]); |
| | | } |
| | | else if (preg_match('/^(\S+@\S+)$/', $val, $m)) { |
| | | $address = $m[1]; |
| | | $name = ''; |
| | | } |
| | | else { |
| | | $name = $val; |
| | | } |
| | | |
| | | // if (empty($result[$key]['name'])) |
| | | // $result[$key]['name'] = $result[$key]['address']; |
| | | if (empty($result[$key]['address'])) |
| | | $result[$key]['address'] = $result[$key]['name']; |
| | | // dequote and/or decode name |
| | | if ($name) { |
| | | if ($name[0] == '"') { |
| | | $name = substr($name, 1, -1); |
| | | $name = stripslashes($name); |
| | | } |
| | | if ($decode) { |
| | | $name = $this->decode_header($name); |
| | | } |
| | | } |
| | | |
| | | if (!$address && $name) { |
| | | $address = $name; |
| | | } |
| | | |
| | | if ($address) { |
| | | $result[$key] = array('name' => $name, 'address' => $address); |
| | | } |
| | | } |
| | | |
| | | return $result; |