steffen: server/kolab-horde-framework/kolab-horde-framework/Prefs/Prefs CategoryManager.php, NONE, 1.1 UI.php, NONE, 1.1 imsp.php, NONE, 1.1 ldap.php, NONE, 1.1 session.php, NONE, 1.1 sql.php, NONE, 1.1

cvs at intevation.de cvs at intevation.de
Fri Oct 14 16:33:12 CEST 2005


Author: steffen

Update of /kolabrepository/server/kolab-horde-framework/kolab-horde-framework/Prefs/Prefs
In directory doto:/tmp/cvs-serv28903/kolab-horde-framework/kolab-horde-framework/Prefs/Prefs

Added Files:
	CategoryManager.php UI.php imsp.php ldap.php session.php 
	sql.php 
Log Message:
Separated Horde Framework from kolab-resource-handlers

--- NEW FILE: CategoryManager.php ---
<?php
/**
 * Class for handling a list of categories stored in a user's
 * preferences.
 *
 * $Horde: framework/Prefs/Prefs/CategoryManager.php,v 1.8 2004/05/27 17:51:54 chuck Exp $
 *
 * Copyright 2004 Chuck Hagenbuch <chuck at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck at horde.org>
 * @version $Revision: 1.1 $
 * @since   Horde 3.0
 * @package Horde_Prefs
 */
class Prefs_CategoryManager {

    /**
     * Get all categories.
     */
    function get()
    {
        global $prefs;

        $string = $prefs->getValue('categories');
        if (empty($string)) {
            return array();
        }

        $categories = explode('|', $string);
        asort($categories);

        return $categories;
    }

    function getSelect($id, $current = null)
    {
        global $prefs;

        $html = '<select id="' . htmlspecialchars($id) . '" name="' . htmlspecialchars($id) . '">';

        $categories = $this->get();
        if (!in_array($current, $categories) && !empty($current)) {
            $html .= '<option value="*new*' . htmlspecialchars($current) . '">' . sprintf(_("Use Current: %s"), htmlspecialchars($current)) . '</option>';
            $html .= '<option value="">----</option>';
        }

        if (!$prefs->isLocked('categories')) {
            $html .= '<option value="*new*">' . _("New Category") . "</option>\n";
            $html .= '<option value="">----</option>';
        }

        // Always add an Unfiled option.
        $html .= '<option value=""';
        $html .= empty($current) ? ' selected="selected">' : '>';
        $html .= htmlspecialchars(_("Unfiled")) . '</option>';

        foreach ($categories as $name) {
            $html .= '<option value="' . htmlspecialchars($name) . '"';
            $html .= ($name == $current) ? ' selected="selected">' : '>';
            $html .= htmlspecialchars($name) . '</option>';
        }
        $html .= '</select>';

        return $html;
    }

    function getJavaScript($formname, $elementname)
    {
        $prompt = addslashes(_("Please type the new category name:"));
        $error = addslashes(_("You must type a new category name."));

        return <<<JAVASCRIPT

<script language="JavaScript" type="text/javascript">
<!--
function checkCategory()
{
    if (document.$formname.$elementname.value == '*new*') {
        var category = window.prompt('$prompt', '');
        if (category != null && category != '') {
            document.$formname.new_category.value = category;
        } else {
            window.alert('$error');
            return false;
        }
    } else if (document.$formname.$elementname.value.indexOf('*new*') != -1) {
        document.$formname.new_category.value = document.$formname.$elementname.value.substr(5, document.$formname.$elementname.value.length);
    }

    return true;
}
//-->
</script>
JAVASCRIPT;
    }

    /**
     * Add a new category.
     *
     * @param string $category  The name of the category to add.
     *
     * @return mixed  False on failure, or the new category's name.
     */
    function add($category)
    {
        global $prefs;

        if ($prefs->isLocked('categories') || empty($category)) {
            return false;
        }

        $categories = $this->get();
        if (in_array($category, $categories)) {
            return false;
        }

        $categories[] = $category;
        $prefs->setValue('categories', implode('|', $categories));

        return $category;
    }

    /**
     * Delete a category.
     *
     * @param string $category  The category to remove.
     *
     * @return boolean  True on success, false on failure.
     */
    function remove($category)
    {
        global $prefs;

        if ($prefs->isLocked('categories')) {
            return false;
        }

        $categories = $this->get();

        $key = array_search($category, $categories);
        if ($key === false) {
            return $key;
        }

        unset($categories[$key]);
        $prefs->setValue('categories', implode('|', $categories));

        // Remove any color settings for $category.
        $colors = $this->colors();
        unset($colors[$category]);
        $this->setColors($colors);

        return true;
    }

    /**
     * Returns the color for each of the user's categories.
     *
     * @return array  A list of colors, key is the category name,
     *                                  value is the HTML color code.
     */
    function colors()
    {
        global $prefs;

        /* Default values that can be overridden but must always be
         * present. */
        $colors['_default_'] = '#FFFFFF';
        $colors['_unfiled_'] = '#DDDDDD';

        $pairs = explode('|', $prefs->getValue('category_colors'));
        foreach ($pairs as $pair) {
            if (!empty($pair)) {
                list($category, $color) = explode(':', $pair);
                $colors[$category] = $color;
            }
        }

        $colors[''] = $colors['_unfiled_'];

        return $colors;
    }

    function setColor($category, $color)
    {
        $colors = $this->colors();
        $colors[$category] = $color;
        $this->setColors($colors);
    }

    function setColors($colors)
    {
        global $prefs;

        $pairs = array();
        foreach ($colors as $category => $color) {
            if (!empty($category)) {
                $pairs[] = "$category:$color";
            }
        }

        $prefs->setValue('category_colors', implode('|', $pairs));
    }

}

--- NEW FILE: UI.php ---
<?php
/**
 * Class for auto-generating the preferences user interface and
 * processing the forms.
 *
 * $Horde: framework/Prefs/Prefs/UI.php,v 1.46 2004/05/18 19:48:24 chuck Exp $
 *
 * Copyright 2001-2004 Chuck Hagenbuch <chuck at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck at horde.org>
 * @version $Revision: 1.1 $
 * @since   Horde 2.1
 * @package Horde_Prefs
 */
class Prefs_UI {

