Author: Michael Slusarz (slusarz@horde.org)
Inheritance: implements ArrayAccess, implements Countable, implements Iterator
Example #1
0
 /**
  */
 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;
 }
Example #2
0
 /**
  * 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');
     }
 }
Example #3
0
 /**
  * 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;
 }
Example #4
0
File: Copy.php Project: horde/horde
 /**
  * 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;
 }
Example #5
0
 /**
  * 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');
     }
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * 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;
 }
Example #8
0
 /**
  * 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()));
 }
Example #9
0
 /**
  * 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)));
 }
Example #10
0
 /**
  * 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);
 }
Example #11
0
 /**
  * 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) {
     }
 }
Example #12
0
 /**
  * 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);
 }
Example #13
0
 /**
  * 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);
 }
Example #14
0
 /**
  * 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;
 }
Example #15
0
 /**
  * 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;
 }
Example #16
0
File: Api.php Project: horde/horde
 /**
  * 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);
 }