text() public method

Search for text in either the entire message, or just the body.
public text ( string $text, string $bodyonly = true, boolean $not = false, array $opts = [] )
$text string The search text.
$bodyonly string If true, only search in the body of the message. If false, also search in the headers.
$not boolean If true, do a 'NOT' search of $text.
$opts array Additional options: - fuzzy: (boolean) If true, perform a fuzzy search. The IMAP server MUST support RFC 6203.
Example #1
0
 /**
  * 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];
 }
Example #2
0
 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));
 }
Example #3
0
 /**
  * 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;
 }
Example #4
0
File: Imap.php Project: horde/horde
 /**
  * Performs the filtering specified in the rules.
  *
  * @param integer $change  The timestamp of the latest rule change during
  *                         the current session.
  */
 protected function _perform($change)
 {
     $api = $this->_params['api'];
     $notification = $this->_params['notification'];
     /* Indices that will be ignored by subsequent rules. */
     $ignore_ids = array();
     /* Only do filtering if:
        1. We have not done filtering before -or-
        2. The mailbox has changed -or-
        3. The rules have changed. */
     $cache = $api->getCache();
     if ($cache !== false && $cache == $change) {
         return;
     }
     $filters = Ingo_Storage_FilterIterator_Skip::create($this->_params['storage'], $this->_params['skip']);
     /* Parse through the rules, one-by-one. */
     foreach ($filters as $rule) {
         /* Check to make sure this is a valid rule and that the rule is
            not disabled. */
         if (!$this->_validRule($rule) || $rule->disable) {
             continue;
         }
         switch ($class = get_class($rule)) {
             case 'Ingo_Rule_System_Blacklist':
             case 'Ingo_Rule_System_Whitelist':
                 $addr = $rule->addresses;
                 $bl_folder = $class === 'Ingo_Rule_System_Blacklist' ? $rule->mailbox : null;
                 /* If list is empty, move on. */
                 if (empty($addr)) {
                     continue;
                 }
                 $addr = new Horde_Mail_Rfc822_List($addr);
                 $query = $this->_getQuery();
                 $or_ob = new Horde_Imap_Client_Search_Query();
                 foreach ($addr->bare_addresses as $val) {
                     $ob = new Horde_Imap_Client_Search_Query();
                     $ob->charset('UTF-8', false);
                     $ob->headerText('from', $val);
                     $or_ob->orSearch(array($ob));
                 }
                 $query->andSearch(array($or_ob));
                 $indices = $api->search($query);
                 if (!($msgs = $api->fetchEnvelope($indices))) {
                     continue;
                 }
                 /* Remove any indices that got in there by way of partial
                  * address match. */
                 $remove = array();
                 foreach ($msgs as $v) {
                     foreach ($v->getEnvelope()->from as $v2) {
                         if (!$addr->contains($v2)) {
                             $remove[] = $v->getUid();
                             break;
                         }
                     }
                 }
                 if ($remove) {
                     $indices = array_diff($indices, $remove);
                 }
                 if ($class === 'Ingo_Rule_System_Blacklist') {
                     $indices = array_diff($indices, $ignore_ids);
                     if (!empty($indices)) {
                         if (!empty($bl_folder)) {
                             $api->moveMessages($indices, $bl_folder);
                         } else {
                             $api->deleteMessages($indices);
                         }
                         $notification->push(sprintf(_("Filter activity: %s message(s) that matched the blacklist were deleted."), count($indices)), 'horde.message');
                     }
                 } else {
                     $ignore_ids = $indices;
                 }
                 break;
             case 'Ingo_Rule_User_Discard':
             case 'Ingo_Rule_User_Keep':
             case 'Ingo_Rule_User_Move':
             case 'Ingo_Rule_User_MoveKeep':
                 $base_query = $this->_getQuery();
                 $query = new Horde_Imap_Client_Search_Query();
                 foreach ($rule->conditions as $val) {
                     $ob = new Horde_Imap_Client_Search_Query();
                     if (!empty($val['type']) && $val['type'] == Ingo_Rule_User::TEST_SIZE) {
                         $ob->size($val['value'], $val['match'] == 'greater than');
                     } elseif (!empty($val['type']) && $val['type'] == Ingo_Rule_User::TEST_BODY) {
                         $ob->charset('UTF-8', false);
                         $ob->text($val['value'], true, $val['match'] == 'not contain');
                     } else {
                         if (strpos($val['field'], ',') == false) {
                             $ob->charset('UTF-8', false);
                             $ob->headerText($val['field'], $val['value'], $val['match'] == 'not contain');
                         } else {
                             foreach (explode(',', $val['field']) as $header) {
                                 $hdr_ob = new Horde_Imap_Client_Search_Query();
                                 $hdr_ob->charset('UTF-8', false);
                                 $hdr_ob->headerText($header, $val['value'], $val['match'] == 'not contain');
                                 if ($val['match'] == 'contains') {
                                     $ob->orSearch(array($hdr_ob));
                                 } elseif ($val['match'] == 'not contain') {
                                     $ob->andSearch(array($hdr_ob));
                                 }
                             }
                         }
                     }
                     switch ($rule->combine) {
                         case Ingo_Rule_User::COMBINE_ALL:
                             $query->andSearch(array($ob));
                             break;
                         case Ingo_Rule_User::COMBINE_ANY:
                             $query->orSearch(array($ob));
                             break;
                     }
                 }
                 $base_query->andSearch(array($query));
                 $indices = $api->search($base_query);
                 if ($indices = array_diff($indices, $ignore_ids)) {
                     if ($rule->stop) {
                         /* If the stop action is set, add these
                          * indices to the list of ids that will be
                          * ignored by subsequent rules. */
                         $ignore_ids = array_unique($indices + $ignore_ids);
                     }
                     /* Set the flags. */
                     if ($class !== 'Ingo_Rule_User_Discard') {
                         $flags = array();
                         if ($rule->flags & Ingo_Rule_User::FLAG_ANSWERED) {
                             $flags[] = '\\answered';
                         }
                         if ($rule->flags & Ingo_Rule_User::FLAG_DELETED) {
                             $flags[] = '\\deleted';
                         }
                         if ($rule->flags & Ingo_Rule_User::FLAG_FLAGGED) {
                             $flags[] = '\\flagged';
                         }
                         if ($rule->flags & Ingo_Rule_User::FLAG_SEEN) {
                             $flags[] = '\\seen';
                         }
                         if (!empty($flags)) {
                             $api->setMessageFlags($indices, $flags);
                         }
                     }
                     switch ($class) {
                         case 'Ingo_Rule_User_Keep':
                             /* Add these indices to the ignore list. */
                             $ignore_ids = array_unique($indices + $ignore_ids);
                             break;
                         case 'Ingo_Rule_User_Move':
                             /* We need to grab the envelope first. */
                             if ($this->_params['show_filter_msg'] && !($fetch = $api->fetchEnvelope($indices))) {
                                 continue 2;
                             }
                             $mbox = new Horde_Imap_Client_Mailbox($rule->value);
                             /* Move the messages to the requested mailbox. */
                             $api->moveMessages($indices, strval($mbox));
                             /* Display notification message(s). */
                             if ($this->_params['show_filter_msg']) {
                                 foreach ($fetch as $msg) {
                                     $envelope = $msg->getEnvelope();
                                     $notification->push(sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been moved to the folder \"%s\"."), !empty($envelope->subject) ? Horde_Mime::decode($envelope->subject) : _("[No Subject]"), !empty($envelope->from) ? strval($envelope->from) : _("[No Sender]"), $mbox), 'horde.message');
                                 }
                             } else {
                                 $notification->push(sprintf(_("Filter activity: %s message(s) have been moved to the folder \"%s\"."), count($indices), $mbox), 'horde.message');
                             }
                             break;
                         case 'Ingo_Rule_User_Discard':
                             /* We need to grab the envelope first. */
                             if ($this->_params['show_filter_msg'] && !($fetch = $api->fetchEnvelope($indices))) {
                                 continue;
                             }
                             /* Delete the messages now. */
                             $api->deleteMessages($indices);
                             /* Display notification message(s). */
                             if ($this->_params['show_filter_msg']) {
                                 foreach ($fetch as $msg) {
                                     $envelope = $msg->getEnvelope();
                                     $notification->push(sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been deleted."), !empty($envelope->subject) ? Horde_Mime::decode($envelope->subject) : _("[No Subject]"), !empty($envelope->from) ? strval($envelope->from) : _("[No Sender]")), 'horde.message');
                                 }
                             } else {
                                 $notification->push(sprintf(_("Filter activity: %s message(s) have been deleted."), count($indices)), 'horde.message');
                             }
                             break;
                         case 'Ingo_Rule_User_MoveKeep':
                             $mbox = new Horde_Imap_Client_Mailbox($rule->value);
                             /* Copy the messages to the requested mailbox. */
                             $api->copyMessages($indices, strval($mbox));
                             /* Display notification message(s). */
                             if ($this->_params['show_filter_msg']) {
                                 if (!($fetch = $api->fetchEnvelope($indices))) {
                                     continue;
                                 }
                                 foreach ($fetch as $msg) {
                                     $envelope = $msg->getEnvelope();
                                     $notification->push(sprintf(_("Filter activity: The message \"%s\" from \"%s\" has been copied to the folder \"%s\"."), !empty($envelope->subject) ? Horde_Mime::decode($envelope->subject) : _("[No Subject]"), !empty($envelope->from) ? strval($envelope->from) : _("[No Sender]"), $mbox), 'horde.message');
                                 }
                             } else {
                                 $notification->push(sprintf(_("Filter activity: %s message(s) have been copied to the folder \"%s\"."), count($indices), $mbox), 'horde.message');
                             }
                     }
                 }
                 break;
         }
     }
     /* Set cache flag. */
     $api->storeCache($change);
 }
Example #5
0
 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))));
 }
Example #6
0
 /**
  * Determines if the given charset is valid for search-related queries.
  * This check pertains just to the basic IMAP SEARCH command.
  *
  * @param string $charset  The query charset.
  *
  * @return boolean  True if server supports this charset.
  */
 public function validSearchCharset($charset)
 {
     $charset = strtoupper($charset);
     if ($charset == 'US-ASCII') {
         return true;
     }
     if (!isset($this->_init['s_charset'][$charset])) {
         $s_charset = $this->_init['s_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->getIdsOb(1, true));
         $query->text('a');
         try {
             $this->search('INBOX', $query, array('nocache' => true, 'sequence' => true));
             $s_charset[$charset] = true;
         } catch (Horde_Imap_Client_Exception $e) {
             $s_charset[$charset] = $e->getCode() !== Horde_Imap_Client_Exception::BADCHARSET;
         }
         $this->_setInit('s_charset', $s_charset);
     }
     return $this->_init['s_charset'][$charset];
 }