    /**
     * Determine whether or not a preferences group is editable.
     *
     * @access public
     *
     * @param string $group  The preferences group to check.
     *
     * @return boolean  Whether or not the group is editable.
     */
    function groupIsEditable($group)
    {
        global $prefs, $prefGroups;
        static $results;

        if (!isset($results)) {
            $results = array();
        }

        if (!isset($results[$group])) {
            if (!empty($group['url'])) {
                $results[$group] = true;
            } else {
                $results[$group] = false;
                if (isset($prefGroups[$group]['members'])) {
                    foreach ($prefGroups[$group]['members'] as $pref) {
                        if (!$prefs->isLocked($pref)) {
                            $results[$group] = true;
                            return true;
                        }
                    }
                }
            }
        }

        return $results[$group];
    }

    /**
     * Handle a preferences form submission if there is one, updating
     * any preferences which have been changed.
     *
     * @param string $group  The preferences group that was edited.
     * @param object $save   The object where the changed values are
     *                       saved. Must implement setValue(string, string).
     *
     * @return boolean  Whether preferences have been updated.
     */
    function handleForm(&$group, &$save)
    {
        global $prefs, $prefGroups, $_prefs, $notification, $registry;

        $updated = false;

        /* Run through the action handlers */
        if (Util::getFormData('actionID') == 'update_prefs') {
            if (isset($group) && Prefs_UI::groupIsEditable($group)) {
                $updated = false;

                foreach ($prefGroups[$group]['members'] as $pref) {
                    if (!$prefs->isLocked($pref) ||
                        ($_prefs[$pref]['type'] == 'special')) {
                        switch ($_prefs[$pref]['type']) {

                        /* These either aren't set or are set in other parts
                           of the UI. */
                        case 'implicit':
                        case 'link':
                            break;

                        case 'select':
                        case 'text':
                        case 'textarea':
                        case 'password':
                            $updated = $updated | $save->setValue($pref, Util::getFormData($pref));
                            break;

                        case 'enum':
                            $val = Util::getFormData($pref);
                            if (isset($_prefs[$pref]['enum'][$val])) {
                                $updated = $updated | $save->setValue($pref, $val);
                            } else {
                                $notification->push(_("An illegal value was specified."), 'horde.error');
                            }
                            break;

                        case 'multienum':
                            $vals = Util::getFormData($pref);
                            $set = array();
                            $invalid = false;
                            if (is_array($vals)) {
                                foreach ($vals as $val) {
                                    if (isset($_prefs[$pref]['enum'][$val])) {
                                        $set[] = $val;
                                    } else {
                                        $invalid = true;
                                        continue;
                                    }
                                }
                            }

                            if ($invalid) {
                                $notification->push(_("An illegal value was specified."), 'horde.error');
                            } else {
                                $updated = $updated | $save->setValue($pref, @serialize($set));
                            }
                            break;

                        case 'number':
                            $num = Util::getFormData($pref);
                            if (intval($num) != $num) {
                                $notification->push(_("This value must be a number."), 'horde.error');
                            } elseif ($num == 0) {
                                $notification->push(_("This number must be at least one."), 'horde.error');
                            } else {
                                $updated = $updated | $save->setValue($pref, $num);
                            }
                            break;

                        case 'checkbox':
                            $val = Util::getFormData($pref);
                            $updated = $updated | $save->setValue($pref, isset($val) ? 1 : 0);
                            break;

                        case 'special':
                            /* Code for special elements must be
                             * written specifically for each
                             * application. */
                            if (function_exists('handle_' . $pref)) {
                                $updated = $updated | call_user_func('handle_' . $pref, $updated);
                            }
                            break;
                        }
                    }
                }

                /* Do anything that we need to do as a result of
                 * certain preferences changing. */
                if ($prefs->isDirty('language')) {
                    NLS::setLang($prefs->getValue('language'));
                    NLS::setTextdomain($registry->getApp(), $registry->getParam('fileroot') . '/locale', NLS::getCharset());
                    String::setDefaultCharset(NLS::getCharset());
                }
                if ($prefs->isDirty('language') ||
                    $prefs->isDirty('theme') ||
                    $prefs->isDirty('menu_view')) {
                    $notification->push('if (window.parent.frames.horde_menu) window.parent.frames.horde_menu.location.reload();', 'javascript');
                }

                if ($updated) {
                    if (function_exists('prefs_callback')) {
                        prefs_callback();
                    }
                    $notification->push(_("Your options have been updated."), 'horde.message');
                    $group = null;
                }
            }
        }

        return $updated;
    }

    /**
     * Generate the UI for the preferences interface, either for a
     * specific group, or the group selection interface.
     *
     * @access public
     *
     * @param optional string $group  The group to generate the UI for.
     */
    function generateUI($group = null)
    {
        global $browser, $conf, $prefs, $prefGroups, $_prefs, $registry, $app;

        /* Show the header. */
        Prefs_UI::generateHeader($group);

        /* Assign variables to hold select lists. */
        if (!$prefs->isLocked('language')) {
            $GLOBALS['language_options'] = &$GLOBALS['nls']['languages'];
        }

        if (!empty($group) && Prefs_UI::groupIsEditable($group)) {
            foreach ($prefGroups[$group]['members'] as $pref) {
                if (!$prefs->isLocked($pref)) {
                    /* Get the help link. */
                    if (isset($_prefs[$pref]['help']) &&
                        $_prefs[$pref]['help'] &&
                        $conf['user']['online_help'] &&
                        $browser->hasFeature('javascript')) {
                        $helplink = Help::link(!empty($_prefs[$pref]['shared']) ? 'horde' : $registry->getApp(), $_prefs[$pref]['help']);
                    } else {
                        $helplink = null;
                    }

                    switch ($_prefs[$pref]['type']) {
                    case 'implicit':
                        break;

                    case 'special':
                        require $registry->getParam('templates', !empty($_prefs[$pref]['shared']) ? 'horde' : $registry->getApp()) . "/prefs/$pref.inc";
                        break;

                    default:
                        require $registry->getParam('templates', 'horde') . '/prefs/' . $_prefs[$pref]['type'] . '.inc';
                        break;
                    }
                }
            }
            require $registry->getParam('templates', 'horde') . '/prefs/end.inc';
        } else {
            $columns = array();
            if (is_array($prefGroups)) {
                foreach ($prefGroups as $group => $gvals) {
                    $col = $gvals['column'];
                    unset($gvals['column']);
                    $columns[$col][$group] = $gvals;
                }
                $span = round(100 / count($columns));
            } else {
                $span = 100;
            }

            require $registry->getParam('templates', 'horde') . '/prefs/overview.inc';
        }
    }

