protected $_nsdefault;
/**
+ * UIDVALIDITY check cache.
+ *
+ * @var array
+ */
+ protected $_uidvalid = array();
+
+ /**
* Constructor.
*/
function __construct()
}
/**
+ * Do a UIDVALIDITY check - needed if UIDs are passed between page
+ * accesses.
+ *
+ * @param string $mailbox The mailbox to check. Must be an IMAP mailbox.
+ *
+ * @throws Horde_Exception
+ */
+ public function checkUidvalidity($mailbox)
+ {
+ // TODO: POP3 also?
+ if ($_SESSION['imp']['protocol'] == 'pop') {
+ return;
+ }
+
+ if (!isset($this->_uidvalid[$mailbox])) {
+ $status = $this->ob->status($mailbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
+ $ptr = &$_SESSION['imp']['cache'];
+ $val = isset($ptr['uidvalid'][$mailbox])
+ ? $ptr['uidvalid'][$mailbox]
+ : null;
+ $ptr['uidvalid'][$mailbox] = $status['uidvalidity'];
+
+ $this->_uidvalid[$mailbox] = (!is_null($val) && ($status['uidvalidity'] != $val));
+ }
+
+ if ($this->_uidvalid[$mailbox]) {
+ throw new Horde_Exception(_("Mailbox structure on server has changed."));
+ }
+ }
+
+ /**
* Logs an exception from Horde_Imap_Client.
*
* @param object Horde_Imap_Client_Exception $e The exception object.
}
foreach ($msgList as $mbox => $msgIndices) {
+ $error = null;
+
if (($action == 'move') && $GLOBALS['imp_imap']->isReadOnly($mbox)) {
- $notification->push(sprintf($message, IMP::displayFolder($mbox), IMP::displayFolder($targetMbox)) . ': ' . _("The target directory is read-only."), 'horde.error');
- $return_value = false;
- continue;
+ $error = _("The target directory is read-only.");
+ }
+
+ if (!$error) {
+ try {
+ $GLOBALS['imp_imap']->checkUidvalidity($mbox);
+ } catch (Horde_Exception $e) {
+ $error = $e->getMessage();
+ }
}
/* Attempt to copy/move messages to new mailbox. */
- try {
- $GLOBALS['imp_imap']->ob->copy($mbox, $targetMbox, array('ids' => $msgIndices, 'move' => $imap_move));
+ if (!$error) {
+ try {
+ $GLOBALS['imp_imap']->ob->copy($mbox, $targetMbox, array('ids' => $msgIndices, 'move' => $imap_move));
- $imp_mailbox = IMP_Mailbox::singleton($mbox);
- if (($action == 'move') && $imp_mailbox->isBuilt()) {
- $imp_mailbox->removeMsgs(array($mbox => $msgIndices));
+ $imp_mailbox = IMP_Mailbox::singleton($mbox);
+ if (($action == 'move') && $imp_mailbox->isBuilt()) {
+ $imp_mailbox->removeMsgs(array($mbox => $msgIndices));
+ }
+ } catch (Horde_Imap_Client_Exception $e) {
+ $error = $e->getMessage();
}
- } catch (Horde_Imap_Client_Exception $e) {
- $notification->push(sprintf($message, IMP::displayFolder($mbox), IMP::displayFolder($targetMbox)) . ': ' . $e->getMessage(), 'horde.error');
+ }
+
+ if ($error) {
+ $notification->push(sprintf($message, IMP::displayFolder($mbox), IMP::displayFolder($targetMbox)) . ': ' . $error, 'horde.error');
$return_value = false;
+ continue;
}
}
}
foreach ($msgList as $mbox => $msgIndices) {
+ $error = null;
+
if ($GLOBALS['imp_imap']->isReadOnly($mbox)) {
- $notification->push(sprintf(_("There was an error deleting messages from the folder \"%s\". This folder is read-only."), IMP::displayFolder($mbox)), 'horde.error');
+ $error = _("This folder is read-only.");
+ }
+
+ if (!$error) {
+ try {
+ $GLOBALS['imp_imap']->checkUidvalidity($mbox);
+ } catch (Horde_Exception $e) {
+ $error = $e->getMessage();
+ }
+ }
+
+ if ($error) {
+ $notification->push(sprintf(_("There was an error deleting messages from the folder \"%s\"."), IMP::displayFolder($mbox)) . ' ' . $error, 'horde.error');
$return_value = false;
continue;
}
throw new Horde_Exception(_("Cannot strip the MIME part as the mailbox is read-only"));
}
+ $GLOBALS['imp_imap']->checkUidvalidity($mbox);
+
/* Get a local copy of the message. */
$contents = IMP_Contents::singleton($index . IMP::IDX_SEP . $mbox);
*/
public function flag($flags, $indices, $action = true)
{
- global $notification;
-
if (!($msgList = IMP::parseIndicesList($indices))) {
return false;
}
: array('remove' => $flags);
foreach ($msgList as $mbox => $msgIndices) {
+ $error = null;
+
if ($GLOBALS['imp_imap']->isReadOnly($mbox)) {
- $notification->push(sprintf(_("There was an error flagging messages in the folder \"%s\". This folder is read-only."), IMP::displayFolder($mbox)), 'horde.error');
- continue;
+ $error = _("This folder is read-only.");
}
- /* Flag/unflag the messages now. */
- try {
- $GLOBALS['imp_imap']->ob->store($mbox, array_merge($action_array, array('ids' => $msgIndices)));
- } catch (Horde_Imap_Client_Exception $e) {
- $notification->push(sprintf(_("There was an error flagging messages in the folder \"%s\". This is what the server said"), IMP::displayFolder($mbox)) . ': ' . $e->getMessage(), 'horde.error');
+ if (!$error) {
+ try {
+ $GLOBALS['imp_imap']->checkUidvalidity($mbox);
+ } catch (Horde_Exception $e) {
+ $error = $e->getMessage();
+ }
+ }
+
+ if (!$error) {
+ /* Flag/unflag the messages now. */
+ try {
+ $GLOBALS['imp_imap']->ob->store($mbox, array_merge($action_array, array('ids' => $msgIndices)));
+ } catch (Horde_Imap_Client_Exception $e) {
+ $error = $e->getMessage();
+ }
+ }
+
+ if ($error) {
+ $GLOBALS['notification']->push(sprintf(_("There was an error flagging messages in the folder \"%s\". This folder is read-only."), IMP::displayFolder($mbox)), 'horde.error');
return false;
}
}
}
foreach ($process_list as $key => $val) {
+ /* If expunging a particular UID list, need to check
+ * UIDVALIDITY. */
+ if (is_array($val)) {
+ try {
+ $GLOBALS['imp_imap']->checkUidvalidity($key);
+ } catch (Horde_Exception $e) {
+ continue;
+ }
+ }
+
try {
$update_list[$key] = $GLOBALS['imp_imap']->ob->expunge($key, array('ids' => is_array($val) ? $val : array(), 'list' => $msg_list));