<?php
/**
 * The IMP_IMAP:: class facilitates connections to the IMAP/POP3 server
 * via the c-client PHP extensions.
 *
 * $Horde: imp/lib/IMAP.php,v 1.8 2003/07/25 05:55:03 slusarz Exp $
 *
 * Copyright 2003 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>
 * @version $Revision: 1.8 $
 * @since   IMP 4.0
 * @package imp
 */
class IMP_IMAP {

    /**
     * The server string.
     *
     * @var string $_serverString
     */
    var $_serverString;

    /**
     * The username for the server.
     *
     * @var string $_user
     */
    var $_user;

    /**
     * The password for the mail server.
     *
     * @var string $_pass
     */
    var $_pass;

    /**
     * The currently open mailbox.
     *
     * @var string $_openMbox
     */
    var $_openMbox = null;

    /**
     * The IMAP flags set in the currently open mailbox.
     *
     * @var integer $_mboxFlags
     */
    var $_mboxFlags = null;

    /**
     * Attempts to return a reference to a concrete IMP_IMAP instance.
     * It will only create a new instance if no IMP_IMAP instance currently
     * exists.
     *
     * This method must be invoked as:
     *   $imp_imap = &IMP_IMAP::singleton();
     *
     * @access public
     *
     * @param optional array $params  Parameters needed.
     *
     * @return object IMP_IMAP  The concrete IMP_IMAP reference, or
     *                          false on error.
     */
    function &singleton($params = array())
    {
        static $instance;

        if (!isset($instance)) {
            $instance = new IMP_IMAP($params);
        }

        return $instance;
    }

    /**
     * Constructor.
     *
     * @access public
     *
     * @param optional array $params  Any additional parameters needed.
     */
    function IMP_IMAP($params = array())
    {
        $this->_serverString = IMP::serverString(null, $_SESSION['imp']['protocol']);
        $this->_user = $_SESSION['imp']['user'];
        $this->_pass = Secret::read(Secret::getKey('imp'), $_SESSION['imp']['pass']);
    }

    /**
     * Open an IMAP stream.
     *
     * @access public
     *
     * @param optional string $mbox    A mailbox to open.
     * @param optional integer $flags  Any flags that need to be passed to
     *                                 imap_open().
     *
     * @return boolean  The return from the imap_open() call.
     */
    function openIMAPStream($mbox = null, $flags = 0)
    {
        return @imap_open($this->_serverString . $mbox, $this->_user, $this->_pass, $flags);
    }

    /**
     * Change the currently active IMP IMAP stream to a new mailbox
     * (if necessary).
     *
     * @access public
     *
     * @param string $mbox             The new mailbox.
     * @param optional integer $flags  Any flags that need to be passed to
     *                                 imap_reopen().
     *
     * @return boolean  True on success, false on error.
     */
    function changeMbox($mbox, $flags = null)
    {
        /* Open a connection if none exists. */
        if (!isset($_SESSION['imp']['stream']) ||
            empty($_SESSION['imp']['stream'])) {
            if (($_SESSION['imp']['stream'] = $this->openIMAPStream($mbox, $flags))) {
                $this->_openMbox = $mbox;
                $this->_mboxFlags = $flags;
                return true;
            } else {
                return false;
            }
        }

        if ($_SESSION['imp']['base_protocol'] == 'pop3') {
            return true;
        }

        /* Only reopen mailbox if we need to - either we are changing
           mailboxes or the flags for the current mailbox has changed. */
        if (($this->_openMbox != $mbox) || ($this->_mboxFlags != $flags)) {
            if (is_null($flags)) {
                $result = @imap_reopen($_SESSION['imp']['stream'], $this->_serverString . $mbox);
            } else {
                $result = @imap_reopen($_SESSION['imp']['stream'], $this->_serverString . $mbox, $flags);
            }

            if ($result) {
                $this->_openMbox = $mbox;
                $this->_mboxFlags = $flags;
                return true;
            } else {
                return false;
            }
        }

        return true;
    }

    /**
     * Reopen an IMAP stream.
     *
     * @access public
     *
     * @param optional boolean $expunge  Expunge before closing?
     *
     * @return boolean  See Auth_imp::authenticate().
     */
    function reopenIMAPStream($expunge = false)
    {
        $flags = 0;
        if ($expunge) {
            $flags = CL_EXPUNGE;
        }

        @imap_close($_SESSION['imp']['stream'], $flags);
        unset($_SESSION['imp']['stream']);

        return IMP::checkAuthentication(null, true);
    }

}