    /**
     * Generates the the full header of a preference screen including
     * menu and navigation bars.
     *
     * @access public
     *
     * @param optional string $group  The group to generate the header for.
     */
    function generateHeader($group = null)
    {
        global $registry, $prefGroups, $app, $menu, $perms;

        $title = _("User Options");
        require $registry->getParam('templates', $app) . '/common-header.inc';
        if (isset($menu) && is_a($menu, 'Menu')) {
            /* App has a defined menu object and can return a menu
             * array. */
            $menu = $menu->getMenu();

            /* Use the default menu template to output this menu array. */
            require $registry->getParam('templates', 'horde') . '/menu/menu.inc';
        } else {
            /* App has no menu object so is probably using a ::menu()
             * function. */
            call_user_func(array($app, 'menu'));
        }

        if (is_callable(array($app, 'status'))) {
            call_user_func(array($app, 'status'));
        } else {
            $GLOBALS['notification']->notify(array('listeners' => 'status'));
        }

        /* Get list of accessible applications. */
        $apps = array();
        foreach ($registry->applications as $application => $params) {
            if ($application == 'problem' || $application == 'logout' || $params['status'] == 'heading') {
                continue;
            }

            /* Check if the current user has permisson to see this
             * application, and if the application is active.
             * Administrators always see all applications. */
            if ((Auth::isAdmin() &&
                 ($params['status'] != 'inactive')) ||
                (($perms->exists($application) ? $perms->hasPermission($application, Auth::getAuth(), PERMS_READ) : Auth::getAuth()) &&
                 ($params['status'] == 'active' || $params['status'] == 'notoolbar'))) {
                $apps[$application] = _($params['name']);
            }
        }
        asort($apps);

        /* Show the current application and a form for switching
         * applications. */
        require $registry->getParam('templates', 'horde') . '/prefs/app.inc';

        if (!empty($group) && Prefs_UI::groupIsEditable($group)) {
            require $registry->getParam('templates', 'horde') . '/prefs/begin.inc';
        }
    }

    /**
     * Generate the content of the title bar navigation cell (previous
     * | next option group).
     *
     * @access public
     *
     * @param          string $group        Current option group.
     * @param optional string $attributes   The optional <td> attributes.
     */
    function generateNavigationCell($group, $attributes = 'class="header" align="right"')
    {
        global $prefGroups, $registry, $app;

        // Search for previous and next groups.
        $previous = null;
        $next = null;
        $last = null;
        $first = null;
        $found = false;
        $finish = false;
        foreach ($prefGroups as $pgroup => $gval) {
            if (Prefs_UI::groupIsEditable($pgroup)) {
                if (!$first) {
                    $first = $pgroup;
                }
                if (!$found) {
                    if ($pgroup == $group) {
                        $previous = $last;
                        $found = true;
                    }
                } else {
                    if (!$finish) {
                        $finish = true;
                        $next = $pgroup;
                    }
                }
                $last = $pgroup;
            }
        }
        if (!$previous) {
            $previous = $last;
        }
        if (!$next) {
            $next = $first;
        }

        /* Don't loop if there's only one group. */
        if ($next == $previous) {
            return;
        }

        echo "<td $attributes><span class='smallheader'>";
        if (!empty($prefGroups[$previous]['url'])) {
            echo Horde::link(Horde::applicationUrl($prefGroups[$previous]['url']),
                             _("Previous options"), 'menuitem');
            echo '<< ' . $prefGroups[$previous]['label'];
        } else {
            echo Horde::link(Util::addParameter(Horde::url($registry->getParam('webroot', 'horde') . '/services/prefs.php'), array('group' => $previous, 'app' => $app)),
                             _("Previous options"), 'menuitem');
            echo '<< ' . $prefGroups[$previous]['label'];
        }
        echo '</a> | ';
        if (!empty($prefGroups[$next]['url'])) {
            echo Horde::link(Horde::applicationUrl($prefGroups[$next]['url']),
                             _("Next options"), 'menuitem');
            echo $prefGroups[$next]['label'] . ' >>';
        } else {
            echo Horde::link(Util::addParameter(Horde::url($registry->getParam('webroot', 'horde') . '/services/prefs.php'), array('group' => $next, 'app' => $app)),
                             _("Next options"), 'menuitem');
            echo $prefGroups[$next]['label'] . ' >>';
        }
        echo '</a></span></td>';
    }

    /**
     * Get the default application to show preferences for. Defaults
     * to 'horde'.
     */
    function getDefaultApp()
    {
        global $registry;

        $applications = $registry->listApps(null, true, PERMS_READ);
        $default = isset($applications['horde']) ? 'horde' : array_shift($applications);
        while ($default == 'logout' || $default == 'problem') {
            /* FIXME: We should probably have a better way of filtering stuff
             * like this out. */
            $default = array_shift($applications);
        }

        return $default;
    }

}

--- NEW FILE: imsp.php ---
<?php
/**
 * Prefrence storage implementation for an IMSP server.
 *
 * $Horde: framework/Prefs/Prefs/imsp.php,v 1.1 2004/04/16 22:55:32 chuck Exp $
 *
 * Copyright 2004 Michael Rubinsky <mike at theupstairsroom.com>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @version $Revision: 1.1 $
 * @author  Michael Rubinsky <mike at theupstairsroom.com>
 * @package Horde_Prefs
 */
class Prefs_imsp extends Prefs {

    /**
     * Constructor function.
     * $params must contain:
     * 'auth_method', 'server', 'port'
     *
     * @param string $user Username of current user.
     * @param string $password Password for current user.
     * @param string $scope The scope for these preferences.
     * @param array $params The parameters needed for this object.
     * @param boolean $caching are we using session cache?
     */
    function Prefs_imsp($user, $password = '', $scope = '',
                        $params = null, $caching = true)
    {
        global $conf;

        parent::Prefs();
        require_once 'Net/IMSP.php';

        $this->_scope = $scope;
        $this->_caching = $caching;
        $this->_user = $user;
        $this->params = $params;

        if (preg_match('/(^.*)@/', $user, $matches)) {
            $this->params['username'] = $matches[1];
        } else {
            $this->params['username'] = $user;
        }
        $this->params['password'] = $password;

        $this->_imsp = &Net_IMSP::singleton('Options', $this->params);
        $result = $this->_imsp->init();
        if (is_a($result,'PEAR_Error')) {
            Horde::fatal($result, __FILE__, __LINE__);
        }
        $this->_imsp->setLogger($conf['log']);
    }

