| | |
| | | /** |
| | | * Interface class for accessing an IMAP server |
| | | * |
| | | * @package Mail |
| | | * @package Framework |
| | | * @subpackage Storage |
| | | * @author Thomas Bruederli <roundcube@gmail.com> |
| | | * @author Aleksander Machniak <alec@alec.pl> |
| | | * @version 2.0 |
| | | */ |
| | | class rcube_imap extends rcube_storage |
| | | { |
| | |
| | | |
| | | return array( |
| | | $this->search_string, |
| | | $this->search_set, |
| | | $this->search_charset, |
| | | $this->search_sort_field, |
| | | $this->search_sorted, |
| | | ); |
| | | $this->search_set, |
| | | $this->search_charset, |
| | | $this->search_sort_field, |
| | | $this->search_sorted, |
| | | ); |
| | | } |
| | | |
| | | |
| | |
| | | $a_msg_headers, $this->sort_field, $this->sort_order); |
| | | |
| | | // only return the requested part of the set |
| | | $a_msg_headers = array_slice(array_values($a_msg_headers), |
| | | $from, min($cnt-$to, $this->page_size)); |
| | | $slice_length = min($this->page_size, $cnt - ($to > $cnt ? $from : $to)); |
| | | $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length); |
| | | |
| | | if ($slice) { |
| | | $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice); |
| | |
| | | $criteria = 'UNDELETED '.$criteria; |
| | | } |
| | | |
| | | // unset CHARSET if criteria string is ASCII, this way |
| | | // SEARCH won't be re-sent after "unsupported charset" response |
| | | if ($charset && $charset != 'US-ASCII' && is_ascii($criteria)) { |
| | | $charset = 'US-ASCII'; |
| | | } |
| | | |
| | | if ($this->threading) { |
| | | $threads = $this->conn->thread($folder, $this->threading, $criteria, true, $charset); |
| | | |
| | |
| | | } |
| | | |
| | | $messages = $this->conn->search($folder, |
| | | ($charset ? "CHARSET $charset " : '') . $criteria, true); |
| | | ($charset && $charset != 'US-ASCII' ? "CHARSET $charset " : '') . $criteria, true); |
| | | |
| | | // Error, try with US-ASCII (some servers may support only US-ASCII) |
| | | if ($messages->is_error() && $charset && $charset != 'US-ASCII') { |
| | |
| | | |
| | | if ($o_part && $o_part->size) { |
| | | $body = $this->conn->handlePartBody($this->folder, $uid, true, |
| | | $part ? $part : 'TEXT', $o_part->encoding, $print, $fp); |
| | | $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text'); |
| | | } |
| | | |
| | | if ($fp || $print) { |
| | |
| | | |
| | | /** |
| | | * Sends the whole message source to stdout |
| | | * |
| | | * @param int $uid Message UID |
| | | * @param bool $formatted Enables line-ending formatting |
| | | */ |
| | | public function print_raw_body($uid) |
| | | public function print_raw_body($uid, $formatted = true) |
| | | { |
| | | if (!$this->check_connection()) { |
| | | return; |
| | | } |
| | | |
| | | $this->conn->handlePartBody($this->folder, $uid, true, NULL, NULL, true); |
| | | $this->conn->handlePartBody($this->folder, $uid, true, null, null, true, null, $formatted); |
| | | } |
| | | |
| | | |
| | |
| | | * @param string $message The message source string or filename |
| | | * @param string $headers Headers string if $message contains only the body |
| | | * @param boolean $is_file True if $message is a filename |
| | | * @param array $flags Message flags |
| | | * @param mixed $date Message internal date |
| | | * |
| | | * @return int|bool Appended message UID or True on success, False on error |
| | | */ |
| | | public function save_message($folder, &$message, $headers='', $is_file=false) |
| | | public function save_message($folder, &$message, $headers='', $is_file=false, $flags = array(), $date = null) |
| | | { |
| | | if (!strlen($folder)) { |
| | | $folder = $this->folder; |
| | | } |
| | | |
| | | if (!$this->check_connection()) { |
| | | return false; |
| | | } |
| | | |
| | | // make sure folder exists |
| | | if ($this->folder_exists($folder)) { |
| | | if ($is_file) { |
| | | $saved = $this->conn->appendFromFile($folder, $message, $headers); |
| | | } |
| | | else { |
| | | $saved = $this->conn->append($folder, $message); |
| | | } |
| | | if (!$this->folder_exists($folder)) { |
| | | return false; |
| | | } |
| | | |
| | | $date = $this->date_format($date); |
| | | |
| | | if ($is_file) { |
| | | $saved = $this->conn->appendFromFile($folder, $message, $headers, $flags, $date); |
| | | } |
| | | else { |
| | | $saved = $this->conn->append($folder, $message, $flags, $date); |
| | | } |
| | | |
| | | if ($saved) { |
| | |
| | | $cache_key = 'mailboxes.folder-info.' . $folder; |
| | | $cached = $this->get_cache($cache_key); |
| | | |
| | | if (is_array($cached)) |
| | | if (is_array($cached)) { |
| | | return $cached; |
| | | } |
| | | |
| | | $acl = $this->get_capability('ACL'); |
| | | $namespace = $this->get_namespace(); |
| | |
| | | $options['name'] = $folder; |
| | | $options['attributes'] = $this->folder_attributes($folder, true); |
| | | $options['namespace'] = $this->folder_namespace($folder); |
| | | $options['rights'] = $acl && !$options['is_root'] ? (array)$this->my_rights($folder) : array(); |
| | | $options['special'] = in_array($folder, $this->default_folders); |
| | | |
| | | // Set 'noselect' and 'norename' flags |
| | | // Set 'noselect' flag |
| | | if (is_array($options['attributes'])) { |
| | | foreach ($options['attributes'] as $attrib) { |
| | | $attrib = strtolower($attrib); |
| | |
| | | $options['noselect'] = true; |
| | | } |
| | | |
| | | // Get folder rights (MYRIGHTS) |
| | | if ($acl && ($rights = $this->my_rights($folder))) { |
| | | $options['rights'] = $rights; |
| | | } |
| | | |
| | | // Set 'norename' flag |
| | | if (!empty($options['rights'])) { |
| | | $options['norename'] = !in_array('x', $options['rights']) && !in_array('d', $options['rights']); |
| | | |
| | |
| | | protected function rsort($folder, $delimiter, &$list, &$out) |
| | | { |
| | | while (list($key, $name) = each($list)) { |
| | | if (strpos($name, $folder.$delimiter) === 0) { |
| | | // set the type of folder name variable (#1485527) |
| | | $out[] = (string) $name; |
| | | unset($list[$key]); |
| | | $this->rsort($name, $delimiter, $list, $out); |
| | | } |
| | | if (strpos($name, $folder.$delimiter) === 0) { |
| | | // set the type of folder name variable (#1485527) |
| | | $out[] = (string) $name; |
| | | unset($list[$key]); |
| | | $this->rsort($name, $delimiter, $list, $out); |
| | | } |
| | | } |
| | | reset($list); |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * Converts date string/object into IMAP date/time format |
| | | */ |
| | | protected function date_format($date) |
| | | { |
| | | if (empty($date)) { |
| | | return null; |
| | | } |
| | | |
| | | if (!is_object($date) || !is_a($date, 'DateTime')) { |
| | | try { |
| | | $timestamp = rcube_utils::strtotime($date); |
| | | $date = new DateTime("@".$timestamp); |
| | | } |
| | | catch (Exception $e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | return $date->format('d-M-Y H:i:s O'); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * This is our own debug handler for the IMAP connection |
| | | * @access public |
| | | */ |
| | |
| | | return $this->delete_folder($folder); |
| | | } |
| | | |
| | | function clear_mailbox($folder = null) |
| | | { |
| | | return $this->clear_folder($folder); |
| | | } |
| | | |
| | | public function mailbox_exists($folder, $subscription=false) |
| | | { |
| | | return $this->folder_exists($folder, $subscription); |