<?php
/**
 * The IMP_Search:: class contains all functions related to handling
 * searching mailboxes in IMP.
 *
 * $Horde: imp/lib/Search.php,v 1.37.10.8 2005/07/31 05:52:44 slusarz Exp $
 *
 * Copyright 2002-2005 Michael Slusarz <slusarz@bigworm.colorado.edu>
 *
 * See the enclosed file COPYING for license information (GPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
 *
 * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
 * @since   IMP 4.0
 * @package IMP
 */
class IMP_Search {

    /**
     * Run a search.
     *
     * @param IMAP_Search_Query &$ob  An optional search query to add (via
     *                                'AND') to the active search.
     *
     * @return array  The sorted list.
     */
    function runSearch(&$ob)
    {
        global $imp, $prefs;

        $mbox = '';
        $sorted = array();
        $use_pop3 = ($imp['base_protocol'] == 'pop3');

        if (empty($imp['search']['query']) ||
            empty($imp['search']['folders'])) {
            return array();
        }

        require_once 'Horde/IMAP/Search.php';
        $imap_search = &IMAP_Search::singleton(array('pop3' => $use_pop3,
                                                     'charset' => NLS::getCharset()));

        /* Prepare the search query. */
        if (!empty($ob)) {
            $old_query = unserialize($imp['search']['query']);
            $query = &new IMAP_Search_Query();
            $query->imapAnd(array($ob, $old_query));
        } else {
            $query = unserialize($imp['search']['query']);
        }

        /* How do we want to sort results? */
        $sortby = $prefs->getValue('sortby');
        if ($sortby == SORTTHREAD) {
            $sortby = SORTDATE;
        }
        $sortdir = $prefs->getValue('sortdir');

        /* Prepare the IMAP string. */
        if ($use_pop3) {
            $stream = &$imp['stream'];
        } else {
            require_once IMP_BASE . '/lib/IMAP.php';
            $imp_imap = &IMP_IMAP::singleton();
            $stream = $imp_imap->openIMAPStream(null, OP_READONLY);
        }

        if (!$stream) {
            return $sorted;
        }

        for ($i = 0; $i < count($imp['search']['folders']); $i++) {
            if (!$use_pop3) {
                $mbox = IMP::serverString($imp['search']['folders'][$i]);
            }

            $results = $imap_search->searchSortMailbox($query, $stream, $mbox,
                                                       $sortby, $sortdir);

            if (is_array($results)) {
                for ($j = 0; $j < count($results); $j++) {
                    $sorted[] = $results[$j] . IMP_IDX_SEP .
                        $imp['search']['folders'][$i];
                }
            }
        }

        /* Close connection if not POP3. */
        if (!$use_pop3) {
            @imap_close($stream);
        }

        return $sorted;
    }

    /**
     * Sets the IMAP search query in the IMP session.
     *
     * @param IMAP_Search_Query $query  The search query object.
     * @param array $folders            The list of folders to search.
     * @param array $search             The search array used to build the
     *                                  search UI screen.
     * @param string $label             The label to use for the search
     *                                  results.
     * @param string $id                The virtual folder id.
     */
    function createSearchQuery($query, $folders, $search, $label, $id = null)
    {
        $_SESSION['imp']['search'] = array(
            'query' => serialize($query),
            'folders' => $folders,
            'uiinfo' => serialize($search),
            'label' => $label,
            'vfolder_id' => $id
        );
    }

    /**
     * Retrieves the previously stored search UI information.
     *
     * @return array  The array necessary to rebuild the search UI page.
     */
    function retrieveUIQuery()
    {
        return (isset($GLOBALS['imp']['search']['uiinfo']))
            ? unserialize($GLOBALS['imp']['search']['uiinfo'])
            : array();
    }

    /**
     * Generates the label to use for search results.
     *
     * @return string  The search results label.
     */
    function searchLabel()
    {
        return $GLOBALS['imp']['search']['label'];
    }

    /**
     * Generates a URL with any necessary information required for handling a
     * search mailbox added to the parameters.
     *
     * @param string $page     Page name to link to.
     * @param string $mailbox  The mailbox to use on the linked page.
     *
     * @return string  URL to $page with any necessary search information
     *                 added to the parameter list of the URL.
     */
    function generateSearchUrl($page, $mailbox)
    {
        $link = Horde::applicationUrl($page);

        foreach (IMP_Search::getSearchParameters($mailbox) as $key => $val) {
            $link = Util::addParameter($link, $key, $val);
        }

        return $link;
    }

    /**
     * Returns a list of parameters necessary for handling a search mailbox.
     *
     * @param string $mailbox  The mailbox to use on the linked page.
     *
     * @return array  The list of parameters needed for handling a search
     *                mailbox (may be empty if not currently in a search
     *                mailbox).
     */
    function getSearchParameters($mailbox)
    {
        global $imp;

        $params = array();

        if ($imp['mailbox'] == IMP_SEARCH_MBOX) {
            $params['thismailbox'] = $mailbox;
            $params['mailbox'] = $imp['mailbox'];
        }

        return $params;
    }

}