    /**
     * Retrieves the requested set of preferences from the IMSP server.
     *
     * @access public
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function retrieve()
    {
        // Get the defaults.
        parent::retrieve();

        // Get the shared prefs and remove the scope value from the
        // string.
        $global_prefs = $this->_imsp->get('horde.*');
        if (is_a($global_prefs, 'PEAR_Error')) {
            return $global_prefs;
        }

        foreach ($global_prefs as $key => $val) {
            $newKey = str_replace('horde.', '', $key);
            if ($val == '-') {
                $val = $this->getDefault($newKey);
            }

            if (isset($this->_prefs[$newKey])) {
                $this->setValue($newKey, $val);
            } else {
                $this->add($newKey, $val, _PREF_SHARED);
            }

            // Don't forget to clean it.
            $this->setDirty($newKey, false);
        }

        // Now the app specific prefs.
        $local_prefs = $this->_imsp->get($this->_scope . '.*');
        if (is_a($local_prefs, 'PEAR_Error')) {
            return $local_prefs;
        }

        foreach ($local_prefs as $key => $val) {
            $newKey = str_replace($this->_scope . '.' , '', $key);
            if ($val == '-') {
                $val = $this->getDefault($newKey);
            }
            if (isset($this->_prefs[$newKey])) {
                $this->setValue($newKey, $val);
            } else {
                $this->add($newKey, $val, 0);
            }

            // Clean the pref.
            $this->setDirty($newKey, false);
        }

        $_SESSION['prefs_cache']['_filled']['horde'] = true;
        $_SESSION['prefs_cache']['_filled'][$this->_scope] = true;
        $this->_callHooks();
        $this->cacheUpdate();
        return true;
    }

    /**
     * Stores all dirty prefs to IMSP server.
     *
     * @access public
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function store()
    {
        $dirty_prefs = $this->_dirtyPrefs();
        if (!count($dirty_prefs)) {
            return true;
        }

        foreach ($dirty_prefs as $name) {
            $scope = $this->getScope($name);
            $value = $this->getValue($name);
            if (empty($value)) {
                $value = '-';
            }

            $result = $this->_imsp->set($scope . '.' . $name, $value);
            if (is_a($result, 'PEAR_Error')) {
                $GLOBALS['notification']->push("There was a problem saving the prefrences");
                return $result;
            }

            // Clean the pref since it was just saved.
            $this->setDirty($name, false);
        }

        $this->cacheUpdate();
        return true;
    }

}

--- NEW FILE: ldap.php ---
<?php
/**
 * Preferences storage implementation for PHP's LDAP extention.
 *
 * Required parameters:
 * ====================
 *   'basedn'    --  The base DN for the LDAP server.
 *   'hostspec'  --  The hostname of the LDAP server.
 *   'uid'       --  The username search key.
 *
 * Optional parameters:
 * ====================
 *   'password'  --  'rootdn's password for bind authentication.
 *   'port'      --  The port of the LDAP server.
 *                   DEFAULT: 389
 *   'rootdn'    --  The DN of the root (administrative) account to bind for
 *                   write operations.
 *   'username'  --  TODO
 *   'version'   --  The version of the LDAP protocol to use.
 *                   DEFAULT: NONE (system default will be used)
 *
 * NOTE: parameter 'username' for $params has been deprecated. Use 'rootdn'.
 *
 *
 * If setting up as the Horde preference handler in conf.php, the following
 * is an example configuration.
 * The schemas needed for ldap are in horde/scripts/ldap.
 *
 *   $conf['prefs']['driver'] = 'ldap';
 *   $conf['prefs']['params']['hostspec'] = 'localhost';
 *   $conf['prefs']['params']['port'] = '389';
 *   $conf['prefs']['params']['basedn'] = 'dc=example,dc=org';
 *   $conf['prefs']['params']['uid'] = 'mail';
 *
 * The following is valid but would only be necessary if users
 * do NOT have permission to modify their own LDAP accounts.
 *
 *   $conf['prefs']['params']['rootdn'] = 'cn=Manager,dc=example,dc=org';
 *   $conf['prefs']['params']['password'] = 'password';
 *
 *
 * $Horde: framework/Prefs/Prefs/ldap.php,v 1.84 2004/02/21 17:40:32 chuck Exp $
 *
 * Copyright 1999-2004 Jon Parise <jon at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Jon Parise <jon at horde.org>
 * @version $Revision: 1.1 $
 * @since   Horde 1.3
 * @package Horde_Prefs
 */
class Prefs_ldap extends Prefs {

    /**
     * Hash containing connection parameters.
     *
     * @var array $params
     */
    var $_params = array();

    /**
     * Handle for the current LDAP connection.
     *
     * @var integer $connection
     */
    var $_connection;

    /**
     * Boolean indicating whether or not we're connected to the LDAP server.
     *
     * @var boolean $_connected
     */
    var $_connected = false;

    /**
     * String holding the user's DN.
     *
     * @var string $dn
     */
    var $_dn = '';


    /**
     * Constructs a new LDAP preferences object.
     *
     * @access public
     *
     * @param string $user               The user who owns these preferences.
     * @param string $password           The password associated with $user.
     * @param string $scope              The current application scope.
     * @param array $params              A hash containing connection
     *                                   parameters.
     * @param optional boolean $caching  Should caching be used?
     */
    function Prefs_ldap($user, $password, $scope = '',
                        $params = array(), $caching = false)
    {
        if (!Util::extensionExists('ldap')) {
            Horde::fatal(PEAR::raiseError(_("Prefs_ldap: Required LDAP extension not found."), __FILE__, __LINE__));
        }

        $this->_user = $user;
        $this->_scope = $scope;
        $this->_params = $params;
        $this->_caching = $caching;

        /* If a valid server port has not been specified, set the default. */
        if (!isset($this->_params['port']) || !is_int($this->_params['port'])) {
            $this->_params['port'] = 389;
        }

        /* If $params['rootdn'] is empty, authenticate as the current user.
           Note: This assumes the user is allowed to modify their own LDAP
                 entry. */
        if (empty($this->_params['username']) &&
            empty($this->_params['rootdn'])) {
            $this->_params['username'] = $user;
            $this->_params['password'] = $password;
        }

        parent::Prefs();
    }

