steffen: server/kolab-horde-framework/kolab-horde-framework/Prefs Prefs.php, NONE, 1.1 package.xml, 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
In directory doto:/tmp/cvs-serv28903/kolab-horde-framework/kolab-horde-framework/Prefs
Added Files:
Prefs.php package.xml
Log Message:
Separated Horde Framework from kolab-resource-handlers
--- NEW FILE: Prefs.php ---
<?php
// Preference constants (bitmasks)
/** @constant _PREF_LOCKED Preference is administratively locked. */
define('_PREF_LOCKED', 1);
/** @constant _PREF_SHARED Preference is shared amongst applications. */
define('_PREF_SHARED', 2);
/** @constant _PREF_DIRTY Preference value has been changed. */
define('_PREF_DIRTY', 4);
/** @constant _PREF_DEFAULT Preference value is the application default. */
define('_PREF_DEFAULT', 8);
require_once 'Horde/String.php';
/**
* The Prefs:: class provides a common abstracted interface into the
* various preferences storage mediums. It also includes all of the
* functions for retrieving, storing, and checking preference values.
*
* TODO: document the format of the $_prefs hash here
*
* $_prefs[*pref name*] = array(
* 'value' => *Default value*,
* 'locked' => *boolean*,
* 'shared' => *boolean*,
* 'type' => 'checkbox'
* 'text'
* 'password'
* 'textarea'
* 'select'
* 'number'
* 'implicit'
* 'special'
* 'link' - There must be a field named either 'url'
* (internal application link) or 'xurl'
* (external application link) if this type is used.
* 'enum'
* 'enum' => TODO,
* 'desc' => _(*Description string*),
* 'help' => *Name of the entry in the XML help file*
* );
*
* $Horde: framework/Prefs/Prefs.php,v 1.132 2004/04/07 14:43:12 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 {
/**
* Hash holding all of the user's preferences. Each preference is
* itself a hash, so this will ultimately be multi-dimensional.
*
* @access private
*
* [*pref name*] => Array(
* [d] => *default value*
* [m] => *pref mask*
* [v] => *pref value*
* )
*
* @var array $_prefs
*/
var $_prefs = array();
/**
* String containing the name of this scope. This is used to
* maintain the application scope between sets of preferences. By
* default, all preferences belong to the "global" (Horde) scope.
*
* @var string $scope
*/
var $_scope = 'horde';
/**
* String containing the current username. This indicates the
* owner of the preferences.
*
* @var string $user
*/
var $_user = '';
/**
* Boolean indicating whether preference caching should be used.
*
* @var boolean $caching
*/
var $_caching = false;
/**
* Hash holding preferences with hook functions defined.
*
* @var array $_hooks
*/
var $_hooks = array();
/**
* Have we run hook functions yet?
*
* @var boolean $_hooksCalled
*/
var $_hooksCalled = null;
/**
* Default constructor (must be called from each extending class
* in their constructors via parent::Prefs()).
*
* @access public
*/
function Prefs()
{
$this->_shutdown();
}
/**
* Returns the charset used by the concrete preference backend.
*
* @access public
*
* @return string The preference backend's charset.
*/
function getCharset()
{
return NLS::getCharset();
}
/**
* Updates the session-based preferences cache (if available) with
* the current set of preferences.
*
* @access public
*/
function cacheUpdate()
{
/* Return immediately if caching is disabled. */
if (!$this->_caching) {
return;
}
if (isset($_SESSION['prefs_cache'])) {
/* Place each preference in the cache according to its
* scope. */
foreach ($this->_prefs as $name => $pref) {
$_SESSION['prefs_cache'][$this->getScope($name)][$name] = $pref;
}
}
}
/**
* Tries to find the requested preferences in the cache. If they
* exist, update the $prefs hash with the cached values.
*
* @access public
*
* @return boolean True on success, false on failure.
*/
function cacheLookup()
{
/* Return immediately if caching is disabled. */
if (!$this->_caching) {
return false;
}
if (isset($_SESSION['prefs_cache']['horde']) &&
!empty($_SESSION['prefs_cache']['_filled'][$this->_scope]) &&
isset($_SESSION['prefs_cache'][$this->_scope])) {
/* Restore global preferences. */
foreach ($_SESSION['prefs_cache']['horde'] as $name => $pref) {
$this->_prefs[$name] = $pref;
}
/* Restore application-specific preferences. */
foreach ($_SESSION['prefs_cache'][$this->_scope] as $name => $pref) {
$this->_prefs[$name] = $pref;
}
return true;
}
return false;
}
/**
* Adds a new preference entry to the $prefs hash.
*
* @access public
*
* @param string $pref The name of the preference to add.
* @param optional string $val The initial value of the preference.
* @param optional integer $mask The initial bitmask of the preference.
*/
function add($pref, $val = '', $mask = 0)
{
if (is_array($this->_prefs)) {
$this->_prefs[$pref] = array('v' => $val, 'm' => $mask, 'd' => $val);
}
}
/**
* Removes a preference entry from the $prefs hash.
*
* @access public
*
* @param string $pref The name of the preference to remove.
*/
function remove($pref)
{
if (is_array($this->_prefs)) {
unset($this->_prefs[$pref]);
}
}
/**
* Sets the given preferences ($pref) to the specified value
* ($val), if the preference is modifiable.
*
* @access public
*
* @param string $pref The name of the preference to modify.
* @param string $val The new value for this preference.
*
* @return boolean True if the value was successfully set, false on a
* failure.
*/
function setValue($pref, $val)
{
/* Exit early if this preference is locked or doesn't exist. */
if (!isset($this->_prefs[$pref]) || $this->isLocked($pref)) {
return false;
}
return $this->_setValue($pref, $val);
}
/**
* Sets the given preferences ($pref) to the specified value
* ($val), whether or not the preference is user-modifiable, unset
* the default bit, and set the dirty bit.
*
* @access protected
*
* @param string $pref The name of the preference to modify.
* @param string $val The new value for this preference.
* @param boolean $dirty True if we should mark the new value as
* dirty (changed).
*
* @return boolean True if the value was successfully set, false on a
* failure.
*/
function _setValue($pref, $val, $dirty = true)
{
global $conf;
/* If the preference's value is already equal to $val, don't
* bother changing it. Changing it would set the "dirty" bit,
* causing an unnecessary update later on in the storage
* routine. */
if (isset($this->_prefs[$pref]) &&
(($this->_prefs[$pref]['v'] == $val) &&
!$this->isDefault($pref))) {
return true;
}
/* Check to see if the value exceeds the allowable storage
* limit. */
if (isset($conf['prefs']['maxsize'])) {
if (strlen($val) > $conf['prefs']['maxsize']) {
global $notification;
if (isset($notification)) {
$notification->push(sprintf(_("The preference \"%s\" could not be saved because its data exceeded the maximum allowable size"), $pref), 'horde.error');
return false;
}
}
}
/* Assign the new value, unset the "default" bit, and set the
"dirty" bit. */
if (empty($this->_prefs[$pref]['m'])) {
$this->_prefs[$pref]['m'] = 0;
}
$this->_prefs[$pref]['v'] = $val;
$this->setDefault($pref, false);
if ($dirty) {
$this->setDirty($pref, true);
}
return true;
}
/**
* Returns the value of the requested preference.
*
* @access public
*
* @param string $pref The name of the preference to retrieve.
*
* @return string The value of the preference, null if it doesn't exist.
*/
function getValue($pref)
{
return (isset($this->_prefs[$pref]['v'])) ? $this->_prefs[$pref]['v'] : null;
}
/**
* Modifies the "locked" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to modify.
* @param boolean $bool The new boolean value for the "locked" bit.
*/
function setLocked($pref, $bool)
{
$this->_setMask($pref, $bool, _PREF_LOCKED);
}
/**
* Returns the state of the "locked" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to check.
*
* @return boolean The boolean state of $pref's "locked" bit.
*/
function isLocked($pref)
{
return $this->_getMask($pref, _PREF_LOCKED);
}
/**
* Modifies the "shared" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to modify.
* @param boolean $bool The new boolean value for the "shared" bit.
*/
function setShared($pref, $bool)
{
$this->_setMask($pref, $bool, _PREF_SHARED);
}
/**
* Returns the state of the "shared" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to check.
*
* @return boolean The boolean state of $pref's "shared" bit.
*/
function isShared($pref)
{
return $this->_getMask($pref, _PREF_SHARED);
}
/**
* Modifies the "dirty" bit for the given preference.
*
* @param string $pref The name of the preference to modify.
* @param boolean $bool The new boolean value for the "dirty" bit.
*/
function setDirty($pref, $bool)
{
$this->_setMask($pref, $bool, _PREF_DIRTY);
}
/**
* Returns the state of the "dirty" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to check.
*
* @return boolean The boolean state of $pref's "dirty" bit.
*/
function isDirty($pref)
{
return $this->_getMask($pref, _PREF_DIRTY);
}
/**
* Modifies the "default" bit for the given preference.
*
* @access public
*
* @param string $pref The name of the preference to modify.
* @param boolean $bool The new boolean value for the "default" bit.
*
* @since Horde 2.1
*/
function setDefault($pref, $bool)
{
$this->_setMask($pref, $bool, _PREF_DEFAULT);
}
/**
* Returns the default value of the given preference.
*
* @access public
*
* @param string $pref The name of the preference to get the default for.
*
* @return string The preference's default value.
*/
function getDefault($pref)
{
return !empty($this->_prefs[$pref]['d']) ?
$this->_prefs[$pref]['d'] :
'';
}
/**
* Determines if the current preference value is the default
* value from prefs.php or a user defined value
*
* @access public
*
* @param string $pref The name of the preference to check.
*
* @return boolean True if the preference is the application default
* value.
*
* @since Horde 2.1
*/
function isDefault($pref)
{
return $this->_getMask($pref, _PREF_DEFAULT);
}
/**
* Sets the value for a given mask.
*
* @access private
*
* @param string $pref The name of the preference to modify.
* @param boolean $bool The new boolean value for the "default" bit.
* @param integer $mask The mask to add.
*/
function _setMask($pref, $bool, $mask)
{
if (isset($this->_prefs[$pref])) {
if ($bool != $this->_getMask($pref, $mask)) {
if ($bool) {
$this->_prefs[$pref]['m'] |= $mask;
} else {
$this->_prefs[$pref]['m'] &= ~$mask;
}
}
}
}
/**
* Gets the boolean state for a given mask.
*
* @access private
*
* @param string $pref The name of the preference to modify.
* @param integer $mask The mask to get.
*
* @return boolean The boolean state for the given mask.
*/
function _getMask($pref, $mask)
{
return isset($this->_prefs[$pref]['m']) ? ($this->_prefs[$pref]['m'] & $mask) : false;
}
/**
* Determines whether the current preference is empty.
*
* @access public
*
* @param string $pref The name of the preference to check.
*
* @return boolean True if the preference is empty.
*/
function isEmpty($pref)
{
return empty($this->_prefs[$pref]['v']);
}
/**
* Returns the scope of the given preference.
*
* @access public
*
* @param string $pref The name of the preference to examine.
*
* @return string The scope of the $pref.
*/
function getScope($pref)
{
if ($this->isShared($pref)) {
return 'horde';
} else {
return $this->_scope;
}
}
/**
* Return a list of "dirty" preferences.
*
* @access private
*
* @return array The list of "dirty" preferences in $this->_prefs.
*/
function _dirtyPrefs()
{
$dirty_prefs = array();
foreach (array_keys($this->_prefs) as $pref) {
if ($this->isDirty($pref)) {
$dirty_prefs[] = $pref;
}
}
return $dirty_prefs;
}
/**
* This method should be overridden by a subclass
* implementation. It's here to retain code integrity in the case
* that no subclass is loaded ($driver == 'none').
*/
function retrieve()
{
/* Load defaults to make sure we have all preferences. */
$this->_setDefaults('horde');
$this->_setDefaults($this->_scope);
return true;
}
/**
* This is an abstract method that should be overridden by a
* subclass implementation. It's here to retain code integrity in
* the case that no subclass is loaded ($driver == 'none').
*
* This function will be run at the end of every request as a
* shutdown function (registered by the Prefs:: constructor). All
* prefs with the dirty bit set will be saved to the storage
* backend at this time; thus, there is no need to manually call
* $prefs->store() every time a preference is changed.
*
* @abstract
*/
function store()
{
return true;
}
/**
* This function provides common cleanup functions for all of the driver
* implementations.
*
* @param optional boolean $all Clean up all Horde preferences.
*/
function cleanup($all = false)
{
/* Remove this scope from the preferences cache, if it
exists. */
if (isset($_SESSION['prefs_cache'])) {
if (isset($_SESSION['prefs_cache'][$this->_scope])) {
unset($_SESSION['prefs_cache'][$this->_scope]);
}
if (isset($_SESSION['prefs_cache']['_filled'][$this->_scope])) {
unset($_SESSION['prefs_cache']['_filled'][$this->_scope]);
}
}
/* Perform a Horde-wide cleanup? */
if ($all) {
/* Destroy the contents of the preferences hash. */
$this->_prefs = array();
/* Destroy the contents of the preferences cache. */
if (isset($_SESSION['prefs_cache'])) {
unset($_SESSION['prefs_cache']);
}
}
}
/**
* Populates the $prefs hash with new entries and externally
* defined default values.
*
* @param string $app The application to load defaults for.
*
* @access public
*/
function _setDefaults($app)
{
global $registry;
$filename = $registry->getParam('fileroot', $app) . '/config/prefs.php';
/* Ensure that the defaults from this file are only read once.
Also, make sure we can read this file. */
if (!@is_readable($filename)) {
return;
}
/* Read the configuration file. The $_prefs array, which will be
in local scope, is assumed to hold the default values. */
include $filename;
foreach ($_prefs as $pref => $pvals) {
if (isset($pvals['value']) &&
isset($pvals['locked']) &&
isset($pvals['shared']) &&
($pvals['type'] != 'link') &&
($pvals['type'] != 'special')) {
$pref = str_replace('.', '_', $pref);
$mask = 0;
if ($pvals['locked']) {
$mask |= _PREF_LOCKED;
}
if ($pvals['shared'] || $app == 'horde') {
$mask |= _PREF_SHARED;
}
$mask &= ~_PREF_DIRTY;
$mask |= _PREF_DEFAULT;
$this->add($pref, $pvals['value'], $mask);
if (!empty($pvals['hook'])) {
$this->_setHook($pref);
}
}
}
/* Update the preferences cache with the defaults. */
$this->cacheUpdate();
}
/**
* Performs shutdown activities.
*
* @access private
*/
function _shutdown()
{
register_shutdown_function(array(&$this, 'store'));
}
/**
* Add $pref to the list of preferences with hook functions.
*
* @param string $pref The preference with a hook.
*/
function _setHook($pref)
{
$this->_hooks[] = $pref;
}
/**
* After preferences have been loaded, set any locked or empty
* preferences that have hooks to the result of the hook.
*/
function _callHooks()
{
if (!is_null($this->_hooksCalled) && !Auth::getAuth()) {
return;
}
$this->_hooksCalled = true;
if (!count($this->_hooks)) {
return;
}
global $registry;
include $registry->getParam('fileroot', 'horde') . '/config/hooks.php';
foreach ($this->_hooks as $pref) {
if ($this->isLocked($pref) ||
!$this->getValue($pref)) {
$func = '_prefs_hook_' . $pref;
if (function_exists($func)) {
$this->_setValue($pref, $func($this->_user));
}
}
}
}
/**
* Attempts to return a concrete Prefs instance based on $driver.
*
* @param mixed $driver The type of concrete Prefs subclass
* to return. This is based on the
* storage driver ($driver). The code is
* dynamically included. If $driver is
* an array, then we will look in
* $driver[0]/lib/Prefs/ for the subclass
* implementation named $driver[1].php.
* @param optional string $scope The scope for this set of preferences.
* @param optional string $user The name of the user who owns this
* set of preferences.
* @param optional string $password The password associated with $user.
* @param optional array $params A hash containing any additional
* configuration or connection
* parameters a subclass might need.
* @param optional boolean $caching Should caching be used?
*
* @return object Prefs The newly created concrete Prefs instance, or
* false on error.
*/
function &factory($driver, $scope = 'horde', $user = '', $password = '',
$params = null, $caching = true)
{
if (is_array($driver)) {
$app = $driver[0];
$driver = $driver[1];
}
/* Attempt to register (cache) the $prefs hash in session
* storage. */
if ($caching) {
if (!isset($_SESSION['prefs_cache'])) {
$_SESSION['prefs_cache'] = array();
$_SESSION['prefs_cache']['_filled'] = array();
}
}
$driver = basename($driver);
if (empty($driver) || $driver == 'none') {
$prefs = &new Prefs();
$prefs->_scope = $scope;
return $prefs;
}
if (is_null($params)) {
$params = Horde::getDriverConfig('prefs', $driver);
}
/* If $params['user_hook'] is defined, use it to retrieve the
value to use for the username ($this->_user). Otherwise,
just use the value passed in the $user parameter. */
if (!empty($params['user_hook']) &&
function_exists($params['user_hook'])) {
$user = call_user_func($params['user_hook'], $user);
}
if (!empty($app)) {
require_once $GLOBALS['registry']->getParam('fileroot', $app) . '/lib/Prefs/' . $driver . '.php';
} elseif (@file_exists(dirname(__FILE__) . '/Prefs/' . $driver . '.php')) {
require_once dirname(__FILE__) . '/Prefs/' . $driver . '.php';
} else {
@include_once 'Horde/Prefs/' . $driver . '.php';
}
$class = 'Prefs_' . $driver;
if (class_exists($class)) {
return $ret = &new $class($user, $password, $scope, $params, $caching);
} else {
return PEAR::raiseError('Class definition of ' . $class . ' not found.');
}
}
/**
* Attempts to return a reference to a concrete Prefs instance based on
* $driver. It will only create a new instance if no Prefs instance
* with the same parameters currently exists.
*
* This should be used if multiple preference sources (and, thus,
* multiple Prefs instances) are required.
*
* This method must be invoked as: $var = &Prefs::singleton()
*
* @param mixed $driver The type of concrete Prefs subclass
* to return. This is based on the
* storage driver ($driver). The code is
* dynamically included. If $driver is
* an array, then we will look in
* $driver[0]/lib/Prefs/ for the subclass
* implementation named $driver[1].php.
* @param optional string $scope The scope for this set of preferences.
* @param optional string $user The name of the user who owns this
* set of preferences.
* @param optional string $password The password associated with $user.
* @param optional array $params A hash containing any additional
* configuration or connection
* parameters a subclass might need.
* @param optional boolean $caching Should caching be used?
*
* @return object Prefs The concrete Prefs reference, or false on an
* error.
*/
function &singleton($driver, $scope = 'horde', $user = '', $password = '',
$params = null, $caching = true)
{
static $instances;
if (!isset($instances)) {
$instances = array();
}
if (is_null($params)) {
$params = Horde::getDriverConfig('prefs', $driver);
}
$signature = serialize(array($driver, $user, $params));
if (!isset($instances[$signature])) {
$instances[$signature] = &Prefs::factory($driver, $scope, $user, $password, $params, $caching);
}
return $instances[$signature];
}
}
--- NEW FILE: package.xml ---
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- $Horde: framework/Prefs/package.xml,v 1.11 2004/05/18 21:36:24 chuck Exp $ -->
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.1">
<package version="1.0">
<name>Horde_Prefs</name>
<summary>Horde Preferances API</summary>
<description>
The Prefs:: class provides a common abstracted interface into the various preferences storage mediums. It also includes all of the functions for retrieving, storing, and checking preference values.
</description>
<license>LGPL</license>
<maintainers>
<maintainer>
<user>chuck</user>
<role>lead</role>
<name>Chuck Hagenbuch</name>
<email>chuck at horde.org</email>
</maintainer>
<maintainer>
<user>jon</user>
<role>lead</role>
<name>Jon Parise</name>
<email>jon at horde.org</email>
</maintainer>
</maintainers>
<release>
<version>0.0.1</version>
<state>alpha</state>
<date>2003-07-05</date>
<notes>Initial Release.</notes>
<filelist>
<file baseinstalldir="/Horde" role="php" name="Prefs.php" />
<dir baseinstalldir="/Horde" name="Prefs" role="php">
<file name="CategoryManager.php" />
<file name="UI.php" />
<file name="imsp.php" />
<file name="ldap.php" />
<file name="session.php" />
<file name="sql.php" />
</dir>
</filelist>
<provides type="class" name="Prefs" />
<provides type="class" name="Prefs_CategoryManager" />
<provides type="class" name="Prefs_UI" />
<provides type="class" name="Prefs_imsp" />
<provides type="class" name="Prefs_ldap" />
<provides type="class" name="Prefs_session" />
<provides type="class" name="Prefs_sql" />
<deps>
<dep type="ext" rel="has" optional="yes">gettext</dep>
<dep type="pkg" rel="has">Horde_Framework</dep>
<dep type="pkg" rel="has">Horde_Util</dep>
</deps>
</release>
<changelog>
<release>
<version>0.0.1</version>
<state>alpha</state>
<date>2003-07-05</date>
<notes>Initial release as a PEAR package</notes>
</release>
</changelog>
</package>
More information about the commits
mailing list