From c21f95f626e66b052309103e74d445300f68bdab Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Fri, 31 Jul 2015 05:20:50 -0400 Subject: [PATCH] Fix bug where new messages weren't added to the list in search mode --- program/lib/Roundcube/rcube_imap.php | 325 ++++++++++++++++++++++------------------------------- 1 files changed, 134 insertions(+), 191 deletions(-) diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index e29bfc4..9a4843d 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -1,6 +1,6 @@ <?php -/* +/** +-----------------------------------------------------------------------+ | This file is part of the Roundcube Webmail client | | Copyright (C) 2005-2012, The Roundcube Dev Team | @@ -56,6 +56,7 @@ */ protected $icache = array(); + protected $plugins; protected $list_page = 1; protected $delimiter; protected $namespace; @@ -82,6 +83,7 @@ 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 @@ -92,7 +94,6 @@ $this->delimiter = $_SESSION['imap_delimiter']; } } - /** * Magic getter for backward compat. @@ -106,17 +107,16 @@ } } - /** * Connect to an IMAP server * - * @param string $host Host to connect - * @param string $user Username for IMAP account - * @param string $pass Password for IMAP account - * @param integer $port Port to connect to - * @param string $use_ssl SSL schema (either ssl or tls) or null if plain connection + * @param string $host Host to connect + * @param string $user Username for IMAP account + * @param string $pass Password for IMAP account + * @param integer $port Port to connect to + * @param string $use_ssl SSL schema (either ssl or tls) or null if plain connection * - * @return boolean TRUE on success, FALSE on failure + * @return boolean True on success, False on failure */ public function connect($host, $user, $pass, $port=143, $use_ssl=null) { @@ -147,7 +147,7 @@ $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))); @@ -170,8 +170,20 @@ $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 @@ -189,7 +201,6 @@ return false; } - /** * Close IMAP connection. * Usually done on script shutdown @@ -201,7 +212,6 @@ $this->mcache->close(); } } - /** * Check connection state, connect if not connected. @@ -224,7 +234,6 @@ return $this->is_connected(); } - /** * Checks IMAP connection. * @@ -234,7 +243,6 @@ { return $this->conn->connected(); } - /** * Returns code of last error @@ -246,7 +254,6 @@ return $this->conn->errornum; } - /** * Returns text of last error * @@ -256,7 +263,6 @@ { return $this->conn->error; } - /** * Returns code of last command response @@ -287,7 +293,6 @@ } } - /** * Activate/deactivate debug mode * @@ -299,23 +304,21 @@ $this->conn->setDebug($dbg, array($this, 'debug_handler')); } - /** * Set internal folder reference. * All operations will be perfomed on this folder. * - * @param string $folder Folder name + * @param string $folder Folder name */ public function set_folder($folder) { $this->folder = $folder; } - /** * Save a search result for future message listing methods * - * @param array $set Search set, result from rcube_imap::get_search_set(): + * @param array $set Search set, result from rcube_imap::get_search_set(): * 0 - searching criteria, string * 1 - search result, rcube_result_index|rcube_result_thread * 2 - searching character set, string @@ -338,7 +341,6 @@ } } - /** * Return the saved search set as hash array * @@ -358,7 +360,6 @@ $this->search_sorted, ); } - /** * Returns the IMAP server's capability. @@ -383,14 +384,13 @@ return $_SESSION[$sess_key]; } - /** * Checks the PERMANENTFLAGS capability of the current folder * and returns true if the given flag is supported by the IMAP server * - * @param string $flag Permanentflag name + * @param string $flag Permanentflag name * - * @return boolean True if this flag is supported + * @return boolean True if this flag is supported */ public function check_permflag($flag) { @@ -401,11 +401,10 @@ return $imap_flag && !empty($perm_flags) && in_array_nocase($imap_flag, $perm_flags); } - /** * Returns PERMANENTFLAGS of the specified folder * - * @param string $folder Folder name + * @param string $folder Folder name * * @return array Flags */ @@ -433,25 +432,22 @@ return $permflags; } - /** * Returns the delimiter that is used by the IMAP server for folder separation * - * @return string Delimiter string - * @access public + * @return string Delimiter string */ public function get_hierarchy_delimiter() { return $this->delimiter; } - /** * Get namespace * * @param string $name Namespace array index: personal, other, shared, prefix * - * @return array Namespace data + * @return array Namespace data */ public function get_namespace($name = null) { @@ -464,7 +460,6 @@ unset($ns['prefix']); return $ns; } - /** * Sets delimiter and namespaces @@ -546,7 +541,6 @@ $_SESSION['imap_delimiter'] = $this->delimiter; } - /** * Get message count for a specific folder * @@ -556,7 +550,7 @@ * @param boolean $status Enables storing folder status info (max UID/count), * required for folder_status() * - * @return int Number of messages + * @return int Number of messages */ public function count($folder='', $mode='ALL', $force=false, $status=true) { @@ -567,29 +561,31 @@ return $this->countmessages($folder, $mode, $force, $status); } - /** - * protected method for getting nr of messages + * Protected method for getting number of messages * - * @param string $folder Folder name - * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] - * @param boolean $force Force reading from server and update cache - * @param boolean $status Enables storing folder status info (max UID/count), - * required for folder_status() + * @param string $folder Folder name + * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS] + * @param boolean $force Force reading from server and update cache + * @param boolean $status Enables storing folder status info (max UID/count), + * required for folder_status() + * @param boolean $no_search Ignore current search result * * @return int Number of messages * @see rcube_imap::count() */ - protected function countmessages($folder, $mode='ALL', $force=false, $status=true) + protected function countmessages($folder, $mode = 'ALL', $force = false, $status = true, $no_search = false) { $mode = strtoupper($mode); - // count search set, assume search set is always up-to-date (don't check $force flag) - if ($this->search_string && $folder == $this->folder && ($mode == 'ALL' || $mode == 'THREADS')) { + // Count search set, assume search set is always up-to-date (don't check $force flag) + // @TODO: this could be handled in more reliable way, e.g. a separate method + // maybe in rcube_imap_search + if (!$no_search && $this->search_string && $folder == $this->folder) { if ($mode == 'ALL') { return $this->search_set->count_messages(); } - else { + else if ($mode == 'THREADS') { return $this->search_set->count(); } } @@ -682,7 +678,6 @@ return (int)$count; } - /** * Public method for listing message flags * @@ -717,7 +712,6 @@ return $result; } - /** * Public method for listing headers * @@ -727,7 +721,7 @@ * @param string $sort_order Sort order [ASC|DESC] * @param int $slice Number of slice items to extract from result array * - * @return array Indexed array with message header objects + * @return array Indexed array with message header objects */ public function list_messages($folder='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0) { @@ -738,7 +732,6 @@ return $this->_list_messages($folder, $page, $sort_field, $sort_order, $slice); } - /** * protected method for listing message headers * @@ -748,8 +741,8 @@ * @param string $sort_order Sort order [ASC|DESC] * @param int $slice Number of slice items to extract from result array * - * @return array Indexed array with message header objects - * @see rcube_imap::list_messages + * @return array Indexed array with message header objects + * @see rcube_imap::list_messages */ protected function _list_messages($folder='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0) { @@ -761,7 +754,7 @@ $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); } @@ -792,16 +785,15 @@ return array_values($a_msg_headers); } - /** * protected method for listing message headers using threads * - * @param string $folder Folder name - * @param int $page Current page to list - * @param int $slice Number of slice items to extract from result array + * @param string $folder Folder name + * @param int $page Current page to list + * @param int $slice Number of slice items to extract from result array * - * @return array Indexed array with message header objects - * @see rcube_imap::list_messages + * @return array Indexed array with message header objects + * @see rcube_imap::list_messages */ protected function list_thread_messages($folder, $page, $slice=0) { @@ -819,7 +811,7 @@ /** * Method for fetching threads data * - * @param string $folder Folder name + * @param string $folder Folder name * * @return rcube_imap_thread Thread data object */ @@ -843,11 +835,10 @@ return $this->icache['threads'] = $result; } - /** * Method for direct fetching of threads data * - * @param string $folder Folder name + * @param string $folder Folder name * * @return rcube_imap_thread Thread data object */ @@ -862,7 +853,6 @@ $this->options['skip_deleted'] ? 'UNDELETED' : '', true); } - /** * protected method for fetching threaded messages headers * @@ -871,7 +861,7 @@ * @param int $page List page number * @param int $slice Number of threads to slice * - * @return array Messages headers + * @return array Messages headers */ protected function fetch_thread_headers($folder, $threads, $page, $slice=0) { @@ -901,13 +891,12 @@ return array_values($a_msg_headers); } - /** * protected method for setting threaded messages flags: * depth, has_children and unread_children * - * @param array $headers Reference to headers array indexed by message UID - * @param rcube_result_thread $threads Threads data object + * @param array $headers Reference to headers array indexed by message UID + * @param rcube_result_thread $threads Threads data object * * @return array Message headers array indexed by message UID */ @@ -933,7 +922,6 @@ } } - /** * protected method for listing a set of message headers (search results) * @@ -941,7 +929,7 @@ * @param int $page Current page to list * @param int $slice Number of slice items to extract from result array * - * @return array Indexed array with message header objects + * @return array Indexed array with message header objects */ protected function list_search_messages($folder, $page, $slice=0) { @@ -1126,7 +1114,6 @@ } } - /** * protected method for listing a set of threaded message headers (search results) * @@ -1134,7 +1121,7 @@ * @param int $page Current page to list * @param int $slice Number of slice items to extract from result array * - * @return array Indexed array with message header objects + * @return array Indexed array with message header objects * @see rcube_imap::list_search_messages() */ protected function list_search_thread_messages($folder, $page, $slice=0) @@ -1149,7 +1136,6 @@ return $this->fetch_thread_headers($folder, clone $this->search_set, $page, $slice); } - /** * Fetches messages headers (by UID) @@ -1198,7 +1184,6 @@ return $a_msg_headers; } - /** * Returns current status of a folder (compared to the last time use) * @@ -1218,7 +1203,7 @@ $old = $this->get_folder_stats($folder); // refresh message count -> will update - $this->countmessages($folder, 'ALL', true); + $this->countmessages($folder, 'ALL', true, true, true); $result = 0; @@ -1246,7 +1231,6 @@ return $result; } - /** * Stores folder statistic data in session * @TODO: move to separate DB table (cache?) @@ -1259,7 +1243,6 @@ { $_SESSION['folders'][$folder][$name] = $data; } - /** * Gets folder statistic data @@ -1276,7 +1259,6 @@ return array(); } - /** * Return sorted list of message UIDs @@ -1355,7 +1337,6 @@ return $this->index_direct($folder, $this->sort_field, $this->sort_order); } - /** * Return sorted list of message UIDs ignoring current search settings. * Doesn't uses cache by default. @@ -1370,7 +1351,7 @@ 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 @@ -1423,7 +1404,6 @@ return $index; } - /** * Return index of threaded message UIDs * @@ -1454,7 +1434,6 @@ return $threads; } - /** * Sort threaded result, using THREAD=REFS method if available. * If not, use any method and re-sort the result in THREAD=REFS way. @@ -1484,7 +1463,6 @@ } } - /** * Invoke search request to IMAP server * @@ -1506,7 +1484,7 @@ $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, @@ -1560,7 +1538,6 @@ return $results; } - /** * Direct (real and simple) SEARCH request (without result sorting and caching). * @@ -1594,7 +1571,6 @@ return $index; } - /** * protected search method @@ -1672,7 +1648,6 @@ return $messages; } - /** * Converts charset of search criteria string * @@ -1712,7 +1687,6 @@ return $res; } - /** * Refresh saved search set * @@ -1744,7 +1718,6 @@ } } } - /** * Return message headers object of a specific message @@ -1784,13 +1757,12 @@ return $headers; } - /** * Fetch message headers and body structure from the IMAP server and build - * an object structure similar to the one generated by PEAR::Mail_mimeDecode + * an object structure. * - * @param int $uid Message UID to fetch - * @param string $folder Folder to read from + * @param int $uid Message UID to fetch + * @param string $folder Folder to read from * * @return object rcube_message_header Message data */ @@ -1869,8 +1841,8 @@ $structure[1] = $m[2]; } else { - // Try to parse the message using Mail_mimeDecode package - // We need a better solution, Mail_mimeDecode parses message + // Try to parse the message using rcube_mime_decode. + // We need a better solution, it parses message // in memory, which wouldn't work for very big messages, // (it uses up to 10x more memory than the message size) // it's also buggy and not actively developed @@ -1910,7 +1882,6 @@ return $this->icache['message'] = $headers; } - /** * Build message part object * @@ -1918,7 +1889,7 @@ * @param int $count * @param string $parent */ - protected function structure_part($part, $count=0, $parent='', $mime_headers=null) + protected function structure_part($part, $count = 0, $parent = '', $mime_headers = null) { $struct = new rcube_message_part; $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count"; @@ -1943,6 +1914,16 @@ 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; } } @@ -2126,14 +2107,13 @@ return $struct; } - /** * Set attachment filename from message part structure * - * @param rcube_message_part $part Part object - * @param string $headers Part's raw headers + * @param rcube_message_part $part Part object + * @param string $headers Part's raw headers */ - protected function set_part_filename(&$part, $headers=null) + protected function set_part_filename(&$part, $headers = null) { if (!empty($part->d_parameters['filename'])) { $filename_mime = $part->d_parameters['filename']; @@ -2261,11 +2241,10 @@ } } - /** * Get charset name from message structure (first part) * - * @param array $structure Message structure + * @param array $structure Message structure * * @return string Charset name */ @@ -2294,7 +2273,8 @@ * * @return string Message/part body if not printed */ - public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0, $formatted=true) + public function get_message_part($uid, $part = 1, $o_part = null, $print = null, $fp = null, + $skip_charset_conv = false, $max_bytes = 0, $formatted = true) { if (!$this->check_connection()) { return null; @@ -2346,42 +2326,41 @@ return $body; } - /** * 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); } - /** * Sends the whole message source to stdout @@ -2397,7 +2376,6 @@ $this->conn->handlePartBody($this->folder, $uid, true, null, null, true, null, $formatted); } - /** * Set message flag to one or several messages @@ -2458,7 +2436,6 @@ return $result; } - /** * Append a mail message (source) to a specific folder * @@ -2501,7 +2478,7 @@ // 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, @@ -2515,7 +2492,6 @@ return $saved; } - /** * Move a message from one folder to another @@ -2594,7 +2570,6 @@ return $moved; } - /** * Copy a message from one folder to another * @@ -2630,7 +2605,6 @@ return $copied; } - /** * Mark messages as deleted and expunge them @@ -2688,7 +2662,6 @@ return $deleted; } - /** * Send IMAP expunge command and clear cache @@ -2777,7 +2750,7 @@ } // 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'])) { @@ -2812,15 +2785,14 @@ return $a_mboxes; } - /** * Method for direct folders listing (LSUB) * - * @param string $root Optional root folder - * @param string $name Optional name pattern + * @param string $root Optional root folder + * @param string $name Optional name pattern * - * @return array List of subscribed folders - * @see rcube_imap::list_folders_subscribed() + * @return array List of subscribed folders + * @see rcube_imap::list_folders_subscribed() */ public function list_folders_subscribed_direct($root='', $name='*') { @@ -2857,7 +2829,7 @@ if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) { foreach ($a_folders as $idx => $folder) { if (($opts = $this->conn->data['LIST'][$folder]) - && in_array('\\NonExistent', $opts) + && in_array_nocase('\\NonExistent', $opts) ) { $this->conn->unsubscribe($folder); unset($a_folders[$idx]); @@ -2880,7 +2852,6 @@ return $a_folders; } - /** * Get a list of all folders available on the server @@ -2909,7 +2880,7 @@ } // 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'])) { @@ -2950,15 +2921,14 @@ return $a_mboxes; } - /** * Method for direct folders listing (LIST) * - * @param string $root Optional root folder - * @param string $name Optional name pattern + * @param string $root Optional root folder + * @param string $name Optional name pattern * - * @return array List of folders - * @see rcube_imap::list_folders() + * @return array List of folders + * @see rcube_imap::list_folders() */ public function list_folders_direct($root='', $name='*') { @@ -2982,13 +2952,12 @@ return $result; } - /** * Fix folders list by adding folders from other namespaces. * Needed on some servers eg. Courier IMAP * - * @param array $result Reference to folders list - * @param string $type Listing type (ext-subscribed, subscribed or all) + * @param array $result Reference to folders list + * @param string $type Listing type (ext-subscribed, subscribed or all) */ protected function list_folders_update(&$result, $type = null) { @@ -3038,7 +3007,6 @@ } } - /** * Filter the given list of folders according to access rights * @@ -3064,22 +3032,21 @@ return $a_folders; } - /** * Get mailbox quota information - * added by Nuny + * + * @param string $folder Folder name * * @return mixed Quota info or False if not supported */ - public function get_quota() + public function get_quota($folder = null) { if ($this->get_capability('QUOTA') && $this->check_connection()) { - return $this->conn->getQuota(); + return $this->conn->getQuota($folder); } return false; } - /** * Get folder size (size of all messages in a folder) @@ -3104,7 +3071,6 @@ return $result; } - /** * Subscribe to a specific folder(s) * @@ -3118,7 +3084,6 @@ return $this->change_subscription($folders, 'subscribe'); } - /** * Unsubscribe folder(s) * @@ -3131,7 +3096,6 @@ // let this common function do the main work return $this->change_subscription($folders, 'unsubscribe'); } - /** * Create a new folder on the server and register it in local cache @@ -3162,7 +3126,6 @@ return $result; } - /** * Set a new name to an existing folder @@ -3223,7 +3186,6 @@ return $result; } - /** * Remove folder from server * @@ -3271,7 +3233,6 @@ return $result; } - /** * Detect special folder associations stored in storage backend */ @@ -3297,12 +3258,14 @@ // 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; + } } } } @@ -3313,7 +3276,6 @@ return array_merge($result, $special); } - /** * Set special folder associations stored in storage backend @@ -3353,7 +3315,6 @@ return true; } - /** * Checks if folder exists and is subscribed * @@ -3381,7 +3342,7 @@ if ($subscription) { // It's possible we already called LIST command, check LIST data if (!empty($this->conn->data['LIST']) && !empty($this->conn->data['LIST'][$folder]) - && in_array('\\Subscribed', $this->conn->data['LIST'][$folder]) + && in_array_nocase('\\Subscribed', $this->conn->data['LIST'][$folder]) ) { $a_folders = array($folder); } @@ -3406,7 +3367,6 @@ return false; } - /** * Returns the namespace where the folder is in @@ -3437,7 +3397,6 @@ return 'personal'; } - /** * Modify folder name according to namespace. @@ -3477,7 +3436,6 @@ return $folder; } - /** * Gets folder attributes from LIST response, e.g. \Noselect, \Noinferiors * @@ -3509,7 +3467,6 @@ return is_array($opts) ? $opts : array(); } - /** * Gets connection (and current folder) data: UIDVALIDITY, EXISTS, RECENT, @@ -3549,7 +3506,6 @@ return $data; } - /** * Returns extended information about the folder @@ -3646,7 +3602,6 @@ return $options; } - /** * Synchronizes messages cache. * @@ -3658,7 +3613,6 @@ $mcache->synchronize($folder); } } - /** * Get message header names for rcube_imap_generic::fetchHeader(s) @@ -3711,7 +3665,6 @@ return $this->conn->setACL($folder, $user, $acl); } - /** * Removes any <identifier,rights> pair for the * specified user from the ACL for the specified @@ -3736,7 +3689,6 @@ return $this->conn->deleteACL($folder, $user); } - /** * Returns the access control list for folder (GETACL) * @@ -3757,7 +3709,6 @@ return $this->conn->getACL($folder); } - /** * Returns information about what rights can be granted to the @@ -3782,7 +3733,6 @@ return $this->conn->listRights($folder, $user); } - /** * Returns the set of rights that the current user has to * folder (MYRIGHTS) @@ -3804,7 +3754,6 @@ return $this->conn->myRights($folder); } - /** * Sets IMAP metadata/annotations (SETMETADATA/SETANNOTATION) @@ -3839,7 +3788,6 @@ return false; } - /** * Unsets IMAP metadata/annotations (SETMETADATA/SETANNOTATION) * @@ -3872,7 +3820,6 @@ return false; } - /** * Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION) @@ -3924,8 +3871,16 @@ // @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); + } } } } @@ -3937,7 +3892,6 @@ return null; } - /** * Converts the METADATA extension entry name into the correct @@ -4068,7 +4022,6 @@ } } - /** * Getter for messages cache object */ @@ -4087,7 +4040,6 @@ return $this->mcache; } - /** * Clears the messages cache. * @@ -4100,7 +4052,6 @@ $mcache->clear($folder, $uids); } } - /** * Delete outdated cache entries @@ -4130,7 +4081,6 @@ $this->sort_order = strtoupper($sort_order) == 'DESC' ? 'DESC' : 'ASC'; } } - /** * Sort folders first by default folders and then in alphabethical order @@ -4218,12 +4168,11 @@ } } - /** * Find UID of the specified message sequence ID * - * @param int $id Message (sequence) ID - * @param string $folder Folder name + * @param int $id Message (sequence) ID + * @param string $folder Folder name * * @return int Message UID */ @@ -4247,7 +4196,6 @@ return $uid; } - /** * Subscribe/unsubscribe a list of folders and update local cache @@ -4281,7 +4229,6 @@ return $updated; } - /** * Increde/decrese messagecount for a specific folder */ @@ -4312,7 +4259,6 @@ return true; } - /** * Remove messagecount of a specific folder from cache */ @@ -4330,7 +4276,6 @@ $this->update_cache('messagecount', $a_folder_cache); } } - /** * Converts date string/object into IMAP date/time format @@ -4353,7 +4298,6 @@ return $date->format('d-M-Y H:i:s O'); } - /** * This is our own debug handler for the IMAP connection @@ -4484,7 +4428,7 @@ return $this->mod_folder($folder, $mode); } - public function mailbox_attributes($folder, $force=false) + public function mailbox_attributes($folder, $force = false) { return $this->folder_attributes($folder, $force); } @@ -4504,9 +4448,8 @@ return $this->folder_sync($folder); } - public function expunge($folder='', $clear_cache=true) + public function expunge($folder = '', $clear_cache = true) { return $this->expunge_folder($folder, $clear_cache); } - } -- Gitblit v1.9.1