    /**
     * Opens a connection to the LDAP server.
     *
     * @access private
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function _connect()
    {
        /* Return if already connected. */
        if ($this->_connected) {
            return true;
        }

        Horde::assertDriverConfig($this->_params, 'prefs',
            array('hostspec', 'basedn', 'uid', 'rootdn', 'password'),
            'preferences LDAP');

        /* Connect to the LDAP server anonymously. */
        $conn = ldap_connect($this->_params['hostspec'], $this->_params['port']);
        if (!$conn) {
            Horde::logMessage(
                sprintf('Failed to open an LDAP connection to %s.',
                        $this->_params['hostspec']),
                __FILE__, __LINE__);
            return false;
        }

        /* Set the LDAP protocol version. */
        if (isset($this->_params['version'])) {
            if (!ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION,
                                 $this->_params['version'])) {
                Horde::logMessage(
                    sprintf('Set LDAP protocol version to %d failed: [%d] %s',
                            $this->_params['version'],
                            ldap_errno($this->_connection),
                            ldap_error($this->_connection)),
                            __FILE__, __LINE__);
            }
        }

        /* Register our callback function to handle referrals. */
        if (function_exists('ldap_set_rebind_proc') &&
            !ldap_set_rebind_proc($conn, array($this, '_rebindProc'))) {
            Horde::logMessage(
                sprintf('Set rebind proc failed: [%d] %s',
                        ldap_errno($this->_connection),
                        ldap_error($this->_connection)),
                __FILE__, __LINE__);
            return false;
        }

        /* Define the DN of the current user */
        $this->_dn = sprintf('%s=%s,%s', $this->_params['uid'],
                            $this->_user,
                            $this->_params['basedn']);

        /* And the DN of the authenticating user (may be the same as above) */
        if (!empty($this->_params['rootdn'])) {
            $bind_dn = $this->_params['rootdn'];
        } else {
            $bind_dn = sprintf('%s=%s,%s', $this->_params['uid'],
                               $this->_params['username'],
                               $this->_params['basedn']);
        }

        /* Store the connection handle at the instance level. */
        $this->_connection = $conn;
        $this->_connected = true;

        /* Bind to the LDAP server as the authenticating user. */
        $bind = @ldap_bind($this->_connection, $bind_dn,
                           $this->_params['password']);
        if (!$bind) {
            Horde::logMessage(
                sprintf('Bind to server %s:%d with DN %s failed: [%d] %s',
                        $this->_params['hostspec'],
                        $this->_params['port'],
                        $bind_dn,
                        ldap_errno($this->_connection),
                        ldap_error($this->_connection)),
                __FILE__, __LINE__);
            return false;
        }

        /* Search for the user's full DN. */
        $search = ldap_search($this->_connection, $this->_params['basedn'],
                              $this->_params['uid'] . '=' . $this->_user,
                              array('dn'));
        if ($search) {
            $result = ldap_get_entries($this->_connection, $search);
            if ($result && !empty($result[0]['dn'])) {
                $this->_dn = $result[0]['dn'];
            }
        } else {
            Horde::logMessage(
                sprintf('Failed to retrieve user\'s DN: [%d] %s',
                        ldap_errno($this->_connection),
                        ldap_error($this->_connection)),
                __FILE__, __LINE__);
            return false;
        }

