<?php
/**
 * The composite class chains other drivers together to change and a user's
 * password stored on various backends.
 *
 * $Horde: passwd/lib/Driver/composite.php,v 1.1 2003/07/23 20:12:48 max Exp $
 *
 * @author   Max Kalika <max@horde.org>
 * @version $Revision: 1.1 $
 * @package passwd
 */
class Passwd_Driver_composite extends Passwd_Driver {

    /** Hash of instanciated drivers. */
    var $_drivers = array();

    /** Boolean which contains state of loaded drivers. */
    var $_loaded = false;

    /** Hash containing driver configuration and parameters. */
    var $_params = array();

    /**
     * Constructs a new composite Passwd_Driver object.
     *
     * @param array $params  A hash containing chained drivers and their parameters.
     */
    function Passwd_Driver_composite($params = array())
    {
        if (!isset($params['drivers']) || !is_array($params['drivers'])) {
            return PEAR::raiseError(_("Required 'drivers' is misconfigured in Composite configuration."));
        }

        $this->_params = $params['drivers'];
    }

    /**
     * Instanciate configured drivers
     *
     * @return  boolean   True on success or PEAR_Error on failure.
     *
     */
    function _loadDrivers()
    {
        if ($this->_loaded) {
            return true;
        }

        foreach ($this->_params as $key => $settings) {
            if (!array_key_exists($key, $this->_drivers)) {

                $res = &Passwd_Driver::factory($settings['driver'],
                                               $settings['params']);

                if (is_a($res, 'PEAR_Error')) {
                    return PEAR::raiseError(sprintf(_("%s: unable to load driver: %s"),
                                                    $key, $res->getMessage()));
                }

                $this->_drivers[$key] = $res;
            }
        }

        $this->_loaded = true;
        return true;
    }

    /**
     * Change the user's password.
     *
     * @param   $username      The user for which to change the password.
     * @param   $old_password  The old (current) user password.
     * @param   $new_password  The new user password to set.
     *
     * @return  boolean        True or false based on success of the change.
     */
    function changePassword($username,  $old_password, $new_password)
    {
        global $notification;

        $res = $this->_loadDrivers();
        if (is_a($res, 'PEAR_Error')) {
            return $res;
        }

        foreach ($this->_drivers as $key => $driver) {
            $res = $driver->changePassword($username, $old_password,
                                            $new_password);
            if (!is_a($res, 'PEAR_Error')) {
                $notification->push(sprintf(_("Password changed on %s."),
                                            $this->_params[$key]['name']),
                                            'horde.success');
            } else {
                $notification->push(sprintf(_("Failure in changing password on %s: %s"),
                                            $this->_params[$key]['name'],
                                            $res->getMessage()), 'horde.error');
            }
        }

        return true;
    }

}
