| | |
| | | */ |
| | | |
| | | |
| | | /** |
| | | /* |
| | | * Obtain classes from the Iloha IMAP library |
| | | */ |
| | | require_once('lib/imap.inc'); |
| | |
| | | * |
| | | * This is a wrapper that implements the Iloha IMAP Library (IIL) |
| | | * |
| | | * @package RoundCube Webmail |
| | | * @package Mail |
| | | * @author Thomas Bruederli <roundcube@gmail.com> |
| | | * @version 1.36 |
| | | * @link http://ilohamail.org |
| | |
| | | /** |
| | | * Object constructor |
| | | * |
| | | * @param object Database connection |
| | | * @param object DB Database connection |
| | | */ |
| | | function __construct($db_conn) |
| | | { |
| | |
| | | |
| | | /** |
| | | * Return the saved search set as hash array |
| | | * @return array Search set |
| | | */ |
| | | function get_search_set() |
| | | { |
| | |
| | | * Private method for mailbox listing |
| | | * |
| | | * @return array List of mailboxes/folders |
| | | * @see rcube_imap::list_mailboxes() |
| | | * @access private |
| | | * @see rcube_imap::list_mailboxes |
| | | */ |
| | | function _list_mailboxes($root='', $filter='*') |
| | | { |
| | |
| | | * @param string Mailbox/folder name |
| | | * @param string Mode for count [ALL|UNSEEN|RECENT] |
| | | * @param boolean Force reading from server and update cache |
| | | * @return number Number of messages |
| | | * @return int Number of messages |
| | | * @access public |
| | | */ |
| | | function messagecount($mbox_name='', $mode='ALL', $force=FALSE) |
| | |
| | | * Private method for getting nr of messages |
| | | * |
| | | * @access private |
| | | * @see rcube_imap::messagecount |
| | | * @see rcube_imap::messagecount() |
| | | */ |
| | | function _messagecount($mailbox='', $mode='ALL', $force=FALSE) |
| | | { |
| | |
| | | * convert mailbox name with root dir first |
| | | * |
| | | * @param string Mailbox/folder name |
| | | * @param number Current page to list |
| | | * @param int Current page to list |
| | | * @param string Header field to sort by |
| | | * @param string Sort order [ASC|DESC] |
| | | * @return array Indexed array with message header objects |
| | |
| | | * |
| | | * @param string Mailbox/folder name |
| | | * @param array List of message ids to list |
| | | * @param number Current page to list |
| | | * @param int Current page to list |
| | | * @param string Header field to sort by |
| | | * @param string Sort order [ASC|DESC] |
| | | * @return array Indexed array with message header objects |
| | |
| | | * Private method for listing a set of message headers |
| | | * |
| | | * @access private |
| | | * @see rcube_imap::list_header_set |
| | | * @see rcube_imap::list_header_set() |
| | | */ |
| | | function _list_header_set($mailbox, $msgs, $page=NULL, $sort_field=NULL, $sort_order=NULL) |
| | | { |
| | |
| | | /** |
| | | * Helper function to get first and last index of the requested set |
| | | * |
| | | * @param number message count |
| | | * @param int message count |
| | | * @param mixed page number to show, or string 'all' |
| | | * @return array array with two values: first index, last index |
| | | * @access private |
| | |
| | | * @param string Message index to fetch |
| | | * @param array Reference to message headers array |
| | | * @param array Array with cache index |
| | | * @return number Number of deleted messages |
| | | * @return int Number of deleted messages |
| | | * @access private |
| | | */ |
| | | function _fetch_headers($mailbox, $msgs, &$a_msg_headers, $cache_key) |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function sync_header_index($mailbox) |
| | | { |
| | | $cache_key = $mailbox.'.msg'; |
| | |
| | | |
| | | /** |
| | | * Refresh saved search set |
| | | * |
| | | * @return array Current search set |
| | | */ |
| | | function refresh_search() |
| | | { |
| | |
| | | * Fetch body structure from the IMAP server and build |
| | | * an object structure similar to the one generated by PEAR::Mail_mimeDecode |
| | | * |
| | | * @param Int Message UID to fetch |
| | | * @return object Standard object tree or False on failure |
| | | * @param int Message UID to fetch |
| | | * @return object stdClass Message part tree or False on failure |
| | | */ |
| | | function &get_structure($uid) |
| | | { |
| | |
| | | /** |
| | | * Return a flat array with references to all parts, indexed by part numbers |
| | | * |
| | | * @param object Message body structure |
| | | * @param object rcube_message_part Message body structure |
| | | * @return Array with part number -> object pairs |
| | | */ |
| | | function get_mime_numbers(&$structure) |
| | |
| | | /** |
| | | * Helper method for recursive calls |
| | | * |
| | | * @access |
| | | * @access private |
| | | */ |
| | | function _get_part_numbers(&$part, &$a_parts) |
| | | { |
| | |
| | | * |
| | | * @param int Message UID |
| | | * @param string Part number |
| | | * @param object Part object created by get_structure() |
| | | * @param object rcube_message_part Part object created by get_structure() |
| | | * @param mixed True to print part, ressource to write part contents in |
| | | * @return Message/part body if not printed |
| | | * @return string Message/part body if not printed |
| | | */ |
| | | function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL) |
| | | { |
| | |
| | | * Fetch message body of a specific message from the server |
| | | * |
| | | * @param int Message UID |
| | | * @return Message/part body |
| | | * @see ::get_message_part() |
| | | * @return string Message/part body |
| | | * @see rcube_imap::get_message_part() |
| | | */ |
| | | function &get_body($uid, $part=1) |
| | | { |
| | |
| | | * Returns the whole message source as string |
| | | * |
| | | * @param int Message UID |
| | | * @return Message source string |
| | | * @return string Message source string |
| | | */ |
| | | function &get_raw_body($uid) |
| | | { |
| | |
| | | * |
| | | * @param mixed Message UIDs as array or as comma-separated string |
| | | * @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT |
| | | * @return True on success, False on failure |
| | | * @return boolean True on success, False on failure |
| | | */ |
| | | function set_flag($uids, $flag) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | // append a mail message (source) to a specific mailbox |
| | | /** |
| | | * Append a mail message (source) to a specific mailbox |
| | | * |
| | | * @param string Target mailbox |
| | | * @param string Message source |
| | | * @return boolean True on success, False on error |
| | | */ |
| | | function save_message($mbox_name, &$message) |
| | | { |
| | | $mbox_name = stripslashes($mbox_name); |
| | |
| | | } |
| | | |
| | | |
| | | // move a message from one mailbox to another |
| | | /** |
| | | * Move a message from one mailbox to another |
| | | * |
| | | * @param string List of UIDs to move, separated by comma |
| | | * @param string Target mailbox |
| | | * @param string Source mailbox |
| | | * @return boolean True on success, False on error |
| | | */ |
| | | function move_message($uids, $to_mbox, $from_mbox='') |
| | | { |
| | | $to_mbox = stripslashes($to_mbox); |
| | |
| | | } |
| | | |
| | | |
| | | // mark messages as deleted and expunge mailbox |
| | | /** |
| | | * Mark messages as deleted and expunge mailbox |
| | | * |
| | | * @param string List of UIDs to move, separated by comma |
| | | * @param string Source mailbox |
| | | * @return boolean True on success, False on error |
| | | */ |
| | | function delete_message($uids, $mbox_name='') |
| | | { |
| | | $mbox_name = stripslashes($mbox_name); |
| | |
| | | } |
| | | |
| | | |
| | | // clear all messages in a specific mailbox |
| | | /** |
| | | * Clear all messages in a specific mailbox |
| | | * |
| | | * @param string Mailbox name |
| | | * @return int Above 0 on success |
| | | */ |
| | | function clear_mailbox($mbox_name=NULL) |
| | | { |
| | | $mbox_name = stripslashes($mbox_name); |
| | |
| | | } |
| | | |
| | | |
| | | // send IMAP expunge command and clear cache |
| | | /** |
| | | * Send IMAP expunge command and clear cache |
| | | * |
| | | * @param string Mailbox name |
| | | * @param boolean False if cache should not be cleared |
| | | * @return boolean True on success |
| | | */ |
| | | function expunge($mbox_name='', $clear_cache=TRUE) |
| | | { |
| | | $mbox_name = stripslashes($mbox_name); |
| | |
| | | } |
| | | |
| | | |
| | | // send IMAP expunge command and clear cache |
| | | /** |
| | | * Send IMAP expunge command and clear cache |
| | | * |
| | | * @see rcube_imap::expunge() |
| | | * @access private |
| | | */ |
| | | function _expunge($mailbox, $clear_cache=TRUE) |
| | | { |
| | | $result = iil_C_Expunge($this->conn, $mailbox); |
| | |
| | | * Get a list of all folders available on the IMAP server |
| | | * |
| | | * @param string IMAP root dir |
| | | * @return array Inbdexed array with folder names |
| | | * @return array Indexed array with folder names |
| | | */ |
| | | function list_unsubscribed($root='') |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * Get quota |
| | | * Get mailbox quota information |
| | | * added by Nuny |
| | | * |
| | | * @return mixed Quota info or False if not supported |
| | | */ |
| | | function get_quota() |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * subscribe to a specific mailbox(es) |
| | | * Subscribe to a specific mailbox(es) |
| | | * |
| | | * @param string Mailbox name(s) |
| | | * @return boolean True on success |
| | | */ |
| | | function subscribe($mbox_name, $mode='subscribe') |
| | | function subscribe($mbox_name) |
| | | { |
| | | if (is_array($mbox_name)) |
| | | $a_mboxes = $mbox_name; |
| | |
| | | |
| | | |
| | | /** |
| | | * unsubscribe mailboxes |
| | | * Unsubscribe mailboxes |
| | | * |
| | | * @param string Mailbox name(s) |
| | | * @return boolean True on success |
| | | */ |
| | | function unsubscribe($mbox_name) |
| | | { |
| | |
| | | * |
| | | * @param string Mailbox to rename (as utf-7 string) |
| | | * @param string New mailbox name (as utf-7 string) |
| | | * @param string Name of the renames mailbox, false on error |
| | | * @return string Name of the renames mailbox, False on error |
| | | */ |
| | | function rename_mailbox($mbox_name, $new_name) |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * remove mailboxes from server |
| | | * Remove mailboxes from server |
| | | * |
| | | * @param string Mailbox name |
| | | * @return boolean True on success |
| | | */ |
| | | function delete_mailbox($mbox_name) |
| | | { |
| | |
| | | * internal caching methods |
| | | * --------------------------------*/ |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function set_caching($set) |
| | | { |
| | | if ($set && is_object($this->db)) |
| | |
| | | $this->caching_enabled = FALSE; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function get_cache($key) |
| | | { |
| | | // read cache |
| | |
| | | return $this->cache[$key]; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function update_cache($key, $data) |
| | | { |
| | | $this->cache[$key] = $data; |
| | |
| | | $this->cache_changes[$key] = TRUE; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function write_cache() |
| | | { |
| | | if ($this->caching_enabled && $this->cache_changed) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function clear_cache($key=NULL) |
| | | { |
| | | if ($key===NULL) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _read_cache_record($key) |
| | | { |
| | | $cache_data = FALSE; |
| | |
| | | return $cache_data; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _write_cache_record($key, $data) |
| | | { |
| | | if (!$this->db) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _clear_cache_record($key) |
| | | { |
| | | $this->db->query( |
| | |
| | | * --------------------------------*/ |
| | | |
| | | |
| | | // checks if the cache is up-to-date |
| | | // return: -3 = off, -2 = incomplete, -1 = dirty |
| | | /** |
| | | * Checks if the cache is up-to-date |
| | | * |
| | | * @param string Mailbox name |
| | | * @param string Internal cache key |
| | | * @return int -3 = off, -2 = incomplete, -1 = dirty |
| | | */ |
| | | function check_cache_status($mailbox, $cache_key) |
| | | { |
| | | if (!$this->caching_enabled) |
| | |
| | | return -2; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function get_message_cache($key, $from, $to, $sort_field, $sort_order) |
| | | { |
| | | $cache_key = "$key:$from:$to:$sort_field:$sort_order"; |
| | |
| | | return $this->cache[$cache_key]; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function &get_cached_message($key, $uid, $struct=false) |
| | | { |
| | | if (!$this->caching_enabled) |
| | |
| | | return $this->cache[$internal_key][$uid]; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function get_message_cache_index($key, $force=FALSE, $sort_col='idx', $sort_order='ASC') |
| | | { |
| | | static $sa_message_index = array(); |
| | |
| | | return $sa_message_index[$key]; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function add_message_cache($key, $index, $headers, $struct=null) |
| | | { |
| | | if (!$this->caching_enabled || empty($key) || !is_object($headers) || empty($headers->uid)) |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function remove_message_cache($key, $index) |
| | | { |
| | | $this->db->query( |
| | |
| | | $index); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function clear_message_cache($key, $start_index=1) |
| | | { |
| | | $this->db->query( |
| | |
| | | * encoding/decoding methods |
| | | * --------------------------------*/ |
| | | |
| | | |
| | | /** |
| | | * Split an address list into a structured array list |
| | | * |
| | | * @param string Input string |
| | | * @param int List only this number of addresses |
| | | * @param boolean Decode address strings |
| | | * @return array Indexed list of addresses |
| | | */ |
| | | function decode_address_list($input, $max=null, $decode=true) |
| | | { |
| | | $a = $this->_parse_address_list($input, $decode); |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Decode a message header value |
| | | * |
| | | * @param string Header value |
| | | * @param boolean Remove quotes if necessary |
| | | * @return string Decoded string |
| | | */ |
| | | function decode_header($input, $remove_quotes=FALSE) |
| | | { |
| | | $str = $this->decode_mime_string((string)$input); |
| | |
| | | /** |
| | | * Decode a mime-encoded string to internal charset |
| | | * |
| | | * @access static |
| | | * @param string Header value |
| | | * @param string Fallback charset if none specified |
| | | * @return string Decoded string |
| | | * @static |
| | | */ |
| | | function decode_mime_string($input, $fallback=null) |
| | | { |
| | |
| | | /** |
| | | * Decode a part of a mime-encoded string |
| | | * |
| | | * @access static |
| | | * @access private |
| | | */ |
| | | function _decode_mime_string_part($str) |
| | | { |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Decode a mime part |
| | | * |
| | | * @param string Input string |
| | | * @param string Part encoding |
| | | * @return string Decoded string |
| | | * @access private |
| | | */ |
| | | function mime_decode($input, $encoding='7bit') |
| | | { |
| | | switch (strtolower($encoding)) |
| | |
| | | } |
| | | |
| | | |
| | | function mime_encode($input, $encoding='7bit') |
| | | { |
| | | switch ($encoding) |
| | | { |
| | | case 'quoted-printable': |
| | | return quoted_printable_encode($input); |
| | | break; |
| | | |
| | | case 'base64': |
| | | return base64_encode($input); |
| | | break; |
| | | |
| | | default: |
| | | return $input; |
| | | } |
| | | } |
| | | |
| | | |
| | | // convert body chars according to the ctype_parameters |
| | | /** |
| | | * Convert body charset to UTF-8 according to the ctype_parameters |
| | | * |
| | | * @param string Part body to decode |
| | | * @param string Charset to convert from |
| | | * @return string Content converted to internal charset |
| | | */ |
| | | function charset_decode($body, $ctype_param) |
| | | { |
| | | if (is_array($ctype_param) && !empty($ctype_param['charset'])) |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Translate UID to message ID |
| | | * |
| | | * @param int Message UID |
| | | * @param string Mailbox name |
| | | * @return int Message ID |
| | | */ |
| | | function get_id($uid, $mbox_name=NULL) |
| | | { |
| | | $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; |
| | | return $this->_uid2id($uid, $mailbox); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Translate message number to UID |
| | | * |
| | | * @param int Message ID |
| | | * @param string Mailbox name |
| | | * @return int Message UID |
| | | */ |
| | | function get_uid($id,$mbox_name=NULL) |
| | | { |
| | | $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; |
| | | return $this->_id2uid($id, $mailbox); |
| | | } |
| | | |
| | | |
| | | |
| | | /* -------------------------------- |
| | |
| | | * --------------------------------*/ |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _mod_mailbox($mbox_name, $mode='in') |
| | | { |
| | | if ((!empty($this->root_ns) && $this->root_ns == $mbox_name) || $mbox_name == 'INBOX') |
| | |
| | | } |
| | | |
| | | |
| | | // sort mailboxes first by default folders and then in alphabethical order |
| | | /** |
| | | * Sort mailboxes first by default folders and then in alphabethical order |
| | | * @access private |
| | | */ |
| | | function _sort_mailbox_list($a_folders) |
| | | { |
| | | $a_out = $a_defaults = array(); |
| | |
| | | return array_merge($a_defaults, $a_out); |
| | | } |
| | | |
| | | function get_id($uid, $mbox_name=NULL) |
| | | { |
| | | $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; |
| | | return $this->_uid2id($uid, $mailbox); |
| | | } |
| | | |
| | | function get_uid($id,$mbox_name=NULL) |
| | | { |
| | | $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; |
| | | return $this->_id2uid($id, $mailbox); |
| | | } |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _uid2id($uid, $mbox_name=NULL) |
| | | { |
| | | if (!$mbox_name) |
| | |
| | | return $this->uid_id_map[$mbox_name][$uid]; |
| | | } |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _id2uid($id, $mbox_name=NULL) |
| | | { |
| | | if (!$mbox_name) |
| | |
| | | } |
| | | |
| | | |
| | | // parse string or array of server capabilities and put them in internal array |
| | | /** |
| | | * Parse string or array of server capabilities and put them in internal array |
| | | * @access private |
| | | */ |
| | | function _parse_capability($caps) |
| | | { |
| | | if (!is_array($caps)) |
| | |
| | | } |
| | | |
| | | |
| | | // subscribe/unsubscribe a list of mailboxes and update local cache |
| | | /** |
| | | * Subscribe/unsubscribe a list of mailboxes and update local cache |
| | | * @access private |
| | | */ |
| | | function _change_subscription($a_mboxes, $mode) |
| | | { |
| | | $updated = FALSE; |
| | |
| | | } |
| | | |
| | | |
| | | // increde/decrese messagecount for a specific mailbox |
| | | /** |
| | | * Increde/decrese messagecount for a specific mailbox |
| | | * @access private |
| | | */ |
| | | function _set_messagecount($mbox_name, $mode, $increment) |
| | | { |
| | | $a_mailbox_cache = FALSE; |
| | |
| | | } |
| | | |
| | | |
| | | // remove messagecount of a specific mailbox from cache |
| | | /** |
| | | * Remove messagecount of a specific mailbox from cache |
| | | * @access private |
| | | */ |
| | | function _clear_messagecount($mbox_name='') |
| | | { |
| | | $a_mailbox_cache = FALSE; |
| | |
| | | } |
| | | |
| | | |
| | | // split RFC822 header string into an associative array |
| | | /** |
| | | * Split RFC822 header string into an associative array |
| | | * @access private |
| | | */ |
| | | function _parse_headers($headers) |
| | | { |
| | | $a_headers = array(); |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _parse_address_list($str, $decode=true) |
| | | { |
| | | // remove any newlines and carriage returns before |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @access private |
| | | */ |
| | | function _explode_quoted_string($delimiter, $string) |
| | | { |
| | | $result = array(); |
| | |
| | | $result[] = substr($string, $p); |
| | | return $result; |
| | | } |
| | | } |
| | | |
| | | } // end class rcube_imap |
| | | |
| | | |
| | | /** |
| | | * Class representing a message part |
| | | * |
| | | * @package Mail |
| | | */ |
| | | class rcube_message_part |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * rcube_header_sorter |
| | | * |
| | | * Class for sorting an array of iilBasicHeader objects in a predetermined order. |
| | | * |
| | | * @package Mail |
| | | * @author Eric Stadtherr |
| | | */ |
| | | class rcube_header_sorter |
| | |
| | | var $sequence_numbers = array(); |
| | | |
| | | /** |
| | | * set the predetermined sort order. |
| | | * Set the predetermined sort order. |
| | | * |
| | | * @param array $seqnums numerically indexed array of IMAP message sequence numbers |
| | | * @param array Numerically indexed array of IMAP message sequence numbers |
| | | */ |
| | | function set_sequence_numbers($seqnums) |
| | | { |
| | |
| | | } |
| | | |
| | | /** |
| | | * sort the array of header objects |
| | | * Sort the array of header objects |
| | | * |
| | | * @param array $headers array of iilBasicHeader objects indexed by UID |
| | | * @param array Array of iilBasicHeader objects indexed by UID |
| | | */ |
| | | function sort_headers(&$headers) |
| | | { |
| | |
| | | } |
| | | |
| | | /** |
| | | * get the position of a message sequence number in my sequence_numbers array |
| | | * Get the position of a message sequence number in my sequence_numbers array |
| | | * |
| | | * @param integer $seqnum message sequence number contained in sequence_numbers |
| | | * @param int Message sequence number contained in sequence_numbers |
| | | * @return int Position, -1 if not found |
| | | */ |
| | | function position_of($seqnum) |
| | | { |
| | |
| | | /** |
| | | * Add quoted-printable encoding to a given string |
| | | * |
| | | * @param string $input string to encode |
| | | * @param int $line_max add new line after this number of characters |
| | | * @param boolena $space_conf true if spaces should be converted into =20 |
| | | * @return encoded string |
| | | * @param string String to encode |
| | | * @param int Add new line after this number of characters |
| | | * @param boolean True if spaces should be converted into =20 |
| | | * @return string Encoded string |
| | | */ |
| | | function quoted_printable_encode($input, $line_max=76, $space_conv=false) |
| | | { |