        return true;
    }

    /**
     * Disconnect from the LDAP server and clean up the connection.
     *
     * @access private
     *
     * @return boolean  True on success, false on failure.
     */
    function _disconnect()
    {
        if ($this->_connected) {
            $this->_dn = '';
            $this->_connected = false;
            return ldap_close($this->_connection);
        } else {
            return true;
        }
    }

    /**
     * Callback function for LDAP referrals.  This function is called when an
     * LDAP operation returns a referral to an alternate server.
     *
     * @access private
     *
     * @return integer  1 on error, 0 on success.
     *
     * @since Horde 2.1
     */
    function _rebindProc($conn, $who)
    {
        /* Strip out the hostname we're being redirected to. */
        $who = preg_replace(array('|^.*://|', '|:\d*$|'), '', $who);

        /* Figure out the DN of the authenticating user. */
        if (!empty($this->_params['rootdn'])) {
            $bind_dn = $this->_params['rootdn'];
        } else {
            $bind_dn = sprintf('%s=%s,%s', $this->_params['uid'],
                               $this->_params['username'],
                               $this->_params['basedn']);
        }

        /* Make sure the server we're being redirected to is in our list of
           valid servers. */
        if (!strstr($this->_params['hostspec'], $who)) {
            Horde::logMessage(
                sprintf('Referral target %s for DN %s is not in the authorized server list!', $who, $bind_dn),
                __FILE__, __LINE__);
            return 1;
        }

        /* Bind to the new server. */
        $bind = @ldap_bind($conn, $bind_dn, $this->_params['password']);
        if (!$bind) {
            Horde::logMessage(
                sprintf('Rebind to server %s:%d with DN %s failed: [%d] %s',
                        $this->_params['hostspec'],
                        $this->_params['port'],
                        $bind_dn,
                        ldap_errno($this->_connection),
                        ldap_error($this->_connection)),
                __FILE__, __LINE__);
        }

        return 0;
    }

    /**
     * Retrieves the requested set of preferences from the user's LDAP
     * entry.
     *
     * @access public
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function retrieve()
    {
        /* Attempt to pull the values from the session cache first. */
        if ($this->cacheLookup()) {
            return true;
        }

        /* Load defaults to make sure we have all preferences. */
        parent::retrieve();

        /* Make sure we are connected. */
        $this->_connect();

        /* Only fetch the fields for the attributes we need. */
        $attrs = array('hordePrefs');
        if (strcmp($this->_scope, 'horde') != 0) {
            array_push($attrs, $this->_scope . 'Prefs');
        }

        /* Search for the multi-valued field containing the array of
           preferences. */
        $search = ldap_search($this->_connection, $this->_params['basedn'],
                              $this->_params['uid'] . '=' . $this->_user, $attrs);
        if ($search) {
            $result = ldap_get_entries($this->_connection, $search);
        } else {
            Horde::logMessage('Failed to connect to LDAP preferences server.', __FILE__, __LINE__);
        }

        /* ldap_get_entries() converts attribute indexes to lowercase. */
        $field = String::lower($this->_scope . 'prefs');

        if (isset($result)) {
            /* Set the requested values in the $this->_prefs hash based on
               the contents of the LDAP result.

               Preferences are stored as colon-separated name:value pairs.
               Each pair is stored as its own attribute off of the multi-
               value attribute named in: $this->_scope . 'Prefs'

               Note that Prefs::setValue() can't be used here because of the
               check for the "changeable" bit.  We want to override that
               check when populating the $this->_prefs hash from the LDAP
               server.
             */

            $prefs = array();

            /* If hordePrefs exists, merge them as the base of the prefs. */
            if (isset($result[0]['hordeprefs'])) {
                $prefs = array_merge($prefs, $result[0]['hordeprefs']);
            }

            /* If this scope's prefs are available, merge them as will.  Give
             * them a higher precedence than hordePrefs. */
            if (strcmp($this->_scope, 'horde') != 0) {
                if (isset($result[0][$field])) {
                    $prefs = array_merge($prefs, $result[0][$field]);
                }
            }

            foreach ($prefs as $prefstr) {
                /* If the string doesn't contain a colon delimiter, skip it. */
                if (substr_count($prefstr, ':') == 0) {
                    continue;
                }

                /* Split the string into its name:value components. */
                list($pref, $val) = split(':', $prefstr, 2);

                /* Retrieve this preference. */
                if (isset($this->_prefs[$pref])) {
                    $this->_setValue($pref, base64_decode($val), false);
                    $this->setDefault($pref, false);
                } else {
                    $this->add($pref, base64_decode($val), _PREF_SHARED);
                }
            }

            /* Make sure we know that we've loaded these
             * preferences. */
            $_SESSION['prefs_cache']['_filled']['horde'] = true;
            $_SESSION['prefs_cache']['_filled'][$this->_scope] = true;

            /* Call hooks. */
            $this->_callHooks();
        } else {
            Horde::logMessage('No preferences were retrieved.', __FILE__, __LINE__);
            return;
        }

        /* Update the session cache. */
        $this->cacheUpdate();

        return true;
    }

    /**
     * Stores preferences to the LDAP server.
     *
     * @access public
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function store()
    {
        $updated = true;

        /* Check for any "dirty" preferences. If no "dirty"
         * preferences are found, there's no need to update the LDAP
         * server. Exit successfully. */
        $dirty_prefs = $this->_dirtyPrefs();
        if (!count($dirty_prefs)) {
            return true;
        }

        /* Make sure we are connected. */
        $this->_connect();

        /* Build a hash of the preferences and their values that need
         * to be stored in the LDAP server. Because we have to update
         * all of the values of a multi-value entry wholesale, we
         * can't just pick out the dirty preferences; we must update
         * everything. */
        $new_values = array();
        foreach (array_keys($this->_prefs) as $pref) {
            // Don't store locked preferences.
            if (!$this->isLocked($pref)) {
                $entry = $pref . ':' . base64_encode($this->getValue($pref));
                $field = $this->getScope($pref) . 'Prefs';
                $new_values[$field][] = $entry;
            }
        }

        /* Entries must have the objectclasses 'top' and 'hordeperson'
         * to successfully store LDAP prefs. Check for both of them,
         * and add them if necessary. */
        $search = ldap_search($this->_connection, $this->_params['basedn'],
                              $this->_params['uid'] . '=' . $this->_user,
                              array('objectclass'));
        if ($search) {
            $result = ldap_get_entries($this->_connection, $search);
            if ($result) {
                $top = false;
                $hordeperson = false;

                for ($i = 0; $i < $result[0]['objectclass']['count']; $i++) {
                    if ($result[0]['objectclass'][$i] == 'top') {
                        $top = true;
                    } elseif ($result[0]['objectclass'][$i] == 'hordePerson') {
                        $hordeperson = true;
                    }
                }

                /* Add any missing objectclasses. */
                if (!$top) {
                    ldap_mod_add($this->_connection, $this->_dn, array('objectclass' => 'top'));
                }

                if (!$hordeperson) {
                    ldap_mod_add($this->_connection, $this->_dn, array('objectclass' => 'hordePerson'));
                }
            }
        }

        /* Send the hash to the LDAP server. */
        if (ldap_mod_replace($this->_connection, $this->_dn, $new_values)) {
            foreach ($dirty_prefs as $pref) {
                $this->setDirty($pref, false);
            }
        } else {
            Horde::logMessage(
               sprintf('Unable to modify preferences: [%d] %s',
                        ldap_errno($this->_connection),
                        ldap_error($this->_connection)),
                __FILE__, __LINE__);
            $updated = false;
        }

        /* Attempt to cache the preferences in the session. */
        $this->cacheUpdate();

        return $updated;
    }

    /**
     * Perform cleanup operations.
     *
     * @access public
     *
     * @param optional boolean $all  Cleanup all Horde preferences.
     */
    function cleanup($all = false)
    {
        /* Close the LDAP connection. */
        $this->_disconnect();

        parent::cleanup($all);
    }

}

--- NEW FILE: session.php ---
<?php
/**
 * Preferences storage implementation for PHP's session implementation.
 *
 * $Horde: framework/Prefs/Prefs/session.php,v 1.32 2004/01/07 17:25:58 jan Exp $
 *
 * Copyright 1999-2004 Jon Parise <jon at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Jon Parise <jon at horde.org>
 * @version $Revision: 1.1 $
 * @since   Horde 1.3.4
 * @package Horde_Prefs
 */
class Prefs_session extends Prefs {

    /**
     * Constructs a new session preferences object.
     *
     * @access public
     *
     * @param string $user       The user who owns these preferences. (Unused)
     * @param string $password   The password associated with $user. (Unused)
     * @param string $scope      The current preferences scope.
     * @param array $params      (optional) A hash containing connection
     *                           parameters. (Unused)
     * @param boolean $caching   (optional) Should caching be used? (Unused)
     * 
     */
    function Prefs_session($user, $password = '', $scope = '',
                           $params = null, $caching = true)
    {
        if (!Util::extensionExists('session')) {
            Horde::fatal(PEAR::raiseError(_("Prefs_session: Required session extension not found."), __FILE__, __LINE__));
        }

        $this->_scope = $scope;

        parent::Prefs();
    }

