Skip to content

Commit

Permalink
Fix attachment filter
Browse files Browse the repository at this point in the history
  • Loading branch information
slusarz committed Feb 20, 2015
1 parent 468b258 commit e1b9865
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 29 deletions.
19 changes: 15 additions & 4 deletions imp/lib/Mailbox/List.php
Expand Up @@ -251,14 +251,16 @@ protected function _buildMailbox()
}

foreach ($query_ob as $mbox => $val) {
$mbox_ob = IMP_Mailbox::get($mbox);

if ($thread_sort) {
$this->_getThread($mbox, $val ? array('search' => $val) : array());
$sorted = $this->_thread[$mbox]->messageList()->ids;
if ($sortpref->sortdir) {
$sorted = array_reverse($sorted);
}
} else {
$res = IMP_Mailbox::get($mbox)->imp_imap->search($mbox, $val, array(
$res = $mbox_ob->imp_imap->search($mbox, $val, array(
'sort' => array($sortpref->sortby)
));
if ($sortpref->sortdir) {
Expand All @@ -267,8 +269,10 @@ protected function _buildMailbox()
$sorted = $res['match']->ids;
}

$this->_sorted = array_merge($this->_sorted, $sorted);
$this->_buildMailboxProcess($mbox, $sorted);
$this->_sorted = array_merge(
$this->_sorted,
$this->_buildMailboxProcess($mbox_ob, $sorted)
);
}
}

Expand All @@ -280,9 +284,16 @@ protected function _buildMailboxQuery()
}

/**
* Run after the initial mailbox search is completed.
*
* @param IMP_Mailbox $mbox Mailbox searched.
* @param array $sorted Sorted list of UIDs.
*
* @return array Sorted list of UIDs.
*/
protected function _buildMailboxProcess($mbox, $sorted)
protected function _buildMailboxProcess(IMP_Mailbox $mbox, $sorted)
{
return $sorted;
}

/**
Expand Down
14 changes: 12 additions & 2 deletions imp/lib/Mailbox/List/Virtual.php
Expand Up @@ -45,11 +45,21 @@ protected function _buildMailboxQuery()

/**
*/
protected function _buildMailboxProcess($mbox, $sorted)
protected function _buildMailboxProcess(IMP_Mailbox $mbox, $sorted)
{
if (count($sorted)) {
$this->_sortedMbox = array_merge($this->_sortedMbox, array_fill(0, count($sorted), strval($mbox)));
$imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
$sorted = $imp_search[strval($this->_mailbox)]->runElementCallbacks(
$mbox, $sorted
);

$this->_sortedMbox = array_merge(
$this->_sortedMbox,
array_fill(0, count($sorted), strval($mbox))
);
}

return $sorted;
}

/**
Expand Down
76 changes: 53 additions & 23 deletions imp/lib/Search/Element/Attachment.php
Expand Up @@ -14,16 +14,15 @@
/**
* The attachment search query.
*
* Right now, uses a tremendously simplistic algorithm: it checks if the
* base part is 'multipart/mixed' or 'message/rfc822'.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2010-2015 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
class IMP_Search_Element_Attachment extends IMP_Search_Element
class IMP_Search_Element_Attachment
extends IMP_Search_Element
implements IMP_Search_Element_Callback
{
/**
* Constructor.
Expand All @@ -40,25 +39,7 @@ public function __construct($not = false)
*/
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);

/* Filtering takes place in searchCallback(). */
return $queryob;
}

Expand All @@ -71,4 +52,53 @@ public function queryText()
: _("messages with attachment(s)");
}

/**
*/
public function searchCallback(IMP_Mailbox $mbox, array $ids)
{
$fetch_query = new Horde_Imap_Client_Fetch_Query();
$fetch_query->structure();

$fetch_res = $mbox->imp_imap->fetch($mbox, $fetch_query, array(
'ids' => $mbox->imp_imap->getIdsOb($ids)
));

$out = array();

foreach ($ids as $v) {
if (isset($fetch_res[$v])) {
$atc = $this->_attachmentSearch(
array($fetch_res[$v]->getStructure())
);
if (($this->_data && $atc) || (!$this->_data && !$atc)) {
continue;
}
}

$out[] = $v;
}

return $out;
}

/**
* Recursively search message for Content-Disposition of 'attachment'
*
* @param Horde_Mime_Part $data MIME part.
*
* @return boolean True if the part contains an attachment.
*/
private function _attachmentSearch($data)
{
foreach ($data as $val) {
if ($val->getDisposition() === 'attachment') {
return true;
} elseif ($this->_attachmentSearch($val->getParts())) {
return true;
}
}

return false;
}

}
35 changes: 35 additions & 0 deletions imp/lib/Search/Element/Callback.php
@@ -0,0 +1,35 @@
<?php
/**
* Copyright 2015 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @category Horde
* @copyright 2015 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/

/**
* Interface implementing callbacks to reduce/filter search results.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2015 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
interface IMP_Search_Element_Callback
{
/**
* Callback allowing search results to be reduced/filtered.
*
* @param IMP_Mailbox $mbox Mailbox.
* @param array $ids Sorted ID list.
*
* @return array Sorted ID list.
*/
public function searchCallback(IMP_Mailbox $mbox, array $ids);

}
23 changes: 23 additions & 0 deletions imp/lib/Search/Query.php
Expand Up @@ -324,6 +324,29 @@ public function replace(array $criteria = array())
}
}

/**
* Reduce the sorted return ID list by running search element callbacks..
*
* @param IMP_Mailbox $mbox Mailbox.
* @param array $ids Sorted ID list.
*
* @return array Sorted ID list.
*/
public function runElementCallbacks(IMP_Mailbox $mbox, array $ids)
{
foreach ($this->_criteria as $val) {
if (empty($ids)) {
break;
}

if ($val instanceof IMP_Search_Element_Callback) {
$ids = $val->searchCallback($mbox, $ids);
}
}

return $ids;
}

/* Serializable methods. */

/**
Expand Down
2 changes: 2 additions & 0 deletions imp/package.xml
Expand Up @@ -527,6 +527,7 @@
<file name="Attachment.php" role="horde" />
<file name="Autogenerated.php" role="horde" />
<file name="Bulk.php" role="horde" />
<file name="Callback.php" role="horde" />
<file name="Contacts.php" role="horde" />
<file name="Daterange.php" role="horde" />
<file name="Flag.php" role="horde" />
Expand Down Expand Up @@ -1844,6 +1845,7 @@
<install as="imp/lib/Search/Element/Attachment.php" name="lib/Search/Element/Attachment.php" />
<install as="imp/lib/Search/Element/Autogenerated.php" name="lib/Search/Element/Autogenerated.php" />
<install as="imp/lib/Search/Element/Bulk.php" name="lib/Search/Element/Bulk.php" />
<install as="imp/lib/Search/Element/Callback.php" name="lib/Search/Element/Callback.php" />
<install as="imp/lib/Search/Element/Contacts.php" name="lib/Search/Element/Contacts.php" />
<install as="imp/lib/Search/Element/Daterange.php" name="lib/Search/Element/Daterange.php" />
<install as="imp/lib/Search/Element/Flag.php" name="lib/Search/Element/Flag.php" />
Expand Down

0 comments on commit e1b9865

Please sign in to comment.