| | |
| | | */ |
| | | protected $icache = array(); |
| | | |
| | | protected $plugins; |
| | | protected $list_page = 1; |
| | | protected $delimiter; |
| | | protected $namespace; |
| | |
| | | public function __construct() |
| | | { |
| | | $this->conn = new rcube_imap_generic(); |
| | | $this->plugins = rcube::get_instance()->plugins; |
| | | |
| | | // Set namespace and delimiter from session, |
| | | // so some methods would work before connection |
| | |
| | | |
| | | $attempt = 0; |
| | | do { |
| | | $data = rcube::get_instance()->plugins->exec_hook('storage_connect', |
| | | $data = $this->plugins->exec_hook('storage_connect', |
| | | array_merge($this->options, array('host' => $host, 'user' => $user, |
| | | 'attempt' => ++$attempt))); |
| | | |
| | |
| | | $this->connect_done = true; |
| | | |
| | | if ($this->conn->connected()) { |
| | | // check for session identifier |
| | | $session = null; |
| | | if (preg_match('/\s+SESSIONID=([^=\s]+)/', $this->conn->result, $m)) { |
| | | $session = $m[1]; |
| | | } |
| | | |
| | | // get namespace and delimiter |
| | | $this->set_env(); |
| | | |
| | | // trigger post-connect hook |
| | | $this->plugins->exec_hook('storage_connected', array( |
| | | 'host' => $host, 'user' => $user, 'session' => $session |
| | | )); |
| | | |
| | | return true; |
| | | } |
| | | // write error log |
| | |
| | | $page = $page ? $page : $this->list_page; |
| | | |
| | | // use saved message set |
| | | if ($this->search_string && $folder == $this->folder) { |
| | | if ($this->search_string) { |
| | | return $this->list_search_messages($folder, $page, $slice); |
| | | } |
| | | |
| | |
| | | public function index_direct($folder, $sort_field = null, $sort_order = null, $search = null) |
| | | { |
| | | if (!empty($search)) { |
| | | $search = $this->search_set->get_compressed(); |
| | | $search = $search->get_compressed(); |
| | | } |
| | | |
| | | // use message index sort as default sorting |
| | |
| | | $folder = $this->folder; |
| | | } |
| | | |
| | | $plugin = rcube::get_instance()->plugins->exec_hook('imap_search_before', array( |
| | | $plugin = $this->plugins->exec_hook('imap_search_before', array( |
| | | 'folder' => $folder, |
| | | 'search' => $search, |
| | | 'charset' => $charset, |
| | |
| | | for ($i=1; $i<count($part); $i++) { |
| | | if (!is_array($part[$i])) { |
| | | $struct->ctype_secondary = strtolower($part[$i]); |
| | | |
| | | // read content type parameters |
| | | if (is_array($part[$i+1])) { |
| | | $struct->ctype_parameters = array(); |
| | | for ($j=0; $j<count($part[$i+1]); $j+=2) { |
| | | $param = strtolower($part[$i+1][$j]); |
| | | $struct->ctype_parameters[$param] = $part[$i+1][$j+1]; |
| | | } |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | |
| | | /** |
| | | * Returns the whole message source as string (or saves to a file) |
| | | * |
| | | * @param int $uid Message UID |
| | | * @param resource $fp File pointer to save the message |
| | | * @param int $uid Message UID |
| | | * @param resource $fp File pointer to save the message |
| | | * @param string $part Optional message part ID |
| | | * |
| | | * @return string Message source string |
| | | */ |
| | | public function get_raw_body($uid, $fp=null) |
| | | public function get_raw_body($uid, $fp=null, $part = null) |
| | | { |
| | | if (!$this->check_connection()) { |
| | | return null; |
| | | } |
| | | |
| | | return $this->conn->handlePartBody($this->folder, $uid, |
| | | true, null, null, false, $fp); |
| | | true, $part, null, false, $fp); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns the message headers as string |
| | | * |
| | | * @param int $uid Message UID |
| | | * @param int $uid Message UID |
| | | * @param string $part Optional message part ID |
| | | * |
| | | * @return string Message headers string |
| | | */ |
| | | public function get_raw_headers($uid) |
| | | public function get_raw_headers($uid, $part = null) |
| | | { |
| | | if (!$this->check_connection()) { |
| | | return null; |
| | | } |
| | | |
| | | return $this->conn->fetchPartHeader($this->folder, $uid, true); |
| | | return $this->conn->fetchPartHeader($this->folder, $uid, true, $part); |
| | | } |
| | | |
| | | |
| | |
| | | // increase messagecount of the target folder |
| | | $this->set_messagecount($folder, 'ALL', 1); |
| | | |
| | | rcube::get_instance()->plugins->exec_hook('message_saved', array( |
| | | $this->plugins->exec_hook('message_saved', array( |
| | | 'folder' => $folder, |
| | | 'message' => $message, |
| | | 'headers' => $headers, |
| | |
| | | } |
| | | |
| | | // Give plugins a chance to provide a list of folders |
| | | $data = rcube::get_instance()->plugins->exec_hook('storage_folders', |
| | | $data = $this->plugins->exec_hook('storage_folders', |
| | | array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB')); |
| | | |
| | | if (isset($data['folders'])) { |
| | |
| | | } |
| | | |
| | | // Give plugins a chance to provide a list of folders |
| | | $data = rcube::get_instance()->plugins->exec_hook('storage_folders', |
| | | $data = $this->plugins->exec_hook('storage_folders', |
| | | array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST')); |
| | | |
| | | if (isset($data['folders'])) { |
| | |
| | | |
| | | $result = $this->conn->createFolder($folder, $type ? array("\\" . ucfirst($type)) : null); |
| | | |
| | | // it's quite often situation that we're trying to create and subscribe |
| | | // a folder that already exist, but is unsubscribed |
| | | if (!$result) { |
| | | if ($this->get_response_code() == rcube_storage::ALREADYEXISTS |
| | | || preg_match('/already exists/i', $this->get_error_str()) |
| | | ) { |
| | | $result = true; |
| | | } |
| | | } |
| | | |
| | | // try to subscribe it |
| | | if ($result) { |
| | | // clear cache |
| | |
| | | // request \Subscribed flag in LIST response as performance improvement for folder_exists() |
| | | $folders = $this->conn->listMailboxes('', '*', array('SUBSCRIBED'), array('SPECIAL-USE')); |
| | | |
| | | foreach ($folders as $folder) { |
| | | if ($flags = $this->conn->data['LIST'][$folder]) { |
| | | foreach ($types as $type) { |
| | | if (in_array($type, $flags)) { |
| | | $type = strtolower(substr($type, 1)); |
| | | $special[$type] = $folder; |
| | | if (!empty($folders)) { |
| | | foreach ($folders as $folder) { |
| | | if ($flags = $this->conn->data['LIST'][$folder]) { |
| | | foreach ($types as $type) { |
| | | if (in_array($type, $flags)) { |
| | | $type = strtolower(substr($type, 1)); |
| | | $special[$type] = $folder; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | // @TODO: Honor MAXSIZE and DEPTH options |
| | | foreach ($queries as $attrib => $entry) { |
| | | if ($result = $this->conn->getAnnotation($folder, $entry, $attrib)) { |
| | | $res = array_merge_recursive($res, $result); |
| | | $result = $this->conn->getAnnotation($folder, $entry, $attrib); |
| | | |
| | | // an error, invalidate any previous getAnnotation() results |
| | | if (!is_array($result)) { |
| | | return null; |
| | | } |
| | | else { |
| | | foreach ($result as $fldr => $data) { |
| | | $res[$fldr] = array_merge((array) $res[$fldr], $data); |
| | | } |
| | | } |
| | | } |
| | | } |