    /**
     * Retrieves the requested set of preferences from the current session.
     *
     * @access public
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function retrieve()
    {
        /* Load defaults to make sure we have all preferences. */
        parent::retrieve();

        $global_prefs = array();
        $local_prefs = array();

        /* Retrieve global and local preferences from the session variable. */
        if (isset($_SESSION['horde_prefs']['horde'])) {
            $global_prefs = $_SESSION['horde_prefs']['horde'];
        }
        if (isset($_SESSION['horde_prefs'][$this->_scope])) {
            $local_prefs = $_SESSION['horde_prefs'][$this->_scope];
        }

        /* Retrieve and store the local and global preferences. */
        $this->_prefs = array_merge($this->_prefs, $global_prefs, $local_prefs);

        /* Call hooks. */
        $this->_callHooks();

        return true;
    }

    /**
     * Stores preferences in the current session.
     *
     * @access public
     *
     * @param optional array $prefs  An array listing the preferences to be
     *                               stored. If not specified, store all the
     *                               preferences listed in the $prefs hash.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function store($prefs = array())
    {
        /* Create and register the preferences array, if necessary. */
        if (!isset($_SESSION['horde_prefs'])) {
            $_SESSION['horde_prefs'] = array();
        }

        /* Copy the current preferences into the session variable. */
        foreach ($this->_prefs as $name => $pref) {
            $scope = $this->getScope($name);
            $_SESSION['horde_prefs'][$scope][$name] = $pref;
        }

        return true;
    }

    /**
     * Perform cleanup operations.
     *
     * @access public
     *
     * @param optional boolean $all  Cleanup all Horde preferences.
     */
    function cleanup($all = false)
    {
        /* Perform a Horde-wide cleanup? */
        if ($all) {
            unset($_SESSION['horde_prefs']);
        } else {
            unset($_SESSION['horde_prefs'][$this->_scope]);
            $_SESSION['horde_prefs']['_filled'] = false;
        }

        parent::cleanup($all);
    }

}

--- NEW FILE: sql.php ---
<?php
/**
 * Preferences storage implementation for PHP's PEAR database abstraction
 * layer.
 *
 * Required parameters:
 * ====================
 *   'charset'   --  The database's internal charset.
 *   'database'  --  The name of the database.
 *   'hostspec'  --  The hostname of the database server.
 *   'password'  --  The password associated with 'username'.
 *   'phptype'   --  The database type (ie. 'pgsql', 'mysql, etc.).
 *   'protocol'  --  The communication protocol ('tcp', 'unix', etc.).
 *   'username'  --  The username with which to connect to the database.
 *
 * Optional preferences:
 * =====================
 *   'table'  --  The name of the preferences table in 'database'.
 *                DEFAULT: 'horde_prefs'
 *
 * Required by some database implementations:
 * ==========================================
 *   'options'  --  Additional options to pass to the database.
 *   'port'     --  The port on which to connect to the database.
 *   'tty'      --  The TTY on which to connect to the database.
 *
 *
 * The table structure for the preferences is as follows:
 *
 *  create table horde_prefs (
 *      pref_uid        varchar(255) not null,
 *      pref_scope      varchar(16) not null default '',
 *      pref_name       varchar(32) not null,
 *      pref_value      text null,
 *      primary key (pref_uid, pref_scope, pref_name)
 *  );
 *
 *
 * If setting up as the Horde preference handler in conf.php, simply configure
 * $conf['sql'] and don't enter anything for $conf['prefs']['params'].
 *
 *
 * $Horde: framework/Prefs/Prefs/sql.php,v 1.86 2004/05/24 21:55:00 mdjukic Exp $
 *
 * Copyright 1999-2004 Jon Parise <jon at horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Jon Parise <jon at horde.org>
 * @version $Revision: 1.1 $
 * @since   Horde 1.3
 * @package Horde_Prefs
 */
class Prefs_sql extends Prefs {

    /**
     * Hash containing connection parameters.
     *
     * @var array $params
     */
    var $_params = array();

    /**
     * Handle for the current database connection.
     *
     * @var object DB $db
     */
    var $_db;

    /**
     * Boolean indicating whether or not we're connected to the SQL server.
     *
     * @var boolean $_connected
     */
    var $_connected = false;

    /**
     * Constructs a new SQL preferences object.
     *
     * @access public
     *
     * @param string $user               The user who owns these preferences.
     * @param string $password           The password associated with $user.
     *                                   (Unused)
     * @param string $scope              The current preferences scope.
     * @param array  $params             A hash containing connection
     *                                   parameters.
     * @param optional boolean $caching  Should caching be used?
     */
    function Prefs_sql($user, $password = '', $scope = '',
                       $params = array(), $caching = false)
    {
        $this->_user = $user;
        $this->_scope = $scope;
        $this->_params = $params;
        $this->_caching = $caching;

        parent::Prefs();
    }

    /**
     * Returns the charset used by the concrete preference backend.
     *
     * @access public
     *
     * @return string  The preference backend's charset.
     */
    function getCharset()
    {
        return $this->_params['charset'];
    }

    /**
     * Retrieves the requested set of preferences from the user's database
     * entry.
     *
     * @access public
     *
     * @param optional array $prefs  An array listing the preferences to
     *                               retrieve. If not specified, retrieve all
     *                               of the preferences listed in the $prefs
     *                               hash.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function retrieve($prefs = array())
    {
        /* Attempt to pull the values from the session cache first. */
        if ($this->cacheLookup()) {
            return true;
        }

        /* Load defaults to make sure we have all preferences. */
        parent::retrieve();

        /* Make sure we're connected. */
        $this->_connect();

        /* Build the SQL query. */
        $query = 'SELECT pref_scope, pref_name, pref_value FROM ';
        $query .= $this->_params['table'] . ' ';
        $query .= 'WHERE pref_uid = ' . $this->_db->quote($this->_user);
        $query .= ' AND (pref_scope = ' . $this->_db->quote($this->_scope);
        $query .= " OR pref_scope = 'horde') ORDER BY pref_scope";

