| | |
| | | | program/include/rcube_imap.inc | |
| | | | | |
| | | | This file is part of the RoundCube Webmail client | |
| | | | Copyright (C) 2005-2006, RoundCube Dev. - Switzerland | |
| | | | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland | |
| | | | Licensed under the GNU GPL | |
| | | | | |
| | | | PURPOSE: | |
| | |
| | | * |
| | | * @package Mail |
| | | * @author Thomas Bruederli <roundcube@gmail.com> |
| | | * @version 1.39 |
| | | * @version 1.40 |
| | | * @link http://ilohamail.org |
| | | */ |
| | | class rcube_imap |
| | |
| | | var $sort_order = 'DESC'; |
| | | var $delimiter = NULL; |
| | | var $caching_enabled = FALSE; |
| | | var $default_charset = 'ISO-8859-1'; |
| | | var $default_folders = array('INBOX'); |
| | | var $default_folders_lc = array('inbox'); |
| | | var $cache = array(); |
| | |
| | | * @param string Username for IMAP account |
| | | * @param string Password for IMAP account |
| | | * @param number Port to connect to |
| | | * @param boolean Use SSL connection |
| | | * @param string SSL schema (either ssl or tls) or null if plain connection |
| | | * @return boolean TRUE on success, FALSE on failure |
| | | * @access public |
| | | */ |
| | | function connect($host, $user, $pass, $port=143, $use_ssl=FALSE) |
| | | function connect($host, $user, $pass, $port=143, $use_ssl=null) |
| | | { |
| | | global $ICL_SSL, $ICL_PORT, $IMAP_USE_INTERNAL_DATE; |
| | | |
| | | // check for Open-SSL support in PHP build |
| | | if ($use_ssl && in_array('openssl', get_loaded_extensions())) |
| | | $ICL_SSL = TRUE; |
| | | $ICL_SSL = $use_ssl == 'imaps' ? 'ssl' : $use_ssl; |
| | | else if ($use_ssl) |
| | | { |
| | | raise_error(array('code' => 403, 'type' => 'imap', 'file' => __FILE__, |
| | |
| | | |
| | | if (empty($this->delimiter)) |
| | | $this->get_hierarchy_delimiter(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Set default message charset |
| | | * |
| | | * This will be used for message decoding if a charset specification is not available |
| | | * |
| | | * @param string Charset string |
| | | * @access public |
| | | */ |
| | | function set_charset($cs) |
| | | { |
| | | $this->default_charset = $ch; |
| | | } |
| | | |
| | | |
| | |
| | | $mailbox = $this->mailbox; |
| | | |
| | | // count search set |
| | | if ($this->search_string && $mailbox == $this->mailbox && $mode == 'ALL') |
| | | if ($this->search_string && $mailbox == $this->mailbox && $mode == 'ALL' && !$force) |
| | | return count((array)$this->search_set); |
| | | |
| | | $a_mailbox_cache = $this->get_cache('messagecount'); |
| | |
| | | if ($this->search_string && $mailbox == $this->mailbox) |
| | | return $this->_list_header_set($mailbox, $this->search_set, $page, $sort_field, $sort_order); |
| | | |
| | | if ($sort_field!=NULL) |
| | | $this->sort_field = $sort_field; |
| | | if ($sort_order!=NULL) |
| | | $this->sort_order = strtoupper($sort_order); |
| | | $this->_set_sort_order($sort_field, $sort_order); |
| | | |
| | | $max = $this->_messagecount($mailbox); |
| | | $start_msg = ($this->list_page-1) * $this->page_size; |
| | |
| | | if (!strlen($mailbox) || empty($msgs)) |
| | | return array(); |
| | | |
| | | if ($sort_field!=NULL) |
| | | $this->sort_field = $sort_field; |
| | | if ($sort_order!=NULL) |
| | | $this->sort_order = strtoupper($sort_order); |
| | | $this->_set_sort_order($sort_field, $sort_order); |
| | | |
| | | $max = count($msgs); |
| | | $start_msg = ($this->list_page-1) * $this->page_size; |
| | |
| | | */ |
| | | function message_index($mbox_name='', $sort_field=NULL, $sort_order=NULL) |
| | | { |
| | | if ($sort_field!=NULL) |
| | | $this->sort_field = $sort_field; |
| | | if ($sort_order!=NULL) |
| | | $this->sort_order = strtoupper($sort_order); |
| | | $this->_set_sort_order($sort_field, $sort_order); |
| | | |
| | | $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; |
| | | $key = "$mbox:".$this->sort_field.":".$this->sort_order.".msgi"; |
| | | $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 && $mailbox == $this->mailbox) |
| | | { |
| | | $this->cache[$key] = $a_msg_headers = array(); |
| | | $this->_fetch_headers($mailbox, join(',', $this->search_set), $a_msg_headers, NULL); |
| | | |
| | | foreach (iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order) as $i => $msg) |
| | | $this->cache[$key][] = $msg->uid; |
| | | } |
| | | |
| | | // have stored it in RAM |
| | | if (isset($this->cache[$key])) |
| | |
| | | |
| | | return $this->get_search_set(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Check if the given message ID is part of the current search set |
| | | * |
| | | * @return boolean True on match or if no search request is stored |
| | | */ |
| | | function in_searchset($msgid) |
| | | { |
| | | if (!empty($this->search_string)) |
| | | return in_array("$msgid", (array)$this->search_set, true); |
| | | else |
| | | return true; |
| | | } |
| | | |
| | | |
| | | /** |
| | |
| | | // write headers cache |
| | | if ($headers) |
| | | { |
| | | if ($is_uid) |
| | | $this->uid_id_map[$mbox_name][$uid] = $headers->id; |
| | | if ($headers->uid && $headers->id) |
| | | $this->uid_id_map[$mailbox][$headers->uid] = $headers->id; |
| | | |
| | | $this->add_message_cache($mailbox.'.msg', $headers->id, $headers); |
| | | } |
| | |
| | | if (!empty($structure)) |
| | | { |
| | | $this->_msg_id = $msg_id; |
| | | $headers = $this->get_headers($msg_id, NULL, FALSE); |
| | | $headers = $this->get_headers($uid); |
| | | |
| | | $struct = &$this->_structure_part($structure); |
| | | $struct->headers = get_object_vars($headers); |
| | |
| | | } |
| | | |
| | | // normalize filename property |
| | | if (!empty($struct->d_parameters['filename'])) |
| | | $struct->filename = $this->decode_mime_string($struct->d_parameters['filename']); |
| | | else if (!empty($struct->ctype_parameters['name'])) |
| | | $struct->filename = $this->decode_mime_string($struct->ctype_parameters['name']); |
| | | if ($filename_mime = $struct->d_parameters['filename'] ? $struct->d_parameters['filename'] : $struct->ctype_parameters['name']) |
| | | $struct->filename = rcube_imap::decode_mime_string($filename_mime, $this->default_charset); |
| | | else if ($filename_encoded = $struct->d_parameters['filename*'] ? $struct->d_parameters['filename*'] : $struct->ctype_parameters['name*']) |
| | | { |
| | | // decode filename according to RFC 2231, Section 4 |
| | | list($filename_charset,, $filename_urlencoded) = split('\'', $filename_encoded); |
| | | $struct->filename = rcube_charset_convert(urldecode($filename_urlencoded), $filename_charset); |
| | | } |
| | | else if (!empty($struct->headers['content-description'])) |
| | | $struct->filename = $this->decode_mime_string($struct->headers['content-description']); |
| | | $struct->filename = rcube_imap::decode_mime_string($struct->headers['content-description'], $this->default_charset); |
| | | |
| | | return $struct; |
| | | } |
| | |
| | | // convert charset (if text or message part) |
| | | if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') |
| | | { |
| | | // assume ISO-8859-1 if no charset specified |
| | | // assume default if no charset specified |
| | | if (empty($o_part->charset)) |
| | | $o_part->charset = 'ISO-8859-1'; |
| | | $o_part->charset = $this->default_charset; |
| | | |
| | | $body = rcube_charset_convert($body, $o_part->charset); |
| | | } |
| | |
| | | * Set message flag to one or several messages |
| | | * |
| | | * @param mixed Message UIDs as array or as comma-separated string |
| | | * @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT |
| | | * @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT |
| | | * @return boolean True on success, False on failure |
| | | */ |
| | | function set_flag($uids, $flag) |
| | |
| | | $deleted = TRUE; |
| | | |
| | | foreach ($all_mboxes as $c_mbox) |
| | | if (preg_match('/^'.preg_quote($mailbox.$this->delimiter).'/', $c_mbox)) |
| | | { |
| | | $regex = preg_quote($mailbox . $this->delimiter, '/'); |
| | | $regex = '/^' . $regex . '/'; |
| | | if (preg_match($regex, $c_mbox)) |
| | | { |
| | | iil_C_UnSubscribe($this->conn, $c_mbox); |
| | | $result = iil_C_DeleteFolder($this->conn, $c_mbox); |
| | | if ($result>=0) |
| | | $deleted = TRUE; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // clear mailboxlist cache |
| | |
| | | */ |
| | | function &get_cached_message($key, $uid, $struct=false) |
| | | { |
| | | if (!$this->caching_enabled) |
| | | return FALSE; |
| | | |
| | | $internal_key = '__single_msg'; |
| | | |
| | | if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) || |
| | | ($struct && empty($this->cache[$internal_key][$uid]->structure)))) |
| | | { |
| | |
| | | */ |
| | | function add_message_cache($key, $index, $headers, $struct=null) |
| | | { |
| | | if (!$this->caching_enabled || empty($key) || !is_object($headers) || empty($headers->uid)) |
| | | if (empty($key) || !is_object($headers) || empty($headers->uid)) |
| | | return; |
| | | |
| | | // add to internal (fast) cache |
| | | $this->cache['__single_msg'][$headers->uid] = $headers; |
| | | $this->cache['__single_msg'][$headers->uid]->structure = $struct; |
| | | |
| | | // no further caching |
| | | if (!$this->caching_enabled) |
| | | return; |
| | | |
| | | |
| | | // check for an existing record (probly headers are cached but structure not) |
| | | $sql_result = $this->db->query( |
| | | "SELECT message_id |
| | |
| | | */ |
| | | function decode_header($input, $remove_quotes=FALSE) |
| | | { |
| | | $str = $this->decode_mime_string((string)$input); |
| | | $str = rcube_imap::decode_mime_string((string)$input, $this->default_charset); |
| | | if ($str{0}=='"' && $remove_quotes) |
| | | $str = str_replace('"', '', $str); |
| | | |
| | |
| | | return rcube_charset_convert($body, $ctype_param['charset']); |
| | | |
| | | // defaults to what is specified in the class header |
| | | return rcube_charset_convert($body, 'ISO-8859-1'); |
| | | return rcube_charset_convert($body, $this->default_charset); |
| | | } |
| | | |
| | | |
| | |
| | | return $mbox_name; |
| | | } |
| | | |
| | | /** |
| | | * Validate the given input and save to local properties |
| | | * @access private |
| | | */ |
| | | function _set_sort_order($sort_field, $sort_order) |
| | | { |
| | | if ($sort_field != null) |
| | | $this->sort_field = asciiwords($sort_field); |
| | | if ($sort_order != null) |
| | | $this->sort_order = strtoupper($sort_order) == 'DESC' ? 'DESC' : 'ASC'; |
| | | } |
| | | |
| | | /** |
| | | * Sort mailboxes first by default folders and then in alphabethical order |
| | |
| | | if ($folder{0}=='.') |
| | | continue; |
| | | |
| | | if (($p = array_search(strtolower($folder), $this->default_folders_lc))!==FALSE) |
| | | if (($p = array_search(strtolower($folder), $this->default_folders_lc)) !== false && !$a_defaults[$p]) |
| | | $a_defaults[$p] = $folder; |
| | | else |
| | | $a_out[] = $folder; |
| | |
| | | if (!$mbox_name) |
| | | $mbox_name = $this->mailbox; |
| | | |
| | | return iil_C_ID2UID($this->conn, $mbox_name, $id); |
| | | $index = array_flip((array)$this->uid_id_map[$mbox_name]); |
| | | if (isset($index[$id])) |
| | | $uid = $index[$id]; |
| | | else |
| | | { |
| | | $uid = iil_C_ID2UID($this->conn, $mbox_name, $id); |
| | | $this->uid_id_map[$mbox_name][$uid] = $id; |
| | | } |
| | | |
| | | return $uid; |
| | | } |
| | | |
| | | |