<?php
/**
 * $Horde: vacation/lib/Driver/sql.php,v 1.13 2003/08/25 18:28:41 jan Exp $
 *
 * Copyright 2001-2003 Ilya Krel and Mike Cochrane
 *
 * See the enclosed file LICENSE for license information (BSD). If you
 * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
 *
 * Vacation_Driver_sql:: implements the Vacation_Driver API for SQL servers.
 *
 * @author  Ilya Krel <mail@krel.org.org>
 * @author  Mike Cochrane <mike@graftonhall.co.nz>
 * @version $Revision: 1.13 $
 * @since   Vacation 2.1
 * @package vacation
 */
class Vacation_Driver_sql extends Vacation_Driver {

    /** SQL connection object. */
    var $_db;

    /** Boolean which contains the state of the SQL connection. */
    var $_connected = false;

    /**
     * Enable a vacation message for a user.
     *
     * @param string    $user      The username to enable vacation for.
     * @param string    $realm     The realm of the user.
     * @param string    $password  The password of the user.
     * @param string    $message   The message to install.
     * @param string    $alias     The email alias for vacation to use --
     *                             Not yet implemented.
     *
     * @return boolean  Returns true on success, false on error.
     */
    function setVacation($user, $realm, $password, $message, $alias)
    {
        /* _connect() will die with Horde::fatal() upon failure. */
        $this->_connect();

        // Split message into parts to get subject.
        $myarray = explode("\n", $message);

        /* Determine if $message contains Subject: and if it does
         * split it. */
        if (strstr($myarray[0], 'Subject:')) {
            $mysubject = $myarray[0];
            $myarray[0] = '';
            $mymessage = implode('', $myarray);
        } else {
            $mysubject = '';
            $mymessage = $message;
        }

        /* Build the SQL query. */
        $query = 'UPDATE ' . $this->params['table'];
        $query .= ' SET ' . $this->params['vacation'] . ' = ' . $this->_db->quote('y');
        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($user);
        $query .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));

        $query1 = 'UPDATE ' . $this->params['table'];
        $query1 .= ' SET ' . $this->params['message'] . ' = ' . $this->_db->quote($mymessage);
        $query1 .= ' ,  ' . $this->params['subject'] . ' = ' . $this->_db->quote($mysubject);
        $query1 .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($user);
        $query1 .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));

        /* Execute the query. */
        $result = $this->_db->query($query);
        $result1 = $this->_db->query($query1);

        if (!is_a($result, 'PEAR_Error') && !is_a($result1, 'PEAR_Error')) {
            if ($result === DB_OK && $result1 === DB_OK) {
                $this->_disconnect();
                return true;
            } else {
                $this->_disconnect();
                return false;
            }
        } else {
            $this->_disconnect();
            return false;
        }
        $this->_disconnect();
        return false;
    }

    /**
     * Disable the vacation message for a user.
     *
     * @param string    $user      The username of the user.
     * @param string    $realm     The realm of the user.
     * @param string    $pass      The password of the user.
     *
     * @return boolean  Returns true on success, false on error.
     */
    function unsetVacation($user, $realm, $password)
    {
        /* _connect() will die with Horde::fatal() upon failure. */
        $this->_connect();

        /* Build the SQL query. */
        $query = 'UPDATE ' . $this->params['table'];
        $query .= ' SET ' . $this->params['vacation'] . ' = ' . $this->_db->quote('n');
        $query .= ' ,  ' . $this->params['message'] . ' = ' . $this->_db->quote('');
        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($user);
        $query .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));

        /* Execute the query. */
        $result = $this->_db->query($query);

        if (!is_a($result, 'PEAR_Error')) {
            if ($result === DB_OK) {
                $this->_disconnect();
                return true;
            } else {
                $this->_disconnect();
                return false;
            }
        } else {
            $this->_disconnect();
            return false;
        }
        $this->_disconnect();
        return false;
    }

    /**
     * Retrieve the current vacation details for the user.
     *
     * @param   $user        The username for which to retrieve details.
     * @param   $realm       The realm (domain) for the user.
     * @param   $password    The password for user.
     *
     * @return  mixed        Vacation details or false.
     */
    function _getUserDetails($user, $realm, $password)
    {
        /* _connect() will die with Horde::fatal() upon failure. */
        $this->_connect();

        /* Build the SQL query. */
        $query = 'SELECT ' . $this->params['vacation'] . ' . AS vacation, ' . $this->params['message'] . ' AS message';
        $query .= ' FROM ' . $this->params['table'];
        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($user);
        $query .= ' AND password = ' . $this->_db->quote(md5($password));

        /* Execute the query. */
        $result = $this->_db->query($query);

        if (!is_a($result, 'PEAR_Error')) {
            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);

            if (is_array($row)) {
                $this->_disconnect();
                return $row;
            } else {
                $this->_disconnect();
                $result->free();
                return false;
            }
        }

        $this->_disconnect();
        return false;
    }

    /**
     * Do an SQL connect and login as user with privilege to change
     * vacation.
     *
     * @return   boolean   True or False based on success of connect
     */
    function _connect()
    {
        if (!$this->_connected) {
            Horde::assertDriverConfig($this->params, 'server',
                array('phptype', 'hostspec', 'username', 'database', 'table'),
                'vacation authentication SQL');

            /* Connect to the SQL server using the supplied parameters. */
            require_once 'DB.php';
            $this->_db = &DB::connect($this->params,
                                      array('persistent' => !empty($this->_params['persistent'])));
            if (is_a($this->_db, 'PEAR_Error')) {
                Horde::fatal(PEAR::raiseError(_("Unable to connect to SQL server.")), __FILE__, __LINE__);
            }

            /* Enable the "portability" option. */
            $this->_db->setOption('optimize', 'portability');
            $this->_connected = true;
        }

        return true;
    }

    /**
     * Disconnect from the SQL server and clean up the connection.
     *
     * @return boolean true on success, false on failure.
     */
    function _disconnect()
    {
        if ($this->_connected) {
            $this->_connected = false;
            return $this->_db->disconnect();
        }

        return true;
    }

}
