/**
* Initialize the Horde_Imap_Client_Cache object, if necessary.
*
+ * @param boolean $current If true, we are going to update the currently
+ * selected mailbox. Add an additional check to
+ * see if caching is available in current
+ * mailbox.
+ *
* @return boolean Returns true if caching is enabled.
* @throws Horde_Imap_Client_Exception
*/
- protected function _initCache()
+ protected function _initCache($current = false)
{
if (empty($this->_params['cache']['fields'])) {
return false;
)));
}
- return true;
+ if (!$current) {
+ return true;
+ }
+
+ /* If UIDs are labeled as not sticky, don't cache since UIDs will
+ * change on every access. */
+ $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_UIDNOTSTICKY);
+ return !$status['uidnotsticky'];
}
/**
}
}
$capability = strtoupper($capability);
- return isset($this->_init['capability'][$capability]) ? $this->_init['capability'][$capability] : false;
+ return isset($this->_init['capability'][$capability])
+ ? $this->_init['capability'][$capability]
+ : false;
}
/**
* Return key: 'highestmodseq'
* Return format: (integer) If the server supports the CONDSTORE IMAP
* extension, this will be the highest mod-sequence value
- * of all messages in the mailbox or 0 if the mailbox
- * does not support mod-sequences. Else, this value will
- * be undefined.
+ * of all messages in the mailbox. Else 0 if CONDSTORE
+ * not available or the mailbox does not support
+ * mod-sequences.
*
* Flag: Horde_Imap_Client::STATUS_UIDNOTSTICKY
* Return key: 'uidnotsticky'
}
}
+ /* Catch flags that are not supported. */
+ if (($flags & Horde_Imap_Client::STATUS_HIGHESTMODSEQ) &&
+ isset($this->_init['enabled']['CONDSTORE'])) {
+ $ret['highestmodseq'] = 0;
+ $flags &= ~$val;
+ }
+
+ if (($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY) &&
+ !$this->queryCapability('UIDPLUS')) {
+ $ret['uidnotsticky'] = false;
+ $flags &= ~$val;
+ }
+
if (!$flags) {
return $ret;
}
}
/* If we are caching, search for deleted messages. */
- if (!empty($options['expunge']) && $this->_initCache()) {
+ if (!empty($options['expunge']) &&
+ $this->_initCache(true)) {
$search_query = new Horde_Imap_Client_Search_Query();
$search_query->flag('\\deleted', true);
$search_res = $this->search($this->_selected, $search_query);
$type = empty($options['sort']) ? 'match' : 'sort';
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
+
/* Take advantage of search result caching. If CONDSTORE available,
* we can cache all queries and invalidate the cache when the MODSEQ
* changes. If CONDSTORE not available, we can only store queries
* array - the generated query is already added to '_query' key
* above. */
$cache = null;
- if ($this->_initCache() &&
+ if ($this->_initCache(true) &&
(isset($this->_init['enabled']['CONDSTORE']) ||
!$query->flagSearch())) {
$cache = $this->_getSearchCache('search', $mailbox, $options);
}
}
- $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
-
$ret = $this->_search($query, $options);
if (!empty($options['reverse'])) {
*/
public function thread($mailbox, $options = array())
{
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
+
/* Take advantage of search result caching. If CONDSTORE available,
* we can cache all queries and invalidate the cache when the MODSEQ
* changes. If CONDSTORE not available, we can only store queries
* that don't involve flags. See search() for similar caching. */
$cache = null;
- if ($this->_initCache() &&
+ if ($this->_initCache(true) &&
(isset($this->_init['enabled']['CONDSTORE']) ||
empty($options['search']) ||
!$options['search']->flagSearch())) {
}
}
- $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
-
$ob = new Horde_Imap_Client_Thread($this->_thread($options), empty($options['sequence']) ? 'uid' : 'sequence');
if ($cache) {
public function fetch($mailbox, $criteria, $options = array())
{
$cache_array = $get_fields = $new_criteria = $ret = array();
- $cf = $this->_initCache() ? $this->_params['cache']['fields'] : array();
$qresync = isset($this->_init['enabled']['QRESYNC']);
$seq = !empty($options['sequence']);
throw new Horde_Imap_Client_Exception('The vanished FETCH modifier is missing a pre-requisite.');
}
+ $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
+
+ $cf = $this->_initCache(true)
+ ? $this->_params['cache']['fields']
+ : array();
+
/* The 'changedsince' modifier implicitly adds the MODSEQ FETCH item.
* (RFC 4551 [3.3.1]). A UID SEARCH will always return UID
* information (RFC 3501 [6.4.8]). Don't add to criteria because it
* simply creates a longer FETCH command. */
-
- $this->openMailbox($mailbox, Horde_Imap_Client::OPEN_AUTO);
-
if (!empty($cf)) {
/* We need the UIDVALIDITY for the current mailbox. */
$status_res = $this->status($this->_selected, Horde_Imap_Client::STATUS_HIGHESTMODSEQ | Horde_Imap_Client::STATUS_UIDVALIDITY);
*/
protected function _updateCache($data, $options = array())
{
- if (!$this->_initCache()) {
+ $mailbox = empty($options['mailbox'])
+ ? $this->_selected
+ : $options['mailbox'];
+
+ if (!$this->_initCache(empty($options['mailbox']))) {
return;
}
$cf = $this->_params['cache']['fields'];
$tocache = array();
- $mailbox = empty($options['mailbox']) ? $this->_selected : $options['mailbox'];
$status_flags = 0;
if (isset($this->_init['enabled']['CONDSTORE'])) {
$this->_init['enabled']['CONDSTORE'] = true;
}
- if (isset($this->_init['enabled']['CONDSTORE'])) {
- /* MODSEQ should be set if CONDSTORE is active. Some servers won't
- * advertise in SELECT/EXAMINE info though. */
- if (!isset($this->_temp['mailbox']['highestmodseq'])) {
- $this->_temp['mailbox']['highestmodseq'] = 1;
- } elseif ($qresync &&
- empty($this->_temp['mailbox']['highestmodseq'])) {
- /* Check that MODSEQ is enabled for the mailbox and, if not,
- * delete the cache. Note: Invalidating the cache based on
- * UIDVALIDITY is done within Horde_Imap_Client_Cache::. */
- $this->_cache->deleteMailbox($mailbox);
- }
+ /* MODSEQ should be set if CONDSTORE is active. Some servers won't
+ * advertise in SELECT/EXAMINE info though. */
+ if (isset($this->_init['enabled']['CONDSTORE']) &&
+ !isset($this->_temp['mailbox']['highestmodseq'])) {
+ $this->_temp['mailbox']['highestmodseq'] = 1;
}
}
} else {
// If caching, we need to know the UIDs being deleted, so call
// expunge() before calling close().
- if ($this->_initCache()) {
+ if ($this->_initCache(true)) {
$this->expunge($this->_selected);
}
$seq = !empty($options['sequence']);
$s_res = null;
$uidplus = $this->queryCapability('UIDPLUS');
- $use_cache = $this->_initCache();
+ $use_cache = $this->_initCache(true);
if (empty($options['ids'])) {
$uid_string = '1:*';
if (!empty($expunged)) {
$this->_cache->deleteMsgs($mailbox, $expunged);
$tmp['mailbox']['messages'] -= $i;
- if (isset($this->_init['enabled']['QRESYNC'])) {
- $this->_updateMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq']));
- } elseif (isset($this->_init['enabled']['CONDSTORE'])) {
- /* Unfortunately, RFC 4551 does not provide any method to
- * obtain the HIGHESTMODSEQ after an EXPUNGE is completed.
- * Instead, unselect the mailbox - if we need to reselect
- * the mailbox, the HIGHESTMODSEQ info will appear in the
- * EXAMINE/SELECT response. */
- $this->close();
+
+ /* Update MODSEQ if active for mailbox. */
+ if (!empty($this->_temp['mailbox']['highestmodseq'])) {
+ if (isset($this->_init['enabled']['QRESYNC'])) {
+ $this->_updateMetaData($mailbox, array('HICmodseq' => $this->_temp['mailbox']['highestmodseq']));
+ } else {
+ /* Unfortunately, RFC 4551 does not provide any method
+ * to obtain the HIGHESTMODSEQ after an EXPUNGE is
+ * completed. Instead, unselect the mailbox - if we
+ * need to reselect the mailbox, the HIGHESTMODSEQ
+ * info will appear in the EXAMINE/SELECT
+ * HIGHESTMODSEQ response. */
+ $this->close();
+ }
}
}
$cmd_prefix = (empty($options['sequence']) ? 'UID ' : '') .
'STORE ' . $seq . ' ';
- $ucsince = null;
+ $condstore = $ucsince = null;
+
if (empty($this->_temp['mailbox']['highestmodseq'])) {
if (!empty($options['unchangedsince'])) {
/* RFC 4551 [3.1] - trying to do a UNCHANGEDSINCE STORE on a
* here and throw an exception. */
throw new Horde_Imap_Client_Exception('Mailbox does not support mod-sequences.', Horde_Imap_Client_Exception::MBOXNOMODSEQ);
}
- } elseif (!empty($options['unchangedsince'])) {
- $ucsince = intval($options['unchangedsince']);
} else {
- /* If CONDSTORE is enabled, we need to add UNCHANGEDSINCE output
- * to ensure we get MODSEQ updated information. */
- $ucsince = $this->_temp['mailbox']['highestmodseq'];
+ if (!empty($options['unchangedsince'])) {
+ $ucsince = intval($options['unchangedsince']);
+ }
+
+ if (isset($this->_init['enabled']['CONDSTORE'])) {
+ /* If we reach here, MODSEQ is active for mailbox. */
+ $condstore = true;
+
+ /* If CONDSTORE is enabled, we need to verify UNCHANGEDSINCE
+ * added to ensure we get MODSEQ updated information. */
+ if (is_null($ucsince)) {
+ $ucsince = $this->_temp['mailbox']['highestmodseq'];
+ }
+ }
}
if ($ucsince) {
/* Update the flags in the cache. Only update if store was successful
* and flag information was not returned. */
- if (!empty($this->_temp['fetchresp']) &&
- isset($this->_init['enabled']['CONDSTORE'])) {
+ if ($condstore && !empty($this->_temp['fetchresp'])) {
$fr = $this->_temp['fetchresp'];
$out = $uids = array();
break;
case 'HIGHESTMODSEQ':
+ // Defined by RFC 4551 [3.1.1]
+ $this->_temp['mailbox']['highestmodseq'] = $data;
+ break;
+
case 'NOMODSEQ':
- // Defined by RFC 4551 [3.1.1 & 3.1.2]
- $this->_temp['mailbox']['highestmodseq'] = ($code == 'HIGHESTMODSEQ') ? $data : 0;
+ // Defined by RFC 4551 [3.1.2]
+ $this->_temp['mailbox']['highestmodseq'] = 0;
+
+ // Delete cache for mailbox, if it exists.
+ if ($this->_initCache()) {
+ $this->_cache->deleteMailbox($this->_selected);
+ }
break;
case 'MODIFIED':