Files
server/usr/share/psa-horde/imp/lib/Message.php
2026-01-07 20:52:11 +01:00

854 lines
32 KiB
PHP

<?php
/**
* Copyright 2000-2001 Chris Hyde <chris@jeks.net>
* Copyright 2000-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @category Horde
* @copyright 2000-2001 Chris Hyde
* @copyright 2000-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
/**
* This class contains all functions related to handling messages within IMP.
* Actions such as moving, copying, and deleting messages are handled in here
* so that code need not be repeated between mailbox, message, and other
* pages.
*
* @author Chris Hyde <chris@jeks.net>
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2000-2001 Chris Hyde
* @copyright 2000-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
class IMP_Message
{
/**
* Copies or moves a list of messages to a new mailbox.
* Handles search and Trash mailboxes.
* Also handles moves to the tasklist and/or notepad applications.
*
* @param string $targetMbox The mailbox to move/copy messages to
* (UTF-8).
* @param string $action Either 'copy' or 'move'.
* @param IMP_Indices $indices An indices object.
* @param array $opts Additional options:
* - create: (boolean) Should the target mailbox be created?
* DEFAULT: false
* - mailboxob: (IMP_Mailbox_List) Update this mailbox object.
* DEFAULT: No update.
*
* @return boolean True if successful, false if not.
*/
public function copy($targetMbox, $action, IMP_Indices $indices,
array $opts = array())
{
global $conf, $notification;
if (!count($indices)) {
return false;
}
$targetMbox = IMP_Mailbox::get($targetMbox);
/* If the target is a tasklist, handle the move/copy specially. */
if ($conf['tasklist']['use_tasklist'] &&
(strpos($targetMbox, IMP::TASKLIST_EDIT) === 0)) {
$this->_createTasksOrNotes(str_replace(IMP::TASKLIST_EDIT, '', $targetMbox), $action, $indices, 'task');
return true;
}
/* If the target is a notepad, handle the move/copy specially. */
if ($conf['notepad']['use_notepad'] &&
(strpos($targetMbox, IMP::NOTEPAD_EDIT) === 0)) {
$this->_createTasksOrNotes(str_replace(IMP::NOTEPAD_EDIT, '', $targetMbox), $action, $indices, 'note');
return true;
}
if (!empty($opts['create']) && !$targetMbox->create()) {
return false;
}
$imap_move = false;
$return_value = true;
switch ($action) {
case 'move':
$imap_move = true;
$message = _("There was an error moving messages from \"%s\" to \"%s\". This is what the server said");
break;
case 'copy':
$message = _("There was an error copying messages from \"%s\" to \"%s\". This is what the server said");
break;
}
foreach ($indices as $ob) {
try {
if ($targetMbox->readonly) {
throw new IMP_Exception(_("The target directory is read-only."));
}
if (($action == 'move') && $ob->mbox->readonly) {
throw new IMP_Exception(_("The source directory is read-only."));
}
$ob->mbox->uidvalid;
/* Attempt to copy/move messages to new mailbox. */
$imp_imap = $ob->mbox->imp_imap;
$imp_imap->copy($ob->mbox, $targetMbox, array(
'ids' => $imp_imap->getIdsOb($ob->uids),
'move' => $imap_move
));
if (($action == 'move') &&
!empty($opts['mailboxob']) &&
$opts['mailboxob']->isBuilt()) {
$opts['mailboxob']->removeMsgs($ob->mbox->getIndicesOb($ob->uids));
}
} catch (Exception $e) {
$error_msg = sprintf($message, $ob->mbox->display, $targetMbox->display) . ': ' . $e->getMessage();
if ($e instanceof IMP_Imap_Exception) {
$e->notify($error_msg);
} else {
$notification->push($error_msg, 'horde.error');
}
$return_value = false;
}
}
return $return_value;
}
/**
* Deletes a list of messages.
* Handles search and Trash mailboxes.
*
* @param IMP_Indices $indices An indices object.
* @param array $opts Additional options:
* - keeplog: (boolean) Should any history information of the message be
* kept?
* - mailboxob: (IMP_Mailbox_List) Update this mailbox object.
* DEFAULT: No update.
* - nuke: (boolean) Override user preferences and nuke (i.e.
* permanently delete) the messages instead?
*
* @return integer|boolean The number of messages deleted if successful,
* false if not.
*/
public function delete(IMP_Indices $indices, array $opts = array())
{
global $injector, $notification, $prefs;
if (!count($indices)) {
return false;
}
$trash = IMP_Mailbox::getPref(IMP_Mailbox::MBOX_TRASH);
$use_trash = $prefs->getValue('use_trash');
if ($use_trash && !$trash) {
$notification->push(_("Cannot move messages to Trash - no Trash mailbox set in preferences."), 'horde.error');
return false;
}
$ajax_queue = $injector->getInstance('IMP_Ajax_Queue');
$maillog = empty($opts['keeplog'])
? $injector->getInstance('IMP_Maillog')
: null;
$return_value = 0;
/* Check for Trash mailbox. */
$no_expunge = $use_trash_mbox = $use_vtrash = false;
if ($use_trash &&
empty($opts['nuke']) &&
$injector->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_TRASH)) {
$use_vtrash = $trash->vtrash;
$use_trash_mbox = !$use_vtrash;
}
/* Check whether we are marking messages as seen.
* If using virtual trash, we must mark the message as seen or else it
* will appear as an 'unseen' message for purposes of new message
* counts. */
$mark_seen = empty($opts['nuke']) &&
($use_vtrash || $prefs->getValue('delete_mark_seen'));
if ($use_trash_mbox && !$trash->create()) {
/* If trash mailbox could not be created, just mark message as
* deleted. */
$no_expunge = true;
$return_value = $use_trash_mbox = false;
}
foreach ($indices as $ob) {
try {
if (!$ob->mbox->access_deletemsgs) {
throw new IMP_Exception(_("This mailbox is read-only."));
}
$ob->mbox->uidvalid;
} catch (IMP_Exception $e) {
$notification->push(sprintf(_("There was an error deleting messages from the mailbox \"%s\"."), $ob->mbox->display) . ' ' . $e->getMessage(), 'horde.error');
$return_value = false;
continue;
}
$imp_indices = $ob->mbox->getIndicesOb($ob->uids);
if ($return_value !== false) {
$return_value += count($ob->uids);
}
$imp_imap = $ob->mbox->imp_imap;
$ids_ob = $imp_imap->getIdsOb($ob->uids);
/* Trash is only valid for IMAP mailboxes. */
if ($use_trash_mbox &&
($ob->mbox != $trash) &&
/* TODO(?): Don't use Trash mailbox for remote accounts. */
!$ob->mbox->remote_mbox) {
if ($ob->mbox->access_expunge) {
try {
if ($mark_seen) {
$imp_imap->store($ob->mbox, array(
'add' => array(
Horde_Imap_Client::FLAG_SEEN
),
'ids' => $ids_ob
));
}
$imp_imap->copy($ob->mbox, $trash, array(
'ids' => $ids_ob,
'move' => true
));
if (!empty($opts['mailboxob']) &&
$opts['mailboxob']->isBuilt()) {
$opts['mailboxob']->removeMsgs($imp_indices);
}
} catch (IMP_Imap_Exception $e) {
if ($e->getCode() == $e::OVERQUOTA) {
$notification->push(_("You are over your quota, so your messages will be permanently deleted instead of moved to the Trash mailbox."), 'horde.warning');
$opts['nuke'] = true;
return $this->delete(new IMP_Indices($ob->mbox, $ob->uids), $opts);
}
return false;
}
}
} else {
/* Delete message logs now. This may result in loss of message
* log data for messages that might not be deleted - i.e. if
* an error occurs. But 1) the user has already indicated they
* don't care about this data and 2) message IDs (used by some
* maillog backends) won't be available after deletion. */
if ($maillog) {
$maillog->deleteLog(new IMP_Maillog_Messages($ob->mbox, $ids_ob));
}
/* Delete the messages. */
$expunge_now = false;
$del_flags = array(Horde_Imap_Client::FLAG_DELETED);
if (!$use_vtrash &&
(!$imp_imap->access(IMP_Imap::ACCESS_TRASH) ||
!empty($opts['nuke']) ||
($use_trash &&
($ob->mbox == $trash) || $ob->mbox->remote_mbox))) {
/* Purge messages immediately. */
$expunge_now = !$no_expunge;
} elseif ($mark_seen) {
$del_flags[] = Horde_Imap_Client::FLAG_SEEN;
}
try {
$imp_imap->store($ob->mbox, array(
'add' => $del_flags,
'ids' => $ids_ob
));
if ($expunge_now) {
$this->expungeMailbox(
$imp_indices->indices(),
array(
'mailboxob' => empty($opts['mailboxob']) ? null : $opts['mailboxob']
)
);
} elseif (!empty($opts['mailboxob']) &&
$opts['mailboxob']->isBuilt() &&
$ob->mbox->hideDeletedMsgs()) {
$opts['mailboxob']->removeMsgs($imp_indices);
} else {
$ajax_queue->flag($del_flags, true, new IMP_Indices($ob->mbox, $ids_ob));
}
} catch (IMP_Imap_Exception $e) {}
}
}
return $return_value;
}
/**
* Undeletes a list of messages.
* Handles search mailboxes.
* This function works with IMAP only, not POP3.
*
* @param IMP_Indices $indices An indices object.
*
* @return boolean True if successful, false if not.
*/
public function undelete(IMP_Indices $indices)
{
return $this->flag(array(
'remove' => array(Horde_Imap_Client::FLAG_DELETED)
), $indices);
}
/**
* Copies or moves a list of messages to a tasklist or notepad.
* Handles search and Trash mailboxes.
*
* @param string $list The list in which the task or note will be
* created.
* @param string $action Either 'copy' or 'move'.
* @param IMP_Indices $indices An indices object.
* @param string $type The object type to create ('note' or
* 'task').
*/
protected function _createTasksOrNotes($list, $action,
IMP_Indices $indices, $type)
{
global $injector, $registry, $notification;
foreach ($indices as $ob) {
foreach ($ob->uids as $uid) {
/* Fetch the message contents. */
$imp_contents = $injector->getInstance('IMP_Factory_Contents')->create($ob->mbox->getIndicesOb($uid));
/* Fetch the message headers. */
$imp_headers = $imp_contents->getHeader();
$subject = $imp_headers->getValue('subject');
/* Re-flow the message for prettier formatting. */
$body_part = $imp_contents->getMIMEPart($imp_contents->findBody());
$flowed = new Horde_Text_Flowed($body_part->getContents());
if ($body_part->getContentTypeParameter('delsp') == 'yes') {
$flowed->setDelSp(true);
}
$body = $flowed->toFlowed(false);
/* Convert to current charset */
/* TODO: When Horde_Icalendar supports setting of charsets
* we need to set it there instead of relying on the fact
* that both Nag and IMP use the same charset. */
$body = Horde_String::convertCharset($body, $body_part->getCharset(), 'UTF-8');
/* Create a new iCalendar. */
$vCal = new Horde_Icalendar();
$vCal->setAttribute('PRODID', '-//The Horde Project//IMP ' . $registry->getVersion() . '//EN');
$vCal->setAttribute('METHOD', 'PUBLISH');
switch ($type) {
case 'task':
/* Create a new vTodo object using this message's
* contents. */
$vTodo = Horde_Icalendar::newComponent('vtodo', $vCal);
$vTodo->setAttribute('SUMMARY', $subject);
$vTodo->setAttribute('DESCRIPTION', $body);
$vTodo->setAttribute('PRIORITY', '3');
/* Get the list of editable tasklists. */
try {
$lists = $registry->call('tasks/listTasklists', array(false, Horde_Perms::EDIT));
} catch (Horde_Exception $e) {
$lists = null;
$notification->push($e);
}
/* Attempt to add the new vTodo item to the requested
* tasklist. */
try {
$res = $registry->call('tasks/import', array($vTodo, 'text/calendar', $list));
} catch (Horde_Exception $e) {
$res = null;
$notification->push($e);
}
break;
case 'note':
/* Create a new vNote object using this message's
* contents. */
$vNote = Horde_Icalendar::newComponent('vnote', $vCal);
$vNote->setAttribute('BODY', $subject . "\n". $body);
/* Get the list of editable notepads. */
try {
$lists = $registry->call('notes/listNotepads', array(false, Horde_Perms::EDIT));
} catch (Horde_Exception $e) {
$lists = null;
$notification->push($e);
}
/* Attempt to add the new vNote item to the requested
* notepad. */
try {
$res = $registry->call('notes/import', array($vNote, 'text/x-vnote', $list));
} catch (Horde_Exception $e) {
$res = null;
$notification->push($e);
}
break;
}
if (!is_null($res)) {
if (!$res) {
switch ($type) {
case 'task':
$notification->push(_("An unknown error occured while creating the new task."), 'horde.error');
break;
case 'note':
$notification->push(_("An unknown error occured while creating the new note."), 'horde.error');
break;
}
} elseif (!is_null($lists)) {
$name = '"' . htmlspecialchars($subject) . '"';
/* Attempt to convert the object name into a
* hyperlink. */
try {
switch ($type) {
case 'task':
$link = $registry->link('tasks/show', array('uid' => $res));
break;
case 'note':
$link = $registry->hasMethod('notes/show')
? $registry->link('notes/show', array('uid' => $res))
: false;
break;
}
if ($link) {
$name = sprintf('<a href="%s">%s</a>', Horde::url($link), $name);
}
$notification->push(sprintf(_("%s was successfully added to \"%s\"."), $name, htmlspecialchars($lists[$list]->get('name'))), 'horde.success', array('content.raw'));
} catch (Horde_Exception $e) {}
}
}
}
}
/* Delete the original messages if this is a "move" operation. */
if ($action == 'move') {
$this->delete($indices);
}
}
/**
* Strips one or all MIME parts out of a message.
* Handles search mailboxes.
*
* @param IMP_Indices $indices An indices object.
* @param string $partid The MIME ID of the part to strip. All
* parts are stripped if null.
* @param array $opts Additional options:
* - mailboxob: (IMP_Mailbox_List) Update this mailbox object.
* DEFAULT: No update.
*
* @return IMP_Indices Returns the new indices object.
* @throws IMP_Exception
*/
public function stripPart(IMP_Indices $indices, $partid = null,
array $opts = array())
{
global $injector;
list($mbox, $uid) = $indices->getSingle();
if (!$uid) {
return;
}
if ($mbox->readonly) {
throw new IMP_Exception(_("Cannot strip the MIME part as the mailbox is read-only."));
}
$uidvalidity = $mbox->uidvalid;
$contents = $injector->getInstance('IMP_Factory_Contents')->create($indices);
$message = $contents->getMIMEMessage();
$boundary = trim($message->getContentTypeParameter('boundary'), '"');
$url = new Horde_Imap_Client_Url();
$url->mailbox = $mbox;
$url->uid = $uid;
$url->uidvalidity = $uidvalidity;
$imp_imap = $mbox->imp_imap;
/* Always add the header to output. */
$url->section = 'HEADER';
$parts = array(
array(
't' => 'url',
'v' => strval($url)
)
);
for ($id = 1; ; ++$id) {
$part = $message->getPart($id);
if (!$part) {
break;
}
$parts[] = array(
't' => 'text',
'v' => "\r\n--" . $boundary . "\r\n"
);
if (($id != 1) && is_null($partid) || ($id == $partid)) {
$newPart = new Horde_Mime_Part();
$newPart->setType('text/plain');
/* Need to make sure all text is in the correct charset. */
$newPart->setCharset('UTF-8');
$newPart->setContents(sprintf(_("[Attachment stripped: Original attachment type: %s, name: %s]"), $part->getType(), $contents->getPartName($part)));
$newPart->setDisposition('attachment');
$parts[] = array(
't' => 'text',
'v' => $newPart->toString(array(
'canonical' => true,
'headers' => true,
'stream' => true
))
);
} else {
$url->section = $id . '.MIME';
$parts[] = array(
't' => 'url',
'v' => strval($url)
);
$url->section = $id;
$parts[] = array(
't' => 'url',
'v' => strval($url)
);
}
}
$parts[] = array(
't' => 'text',
'v' => "\r\n--" . $boundary . "--\r\n"
);
/* Get the headers for the message. */
$query = new Horde_Imap_Client_Fetch_Query();
$query->imapDate();
$query->flags();
try {
$res = $imp_imap->fetch($mbox, $query, array(
'ids' => $imp_imap->getIdsOb($uid)
))->first();
if (is_null($res)) {
throw new IMP_Imap_Exception();
}
$flags = $res->getFlags();
/* If in Virtual Inbox, we need to reset flag to unseen so that it
* appears again in the mailbox list. */
if ($mbox->vinbox) {
$flags = array_values(array_diff($flags, array(Horde_Imap_Client::FLAG_SEEN)));
}
$new_uid = $imp_imap->append($mbox, array(
array(
'data' => $parts,
'flags' => $flags,
'internaldate' => $res->getImapDate()
)
))->ids;
$new_uid = reset($new_uid);
} catch (IMP_Imap_Exception $e) {
throw new IMP_Exception(_("An error occured while attempting to strip the attachment."));
}
$this->delete($indices, array(
'keeplog' => true,
'mailboxob' => empty($opts['mailboxob']) ? null : $opts['mailboxob'],
'nuke' => true
));
$indices_ob = $mbox->getIndicesOb($new_uid);
if (!empty($opts['mailboxob'])) {
$opts['mailboxob']->setIndex($indices_ob);
}
/* We need to replace the old UID(s) in the URL params. */
$vars = $injector->getInstance('Horde_Variables');
if (isset($vars->buid)) {
list(,$vars->buid) = $mbox->toBuids($indices_ob)->getSingle();
}
if (isset($vars->uid)) {
$vars->uid = $new_uid;
}
return $indices_ob;
}
/**
* Sets or clears a given flag for a list of messages.
* Handles search mailboxes.
* This function works with IMAP only, not POP3.
*
* @param array $action A list of IMAP flag(s). Keys are 'add'
* and/or 'remove'.
* @param IMP_Indices $indices An indices object.
* @param array $opts Additional options:
* - silent: (boolean) Don't output notification messages.
* - unchangedsince: (array) The unchangedsince value to pass to the
* IMAP store command. Keys are mailbox names, values
* are the unchangedsince values to use for that
* mailbox.
*
* @return boolean True if successful, false if not.
*/
public function flag(array $action, IMP_Indices $indices,
array $opts = array())
{
global $injector, $notification;
if (!count($indices)) {
return false;
}
$opts = array_merge(array(
'unchangedsince' => array()
), $opts);
$ajax_queue = $injector->getInstance('IMP_Ajax_Queue');
$ret = true;
foreach ($indices as $ob) {
try {
if ($ob->mbox->readonly) {
throw new IMP_Exception(_("This mailbox is read-only."));
}
$ob->mbox->uidvalid;
$unchangedsince = isset($opts['unchangedsince'][strval($ob->mbox)])
? $opts['unchangedsince'][strval($ob->mbox)]
: null;
/* Flag/unflag the messages now. */
$imp_imap = $ob->mbox->imp_imap;
$res = $imp_imap->store($ob->mbox, array_merge($action, array_filter(array(
'ids' => $imp_imap->getIdsOb($ob->uids),
'unchangedsince' => $unchangedsince
))));
$flag_change = $ob->mbox->getIndicesOb($ob->uids);
if ($unchangedsince && count($res)) {
foreach ($res as $val) {
unset($flag_change[$val]);
}
if (empty($opts['silent'])) {
$notification->push(sprintf(_("Flags were not changed for at least one message in the mailbox \"%s\" because the flags were altered by another connection to the mailbox prior to this request. You may redo the flag action if desired; this warning is precautionary to ensure you don't overwrite flag changes."), $ob->mbox->display), 'horde.warning');
$ret = false;
}
}
foreach ($action as $key => $val) {
$ajax_queue->flag($val, ($key == 'add'), $flag_change);
if ($indices instanceof IMP_Indices_Mailbox) {
$ajax_queue->flag($val, ($key == 'add'), $indices->mailbox->toBuids($flag_change));
}
}
} catch (Exception $e) {
if (empty($opts['silent'])) {
$notification->push(sprintf(_("There was an error flagging messages in the mailbox \"%s\": %s."), $ob->mbox->display, $e->getMessage()), 'horde.error');
}
$ret = false;
}
}
return $ret;
}
/**
* Adds or removes flag(s) for all messages in a list of mailboxes.
* This function works with IMAP only, not POP3.
*
* @param array $flags The IMAP flag(s) to add or remove.
* @param array $mboxes The list of mailboxes to flag.
* @param boolean $action If true, add the flag(s), otherwise, remove the
* flag(s).
*
* @return boolean True if successful, false if not.
*/
public function flagAllInMailbox($flags, $mboxes, $action = true)
{
if (empty($mboxes) || !is_array($mboxes)) {
return false;
}
$action_array = $action
? array('add' => $flags)
: array('remove' => $flags);
$ajax_queue = $GLOBALS['injector']->getInstance('IMP_Ajax_Queue');
$ajax_queue->poll($mboxes);
foreach (IMP_Mailbox::get($mboxes) as $val) {
try {
/* Grab list of UIDs before flagging, to make sure we
* determine the exact subset that has been flagged. */
$mailbox_list = $val->list_ob->getIndicesOb();
$val->imp_imap->store($val, $action_array);
$ajax_queue->flag(reset($action_array), $action, $mailbox_list);
} catch (IMP_Imap_Exception $e) {
return false;
}
}
return true;
}
/**
* Expunges all deleted messages from the list of mailboxes.
*
* @param array $mbox_list The list of mailboxes to empty as keys; an
* optional array of indices to delete as values.
* If the value is not an array, all messages
* flagged as deleted in the mailbox will be
* deleted.
* @param array $opts Additional options:
* - list: (boolean) Return a list of messages expunged.
* DEFAULT: false
* - mailboxob: (IMP_Mailbox_List) Update this mailbox object.
* DEFAULT: No update.
*
* @return IMP_Indices If 'list' option is true, an indices object
* containing the messages that have been expunged.
*/
public function expungeMailbox($mbox_list, array $opts = array())
{
$msg_list = !empty($opts['list']);
if (empty($mbox_list)) {
return $msg_list ? new IMP_Indices() : null;
}
$process_list = $update_list = array();
foreach ($mbox_list as $key => $val) {
$key = IMP_Mailbox::get($key);
if ($key->access_expunge) {
$ids = $key->imp_imap->getIdsOb(is_array($val) ? $val : Horde_Imap_Client_Ids::ALL);
if ($key->search) {
foreach ($key->getSearchOb()->mboxes as $skey) {
$process_list[] = array($skey, $ids);
}
} else {
$process_list[] = array($key, $ids);
}
}
}
// [0] = IMP_Mailbox object, [1] = Horde_Imap_Client_Ids object
foreach ($process_list as $val) {
/* If expunging a particular UID list, need to check
* UIDVALIDITY. */
if (!$val[1]->all) {
try {
$val[0]->uidvalid;
} catch (IMP_Exception $e) {
continue;
}
}
try {
$update_list[strval($val[0])] = $val[0]->imp_imap->expunge($val[0], array(
'ids' => $val[1],
'list' => $msg_list
));
if (!empty($opts['mailboxob']) &&
$opts['mailboxob']->isBuilt()) {
$opts['mailboxob']->removeMsgs($val[1]->all ? true : $val[0]->getIndicesOb($val[1]));
}
} catch (IMP_Imap_Exception $e) {}
}
if ($msg_list) {
return new IMP_Indices($update_list);
}
}
/**
* Empties an entire mailbox.
*
* @param array $mbox_list The list of mailboxes to empty.
*/
public function emptyMailbox($mbox_list)
{
global $notification, $prefs;
$trash = ($prefs->getValue('use_trash'))
? IMP_Mailbox::getPref(IMP_Mailbox::MBOX_TRASH)
: null;
foreach (IMP_Mailbox::get($mbox_list) as $mbox) {
if (!$mbox->access_empty) {
$notification->push(sprintf(_("Could not delete messages from %s. This mailbox is read-only."), $mbox->display), 'horde.error');
continue;
}
if ($mbox->vtrash) {
$this->expungeMailbox(array_flip($mbox->getSearchOb()->mboxes));
$notification->push(_("Emptied all messages from Virtual Trash Folder."), 'horde.success');
continue;
}
/* Make sure there is at least 1 message before attempting to
* delete. */
try {
$imp_imap = $mbox->imp_imap;
$status = $imp_imap->status($mbox, Horde_Imap_Client::STATUS_MESSAGES);
if (empty($status['messages'])) {
$notification->push(sprintf(_("The mailbox %s is already empty."), $mbox->display), 'horde.message');
continue;
}
if (!$trash || ($trash == $mbox)) {
$imp_imap->store($mbox, array(
'add' => array(Horde_Imap_Client::FLAG_DELETED)
));
$this->expungeMailbox(array(strval($mbox) => 1));
} else {
$ret = $imp_imap->search($mbox);
$this->delete($mbox->getIndicesOb($ret['match']));
}
$notification->push(sprintf(_("Emptied all messages from %s."), $mbox->display), 'horde.success');
} catch (IMP_Imap_Exception $e) {}
}
}
}