diff options
Diffstat (limited to 'engine/lib/configuration.php')
| -rw-r--r-- | engine/lib/configuration.php | 632 | 
1 files changed, 632 insertions, 0 deletions
| diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php new file mode 100644 index 000000000..55e5bbd36 --- /dev/null +++ b/engine/lib/configuration.php @@ -0,0 +1,632 @@ +<?php +/** + * Elgg configuration procedural code. + * + * Includes functions for manipulating the configuration values stored in the database + * Plugin authors should use the {@link elgg_get_config()}, {@link elgg_set_config()}, + * {@link elgg_save_config()}, and {@unset_config()} functions to access or update + * config values. + * + * Elgg's configuration is split among 2 tables and 1 file: + * - dbprefix_config + * - dbprefix_datalists + * - engine/settings.php (See {@link settings.example.php}) + * + * Upon system boot, all values in dbprefix_config are read into $CONFIG. + * + * @package Elgg.Core + * @subpackage Configuration + */ + +/** + * Get the URL for the current (or specified) site + * + * @param int $site_guid The GUID of the site whose URL we want to grab + * @return string + * @since 1.8.0 + */ +function elgg_get_site_url($site_guid = 0) { +	if ($site_guid == 0) { +		global $CONFIG; +		return $CONFIG->wwwroot; +	} + +	$site = get_entity($site_guid); + +	if (!$site instanceof ElggSite) { +		return false; +	} +	/* @var ElggSite $site */ + +	return $site->url; +} + +/** + * Get the plugin path for this installation + * + * @return string + * @since 1.8.0 + */ +function elgg_get_plugins_path() { +	global $CONFIG; +	return $CONFIG->pluginspath; +} + +/** + * Get the data directory path for this installation + * + * @return string + * @since 1.8.0 + */ +function elgg_get_data_path() { +	global $CONFIG; +	return $CONFIG->dataroot; +} + +/** + * Get the root directory path for this installation + * + * @return string + * @since 1.8.0 + */ +function elgg_get_root_path() { +	global $CONFIG; +	return $CONFIG->path; +} + +/** + * Get an Elgg configuration value + * + * @param string $name      Name of the configuration value + * @param int    $site_guid NULL for installation setting, 0 for default site + * + * @return mixed Configuration value or null if it does not exist + * @since 1.8.0 + */ +function elgg_get_config($name, $site_guid = 0) { +	global $CONFIG; + +	$name = trim($name); + +	if (isset($CONFIG->$name)) { +		return $CONFIG->$name; +	} + +	if ($site_guid === null) { +		// installation wide setting +		$value = datalist_get($name); +	} else { +		// hit DB only if we're not sure if value exists or not +		if (!isset($CONFIG->site_config_loaded)) { +			// site specific setting +			if ($site_guid == 0) { +				$site_guid = (int) $CONFIG->site_id; +			} +			$value = get_config($name, $site_guid); +		} else { +			$value = null; +		} +	} + +	// @todo document why we don't cache false +	if ($value === false) { +		return null; +	} + +	$CONFIG->$name = $value; +	return $value; +} + +/** + * Set an Elgg configuration value + * + * @warning This does not persist the configuration setting. Use elgg_save_config() + * + * @param string $name  Name of the configuration value + * @param mixed  $value Value + * + * @return void + * @since 1.8.0 + */ +function elgg_set_config($name, $value) { +	global $CONFIG; + +	$name = trim($name); + +	$CONFIG->$name = $value; +} + +/** + * Save a configuration setting + * + * @param string $name      Configuration name (cannot be greater than 255 characters) + * @param mixed  $value     Configuration value. Should be string for installation setting + * @param int    $site_guid NULL for installation setting, 0 for default site + * + * @return bool + * @since 1.8.0 + */ +function elgg_save_config($name, $value, $site_guid = 0) { +	global $CONFIG; + +	$name = trim($name); + +	if (strlen($name) > 255) { +		elgg_log("The name length for configuration variables cannot be greater than 255", "ERROR"); +		return false; +	} + +	elgg_set_config($name, $value); + +	if ($site_guid === NULL) { +		if (is_array($value) || is_object($value)) { +			return false; +		} +		return datalist_set($name, $value); +	} else { +		if ($site_guid == 0) { +			$site_guid = (int) $CONFIG->site_id; +		} +		return set_config($name, $value, $site_guid); +	} +} + +/** + * Check that installation has completed and the database is populated. + * + * @throws InstallationException|DatabaseException + * @return void + * @access private + */ +function verify_installation() { +	global $CONFIG; + +	if (isset($CONFIG->installed)) { +		return; +	} + +	try { +		$dblink = get_db_link('read'); +		if (!$dblink) { +			throw new DatabaseException(); +		} + +		mysql_query("SELECT value FROM {$CONFIG->dbprefix}datalists WHERE name = 'installed'", $dblink); +		if (mysql_errno($dblink) > 0) { +			throw new DatabaseException(); +		} + +		$CONFIG->installed = true; + +	} catch (DatabaseException $e) { +		throw new InstallationException(elgg_echo('InstallationException:SiteNotInstalled')); +	} +} + +/** + * An array of key value pairs from the datalists table. + * + * Used as a cache in datalist functions. + * + * @global array $DATALIST_CACHE + */ +$DATALIST_CACHE = array(); + +/** + * Get the value of a datalist element. + * + * @internal Datalists are stored in the datalist table. + * + * @tip Use datalists to store information common to a full installation. + * + * @param string $name The name of the datalist + * @return string|null|false String if value exists, null if doesn't, false on error + * @access private + */ +function datalist_get($name) { +	global $CONFIG, $DATALIST_CACHE; + +	$name = trim($name); + +	// cannot store anything longer than 255 characters in db, so catch here +	if (elgg_strlen($name) > 255) { +		elgg_log("The name length for configuration variables cannot be greater than 255", "ERROR"); +		return false; +	} + +	$name = sanitise_string($name); +	if (isset($DATALIST_CACHE[$name])) { +		return $DATALIST_CACHE[$name]; +	} + +	// If memcache enabled then cache value in memcache +	$value = null; +	static $datalist_memcache; +	if ((!$datalist_memcache) && (is_memcache_available())) { +		$datalist_memcache = new ElggMemcache('datalist_memcache'); +	} +	if ($datalist_memcache) { +		$value = $datalist_memcache->load($name); +	} +	if ($value) { +		return $value; +	} + +	// [Marcus Povey 20090217 : Now retrieving all datalist values on first +	// load as this saves about 9 queries per page] +	// This also causes OOM problems when the datalists table is large +	// @todo make a list of datalists that we want to get in one grab +	$result = get_data("SELECT * from {$CONFIG->dbprefix}datalists"); +	if ($result) { +		foreach ($result as $row) { +			$DATALIST_CACHE[$row->name] = $row->value; + +			// Cache it if memcache is available +			if ($datalist_memcache) { +				$datalist_memcache->save($row->name, $row->value); +			} +		} + +		if (isset($DATALIST_CACHE[$name])) { +			return $DATALIST_CACHE[$name]; +		} +	} + +	return null; +} + +/** + * Set the value for a datalist element. + * + * @param string $name  The name of the datalist + * @param string $value The new value + * + * @return bool + * @access private + */ +function datalist_set($name, $value) { +	global $CONFIG, $DATALIST_CACHE; + +	// cannot store anything longer than 255 characters in db, so catch before we set +	if (elgg_strlen($name) > 255) { +		elgg_log("The name length for configuration variables cannot be greater than 255", "ERROR"); +		return false; +	} + +	$sanitised_name = sanitise_string($name); +	$sanitised_value = sanitise_string($value); + +	// If memcache is available then invalidate the cached copy +	static $datalist_memcache; +	if ((!$datalist_memcache) && (is_memcache_available())) { +		$datalist_memcache = new ElggMemcache('datalist_memcache'); +	} + +	if ($datalist_memcache) { +		$datalist_memcache->delete($name); +	} + +	$success = insert_data("INSERT into {$CONFIG->dbprefix}datalists" +		. " set name = '{$sanitised_name}', value = '{$sanitised_value}'" +		. " ON DUPLICATE KEY UPDATE value='{$sanitised_value}'"); + +	if ($success !== FALSE) { +		$DATALIST_CACHE[$name] = $value; +		return true; +	} else { +		return false; +	} +} + +/** + * Run a function one time per installation. + * + * If you pass a timestamp as the second argument, it will run the function + * only if (i) it has never been run before or (ii) the timestamp is >= + * the last time it was run. + * + * @warning Functions are determined by their name.  If you change the name of a function + * it will be run again. + * + * @tip Use $timelastupdatedcheck in your plugins init function to perform automated + * upgrades.  Schedule a function to run once and pass the timestamp of the new release. + * This will cause the run once function to be run on all installations.  To perform + * additional upgrades, create new functions for each release. + * + * @warning The function name cannot be longer than 255 characters long due to + * the current schema for the datalist table. + * + * @internal A datalist entry $functioname is created with the value of time(). + * + * @param string $functionname         The name of the function you want to run. + * @param int    $timelastupdatedcheck A UNIX timestamp. If time() is > than this, + *                                     this function will be run again. + * + * @return bool + */ +function run_function_once($functionname, $timelastupdatedcheck = 0) { +	$lastupdated = datalist_get($functionname); +	if ($lastupdated) { +		$lastupdated = (int) $lastupdated; +	} elseif ($lastupdated !== false) { +		$lastupdated = 0; +	} else { +		// unable to check datalist +		return false; +	} +	if (is_callable($functionname) && $lastupdated <= $timelastupdatedcheck) { +		$functionname(); +		datalist_set($functionname, time()); +		return true; +	} else { +		return false; +	} +} + +/** + * Removes a config setting. + * + * @internal + * These settings are stored in the dbprefix_config table and read during system + * boot into $CONFIG. + * + * @param string $name      The name of the field. + * @param int    $site_guid Optionally, the GUID of the site (current site is assumed by default). + * + * @return int|false The number of affected rows or false on error. + * + * @see get_config() + * @see set_config() + */ +function unset_config($name, $site_guid = 0) { +	global $CONFIG; + +	if (isset($CONFIG->$name)) { +		unset($CONFIG->$name); +	} + +	$name = sanitise_string($name); +	$site_guid = (int) $site_guid; +	if ($site_guid == 0) { +		$site_guid = (int) $CONFIG->site_id; +	} + +	$query = "delete from {$CONFIG->dbprefix}config where name='$name' and site_guid=$site_guid"; +	return delete_data($query); +} + +/** + * Add or update a config setting. + * + * If the config name already exists, it will be updated to the new value. + * + * @internal + * These settings are stored in the dbprefix_config table and read during system + * boot into $CONFIG. + * + * @param string $name      The name of the configuration value + * @param string $value     Its value + * @param int    $site_guid Optionally, the GUID of the site (current site is assumed by default) + * + * @return bool + * @todo The config table doens't have numeric primary keys so insert_data returns 0. + * @todo Use "INSERT ... ON DUPLICATE KEY UPDATE" instead of trying to delete then add. + * @see unset_config() + * @see get_config() + * @access private + */ +function set_config($name, $value, $site_guid = 0) { +	global $CONFIG; + +	$name = trim($name); + +	// cannot store anything longer than 255 characters in db, so catch before we set +	if (elgg_strlen($name) > 255) { +		elgg_log("The name length for configuration variables cannot be greater than 255", "ERROR"); +		return false; +	} + +	// Unset existing +	unset_config($name, $site_guid); + +	$site_guid = (int) $site_guid; +	if ($site_guid == 0) { +		$site_guid = (int) $CONFIG->site_id; +	} +	$CONFIG->$name = $value; +	$value = sanitise_string(serialize($value)); + +	$query = "insert into {$CONFIG->dbprefix}config" +		. " set name = '{$name}', value = '{$value}', site_guid = {$site_guid}"; +	$result = insert_data($query); +	return $result !== false; +} + +/** + * Gets a configuration value + * + * @internal + * These settings are stored in the dbprefix_config table and read during system + * boot into $CONFIG. + * + * @param string $name      The name of the config value + * @param int    $site_guid Optionally, the GUID of the site (current site is assumed by default) + * + * @return mixed|null + * @see set_config() + * @see unset_config() + * @access private + */ +function get_config($name, $site_guid = 0) { +	global $CONFIG; + +	$name = sanitise_string($name); +	$site_guid = (int) $site_guid; + +	// check for deprecated values. +	// @todo might be a better spot to define this? +	$new_name = false; +	switch($name) { +		case 'viewpath': +			$new_name = 'view_path'; +			$dep_version = 1.8; +			break; + +		case 'pluginspath': +			$new_name = 'plugins_path'; +			$dep_version = 1.8; +			break; + +		case 'sitename': +			$new_name = 'site_name'; +			$dep_version = 1.8; +			break; +	} + +	// @todo these haven't really been implemented in Elgg 1.8. Complete in 1.9. +	// show dep message +	if ($new_name) { +		//	$msg = "Config value $name has been renamed as $new_name"; +		$name = $new_name; +		//	elgg_deprecated_notice($msg, $dep_version); +	} + +	// decide from where to return the value +	if (isset($CONFIG->$name)) { +		return $CONFIG->$name; +	} + +	if ($site_guid == 0) { +		$site_guid = (int) $CONFIG->site_id; +	} + +	$result = get_data_row("SELECT value FROM {$CONFIG->dbprefix}config +		WHERE name = '{$name}' and site_guid = {$site_guid}"); + +	if ($result) { +		$result = $result->value; +		$result = unserialize($result->value); +		$CONFIG->$name = $result; +		return $result; +	} + +	return null; +} + +/** + * Loads all configuration values from the dbprefix_config table into $CONFIG. + * + * @param int $site_guid Optionally, the GUID of the site (current site is assumed by default) + * + * @return bool + * @access private + */ +function get_all_config($site_guid = 0) { +	global $CONFIG; + +	$site_guid = (int) $site_guid; + +	if ($site_guid == 0) { +		$site_guid = (int) $CONFIG->site_guid; +	} + +	if ($result = get_data("SELECT * FROM {$CONFIG->dbprefix}config WHERE site_guid = $site_guid")) { +		foreach ($result as $r) { +			$name = $r->name; +			$value = $r->value; +			$CONFIG->$name = unserialize($value); +		} + +		return true; +	} +	return false; +} + +/** + * Loads configuration related to this site + * + * This loads from the config database table and the site entity + * @access private + */ +function _elgg_load_site_config() { +	global $CONFIG; + +	$CONFIG->site_guid = (int) datalist_get('default_site'); +	$CONFIG->site_id = $CONFIG->site_guid; +	$CONFIG->site = get_entity($CONFIG->site_guid); +	if (!$CONFIG->site) { +		throw new InstallationException(elgg_echo('InstallationException:SiteNotInstalled')); +	} + +	$CONFIG->wwwroot = $CONFIG->site->url; +	$CONFIG->sitename = $CONFIG->site->name; +	$CONFIG->sitedescription = $CONFIG->site->description; +	$CONFIG->siteemail = $CONFIG->site->email; +	$CONFIG->url = $CONFIG->wwwroot; + +	get_all_config(); +	// gives hint to elgg_get_config function how to approach missing values +	$CONFIG->site_config_loaded = true; +} + +/** + * Loads configuration related to Elgg as an application + * + * This loads from the datalists database table + * @access private + */ +function _elgg_load_application_config() { +	global $CONFIG; + +	$install_root = str_replace("\\", "/", dirname(dirname(dirname(__FILE__)))); +	$defaults = array( +		'path'			=>	"$install_root/", +		'view_path'		=>	"$install_root/views/", +		'plugins_path'	=>	"$install_root/mod/", +		'language'		=>	'en', + +		// compatibility with old names for plugins not using elgg_get_config() +		'viewpath'		=>	"$install_root/views/", +		'pluginspath'	=>	"$install_root/mod/", +	); + +	foreach ($defaults as $name => $value) { +		if (empty($CONFIG->$name)) { +			$CONFIG->$name = $value; +		} +	} + +	$path = datalist_get('path'); +	if (!empty($path)) { +		$CONFIG->path = $path; +	} +	$dataroot = datalist_get('dataroot'); +	if (!empty($dataroot)) { +		$CONFIG->dataroot = $dataroot; +	} +	$simplecache_enabled = datalist_get('simplecache_enabled'); +	if ($simplecache_enabled !== false) { +		$CONFIG->simplecache_enabled = $simplecache_enabled; +	} else { +		$CONFIG->simplecache_enabled = 1; +	} +	$system_cache_enabled = datalist_get('system_cache_enabled'); +	if ($system_cache_enabled !== false) { +		$CONFIG->system_cache_enabled = $system_cache_enabled; +	} else { +		$CONFIG->system_cache_enabled = 1; +	} + +	// initialize context here so it is set before the get_input call +	$CONFIG->context = array(); + +	// needs to be set before system, init for links in html head +	$viewtype = get_input('view', 'default'); +	$lastcached = datalist_get("simplecache_lastcached_$viewtype"); +	$CONFIG->lastcache = $lastcached; + +	$CONFIG->i18n_loaded_from_cache = false; + +	// this must be synced with the enum for the entities table +	$CONFIG->entity_types = array('group', 'object', 'site', 'user'); +} | 
