Search for messages smaller/larger than a certain size.
public size ( integer $size, boolean $larger = false, boolean $not = false, array $opts = [] ) | ||
$size | integer | The size (in bytes). |
$larger | boolean | Search for messages larger than $size? |
$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. |
/** * @dataProvider sizeQueryProvider */ public function testSizeQuery($larger, $not, $fuzzy, $expected) { $ob = new Horde_Imap_Client_Search_Query(); $ob->size(100, $larger, $not, array('fuzzy' => $fuzzy)); $this->assertEquals($expected, $fuzzy ? $this->_fuzzy($ob) : strval($ob)); }
/** * 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); }