/** */ public function getIndicesOb() { $this->_buildMailbox(); $ob = new IMP_Indices(); reset($this->_sorted); while (list($k, $v) = each($this->_sorted)) { $ob->add($this->_sortedMbox[$k], $v); } return $ob; }
/** * Constructor. * * @param mixed Two possible inputs: * - 1 argument: Horde_Variables object. These GET/POST parameters are * reserved in IMP: * - buid: (string) BUID [Browser UID]. * - mailbox: (string) Base64url encoded mailbox. * - muid: (string) MUID [Mailbox + UID]. * - uid: (string) UID [Actual mail UID]. * - 2 arguments: IMP_Mailbox object, IMP_Indices argument */ public function __construct() { $args = func_get_args(); switch (func_num_args()) { case 1: if ($args[0] instanceof Horde_Variables) { if (isset($args[0]->mailbox) && strlen($args[0]->mailbox)) { $this->mailbox = IMP_Mailbox::formFrom($args[0]->mailbox); if (isset($args[0]->buid)) { $this->buids = new IMP_Indices($this->mailbox, $args[0]->buid); parent::__construct($this->mailbox->fromBuids($this->buids)); } elseif (isset($args[0]->uid)) { parent::__construct($this->mailbox, $args[0]->uid); } } if (isset($args[0]->muid)) { parent::__construct($args[0]->muid); } } break; case 2: if ($args[0] instanceof IMP_Mailbox && $args[1] instanceof IMP_Indices) { $this->mailbox = $args[0]; $this->buids = $args[0]->toBuids($args[1]); parent::__construct($args[1]); } break; } if (!isset($this->buids)) { $this->buids = new IMP_Indices(); } if (!isset($this->mailbox)) { $this->mailbox = IMP_Mailbox::get('INBOX'); } }
/** * Check if we need to send a MDN, and send if needed. * * @param IMP_Indices $indices Indices object of the message. * @param Horde_Mime_Headers $headers The headers of the message. * @param boolean $confirmed Has the MDN request been confirmed? * * @return boolean True if the MDN request needs to be confirmed. */ public function MDNCheck(IMP_Indices $indices, $headers, $confirmed = false) { global $conf, $injector, $prefs; $maillog = $injector->getInstance('IMP_Maillog'); $pref_val = $prefs->getValue('send_mdn'); list($mbox, ) = $indices->getSingle(); if (!$pref_val || $mbox->readonly) { return false; } /* Check to see if an MDN has been requested. */ $mdn = new Horde_Mime_Mdn($headers); if (!($return_addr = $mdn->getMdnReturnAddr())) { return false; } $log_msg = new IMP_Maillog_Message($indices); if (count($maillog->getLog($log_msg, array('forward', 'redirect', 'reply_all', 'reply_list', 'reply')))) { return false; } /* See if we need to query the user. */ if (!$confirmed && (intval($pref_val) == 1 || $mdn->userConfirmationNeeded())) { try { if ($injector->getInstance('Horde_Core_Hooks')->callHook('mdn_check', 'imp', array($headers))) { return true; } } catch (Horde_Exception_HookNotSet $e) { return true; } } /* Send out the MDN now. */ $success = false; try { $mdn->generate(false, $confirmed, 'displayed', $conf['server']['name'], $injector->getInstance('IMP_Mail'), array('charset' => 'UTF-8', 'from_addr' => $injector->getInstance('Horde_Core_Factory_Identity')->create()->getDefaultFromAddress())); $maillog->log($log_msg, new IMP_Maillog_Log_Mdn()); $success = true; } catch (Exception $e) { } $injector->getInstance('IMP_Sentmail')->log(IMP_Sentmail::MDN, '', $return_addr, $success); return false; }
/** * Copy/move messages. * * @param string $mbox The mailbox name to copy/move the task to. * @param IMP_Indices $indices An indices object. * @param boolean $move Move if true, copy if false. * * @return boolean True on success. */ public function copy($mbox, IMP_Indices $indices, $move) { global $injector; $success = true; 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. */ $subject = strval($imp_contents->getHeader()->getHeader('Subject')); /* Re-flow the message for prettier formatting. */ $body_part = $imp_contents->getMimePart($imp_contents->findBody()); if (!$body_part) { $success = false; continue; } $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'); if (!$this->_create($mbox, $subject, $body)) { $success = false; } } } /* Delete the original messages if this is a "move" operation. */ if ($move) { $indices->delete(); } return $success; }
/** * Constructor. * * @param mixed Two possible inputs: * - 1 argument: Horde_Variables object. These GET/POST parameters are * reserved in IMP: * - buid: (string) BUID [Browser UID]. * - mailbox: (string) Base64url encoded mailbox. * - muid: (string) MUID [Mailbox + UID]. * - uid: (string) UID [Actual mail UID]. * - 2 arguments: IMP_Mailbox object, IMP_Indices argument */ public function __construct() { $args = func_get_args(); switch (func_num_args()) { case 1: if ($args[0] instanceof Horde_Variables) { if (isset($args[0]->mailbox) && strlen($args[0]->mailbox)) { $this->mailbox = IMP_Mailbox::formFrom($args[0]->mailbox); if (isset($args[0]->buid)) { /* BUIDs are always integers. Do conversion here since * POP3 won't work otherwise. */ $tmp = new Horde_Imap_Client_Ids($args[0]->buid); $this->buids = new IMP_Indices($this->mailbox, $tmp->ids); parent::__construct($this->mailbox->fromBuids($this->buids)); } elseif (isset($args[0]->uid)) { parent::__construct($this->mailbox, $args[0]->uid); } } if (isset($args[0]->muid)) { parent::__construct($args[0]->muid); } } break; case 2: if ($args[0] instanceof IMP_Mailbox && $args[1] instanceof IMP_Indices) { $this->mailbox = $args[0]; $this->buids = $args[0]->toBuids($args[1]); parent::__construct($args[1]); } break; } if (!isset($this->buids)) { $this->buids = new IMP_Indices($this->_indices); } if (!isset($this->mailbox)) { $this->mailbox = IMP_Mailbox::get('INBOX'); } }
/** * Deletes a list of messages. * * @param array $opts Additional options: * <pre> * - keeplog: (boolean) Should any history information of the message be * kept? * DEFAULT: false * - nuke: (boolean) Override user preferences and nuke (i.e. * permanently delete) the messages instead? * DEFAULT: false * </pre> * * @return integer|boolean The number of messages deleted if successful, * false if not successful. */ public function delete(array $opts = array()) { global $injector, $notification, $prefs; if (!count($this)) { 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 ($this 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; } 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 && !$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)); } 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'); $idx = new IMP_Indices($ob->mbox, $ob->uids); return $idx->delete(array('keeplog' => !empty($opts['keeplog']), 'nuke' => true)); } 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) { $ob->mbox->expunge($ids_ob); } else { $ajax_queue->flag($del_flags, true, new IMP_Indices($ob->mbox, $ids_ob)); } } catch (IMP_Imap_Exception $e) { } } } return $return_value; }
/** * Create a BUID indices object from a list of UIDs. * * @param IMP_Indices $uids UIDs. * * @return IMP_Indices An indices object. */ public function toBuids(IMP_Indices $uids) { $list_ob = $this->list_ob; $out = new IMP_Indices(); foreach ($uids as $val) { foreach ($val->uids as $val2) { $out->add($this->_mbox, $list_ob->getBuid($val->mbox, $val2)); } } return $out; }
/** * Processes delete message requests. * See the list of variables needed for viewPortData(). * * @param IMP_Indices $indices An indices object. * @param boolean $changed If true, add full ViewPort information. * @param boolean $force If true, forces addition of disappear * information. */ public function deleteMsgs(IMP_Indices $indices, $changed, $force = false) { /* Check if we need to update thread information. */ if (!$changed) { $changed = $this->indices->mailbox->getSort()->sortby == Horde_Imap_Client::SORT_THREAD; } if ($changed) { $this->addTask('viewport', $this->viewPortData(true)); } elseif ($indices instanceof IMP_Indices_Mailbox && ($force || $this->indices->mailbox->hideDeletedMsgs(true))) { $vp = new IMP_Ajax_Application_Viewport($this->indices->mailbox); $vp->disappear = $indices->buids[strval($this->indices->mailbox)]; $this->addTask('viewport', $vp); } $this->queue->poll(array_keys($indices->indices())); }
/** * Return the save link for the message source. * * @return Horde_Url URL for the save link. */ public function getSaveAs() { list($bmbox, $buid) = $this->_indices instanceof IMP_Indices_Mailbox ? $this->_indices->buids->getSingle() : $this->_indices->getSingle(); $subject = $this->getSubject(); return IMP_Contents_View::downloadUrl(htmlspecialchars_decode($subject['subject']), array_merge(array('actionID' => 'save_message'), $bmbox->urlParams($buid))); }
/** * Flag messages. * * @param string $mailbox The name of the source mailbox (UTF-8). * @param array $indices The list of UIDs to flag. * @param array $flags The flags to set. * @param boolean $set True to set flags, false to clear flags. * * @return boolean True if successful, false if not. */ public function flagMessages($mailbox, $indices, $flags, $set) { $i = new IMP_Indices($mailbox, $indices); return $i->flag($set ? $flags : array(), $set ? array() : $flags); }
/** * Builds and sends a MIME message. * * @param string $body The message body. * @param array $header List of message headers. * @param IMP_Prefs_Identity $identity The Identity object for the sender * of this message. * @param array $opts An array of options w/the * following keys: * - encrypt: (integer) A flag whether to encrypt or sign the message. * One of: * - IMP_Pgp::ENCRYPT</li> * - IMP_Pgp::SIGNENC</li> * - IMP_Smime::ENCRYPT</li> * - IMP_Smime::SIGNENC</li> * - html: (boolean) Whether this is an HTML message. * DEFAULT: false * - pgp_attach_pubkey: (boolean) Attach the user's PGP public key to the * message? * - priority: (string) The message priority ('high', 'normal', 'low'). * - save_sent: (boolean) Save sent mail? * - sent_mail: (IMP_Mailbox) The sent-mail mailbox (UTF-8). * - strip_attachments: (bool) Strip attachments from the message? * - signature: (string) The message signature. * - readreceipt: (boolean) Add return receipt headers? * - useragent: (string) The User-Agent string to use. * - vcard_attach: (string) Attach the user's vCard (value is name to * display as vcard filename). * * @throws Horde_Exception * @throws IMP_Compose_Exception * @throws IMP_Compose_Exception_Address * @throws IMP_Exception */ public function buildAndSendMessage($body, $header, IMP_Prefs_Identity $identity, array $opts = array()) { global $injector, $prefs, $registry, $session; /* Set up defaults. */ $opts = array_merge(array('encrypt' => IMP::ENCRYPT_NONE), $opts); /* Check body size of message. */ $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create(); if (!$imp_imap->accessCompose(IMP_Imap::ACCESS_COMPOSE_BODYSIZE, strlen($body))) { Horde::permissionDeniedError('imp', 'max_bodysize'); throw new IMP_Compose_Exception(sprintf(_("Your message body has exceeded the limit by body size by %d characters."), strlen($body) - $imp_imap->max_compose_bodysize)); } /* We need at least one recipient. */ $recip = $this->recipientList($header); if (!count($recip['list'])) { if ($recip['has_input']) { throw new IMP_Compose_Exception(_("Invalid e-mail address.")); } throw new IMP_Compose_Exception(_("Need at least one message recipient.")); } /* Recipient checks. */ $this->_prepSendMessageAssert($recip['list']); /* Check for correct identity usage. */ if (!$this->getMetadata('identity_check') && count($recip['list']) === 1) { $identity_search = $identity->getMatchingIdentity($recip['list'], false); if (!is_null($identity_search) && $identity->getDefault() != $identity_search) { $this->_setMetadata('identity_check', true); $e = new IMP_Compose_Exception(_("Recipient address does not match the currently selected identity.")); $e->tied_identity = $identity_search; throw $e; } } /* Initalize a header object for the outgoing message. */ $headers = $this->_prepareHeaders($header, $opts); /* Add a Received header for the hop from browser to server. */ $headers->addHeaderOb(Horde_Core_Mime_Headers_Received::createHordeHop()); /* Add the 'User-Agent' header. */ $headers->addHeaderOb(new Horde_Mime_Headers_UserAgent(null, empty($opts['useragent']) ? 'Internet Messaging Program (IMP) ' . $registry->getVersion() : $opts['useragent'])); /* Add preferred reply language(s). */ if ($lang = @unserialize($prefs->getValue('reply_lang'))) { $headers->addHeader('Accept-Language', implode(',', $lang)); } $message = $this->_createMimeMessage($body, array('html' => !empty($opts['html']), 'identity' => $identity, 'pgp_attach_pubkey' => !empty($opts['pgp_attach_pubkey']) && $prefs->getValue('use_pgp') && $prefs->getValue('pgp_public_key'), 'recip' => $recip['list'], 'signature' => is_null($opts['signature']) ? $identity : $opts['signature'], 'vcard_attach' => !empty($opts['vcard_attach']) && $registry->hasMethod('contacts/ownVCard') ? (strlen($opts['vcard_attach']) ? $opts['vcard_attach'] : 'vcard') . '.vcf' : null)); /* Pass to hook to allow alteration of message details. */ try { $injector->getInstance('Horde_Core_Hooks')->callHook('pre_sent', 'imp', array($message, $headers, $this)); /* Re-parse headers to determine up-to-date recipient list. */ $tmp_recip = array(); foreach (array('to', 'cc', 'bcc') as $val) { if ($tmp_hdr = $headers[$val]) { $tmp_recip[$val] = $tmp_hdr->getAddressList(true); } } $recip = $this->recipientList($tmp_recip); } catch (Horde_Exception_HookNotSet $e) { } /* Get from address. Done after pre_sent hook since from address could * be changed by hook. */ $from = $headers['from']->getAddressList(true)->first(); if (is_null($from->host)) { $from->host = $imp_imap->config->maildomain; } /* Add Reply-To header. Done after pre_sent hook since from address * could be change by hook and/or Reply-To was set by hook. */ if (!empty($header['replyto']) && $header['replyto'] != $from->bare_address && !isset($headers['reply-to'])) { $headers->addHeader('Reply-To', $header['replyto']); } $message = $this->_encryptMessage($message, $opts['encrypt'], $recip['list'], $from); /* Send the messages out now. */ try { $this->sendMessage($recip['list'], $headers, $message); /* Store history information. Even if history is inactive, this * will provide Message ID of message. */ $msgid = $this->_logSentmail($headers, $recip['list'], true); } catch (IMP_Compose_Exception_Address $e) { throw $e; } catch (IMP_Compose_Exception $e) { /* Unsuccessful send. */ if ($e->log()) { $this->_logSentmail($headers, $recip['list'], false); } throw new IMP_Compose_Exception(sprintf(_("There was an error sending your message: %s"), $e->getMessage())); } if ($this->_replytype) { /* Log the reply. */ if ($indices = $this->getMetadata('indices')) { $log_data = array('msgid' => $msgid); switch ($this->_replytype) { case self::FORWARD: case self::FORWARD_ATTACH: case self::FORWARD_BODY: case self::FORWARD_BOTH: $ob = 'IMP_Maillog_Log_Forward'; $log_data['recipients'] = strval($recip['list']); break; case self::REPLY: case self::REPLY_SENDER: $ob = 'IMP_Maillog_Log_Reply'; break; case IMP_Compose::REPLY_ALL: $ob = 'IMP_Maillog_Log_Replyall'; break; case IMP_Compose::REPLY_LIST: $ob = 'IMP_Maillog_Log_Replylist'; break; } $log = new $ob($log_data); $log_msgs = array(); foreach ($indices as $val) { foreach ($val->uids as $val2) { $log_msgs[] = new IMP_Maillog_Message(new IMP_Indices($val->mbox, $val2)); } } $injector->getInstance('IMP_Maillog')->log($log_msgs, $log); } $reply_uid = new IMP_Indices($this); switch ($this->replyType(true)) { case self::FORWARD: /* Set the Forwarded flag, if possible, in the mailbox. * See RFC 5550 [5.9] */ $reply_uid->flag(array(Horde_Imap_Client::FLAG_FORWARDED)); break; case self::REPLY: /* Make sure to set the IMAP reply flag and unset any * 'flagged' flag. */ $reply_uid->flag(array(Horde_Imap_Client::FLAG_ANSWERED), array(Horde_Imap_Client::FLAG_FLAGGED)); break; } } Horde::log(sprintf("Message sent to %s from %s (%s)", strval($recip['list']), $registry->getAuth(), $session->get('horde', 'auth/remoteAddr')), 'INFO'); /* Save message to the sent mail mailbox. */ $this->_saveToSentMail($headers, $message, $recip['list'], $opts); /* Delete the attachment data. */ $this->deleteAllAttachments(); /* Save recipients to address book? */ $this->_saveRecipients($recip['list']); /* Call post-sent hook. */ try { $injector->getInstance('Horde_Core_Hooks')->callHook('post_sent', 'imp', array($message, $headers)); } catch (Horde_Exception_HookNotSet $e) { } }
/** * Resumes a previously saved draft message. * * @param IMP_Indices $indices See resumeDraft(). * @param integer $type Compose type. * @param array $opts Additional options: * - format: (string) Force to this format. * DEFAULT: Auto-determine. * * @return mixed See resumeDraft(). * * @throws IMP_Compose_Exception */ protected function _resumeDraft($indices, $type, $opts) { global $injector, $notification, $prefs; $contents_factory = $injector->getInstance('IMP_Factory_Contents'); try { $contents = $contents_factory->create($indices); } catch (IMP_Exception $e) { throw new IMP_Compose_Exception($e); } $headers = $contents->getHeader(); $imp_draft = false; if ($draft_url = $headers->getValue('x-imp-draft-reply')) { if (is_null($type) && !($type = $headers->getValue('x-imp-draft-reply-type'))) { $type = self::REPLY; } $imp_draft = self::REPLY; } elseif ($draft_url = $headers->getValue('x-imp-draft-forward')) { $imp_draft = self::FORWARD; if (is_null($type)) { $type = self::FORWARD; } } elseif ($headers->getValue('x-imp-draft')) { $imp_draft = self::COMPOSE; } if (!empty($opts['format'])) { $compose_html = $opts['format'] == 'html'; } elseif ($prefs->getValue('compose_html')) { $compose_html = true; } else { switch ($type) { case self::EDITASNEW: case self::FORWARD: case self::FORWARD_BODY: case self::FORWARD_BOTH: $compose_html = $prefs->getValue('forward_format'); break; case self::REPLY: case self::REPLY_ALL: case self::REPLY_LIST: case self::REPLY_SENDER: $compose_html = $prefs->getValue('reply_format'); break; case self::TEMPLATE: $compose_html = true; break; default: /* If this is an draft saved by IMP, we know 100% for sure * that if an HTML part exists, the user was composing in * HTML. */ $compose_html = $imp_draft !== false; break; } } $msg_text = $this->_getMessageText($contents, array('html' => $compose_html, 'imp_msg' => $imp_draft, 'toflowed' => false)); if (empty($msg_text)) { $body = ''; $format = 'text'; $text_id = 0; } else { /* Use charset at time of initial composition if this is an IMP * draft. */ if ($imp_draft !== false) { $this->charset = $msg_text['charset']; } $body = $msg_text['text']; $format = $msg_text['mode']; $text_id = $msg_text['id']; } $mime_message = $contents->getMIMEMessage(); /* Add attachments. */ $parts = array(); if ($mime_message->getPrimaryType() == 'multipart' && $mime_message->getType() != 'multipart/alternative') { for ($i = 1;; ++$i) { if (intval($text_id) == $i) { continue; } if ($part = $contents->getMIMEPart($i)) { $parts[] = $part; } else { break; } } } elseif ($mime_message->getDisposition() == 'attachment') { $parts[] = $contents->getMimePart('1'); } foreach ($parts as $val) { try { $this->addAttachmentFromPart($val); } catch (IMP_Compose_Exception $e) { $notification->push($e, 'horde.warning'); } } $alist = new Horde_Mail_Rfc822_List(); $addr = array('to' => clone $alist, 'cc' => clone $alist, 'bcc' => clone $alist); if ($type != self::EDITASNEW) { foreach (array('to', 'cc', 'bcc') as $val) { if ($tmp = $headers->getOb($val)) { $addr[$val] = $tmp; } } if ($val = $headers->getValue('references')) { $ref_ob = new Horde_Mail_Rfc822_Identification($val); $this->_setMetadata('references', $ref_ob->ids); if ($val = $headers->getValue('in-reply-to')) { $this->_setMetadata('in_reply_to', $val); } } if ($draft_url) { $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create(); $indices = new IMP_Indices(); foreach (explode(',', $draft_url) as $val) { $imap_url = new Horde_Imap_Client_Url(rtrim(ltrim($val, '<'), '>')); try { if ($imap_url->protocol == ($imp_imap->isImap() ? 'imap' : 'pop') && $imap_url->username == $imp_imap->getParam('username') && IMP_Mailbox::get($imap_url->mailbox)->uidvalid == $imap_url->uidvalidity && $contents_factory->create(new IMP_Indices($imap_url->mailbox, $imap_url->uid))) { $indices->add($imap_url->mailbox, $imap_url->uid); } } catch (Exception $e) { } } if (count($indices)) { $this->_setMetadata('indices', $indices); $this->_replytype = $type; } } } $mdn = new Horde_Mime_Mdn($headers); $readreceipt = (bool) $mdn->getMdnReturnAddr(); $this->changed = 'changed'; return array('addr' => $addr, 'body' => $body, 'format' => $format, 'identity' => $this->_getMatchingIdentity($headers, array('from')), 'priority' => $injector->getInstance('IMP_Mime_Headers')->getPriority($headers), 'readreceipt' => $readreceipt, 'subject' => $headers->getValue('subject'), 'type' => $type); }
/** * Create the object used to display the message. * * @param array $args Configuration parameters: * - headers: (array) The headers desired in the returned headers array * (only used with non-preview view). * - preview: (boolean) Is this the preview view? * * @return array Array with the following keys: * - atc_download: The download all link * - atc_label: The label to use for Attachments * - atc_list: The list (HTML code) of attachments * - bcc (FULL): The Bcc addresses * - cc: The CC addresses * - fulldate (FULL): The full canonical date. * - from: The From addresses * - headers (FULL): An array of headers (not including basic headers) * - js: Javascript code to run on display * - list_info (FULL): List information. * - localdate (PREVIEW): The date formatted to the user's timezone * - md: Metadata * - msgtext: The text of the message * - onepart: True if message only contains one part. * - replyTo (FULL): The Reply-to addresses * - save_as: The save link * - subject: The subject * - subjectlink: The subject with linked URLs/email addresses (defaults * to 'subject') * - title (FULL): The title of the page * - to: The To addresses * * @throws IMP_Exception */ public function showMessage($args) { global $injector, $page_output, $prefs, $registry, $session; $preview = !empty($args['preview']); $result = array(); $mime_headers = $this->_peek ? $this->_contents->getHeader() : $this->_contents->getHeaderAndMarkAsSeen(); $headers = array(); $imp_ui = $injector->getInstance('IMP_Message_Ui'); /* Develop the list of Headers to display now. Deal with the 'basic' * header information first since there are various manipulations * done to them. */ $basic_headers = $imp_ui->basicHeaders(); if (empty($args['headers'])) { $args['headers'] = array('from', 'date', 'to', 'cc', 'bcc'); } $headers_list = array_intersect_key($basic_headers, array_flip($args['headers'])); /* Build From/To/Cc/Bcc/Reply-To links. */ foreach (array('from', 'to', 'cc', 'bcc', 'reply-to') as $val) { if (isset($headers_list[$val]) && (!$preview || $val != 'reply-to')) { if ($tmp = $this->getAddressHeader($val)) { $result[$val] = $tmp; } if ($preview) { unset($headers_list[$val]); } } } /* Build the rest of the headers. */ foreach ($headers_list as $head => $str) { if ($val = $mime_headers->getValue($head)) { if ($head == 'date') { /* Add local time to date header. */ $date_ob = new IMP_Message_Date($this->_envelope->date); $val = htmlspecialchars($date_ob->format($date_ob::DATE_LOCAL)); if ($preview) { $result['localdate'] = $val; } else { $result['fulldate'] = $date_ob->format($date_ob::DATE_FORCE); } } elseif (!$preview) { $val = htmlspecialchars($val); } if (!$preview) { $headers[$head] = array('id' => Horde_String::ucfirst($head), 'name' => $str, 'value' => $val); } } } if (empty($result['reply-to']) || $result['from']['addr'][0]->b == $result['reply-to']['addr'][0]->b) { unset($result['reply-to'], $headers['reply-to']); } /* JS requires camelized name for reply-to. */ if (!$preview && isset($headers['reply-to'])) { $result['replyTo'] = $result['reply-to']; $headers['reply-to']['id'] = 'ReplyTo'; unset($result['reply-to']); } /* Maillog information. */ $ajax_queue = $injector->getInstance('IMP_Ajax_Queue'); $ajax_queue->maillog($this->_indices); if (!$preview) { /* Display the user-specified headers for the current identity. */ $user_hdrs = $imp_ui->getUserHeaders(); foreach ($user_hdrs as $user_hdr) { $user_val = $mime_headers->getValue($user_hdr); if (!empty($user_val)) { if (!is_array($user_val)) { $user_val = array($user_val); } foreach ($user_val as $val) { $headers[] = array('name' => $user_hdr, 'value' => htmlspecialchars($val)); } } } $result['headers'] = array_values($headers); } /* Process the subject. */ $subject = $mime_headers->getValue('subject'); if ($subject) { $text_filter = $injector->getInstance('Horde_Core_Factory_TextFilter'); $filtered_subject = preg_replace("/\\b\\s+\\b/", ' ', IMP::filterText($subject)); $result['subject'] = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML)); $subjectlink = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); if ($subjectlink != $result['subject']) { $result['subjectlink'] = $subjectlink; } if (!$preview) { $result['title'] = $subject; } } else { $result['subject'] = _("[No Subject]"); if (!$preview) { $result['title'] = _("[No Subject]"); } } // Create message text and attachment list. $result['msgtext'] = ''; $show_parts = $prefs->getValue('parts_display'); switch ($registry->getView()) { case $registry::VIEW_SMARTMOBILE: $contents_mask = 0; break; default: $contents_mask = IMP_Contents::SUMMARY_BYTES | IMP_Contents::SUMMARY_SIZE | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_DESCRIP_LINK | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_DOWNLOAD_ZIP | IMP_Contents::SUMMARY_PRINT_STUB; break; } $part_info = $part_info_display = array('icon', 'description', 'size', 'download', 'download_zip'); $part_info_display[] = 'print'; list($mbox, $uid) = $this->_indices->getSingle(); /* Do MDN processing now. */ switch ($registry->getView()) { case $registry::VIEW_DYNAMIC: if ($imp_ui->MDNCheck(new IMP_Indices($mbox, $uid), $mime_headers)) { $status = new IMP_Mime_Status(array(_("The sender of this message is requesting notification from you when you have read this message."), sprintf(_("Click %s to send the notification message."), Horde::link('#', '', '', '', '', '', '', array('id' => 'send_mdn_link')) . _("HERE") . '</a>'))); $status->domid('sendMdnMessage'); $result['msgtext'] .= strval($status); } } /* Build body text. This needs to be done before we build the * attachment list. */ $session->close(); $inlineout = $this->_contents->getInlineOutput(array('mask' => $contents_mask, 'part_info_display' => $part_info_display, 'show_parts' => $show_parts)); $session->start(); $result['md'] = $inlineout['metadata']; $result['msgtext'] .= $inlineout['msgtext']; if ($inlineout['one_part']) { $result['onepart'] = true; } if (count($inlineout['atc_parts']) || $show_parts == 'all' && count($inlineout['display_ids']) > 2) { $result['atc_label'] = $show_parts == 'all' ? _("Parts") : sprintf(ngettext("%d Attachment", "%d Attachments", count($inlineout['atc_parts'])), count($inlineout['atc_parts'])); if (count($inlineout['atc_parts']) > 2) { $result['atc_download'] = Horde::link($this->_contents->urlView($this->_contents->getMIMEMessage(), 'download_all')) . '[' . _("Save All") . ']</a>'; } } /* Show attachment information in headers? */ if (!empty($inlineout['atc_parts'])) { $partlist = array(); if ($show_parts == 'all') { array_unshift($part_info, 'id'); } foreach ($inlineout['atc_parts'] as $id) { $contents_mask |= IMP_Contents::SUMMARY_DESCRIP | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_SIZE; $part_info[] = 'description_raw'; $part_info[] = 'download_url'; $summary = $this->_contents->getSummary($id, $contents_mask); $tmp = array(); foreach ($part_info as $val) { if (isset($summary[$val])) { $tmp[$val] = $summary[$val] instanceof Horde_Url ? strval($summary[$val]->setRaw(true)) : $summary[$val]; } } $partlist[] = array_filter($tmp); } $result['atc_list'] = $partlist; } $result['save_as'] = IMP_Contents_View::downloadUrl(htmlspecialchars_decode($result['subject']), array_merge(array('actionID' => 'save_message'), $mbox->urlParams($uid))); if ($preview) { /* Need to grab cached inline scripts. */ Horde::startBuffer(); $page_output->outputInlineScript(true); if ($js_inline = Horde::endBuffer()) { $result['js'] = array($js_inline); } $result['save_as'] = strval($result['save_as']->setRaw(true)); } else { $list_info = $imp_ui->getListInformation($mime_headers); if (!empty($list_info['exists'])) { $result['list_info'] = $list_info; } } /* Add changed flag information. */ if (!$this->_peek && $mbox->is_imap) { $status = $mbox->imp_imap->status($mbox, Horde_Imap_Client::STATUS_PERMFLAGS); if (in_array(Horde_Imap_Client::FLAG_SEEN, $status['permflags'])) { $ajax_queue->flag(array(Horde_Imap_Client::FLAG_SEEN), true, $this->_indices); } } return array_filter($result); }
/** * Returns a list of messages for use with ViewPort. * * @var array $args TODO * - applyfilter: (boolean) If true, apply filters to mailbox. * - change: (boolean) True if the cache value has changed. * - initial: (boolean) Is this the initial load of the view? * - mbox: (string) The mailbox of the view. * - qsearch: (string) The quicksearch search string. * - qsearchfield: (string) The quicksearch search criteria. * - qsearchmbox: (string) The mailbox to do the quicksearch in * (base64url encoded). * - qsearchfilter: TODO * * @return IMP_Ajax_Application_Viewport Viewport data object. */ public function listMessages($args) { global $injector, $notification, $prefs; $is_search = false; $mbox = IMP_Mailbox::get($args['mbox']); $sortpref = $mbox->getSort(true); /* Create the base object. */ $result = new IMP_Ajax_Application_Viewport($mbox); /* Check for quicksearch request. */ if (strlen($args['qsearchmbox'])) { $qsearch_mbox = IMP_Mailbox::formFrom($args['qsearchmbox']); /* Sanity checking: qsearchmbox cannot be a search mailbox * itself. */ if ($qsearch_mbox->search) { $notification->push(_("Error in displaying search results."), 'horde.error'); return $result; } if (strlen($args['qsearchfilter'])) { $injector->getInstance('IMP_Search')->applyFilter($args['qsearchfilter'], array($qsearch_mbox), $mbox); $is_search = true; } else { /* Create the search query. */ $c_list = array(); if (strlen($args['qsearchflag'])) { $c_list[] = new IMP_Search_Element_Flag($args['qsearchflag'], empty($args['qsearchflagnot'])); $is_search = true; } elseif (strlen($args['qsearch'])) { $is_search = true; switch ($args['qsearchfield']) { case 'all': case 'body': $c_list[] = new IMP_Search_Element_Text($args['qsearch'], $args['qsearchfield'] == 'body'); break; case 'from': case 'subject': $c_list[] = new IMP_Search_Element_Header($args['qsearch'], $args['qsearchfield']); break; case 'recip': $c_list[] = new IMP_Search_Element_Recipient($args['qsearch']); break; default: $is_search = false; break; } } /* Store the search in the session. */ if ($is_search) { $injector->getInstance('IMP_Search')->createQuery($c_list, array('id' => $mbox, 'mboxes' => array($qsearch_mbox), 'type' => IMP_Search::CREATE_QUERY)); } } } else { $is_search = $mbox->search; } /* Run filters now. */ if (!empty($args['applyfilter'])) { $mbox->filter(); } elseif ($mbox->inbox) { $mbox->filterOnDisplay(); } $result->label = $mbox->label; /* Optimization: saves at least a STATUS and an EXAMINE call since * we will eventually open mailbox READ-WRITE. */ $imp_imap = $mbox->imp_imap; $imp_imap->openMailbox($mbox, Horde_Imap_Client::OPEN_READWRITE); if ($is_search) { /* For search mailboxes, we need to invalidate all browser data * and repopulate on force update, since BUIDs may have * changed (TODO: only do this if search mailbox has changed?). */ if (!empty($args['change'])) { $args['cache'] = array(); $args['change'] = true; $result->data_reset = $result->rowlist_reset = true; } } elseif (!$args['initial'] && $args['cacheid'] && $args['cache']) { /* Check for UIDVALIDITY expiration. If it has changed, we need to * purge the cached items on the browser. */ $parsed = $imp_imap->parseCacheId($args['cacheid']); $uid_expire = true; if ($parsed['date'] == date('z')) { try { $imp_imap->sync($mbox, $parsed['token'], array('criteria' => Horde_Imap_Client::SYNC_UIDVALIDITY)); $uid_expire = false; } catch (Horde_Imap_Client_Exception_Sync $e) { } } if ($uid_expire) { $args['cache'] = array(); $args['initial'] = true; $result->data_reset = $result->metadata_reset = true; } } else { $parsed = null; } /* Mail-specific viewport information. */ if ($args['initial'] || isset($args['delhide']) && !is_null($args['delhide']) || !is_null($args['sortby'])) { $result->setMetadata('delhide', $mbox->hideDeletedMsgs(true)); } if ($args['initial'] || !is_null($args['sortby']) || !is_null($args['sortdir'])) { $result->setMetadata('sortby', $sortpref->sortby); $result->setMetadata('sortdir', $sortpref->sortdir); } /* Actions only done on 'initial' request. */ if ($args['initial']) { /* Load quota information on original request. */ $injector->getInstance('IMP_Ajax_Queue')->quota($mbox, true); if (!$mbox->is_imap) { $result->setMetadata('nodeleteshow', 1); $result->setMetadata('noundelete', 1); $result->setMetadata('pop3', 1); } if ($sortpref->sortby_locked) { $result->setMetadata('sortbylock', 1); } if ($sortpref->sortdir_locked) { $result->setMetadata('sortdirlock', 1); } if (!$mbox->access_sortthread) { $result->setMetadata('nothread', 1); } if ($mbox->special_outgoing) { $result->setMetadata('special', 1); if ($mbox->drafts) { $result->setMetadata('drafts', 1); } elseif ($mbox->templates) { $result->setMetadata('templates', 1); } } elseif ($mbox->spam) { $result->setMetadata('innocent_show', 1); if ($mbox->spam_show) { $result->setMetadata('spam_show', 1); } } else { if ($mbox->innocent_show) { $result->setMetadata('innocent_show', 1); } $result->setMetadata('spam_show', 1); } if ($is_search) { $result->setMetadata('innocent_show', 1); $result->setMetadata('search', 1); $result->setMetadata('spam_show', 1); } if ($prefs->getValue('use_trash')) { $result->setMetadata('nodeleteshow', 1); if (!$mbox->vtrash) { $result->setMetadata('noundelete', 1); } } $result->addFlagMetadata(); } /* The search query may have changed. */ if ($is_search && ($args['initial'] || strlen($args['qsearchmbox']))) { $imp_search = $injector->getInstance('IMP_Search'); if ($mbox->vfolder) { $result->setMetadata('slabel', $imp_search[$mbox]->label); $result->setMetadata('vfolder', 1); if (!$imp_search->isVFolder($mbox, true)) { $result->setMetadata('noedit', 1); } } else { $result->setMetadata('slabel', $imp_search[$mbox]->querytext); } } /* These entries may change during a session, so always need to * update them. */ if ($mbox->readonly) { $result->setMetadata('readonly', 1); $result->setMetadata('nodelete', 1); $result->setMetadata('nodeleteshow', 1); $result->setMetadata('noundelete', 1); } else { if (!$mbox->access_deletemsgs) { $result->setMetadata('nodelete', 1); } if (!$mbox->access_expunge) { $result->setMetadata('noexpunge', 1); } } /* Generate the sorted mailbox list now. */ $mailbox_list = $mbox->list_ob; if ($is_search && (!empty($args['change']) || $args['initial'])) { $mailbox_list->rebuild(true); } $msgcount = count($mailbox_list); /* Check for mailbox existence now. If there are no messages, there * is a chance that the mailbox doesn't exist. If there is at least * 1 message, we don't need this check. */ if (empty($msgcount) && !$is_search) { if (!$mbox->exists) { $notification->push(sprintf(_("Mailbox %s does not exist."), $mbox->label), 'horde.error'); $result = new IMP_Ajax_Application_Viewport_Error($mbox); } if (!empty($args['change'])) { $result->data_reset = true; $result->rowlist_reset = true; } return $result; } $result->totalrows = $msgcount; /* TODO: This can potentially be optimized for arrival time sort - if * the cache ID changes, we know the changes must occur at end of * mailbox. */ if (!$result->data_reset && !empty($args['change'])) { $result->rowlist_reset = true; } /* Get the cached list. */ if (empty($args['cache'])) { $cached = array(); } else { $cache_indices = new IMP_Indices($mbox, $args['cache']); $cache_uids = $cache_indices->getSingle(true); $cached = array_flip($cache_uids[1]); } if (!$is_search && !empty($args['search_unseen'])) { /* Do an unseen search. We know what messages the browser * doesn't have based on $cached. Thus, search for the first * unseen message not located in $cached. */ $unseen_search = $mailbox_list->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_MATCH, array('uids' => true)); if (!($uid_search = array_diff($unseen_search['match']->ids, array_keys($cached)))) { return $result; } $rownum = $mailbox_list->getArrayIndex(reset($uid_search)); } elseif (!empty($args['search_buid'])) { $search_buid = $mailbox_list->resolveBuid($args['search_buid']); $rownum = $mailbox_list->getArrayIndex($search_buid['u'], $search_buid['m']); } /* If this is the initial request for a mailbox, figure out the * starting location based on user's preferences. */ $rownum = $args['initial'] && !isset($rownum) || isset($rownum) && is_null($rownum) ? intval($mailbox_list->mailboxStart($msgcount)) : (isset($rownum) ? $rownum + 1 : null); /* Determine the row slice to process. */ if (is_null($rownum) || isset($args['slice_start'])) { $slice_start = $args['slice_start']; $slice_end = $args['slice_end']; } else { $slice_start = $rownum - $args['before']; $slice_end = $rownum + $args['after']; if ($slice_start < 1) { $slice_end += abs($slice_start) + 1; } elseif ($slice_end > $msgcount) { $slice_start -= $slice_end - $msgcount; } } if (!is_null($rownum)) { $result->rownum = $rownum; } $slice_start = max(1, $slice_start); $slice_end = min($msgcount, $slice_end); /* Generate BUID list. */ $buidlist = $changed = $data = $msglist = $rowlist = array(); foreach ($mailbox_list as $val) { $buidlist[] = $mailbox_list->getBuid($val['m'], $val['u']); } /* If we are updating the rowlist on the browser, and we have cached * browser data information, we need to send a list of messages that * have 'disappeared'. */ if (!empty($cached) && $result->rowlist_reset) { $disappear = array(); foreach (array_diff(array_keys($cached), $buidlist) as $uid) { $disappear[] = $uid; unset($cached[$uid]); } if (!empty($disappear)) { $result->disappear = $disappear; } } /* Check for cached entries marked as changed. If changed, resend the * entire entry to update the browser cache (done below). */ if (!empty($cached) && !$is_search && !is_null($parsed)) { $sync_ob = $imp_imap->sync($mbox, $parsed['token'], array('criteria' => Horde_Imap_Client::SYNC_FLAGSUIDS, 'ids' => $imp_imap->getIdsOb(array_keys($cached)))); $changed = array_flip($sync_ob->flagsuids->ids); } foreach (array_slice($buidlist, $slice_start - 1, $slice_end - $slice_start + 1, true) as $key => $uid) { $seq = ++$key; $msglist[$seq] = $mailbox_list[$seq]['u']; $rowlist[$uid] = $seq; /* Send browser message data if not already cached or if CONDSTORE * has indicated that data has changed. */ if (!isset($cached[$uid]) || isset($changed[$uid])) { $data[$seq] = 1; } } /* Build the list for rangeslice information. */ if ($args['rangeslice']) { $slice = new IMP_Ajax_Application_Viewport($mbox); $slice->rangelist = array_keys($rowlist); return $slice; } $result->rowlist = $rowlist; /* Build the overview list. */ $result->data = $this->_getOverviewData($mbox, array_keys($data)); /* Get thread information. */ if ($sortpref->sortby == Horde_Imap_Client::SORT_THREAD) { $thread = new stdClass(); foreach ($msglist as $key => $val) { $tmp = $mailbox_list->getThreadOb($key); $thread->{$val} = $sortpref->sortdir ? $tmp->reverse_raw : $tmp->raw; } $result->setMetadata('thread', $thread); } return $result; }
/** * 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; }
/** * Check if we need to send a MDN, and send if needed/able. Will only send * MDN if the request does NOT need to be confirmed by the user. * * @param Horde_Mime_Headers $headers The headers of the message. * * @return boolean True if the MDN request was able to be sent. */ public function mdnSend(Horde_Mime_Headers $headers, $mailbox, $uid) { $indices = new IMP_Indices($mailbox, $uid); return !$indices->mdnCheck($headers); }