Allows translation between abstracted search criteria and a generated IMAP
search criteria string suitable for sending to a remote IMAP server.
/** * Query the validity of a charset. * * @param string $charset The charset to query. * @param boolean $cached If true, only query cached values. * * @return boolean True if the charset is valid for searching. */ public function query($charset, $cached = false) { $charset = Horde_String::upper($charset); if (isset($this->_charsets[$charset])) { return $this->_charsets[$charset]; } elseif ($cached) { return null; } if (!$this->_baseob) { throw new RuntimeException('Base object needs to be defined to query for charset.'); } /* Use a dummy search query and search for BADCHARSET response. */ $query = new Horde_Imap_Client_Search_Query(); $query->charset($charset, false); $query->ids($this->_baseob->getIdsOb(1, true)); $query->text('a'); try { $this->_baseob->search('INBOX', $query, array('nocache' => true, 'sequence' => true)); $this->_charsets[$charset] = true; } catch (Horde_Imap_Client_Exception $e) { $this->_charsets[$charset] = $e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET; } $this->notify(); return $this->_charsets[$charset]; }
public function getLatestMails($o) { $aResults = array(); $aRes = $this->imapProxy->getMMGMaxInFolder($this->imapProxy->currentFolder64, $this->imapProxy->currentFolderStatus['uidvalidity']); $sMinDate = $aRes[0]['max_date'] == '' ? '1980-01-01' : $aRes[0]['max_date']; //$iMinId = max(1,O + $aRes[0]['max_id']); $oUnseenQuery = new Horde_Imap_Client_Search_Query(array('peek' => true)); $oUnseenQuery->flag('SEEN', false); $oUnseenQuery->dateSearch($sMinDate, Horde_Imap_Client_Search_Query::DATE_SINCE); $results = $this->imapProxy->search($oUnseenQuery); $aAllIDs = $results['match']->ids; if (count($aAllIDs)) { $aChunksID = array_chunk($aAllIDs, 30); foreach ($aChunksID as $aMsg) { $oMMG = new MMG_MAIL_MESSAGE(); $aMMG = $oMMG->get(array('cols' => array('group_concat(MMG_UID order by MMG_UID) as UIDS'), 'where' => array('MMG_FOLDER' => $this->imapProxy->currentFolder64, 'MMG_FOLDER_UUID' => $this->imapProxy->currentFolderStatus['uidvalidity'], 'MMG_UID' => array('IN', $aMsg)))); $aMMGId = explode(',', $aMMG[0]['uids']); $aMsgToDo = array_diff($aMsg, $aMMGId); $aTmp = $this->imapProxy->fetch_overviewWithCache($aMsgToDo, array('account' => $o['account'], 'folder' => $this->imapProxy->currentFolder64)); foreach ($aTmp as $aHeader) { $from = $aHeader->from[0]->name ? $aHeader->from[0]->name : $aHeader->from[0]->email; if (!array_key_exists($from, $aResults)) { $aResults[$from] = array(); } $aResults[$from][] = $aHeader->subject; } } if (count($aResults) > 0) { $this->stomp->send("/topic/imapNotifierOnMessage/" . $o['account'], json_encode(array('newEmails' => $aResults))); } } }
/** * Purge old messages in the sent-mail mailbox. * * @return boolean Whether any messages were purged from the mailbox. */ public function execute() { global $prefs, $notification; /* Get the current UNIX timestamp minus the number of days specified * in 'purge_sentmail_keep'. If a message has a timestamp prior to * this value, it will be deleted. */ $del_time = new Horde_Date(time() - $prefs->getValue('purge_sentmail_keep') * 86400); foreach ($this->_getMboxes() as $mbox) { /* Open the sent-mail mailbox and get the list of messages older * than 'purge_sentmail_keep' days. */ $query = new Horde_Imap_Client_Search_Query(); $query->dateSearch($del_time, Horde_Imap_Client_Search_Query::DATE_BEFORE); $msg_ids = $mbox->runSearchQuery($query); /* Go through the message list and delete the messages. */ if ($msg_ids->delete(array('nuke' => true))) { $msgcount = count($msg_ids); if ($msgcount == 1) { $notification->push(sprintf(_("Purging 1 message from sent-mail mailbox %s."), $mbox->display), 'horde.message'); } else { $notification->push(sprintf(_("Purging %d messages from sent-mail mailbox."), $msgcount, $mbox->display), 'horde.message'); } } } return true; }
/** */ public function createQuery($mbox, $queryob) { $ajax = new IMP_Ajax_Imple_ContactAutoCompleter(); foreach ($ajax->getAddressList()->bare_addresses as $val) { $ob = new Horde_Imap_Client_Search_Query(); $ob->headerText('from', $val, $this->_data); $queryob->orSearch($ob); } return $queryob; }
/** */ public function createQuery($mbox, $queryob) { global $injector; $contacts = $injector->getInstance('IMP_Contacts'); foreach ($contacts as $val) { if ($val instanceof Horde_Mail_Rfc822_Address) { $ob = new Horde_Imap_Client_Search_Query(); $ob->headerText('from', $val->bare_address, $this->_data); $queryob->orSearch($ob); } } return $queryob; }
/** */ public function createQuery($mbox, $queryob) { $ob = new Horde_Imap_Client_Search_Query(); $ob2 = clone $ob; $ob3 = clone $ob; $ob->headerText('content-type', 'multipart/mixed', $this->_data); $ob2->headerText('content-type', 'message/rfc822', $this->_data); /* If regular search, searches are OR'd: only one must match. * If NOT search, searches are AND'd: both must not match. */ if ($this->_data) { $ob3->andSearch(array($ob, $ob2)); } else { $ob3->orSearch(array($ob, $ob2)); } /* ...but the combined search must be AND'd with the rest of the * search terms. */ $queryob->andSearch($ob3); return $queryob; }
/** * Purge old messages in the Trash mailbox. * * @return boolean Whether any messages were purged from the mailbox. */ public function execute() { global $injector, $notification, $prefs; /* Get the current UNIX timestamp minus the number of days specified in 'purge_trash_keep'. If a message has a timestamp prior to this value, it will be deleted. */ $del_time = new Horde_Date(time() - $prefs->getValue('purge_trash_keep') * 86400); /* Get the list of messages older than 'purge_trash_keep' days. */ $query = new Horde_Imap_Client_Search_Query(); $query->dateSearch($del_time, Horde_Imap_Client_Search_Query::DATE_BEFORE); $msg_ids = IMP_Mailbox::getPref(IMP_Mailbox::MBOX_TRASH)->runSearchQuery($query); /* Go through the message list and delete the messages. */ if (!$injector->getInstance('IMP_Message')->delete($msg_ids, array('nuke' => true))) { return false; } $msgcount = count($msg_ids); $notification->push(sprintf(ngettext("Purging %d message from Trash mailbox.", "Purging %d messages from Trash mailbox.", $msgcount), $msgcount), 'horde.message'); return true; }
/** * If this MIME part can contain embedded MIME part(s), and those part(s) * exist, return a representation of that data. * * @return mixed A Horde_Mime_Part object representing the embedded data. * Returns null if no embedded MIME part(s) exist. */ protected function _getEmbeddedMimeParts() { $id = $this->_mimepart->getContentTypeParameter('id'); $number = $this->_mimepart->getContentTypeParameter('number'); $total = $this->_mimepart->getContentTypeParameter('total'); if (is_null($id) || is_null($number) || is_null($total)) { return null; } /* Perform the search to find the other parts of the message. */ $query = new Horde_Imap_Client_Search_Query(); $query->headerText('Content-Type', $id); $indices = $this->getConfigParam('imp_contents')->getMailbox()->runSearchQuery($query); /* If not able to find the other parts of the message, prepare a * status message. */ $msg_count = count($indices); if ($msg_count != $total) { $status = new IMP_Mime_Status($this->_mimepart, sprintf(_("Cannot display message - found only %s of %s parts of this message in the current mailbox."), $msg_count, $total)); $status->action(IMP_Mime_Status::ERROR); $cache = $this->getConfigParam('imp_contents')->getViewCache(); $cache->partial[$this->_mimepart->getMimeId()] = $status; return null; } /* Get the contents of each of the parts. */ $parts = array(); foreach ($indices as $ob) { foreach ($ob->uids as $val) { /* No need to fetch the current part again. */ if ($val == $number) { $parts[$number] = $this->_mimepart->getContents(); } else { $ic = $GLOBALS['injector']->getInstance('IMP_Factory_Contents')->create($ob->mbox->getIndicesOb($val)); $parts[$ic->getMIMEMessage()->getContentTypeParameter('number')] = $ic->getBody(); } } } /* Sort the parts in numerical order. */ ksort($parts, SORT_NUMERIC); /* Combine the parts. */ $mime_part = Horde_Mime_Part::parseMessage(implode('', $parts), array('forcemime' => true)); return $mime_part === false ? null : $mime_part; }
/** * Purge old messages in the Spam mailbox. * * @return boolean Whether any messages were purged from the mailbox. */ public function execute() { if (!($spam = $this->_spamMbox())) { return false; } /* Get the current UNIX timestamp minus the number of days specified in 'purge_spam_keep'. If a message has a timestamp prior to this value, it will be deleted. */ $del_time = new Horde_Date(time() - $GLOBALS['prefs']->getValue('purge_spam_keep') * 86400); /* Get the list of messages older than 'purge_spam_keep' days. */ $query = new Horde_Imap_Client_Search_Query(); $query->dateSearch($del_time, Horde_Imap_Client_Search_Query::DATE_BEFORE); $msg_ids = $spam->runSearchQuery($query); /* Go through the message list and delete the messages. */ if ($GLOBALS['injector']->getInstance('IMP_Message')->delete($msg_ids, array('nuke' => true))) { $msgcount = count($msg_ids); $GLOBALS['notification']->push(sprintf(ngettext("Purging %d message from Spam mailbox.", "Purging %d messages from Spam mailbox.", $msgcount), $msgcount), 'horde.message'); return true; } return false; }
/** */ protected function _content() { $inbox = IMP_Mailbox::get('INBOX'); /* Filter on INBOX display, if requested. */ $inbox->filterOnDisplay(); $query = new Horde_Imap_Client_Search_Query(); $query->flag(Horde_Imap_Client::FLAG_SEEN, false); $ids = $inbox->runSearchQuery($query, Horde_Imap_Client::SORT_SEQUENCE, 1); $indices = $ids['INBOX']; $html = '<table cellspacing="0" width="100%">'; $text = _("Go to your Inbox..."); if (empty($indices)) { $html .= '<tr><td><em>' . _("No unread messages") . '</em></td></tr>'; } else { $imp_ui = new IMP_Mailbox_Ui($inbox); $shown = empty($this->_params['msgs_shown']) ? 3 : $this->_params['msgs_shown']; $query = new Horde_Imap_Client_Fetch_Query(); $query->envelope(); try { $imp_imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create($inbox); $fetch_ret = $imp_imap->fetch($inbox, $query, array('ids' => $imp_imap->getIdsOb(array_slice($indices, 0, $shown)))); } catch (IMP_Imap_Exception $e) { $fetch_ret = new Horde_Imap_Client_Fetch_Results(); } foreach ($fetch_ret as $uid => $ob) { $envelope = $ob->getEnvelope(); $date = $imp_ui->getDate(isset($envelope->date) ? $envelope->date : null); $from = $imp_ui->getFrom($envelope); $subject = $imp_ui->getSubject($envelope->subject, true); $html .= '<tr style="cursor:pointer" class="text"><td>' . $inbox->url('message', $uid)->link() . '<strong>' . htmlspecialchars($from['from'], ENT_QUOTES, 'UTF-8') . '</strong><br />' . $subject . '</a></td>' . '<td>' . htmlspecialchars($date, ENT_QUOTES, 'UTF-8') . '</td></tr>'; } $more_msgs = count($indices) - $shown; if ($more_msgs > 0) { $text = sprintf(ngettext("%d more unseen message...", "%d more unseen messages...", $more_msgs), $more_msgs); } } return $html . '<tr><td colspan="2" style="cursor:pointer" align="right">' . $inbox->url('mailbox')->link() . $text . '</a></td></tr>' . '</table>'; }
/** * Return a folder object containing all IMAP server change information. * * @param array $options An array of options. * @see Horde_ActiveSync_Imap_Adapter::getMessageChanges * * @return Horde_ActiveSync_Folder_Base The populated folder object. */ public function getChanges(array $options) { $this->_logger->info(sprintf('[%s] NO CONDSTORE or per mailbox MODSEQ. minuid: %s, total_messages: %s', $this->_procid, $this->_folder->minuid(), $this->_status['messages'])); $query = new Horde_Imap_Client_Search_Query(); if (!empty($options['sincedate'])) { $query->dateSearch(new Horde_Date($options['sincedate']), Horde_Imap_Client_Search_Query::DATE_SINCE); } try { $search_ret = $this->_imap_ob->search($this->_mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH))); } catch (Horde_Imap_Client_Exception $e) { $this->_logger->err($e->getMessage()); throw new Horde_ActiveSync_Exception($e); } $cnt = $search_ret['count'] / Horde_ActiveSync_Imap_Adapter::MAX_FETCH + 1; $query = new Horde_Imap_Client_Fetch_Query(); $query->flags(); $flags = array(); for ($i = 0; $i <= $cnt; $i++) { $ids = new Horde_Imap_Client_Ids(array_slice($search_ret['match']->ids, $i * Horde_ActiveSync_Imap_Adapter::MAX_FETCH, Horde_ActiveSync_Imap_Adapter::MAX_FETCH)); try { $fetch_ret = $this->_imap_ob->fetch($this->_mbox, $query, array('ids' => $ids)); } catch (Horde_Imap_Client_Exception $e) { $this->_logger->err($e->getMessage()); throw new Horde_ActiveSync_Exception($e); } foreach ($fetch_ret as $uid => $data) { $flags[$uid] = array('read' => array_search(Horde_Imap_Client::FLAG_SEEN, $data->getFlags()) !== false ? 1 : 0); if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) { $flags[$uid]['flagged'] = array_search(Horde_Imap_Client::FLAG_FLAGGED, $data->getFlags()) !== false ? 1 : 0; } } } if (!empty($flags)) { $this->_folder->setChanges($search_ret['match']->ids, $flags); } $this->_folder->setRemoved($this->_imap_ob->vanished($this->_mbox, null, array('ids' => new Horde_Imap_Client_Ids($this->_folder->messages())))->ids); return $this->_folder; }
/** * Perform an IMAP search based on a SEARCH request. * * @param array $query The search query. * * @return array The results array containing an array of hashes: * 'uniqueid' => [The unique identifier of the result] * 'searchfolderid' => [The mailbox name that this result comes from] * * @throws Horde_ActiveSync_Exception */ protected function _doQuery(array $query) { $imap_query = new Horde_Imap_Client_Search_Query(); $mboxes = array(); $results = array(); foreach ($query as $q) { switch ($q['op']) { case Horde_ActiveSync_Request_Search::SEARCH_AND: return $this->_doQuery(array($q['value']), $range); default: foreach ($q as $key => $value) { switch ($key) { case 'FolderType': if ($value != Horde_ActiveSync::CLASS_EMAIL) { throw new Horde_ActiveSync_Exception('Only Email folders are supported.'); } break; case 'serverid': $mboxes[] = new Horde_Imap_Client_Mailbox($value); break; case Horde_ActiveSync_Message_Mail::POOMMAIL_DATERECEIVED: if ($q['op'] == Horde_ActiveSync_Request_Search::SEARCH_GREATERTHAN) { $query_range = Horde_Imap_Client_Search_Query::DATE_SINCE; } elseif ($q['op'] == Horde_ActiveSync_Request_Search::SEARCH_LESSTHAN) { $query_range = Horde_Imap_Client_Search_Query::DATE_BEFORE; } else { $query_range = Horde_Imap_Client_Search_Query::DATE_ON; } $imap_query->dateSearch($value, $query_range); break; case Horde_ActiveSync_Request_Search::SEARCH_FREETEXT: $imap_query->text($value, false); break; case 'subquery': $imap_query->andSearch(array($this->_buildSubQuery($value))); } } } } if (empty($mboxes)) { foreach ($this->getMailboxes() as $mailbox) { $mboxes[] = $mailbox['ob']; } } foreach ($mboxes as $mbox) { try { $search_res = $this->_getImapOb()->search($mbox, $imap_query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE, Horde_Imap_Client::SEARCH_RESULTS_COUNT), 'sort' => array(Horde_Imap_Client::SORT_REVERSE, Horde_Imap_Client::SORT_ARRIVAL))); } catch (Horde_Imap_Client_Exception $e) { throw new Horde_ActiveSync_Exception($e); } if ($search_res['count'] == 0) { continue; } $ids = $search_res['match']->ids; foreach ($ids as $id) { $results[] = array('uniqueid' => $mbox->utf8 . ':' . $id, 'searchfolderid' => $mbox->utf8); } if (!empty($range)) { preg_match('/(.*)\\-(.*)/', $range, $matches); $return_count = $matches[2] - $matches[1]; $results = array_slice($results, $matches[1], $return_count + 1, true); } } return $results; }
/** * Returns a query object prepared for adding further criteria. * * @return Ingo_IMAP_Search_Query A query object. */ protected function _getQuery() { $ob = new Horde_Imap_Client_Search_Query(); $ob->flag('\\deleted', false); if ($this->_params['filter_seen'] == Ingo::FILTER_SEEN || $this->_params['filter_seen'] == Ingo::FILTER_UNSEEN) { $ob->flag('\\seen', $this->_params['filter_seen'] == Ingo::FILTER_SEEN); } return $ob; }
/** * Synchronizes the current mailbox cache with the server. */ protected function _syncMailbox() { $status = $this->status($this->_selected, Horde_Imap_Client::STATUS_UIDVALIDITY | Horde_Imap_Client::STATUS_HIGHESTMODSEQ); /* Check that modseqs are available in mailbox. */ if (empty($status['highestmodseq'])) { return; } /* Grab all flags updated since the cached modseq. */ $md = $this->_cache->getMetaData($this->_selected, $status['uidvalidity'], array(self::CACHE_MODSEQ)); if (!isset($md[self::CACHE_MODSEQ]) || $md[self::CACHE_MODSEQ] == $status['highestmodseq']) { return; } $uids = $this->_cache->get($this->_selected, array(), array(), $status['uidvalidity']); if (!empty($uids)) { $uids_ob = $this->getIdsOb($uids); /* Are we caching flags? */ if (array_key_exists(Horde_Imap_Client::FETCH_FLAGS, $this->_cacheFields())) { $fquery = new Horde_Imap_Client_Fetch_Query(); $fquery->flags(); /* Update flags in cache. Cache will be updated in _fetch(). */ $this->_fetch(new Horde_Imap_Client_Fetch_Results(), $fquery, array('changedsince' => $md[self::CACHE_MODSEQ], 'ids' => $uids_ob)); } /* Search for deleted messages, and remove from cache. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->ids($this->getIdsOb($uids_ob->range_string)); $search = $this->search($this->_selected, $squery, array('nocache' => true)); $deleted = array_diff($uids_ob->ids, $search['match']->ids); if (!empty($deleted)) { $this->_deleteMsgs($this->_selected, $deleted); } } $this->_updateMetaData($this->_selected, array(self::CACHE_MODSEQ => $status['highestmodseq']), $status['uidvalidity']); }
public function testSerialize() { $ob = new Horde_Imap_Client_Search_Query(); $ob->ids(new Horde_Imap_Client_Ids('1:3'), true); $ob->text('foo'); $ob->charset('US-ASCII', false); $this->assertEquals('BODY foo NOT UID 1:3', strval(unserialize(serialize($ob)))); }
$request_parts = explode('/-/', $request); if (!empty($request_parts[0])) { $ns_info = $mailbox->imp_imap->getNamespace(IMP_Imap::NS_DEFAULT); $mailbox = IMP_Mailbox::get(preg_replace('/\\//', $ns_info->delimiter, trim($request_parts[0], '/')))->namespace_append; /* Make sure mailbox exists or else exit immediately. */ if (!$mailbox->exists) { exit; } } $new_mail = isset($request_parts[1]) && $request_parts[1] === 'new'; } $imp_mailbox = $mailbox->list_ob; /* Obtain some information describing the mailbox state. */ $total_num = count($imp_mailbox); $unseen_num = $mailbox->vinbox ? $total_num : $imp_mailbox->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_COUNT); $query = new Horde_Imap_Client_Search_Query(); if ($new_mail) { $query->flag(Horde_Imap_Client::FLAG_SEEN, false); } $ids = $mailbox->runSearchQuery($query, Horde_Imap_Client::SORT_ARRIVAL, 1); if (count($ids)) { $imp_ui = new IMP_Mailbox_Ui($mailbox); $overview = $imp_mailbox->getMailboxArray(array_slice($ids[strval($mailbox)], 0, 20), array('preview' => $prefs->getValue('preview_enabled'))); foreach ($overview['overview'] as $ob) { $from_addr = $imp_ui->getFrom($ob['envelope']); $items[] = array_map('htmlspecialchars', array('title' => $imp_ui->getSubject($ob['envelope']->subject), 'pubDate' => $ob['envelope']->date->format('r'), 'description' => isset($ob['preview']) ? $ob['preview'] : '', 'url' => Horde::url($mailbox->url('message', $imp_mailbox->getBuid($mailbox, $ob['uid'])), true, array('append_session' => -1)), 'fromAddr' => strval($from_addr['from_list']), 'toAddr' => strval($ob['envelope']->to))); } } $description = $total_num === 0 ? _("No Messages") : sprintf(_("%u of %u messages in %s unread."), $unseen_num, $total_num, $mailbox->label); $view = new Horde_View(array('templatePath' => IMP_TEMPLATES . '/rss')); $view->addHelper('Text');
/** */ public function createQuery($mbox, $queryob) { $ob = new Horde_Imap_Client_Search_Query(); $ob->orSearch($queryob); return $ob; }
/** */ protected function _expunge($options) { $unflag = array(); $mailbox = clone $this->_selected; $s_res = null; $uidplus = $this->queryCapability('UIDPLUS'); $use_cache = $this->_initCache(true); if ($options['ids']->all) { $uid_string = strval($options['ids']); } elseif ($uidplus) { /* UID EXPUNGE command needs UIDs. */ if ($options['ids']->sequence) { $results = array(Horde_Imap_Client::SEARCH_RESULTS_MATCH); if ($this->queryCapability('SEARCHRES')) { $results[] = Horde_Imap_Client::SEARCH_RESULTS_SAVE; } $s_res = $this->search($mailbox, null, array('results' => $results)); $uid_string = in_array(Horde_Imap_Client::SEARCH_RESULTS_SAVE, $results) && !empty($s_res['save']) ? '$' : strval($s_res['match']); } else { $uid_string = strval($options['ids']); } } else { /* Without UIDPLUS, need to temporarily unflag all messages marked * as deleted but not a part of requested IDs to delete. Use NOT * searches to accomplish this goal. */ $search_query = new Horde_Imap_Client_Search_Query(); $search_query->flag(Horde_Imap_Client::FLAG_DELETED, true); if ($options['ids']->search_res) { $search_query->previousSearch(true); } else { $search_query->ids($options['ids'], true); } $res = $this->search($mailbox, $search_query); $this->store($mailbox, array('ids' => $res['match'], 'remove' => array(Horde_Imap_Client::FLAG_DELETED))); $unflag = $res['match']; } $list_msgs = !empty($options['list']); $tmp =& $this->_temp; $tmp['expunge'] = $tmp['vanished'] = array(); /* We need to get sequence num -> UID lookup table if we are caching. * There is no guarantee that if we are using QRESYNC that we will get * VANISHED responses, so this is unfortunately necessary. */ if (is_null($s_res) && ($list_msgs || $use_cache)) { $s_res = $uidplus ? $this->_getSeqUidLookup($options['ids'], true) : $this->_getSeqUidLookup($this->getIdsOb(Horde_Imap_Client_Ids::ALL, true)); } /* Always use UID EXPUNGE if available. */ if ($uidplus) { $cmd = $this->_clientCommand(array('UID', 'EXPUNGE', $uid_string)); $this->_sendLine($cmd); } elseif ($use_cache || $list_msgs) { $this->_sendLine($this->_clientCommand('EXPUNGE')); } else { /* This is faster than an EXPUNGE because the server will not * return untagged EXPUNGE responses. We can only do this if * we are not updating cache information. */ $this->close(array('expunge' => true)); } if (!empty($unflag)) { $this->store($mailbox, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $unflag)); } if (!$use_cache && !$list_msgs) { return null; } $expunged = array(); if (!empty($tmp['vanished'])) { $expunged = $tmp['vanished']->ids; } elseif (!empty($tmp['expunge'])) { $lookup = $s_res['lookup']; /* Expunge responses can come in any order. Thus, we need to * reindex anytime we have an index that appears equal to or * after a previously seen index. If an IMAP server is smart, * it will expunge in reverse order instead. */ foreach ($tmp['expunge'] as &$val) { $found = false; $tmp2 = array(); foreach (array_keys($lookup) as $i => $seq) { if ($found) { $tmp2[$seq - 1] = $lookup[$seq]; } elseif ($seq == $val) { $expunged[] = $lookup[$seq]; $tmp2 = array_slice($lookup, 0, $i, true); $found = true; } } $lookup = $tmp2; } } if (empty($expunged)) { return null; } if ($use_cache) { $this->_deleteMsgs($mailbox, $expunged); } /* Update MODSEQ if active for mailbox (QRESYNC only; CONDSTORE * requires us to re-SELECT/EXAMINE the mailbox). */ if (!empty($this->_temp['mailbox']['highestmodseq']) && isset($this->_init['enabled']['QRESYNC'])) { $this->_updateMetaData($mailbox, array(self::CACHE_MODSEQ => $this->_temp['mailbox']['highestmodseq']), isset($this->_temp['mailbox']['uidvalidity']) ? $this->_temp['mailbox']['uidvalidity'] : null); } return $list_msgs ? $this->getIdsOb($expunged, $options['ids']->sequence) : null; }
/** * Returns the message ids of the messages in this folder. * * @param string $folder Check the status of this folder. * * @return array The message ids. */ public function getUids($folder) { $search_query = new Horde_Imap_Client_Search_Query(); $search_query->flag('DELETED', false); try { $uidsearch = $this->getBackend()->search($folder, $search_query); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { throw new Horde_Kolab_Storage_Exception($e->details); } catch (Horde_Imap_Client_Exception $e) { throw new Horde_Kolab_Storage_Exception($e); } $uids = $uidsearch['match']; return $uids->ids; }
/** * Get the list of unseen messages in the mailbox (IMAP UNSEEN flag, with * UNDELETED if we're hiding deleted messages). * * @param integer $results A Horde_Imap_Client::SEARCH_RESULTS_* constant * that indicates the desired return type. * @param array $opts Additional options: * - sort: (array) List of sort criteria to use. * - uids: (boolean) Return UIDs instead of sequence numbers (for * $results queries that return message lists). * DEFAULT: false * * @return mixed Whatever is requested in $results. */ public function unseenMessages($results, array $opts = array()) { $count = $results == Horde_Imap_Client::SEARCH_RESULTS_COUNT; if (empty($this->_sorted)) { return $count ? 0 : array(); } $criteria = new Horde_Imap_Client_Search_Query(); $imp_imap = $this->_mailbox->imp_imap; if ($this->_mailbox->hideDeletedMsgs()) { $criteria->flag(Horde_Imap_Client::FLAG_DELETED, false); } elseif ($count) { try { $status_res = $imp_imap->status($this->_mailbox, Horde_Imap_Client::STATUS_UNSEEN); return $status_res['unseen']; } catch (IMP_Imap_Exception $e) { return 0; } } $criteria->flag(Horde_Imap_Client::FLAG_SEEN, false); try { $res = $imp_imap->search($this->_mailbox, $criteria, array('results' => array($results), 'sequence' => empty($opts['uids']), 'sort' => empty($opts['sort']) ? null : $opts['sort'])); return $count ? $res['count'] : $res; } catch (IMP_Imap_Exception $e) { return $count ? 0 : array(); } }
/** * @depends testOptimizedSearches */ public function testMailboxThreadByReferences() { if (!self::$live->capability->query('THREAD', 'REFERENCES')) { $this->markTestSkipped('Server does not support THREAD=REFERENCES'); } $res = self::$live->thread(self::$test_mbox, array('criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'sequence' => true)); $this->assertInstanceOf('Horde_Imap_Client_Data_Thread', $res); $this->assertEquals(4, count($res)); // Thread order: (1,4)(2)(3) $thread = $res->getThread(2); $this->assertArrayHasKey(2, $thread); $this->assertNull($thread[2]->base); $thread = $res->getThread(4); $this->assertArrayHasKey(1, $thread); $this->assertArrayHasKey(4, $thread); $this->assertEquals(1, $thread[1]->base); $this->assertEquals(1, $thread[4]->base); // Sort 1st 2 messages in test mailbox by thread - references // algorithm (UIDs). $ten_query = new Horde_Imap_Client_Search_Query(); $ten_query->ids(new Horde_Imap_Client_Ids('1:2', true)); $res = self::$live->thread(self::$test_mbox, array('criteria' => Horde_Imap_Client::THREAD_REFERENCES, 'search' => $ten_query)); $this->assertInstanceOf('Horde_Imap_Client_Data_Thread', $res); // Thread order: (1)(2) $thread = $res->getThread(1); $this->assertArrayHasKey(1, $thread); $this->assertNull($thread[1]->base); }
/** * Tidy up old messages in the confirmation folder. * * @return bool Whether tidying occurred successfully. */ public function tidy_old_messages() { // Grab the new IMAP client. if (!$this->get_imap_client()) { return false; } // Open the mailbox. mtrace("Searching for messages older than 24 hours in the '" . $this->get_confirmation_folder() . "' folder."); $this->client->openMailbox($this->get_confirmation_folder()); $mailbox = $this->get_mailbox(); // Build the search. $search = new \Horde_Imap_Client_Search_Query(); // Delete messages older than 24 hours old. $search->intervalSearch(DAYSECS, \Horde_Imap_Client_Search_Query::INTERVAL_OLDER); $results = $this->client->search($mailbox, $search); // Build the base query. $query = new \Horde_Imap_Client_Fetch_Query(); $query->envelope(); // Retrieve the messages and mark them for removal. $messages = $this->client->fetch($mailbox, $query, array('ids' => $results['match'])); mtrace("Found " . $messages->count() . " messages for removal."); foreach ($messages as $message) { $this->add_flag_to_message($message->getUid(), self::MESSAGE_DELETED); } mtrace("Finished removing messages."); $this->close_connection(); return true; }
public function getFromId() { $query = new Horde_Imap_Client_Search_Query(); // 604800 = 60 seconds * 60 minutes * 24 hours * 7 days (1 week) $query->intervalSearch(604800, Horde_Imap_Client_Search_Query::INTERVAL_YOUNGER); $results = $this->imap_imp->search('INBOX', $query, array()); }
/** * Return the search query to use to find the sent message. * * @return Horde_Imap_Client_Search_Query The query object. */ public function searchQuery() { $query = new Horde_Imap_Client_Search_Query(); $query->headerText($this->_msgidHeader, $this->msg_id); return $query; }
/** * Constructor. * * @param Horde_Imap_Client_Base $base_ob Base driver object. * @param mixed $mailbox Mailbox to sync. * @param array $sync Token sync data. * @param array $curr Current sync data. * @param integer $criteria Mask of criteria to return. * @param Horde_Imap_Client_Ids $ids List of known UIDs. * * @throws Horde_Imap_Client_Exception * @throws Horde_Imap_Client_Exception_Sync */ public function __construct(Horde_Imap_Client_Base $base_ob, $mailbox, $sync, $curr, $criteria, $ids) { foreach (self::$map as $key => $val) { if (isset($sync[$key])) { $this->{$val} = $sync[$key]; } } /* Check uidvalidity. */ if (!$this->uidvalidity || $curr['V'] != $this->uidvalidity) { throw new Horde_Imap_Client_Exception_Sync('UIDs in cached mailbox have changed.', Horde_Imap_Client_Exception_Sync::UIDVALIDITY_CHANGED); } $this->mailbox = $mailbox; /* This was a UIDVALIDITY check only. */ if (!$criteria) { return; } $sync_all = $criteria & Horde_Imap_Client::SYNC_ALL; /* New messages. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGS || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS) { $this->newmsgs = empty($this->uidnext) ? !empty($curr['U']) : !empty($curr['U']) && $curr['U'] > $this->uidnext; if ($this->newmsgs && ($sync_all || $criteria & Horde_Imap_Client::SYNC_NEWMSGSUIDS)) { $new_ids = empty($this->uidnext) ? Horde_Imap_Client_Ids::ALL : $this->uidnext . ':' . $curr['U']; $squery = new Horde_Imap_Client_Search_Query(); $squery->ids(new Horde_Imap_Client_Ids($new_ids)); $sres = $base_ob->search($mailbox, $squery); $this->_newmsgsuids = $sres['match']; } } /* Do single status call to get all necessary data. */ if ($this->highestmodseq && ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS)) { $status_sync = $base_ob->status($mailbox, Horde_Imap_Client::STATUS_SYNCMODSEQ | Horde_Imap_Client::STATUS_SYNCFLAGUIDS | Horde_Imap_Client::STATUS_SYNCVANISHED); if (!is_null($ids)) { $ids = $base_ob->resolveIds($mailbox, $ids); } } /* Flag changes. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGS) { $this->flags = $this->highestmodseq ? $this->highestmodseq != $curr['H'] : true; } if ($sync_all || $criteria & Horde_Imap_Client::SYNC_FLAGSUIDS) { if ($this->highestmodseq) { if ($this->highestmodseq == $status_sync['syncmodseq']) { $this->_flagsuids = is_null($ids) ? $status_sync['syncflaguids'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncflaguids']->ids)); } else { $squery = new Horde_Imap_Client_Search_Query(); $squery->modseq($this->highestmodseq + 1); $sres = $base_ob->search($mailbox, $squery, array('ids' => $ids)); $this->_flagsuids = $sres['match']; } } else { /* Without MODSEQ, need to mark all FLAGS as changed. */ $this->_flagsuids = $base_ob->resolveIds($mailbox, is_null($ids) ? $base_ob->getIdsOb(Horde_Imap_Client_Ids::ALL) : $ids); } } /* Vanished messages. */ if ($sync_all || $criteria & Horde_Imap_Client::SYNC_VANISHED || $criteria & Horde_Imap_Client::SYNC_VANISHEDUIDS) { if ($this->highestmodseq && $this->highestmodseq == $status_sync['syncmodseq']) { $vanished = is_null($ids) ? $status_sync['syncvanished'] : $base_ob->getIdsOb(array_intersect($ids->ids, $status_sync['syncvanished']->ids)); } else { $vanished = $base_ob->vanished($mailbox, $this->highestmodseq ? $this->highestmodseq : 1, array('ids' => $ids)); } $this->vanished = (bool) count($vanished); $this->_vanisheduids = $vanished; } }
/** */ protected function _expunge($options) { $expunged_ob = $modseq = null; $ids = $options['ids']; $list_msgs = !empty($options['list']); $uidplus = $this->queryCapability('UIDPLUS'); $unflag = array(); $use_cache = $this->_initCache(true); if ($ids->all) { if (!$uidplus || $list_msgs || $use_cache) { $ids = $this->resolveIds($this->_selected, $ids, 2); } } elseif ($uidplus) { /* If QRESYNC is not available, and we are returning the list of * expunged messages (or we are caching), we have to make sure we * have a mapping of Sequence -> UIDs. If we have QRESYNC, the * server SHOULD return a VANISHED response with UIDs. However, * even if the server returns EXPUNGEs instead, we can use * vanished() to grab the list. */ unset($this->_temp['search_save']); if (isset($this->_temp['enabled']['QRESYNC'])) { $ids = $this->resolveIds($this->_selected, $ids, 1); if ($list_msgs) { $modseq = $this->_mailboxOb()->getStatus(Horde_Imap_Client::STATUS_HIGHESTMODSEQ); } } else { $ids = $this->resolveIds($this->_selected, $ids, $list_msgs || $use_cache ? 2 : 1); } if (!empty($this->_temp['search_save'])) { $ids = $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES); } } else { /* Without UIDPLUS, need to temporarily unflag all messages marked * as deleted but not a part of requested IDs to delete. Use NOT * searches to accomplish this goal. */ $squery = new Horde_Imap_Client_Search_Query(); $squery->flag(Horde_Imap_Client::FLAG_DELETED, true); $squery->ids($ids, true); $s_res = $this->search($this->_selected, $squery, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH, Horde_Imap_Client::SEARCH_RESULTS_SAVE))); $this->store($this->_selected, array('ids' => empty($s_res['save']) ? $s_res['match'] : $this->getIdsOb(Horde_Imap_Client_Ids::SEARCH_RES), 'remove' => array(Horde_Imap_Client::FLAG_DELETED))); $unflag = $s_res['match']; } if ($list_msgs) { $expunged_ob = $this->getIdsOb(); $this->_temp['expunged'] = $expunged_ob; } /* Always use UID EXPUNGE if available. */ if ($uidplus) { /* We can only pipeline STORE w/ EXPUNGE if using UIDs and UIDPLUS * is available. */ if (empty($options['delete'])) { $pipeline = $this->_pipeline(); } else { $pipeline = $this->_storeCmd(array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $ids)); } foreach ($ids->split(2000) as $val) { $pipeline->add($this->_command('UID EXPUNGE')->add($val)); } $resp = $this->_sendCmd($pipeline); } else { if (!empty($options['delete'])) { $this->store($this->_selected, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $ids)); } if ($use_cache || $list_msgs) { $this->_sendCmd($this->_command('EXPUNGE')); } else { /* This is faster than an EXPUNGE because the server will not * return untagged EXPUNGE responses. We can only do this if * we are not updating cache information. */ $this->close(array('expunge' => true)); } } unset($this->_temp['expunged']); if (!empty($unflag)) { $this->store($this->_selected, array('add' => array(Horde_Imap_Client::FLAG_DELETED), 'ids' => $unflag)); } if (!is_null($modseq) && !empty($resp->data['expunge_seen'])) { /* There's a chance we actually did a full map of sequence -> UID, * but this code should never be reached in the first place so * be ultra-safe and just do a full VANISHED search. */ $expunged_ob = $this->vanished($this->_selected, $modseq, array('ids' => $ids)); $this->_deleteMsgs($this->_selected, $expunged_ob, array('pipeline' => $resp)); } return $expunged_ob; }
/** * Return message UIDs that are now within the cureent FILTERTYPE value. * * @param array $options Options array. * @param boolean $is_delete If true, return messages * to SOFTDELETE. * * @return Horde_Imap_Client_Search_Results */ protected function _searchQuery($options, $is_delete) { $query = new Horde_Imap_Client_Search_Query(); $query->dateSearch(new Horde_Date($options['sincedate']), $is_delete ? Horde_Imap_Client_Search_Query::DATE_BEFORE : Horde_Imap_Client_Search_Query::DATE_SINCE); $query->ids(new Horde_Imap_Client_Ids($this->_folder->messages()), !$is_delete); try { return $this->_imap_ob->search($this->_mbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MATCH))); } catch (Horde_Imap_Client_Exception $e) { $this->_logger->err($e->getMessage()); throw new Horde_ActiveSync_Exception($e); } }
public function inconsistentCharsetsInAndOrSearchesProvider() { $ob = new Horde_Imap_Client_Search_Query(); $ob->text('foo'); $ob->charset('UTF-8', false); $ob2 = new Horde_Imap_Client_Search_Query(); $ob2->text('foo2'); $ob2->charset('ISO-8859-1', false); $ob2->andSearch($ob); $ob3 = new Horde_Imap_Client_Search_Query(); $ob3->text('foo2'); $ob3->charset('ISO-8859-1', false); $ob3->orSearch($ob); return array(array($ob2), array($ob3)); }
/** * Get a message UID by the Message-ID. Returns the last message in a * mailbox that matches. * * @param Horde_Imap_Client_Mailbox $mailbox The mailbox to search * @param string $msgid Message-ID. * * @return string UID (null if not found). */ protected function _getUidByMessageId($mailbox, $msgid) { if (!$msgid) { return null; } $query = new Horde_Imap_Client_Search_Query(); $query->headerText('Message-ID', $msgid); $res = $this->search($mailbox, $query, array('results' => array(Horde_Imap_Client::SEARCH_RESULTS_MAX))); return $res['max']; }