        Horde::logMessage(sprintf('SQL Query by Prefs_sql::retrieve(): %s', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);

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

        if (isset($result) && !is_a($result, 'PEAR_Error')) {
            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
            if (is_a($row, 'PEAR_Error')) {
                Horde::logMessage($row, __FILE__, __LINE__, PEAR_LOG_ERR);
                return;
            }

            /* Set the requested values in the $this->_prefs hash
               based on the contents of the SQL result.

               Note that Prefs::setValue() can't be used here because
               of the check for the "changeable" bit. We want to
               override that check when populating the $this->_prefs
               hash from the SQL server.
            */
            while ($row && !is_a($row, 'PEAR_Error')) {
                $name = trim($row['pref_name']);
                if (isset($this->_prefs[$name])) {
                    $this->_setValue($name, $this->_convertFromDriver($row['pref_value']), false);
                    $this->setDirty($name, false);
                } else {
                    $this->add($name, $this->_convertFromDriver($row['pref_value']), $row['pref_scope'] == 'horde' ? _PREF_SHARED : 0);
                }
                $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
            }

            /* Make sure we know that we've loaded these
             * preferences. */
            $_SESSION['prefs_cache']['_filled']['horde'] = true;
            $_SESSION['prefs_cache']['_filled'][$this->_scope] = true;

            /* Call hooks. */
            $this->_callHooks();
        } else {
            Horde::logMessage('No preferences were retrieved.', __FILE__, __LINE__, PEAR_LOG_DEBUG);
            return;
        }

        /* Update the session cache. */
        $this->cacheUpdate();

        return true;
    }

    /**
     * Stores preferences to SQL server.
     *
     * @access public
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function store()
    {
        /* Check for any "dirty" preferences. If no "dirty"
           preferences are found, there's no need to update the SQL
           server. Exit successfully. */
        $dirty_prefs = $this->_dirtyPrefs();
        if (!count($dirty_prefs)) {
            return true;
        }

        /* Make sure we're connected. */
        $this->_connect();

        /* Loop through the "dirty" preferences.  If a row already exists for
           this preference, attempt to update it.  Otherwise, insert a new
           row. */
        foreach ($dirty_prefs as $name) {
            // Don't store locked preferences.
            if ($this->isLocked($name)) {
                continue;
            }

            $scope = $this->getScope($name);

            /* Does an entry already exist for this preference? */
            $query = 'SELECT 1 FROM ';
            $query .= $this->_params['table'] . ' ';
            $query .= 'WHERE pref_uid = ' . $this->_db->quote($this->_user);
            $query .= ' AND pref_name = ' . $this->_db->quote($name);
            $query .= ' AND (pref_scope = ' . $this->_db->quote($scope);
            $query .= " OR pref_scope = 'horde')";

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

            /* Return an error if the query fails. */
            if (is_a($check, 'PEAR_Error')) {
                Horde::logMessage('Failed retrieving prefs for ' . $this->_user, __FILE__, __LINE__, PEAR_LOG_ERR);
                return PEAR::raiseError(_("Failed retrieving preferences."));
            }

            /* Is there an existing row for this preference? */
            if (!empty($check)) {
                /* Update the existing row. */
                $query = 'UPDATE ' . $this->_params['table'] . ' ';
                $query .= 'SET pref_value = ' . $this->_db->quote($this->_convertToDriver((string)$this->getValue($name)));
                $query .= ' WHERE pref_uid = ' . $this->_db->quote($this->_user);
                $query .= ' AND pref_name = ' . $this->_db->quote($name);
                $query .= ' AND pref_scope = ' . $this->_db->quote($scope);
                $result = $this->_db->query($query);

                /* Return an error if the update fails. */
                if (is_a($result, 'PEAR_Error')) {
                    Horde::fatal($result, __FILE__, __LINE__);
                }
            } else {
                /* Insert a new row. */
                $query  = 'INSERT INTO ' . $this->_params['table'] . ' ';
                $query .= '(pref_uid, pref_scope, pref_name, pref_value) VALUES';
                $query .= '(' . $this->_db->quote($this->_user) . ', ';
                $query .= $this->_db->quote($scope) . ', ' . $this->_db->quote($name) . ', ';
                $query .= $this->_db->quote($this->_convertToDriver((string)$this->getValue($name))) . ')';
                $result = $this->_db->query($query);

                /* Return an error if the insert fails. */
                if (is_a($result, 'PEAR_Error')) {
                    Horde::fatal($result, __FILE__, __LINE__);
                }
            }

            /* Mark this preference as "clean" now. */
            $this->setDirty($name, false);
        }

        /* Update the session cache. */
        $this->cacheUpdate();

        return true;
    }

    /**
     * Perform cleanup operations.
     *
     * @access public
     *
     * @param optional boolean $all  Cleanup all Horde preferences.
     */
    function cleanup($all = false)
    {
        /* Close the database connection. */
        $this->_disconnect();

        parent::cleanup($all);
    }

    /**
     * Attempts to open a persistent connection to the SQL server.
     *
     * @access private
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function _connect()
    {
        /* Check to see if we are already connected. */
        if ($this->_connected) {
            return true;
        }

        Horde::assertDriverConfig($this->_params, 'prefs',
            array('phptype', 'hostspec', 'username', 'database', 'charset'),
            'preferences SQL');

        if (!isset($this->_params['table'])) {
            $this->_params['table'] = 'horde_prefs';
        }

        if (!isset($this->_params['password'])) {
            $this->_params['password'] = '';
        }

        /* 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($this->_db, __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.
     *
     * @access private
     *
     * @return boolean  True on success, false on failure.
     */
    function _disconnect()
    {
        if ($this->_connected) {
            $this->_connected = false;
            return $this->_db->disconnect();
        } else {
            return true;
        }
    }

    /**
     * Converts a value from the driver's charset to the default charset.
     *
     * @param mixed $value  A value to convert.
     * @return mixed        The converted value.
     */
    function _convertFromDriver($value)
    {
        return String::convertCharset($value, $this->_params['charset'], NLS::getCharset());
    }

    /**
     * Converts a value from the default charset to the driver's charset.
     *
     * @param mixed $value  A value to convert.
     * @return mixed        The converted value.
     */
    function _convertToDriver($value)
    {
        return String::convertCharset($value, NLS::getCharset(), $this->_params['charset']);
    }

}





More information about the commits mailing list