Merge pull request #4540 from MrPetovan/task/4520-load-whole-config
[develop] Performance: Add preloading config adapter
This commit is contained in:
		
				commit
				
					
						b6b67c9044
					
				
			
		
					 17 changed files with 775 additions and 194 deletions
				
			
		
							
								
								
									
										2
									
								
								boot.php
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								boot.php
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -20,6 +20,7 @@
 | 
			
		|||
require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
 | 
			
		||||
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Addon;
 | 
			
		||||
use Friendica\Core\Cache;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
| 
						 | 
				
			
			@ -536,6 +537,7 @@ function get_app()
 | 
			
		|||
 | 
			
		||||
	if (empty($a)) {
 | 
			
		||||
		$a = new App(dirname(__DIR__));
 | 
			
		||||
		BaseObject::setApp($a);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return $a;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ Example: To set the automatic database cleanup process add this line to your .ht
 | 
			
		|||
* **always_show_preview** (Boolean) - Only show small preview picures. Default value is false.
 | 
			
		||||
* **block_local_dir** (Boolean) - Blocks the access to the directory of the local users.
 | 
			
		||||
* **auth_cookie_lifetime** (Integer) - Number of days that should pass without any activity before a user who chose "Remember me" when logging in is considered logged out. Defaults to 7.
 | 
			
		||||
* **config_adapter** (jit|preload) - Allow to switch the configuration adapter to improve performances at the cost of memory consumption. Default value is "jit"
 | 
			
		||||
* **curl_range_bytes** - Maximum number of bytes that should be fetched. Default is 0, which mean "no limit".
 | 
			
		||||
* **db_log** - Name of a logfile to log slow database queries
 | 
			
		||||
* **db_loglimit** - If a database call lasts longer than this value it is logged
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,7 @@ use Friendica\Module\Login;
 | 
			
		|||
 | 
			
		||||
require_once 'boot.php';
 | 
			
		||||
 | 
			
		||||
if (empty($a)) {
 | 
			
		||||
	$a = new App(__DIR__);
 | 
			
		||||
}
 | 
			
		||||
$a = new App(__DIR__);
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
// We assume that the index.php is called by a frontend process
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +76,7 @@ if (!$install) {
 | 
			
		|||
		exit();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Config::init();
 | 
			
		||||
	Session::init();
 | 
			
		||||
	Addon::loadHooks();
 | 
			
		||||
	Addon::callHooks('init_1');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,8 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
use Friendica\Util\ExAuth;
 | 
			
		||||
 | 
			
		||||
if (sizeof($_SERVER["argv"]) == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +55,7 @@ require_once "boot.php";
 | 
			
		|||
require_once "include/dba.php";
 | 
			
		||||
 | 
			
		||||
$a = new App(dirname(__DIR__));
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
@include ".htconfig.php";
 | 
			
		||||
dba::connect($db_host, $db_user, $db_pass, $db_data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ require_once "boot.php";
 | 
			
		|||
require_once "include/dba.php";
 | 
			
		||||
 | 
			
		||||
$a = new App(dirname(__DIR__));
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
@include ".htconfig.php";
 | 
			
		||||
dba::connect($db_host, $db_user, $db_pass, $db_data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Addon;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
use Friendica\Core\Worker;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +27,7 @@ require_once "boot.php";
 | 
			
		|||
require_once "include/dba.php";
 | 
			
		||||
 | 
			
		||||
$a = new App(dirname(__DIR__));
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
require_once ".htconfig.php";
 | 
			
		||||
dba::connect($db_host, $db_user, $db_pass, $db_data);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										112
									
								
								src/App.php
									
										
									
									
									
								
							
							
						
						
									
										112
									
								
								src/App.php
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -944,4 +944,116 @@ class App
 | 
			
		|||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param string $cat     Config category
 | 
			
		||||
	 * @param string $k       Config key
 | 
			
		||||
	 * @param mixed  $default Default value if it isn't set
 | 
			
		||||
	 */
 | 
			
		||||
	public function getConfigValue($cat, $k, $default = null)
 | 
			
		||||
	{
 | 
			
		||||
		$return = $default;
 | 
			
		||||
 | 
			
		||||
		if ($cat === 'config') {
 | 
			
		||||
			if (isset($this->config[$k])) {
 | 
			
		||||
				$return = $this->config[$k];
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (isset($this->config[$cat][$k])) {
 | 
			
		||||
				$return = $this->config[$cat][$k];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets a value in the config cache. Accepts raw output from the config table
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $cat Config category
 | 
			
		||||
	 * @param string $k   Config key
 | 
			
		||||
	 * @param mixed  $v   Value to set
 | 
			
		||||
	 */
 | 
			
		||||
	public function setConfigValue($cat, $k, $v)
 | 
			
		||||
	{
 | 
			
		||||
		// Only arrays are serialized in database, so we have to unserialize sparingly
 | 
			
		||||
		$value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
 | 
			
		||||
 | 
			
		||||
		if ($cat === 'config') {
 | 
			
		||||
			$this->config[$k] = $value;
 | 
			
		||||
		} else {
 | 
			
		||||
			$this->config[$cat][$k] = $value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Deletes a value from the config cache
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $cat Config category
 | 
			
		||||
	 * @param string $k   Config key
 | 
			
		||||
	 */
 | 
			
		||||
	public function deleteConfigValue($cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		if ($cat === 'config') {
 | 
			
		||||
			if (isset($this->config[$k])) {
 | 
			
		||||
				unset($this->config[$k]);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (isset($this->config[$cat][$k])) {
 | 
			
		||||
				unset($this->config[$cat][$k]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Retrieves a value from the user config cache
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int    $uid     User Id
 | 
			
		||||
	 * @param string $cat     Config category
 | 
			
		||||
	 * @param string $k       Config key
 | 
			
		||||
	 * @param mixed  $default Default value if key isn't set
 | 
			
		||||
	 */
 | 
			
		||||
	public function getPConfigValue($uid, $cat, $k, $default = null)
 | 
			
		||||
	{
 | 
			
		||||
		$return = $default;
 | 
			
		||||
 | 
			
		||||
		if (isset($this->config[$uid][$cat][$k])) {
 | 
			
		||||
			$return = $this->config[$uid][$cat][$k];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets a value in the user config cache
 | 
			
		||||
	 *
 | 
			
		||||
	 * Accepts raw output from the pconfig table
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int    $uid User Id
 | 
			
		||||
	 * @param string $cat Config category
 | 
			
		||||
	 * @param string $k   Config key
 | 
			
		||||
	 * @param mixed  $v   Value to set
 | 
			
		||||
	 */
 | 
			
		||||
	public function setPConfigValue($uid, $cat, $k, $v)
 | 
			
		||||
	{
 | 
			
		||||
		// Only arrays are serialized in database, so we have to unserialize sparingly
 | 
			
		||||
		$value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
 | 
			
		||||
 | 
			
		||||
		$this->config[$uid][$cat][$k] = $value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Deletes a value from the user config cache
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int    $uid User Id
 | 
			
		||||
	 * @param string $cat Config category
 | 
			
		||||
	 * @param string $k   Config key
 | 
			
		||||
	 */
 | 
			
		||||
	public function deletePConfigValue($uid, $cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		if (isset($this->config[$uid][$cat][$k])) {
 | 
			
		||||
			unset($this->config[$uid][$cat][$k]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,26 +8,33 @@
 | 
			
		|||
 */
 | 
			
		||||
namespace Friendica\Core;
 | 
			
		||||
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
use dba;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Arbitrary sytem configuration storage
 | 
			
		||||
 * @brief Arbitrary system configuration storage
 | 
			
		||||
 *
 | 
			
		||||
 * Note:
 | 
			
		||||
 * If we ever would decide to return exactly the variable type as entered,
 | 
			
		||||
 * we will have fun with the additional features. :-)
 | 
			
		||||
 *
 | 
			
		||||
 * The config class always returns strings but in the default features
 | 
			
		||||
 * we use a "false" to determine if the config value isn't set.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class Config
 | 
			
		||||
class Config extends BaseObject
 | 
			
		||||
{
 | 
			
		||||
	private static $cache;
 | 
			
		||||
	private static $in_db;
 | 
			
		||||
	/**
 | 
			
		||||
	 * @var Friendica\Core\Config\IConfigAdapter
 | 
			
		||||
	 */
 | 
			
		||||
	private static $adapter = null;
 | 
			
		||||
 | 
			
		||||
	public static function init()
 | 
			
		||||
	{
 | 
			
		||||
		if (self::getApp()->getConfigValue('system', 'config_adapter') == 'preload') {
 | 
			
		||||
			self::$adapter = new Config\PreloadConfigAdapter();
 | 
			
		||||
		} else {
 | 
			
		||||
			self::$adapter = new Config\JITConfigAdapter();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Loads all configuration values of family into a cached storage.
 | 
			
		||||
| 
						 | 
				
			
			@ -41,26 +48,11 @@ class Config
 | 
			
		|||
	 */
 | 
			
		||||
	public static function load($family = "config")
 | 
			
		||||
	{
 | 
			
		||||
		// We don't preload "system" anymore.
 | 
			
		||||
		// This reduces the number of database reads a lot.
 | 
			
		||||
		if ($family === 'system') {
 | 
			
		||||
			return;
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		$r = dba::select('config', ['v', 'k'], ['cat' => $family]);
 | 
			
		||||
		while ($rr = dba::fetch($r)) {
 | 
			
		||||
			$k = $rr['k'];
 | 
			
		||||
			if ($family === 'config') {
 | 
			
		||||
				$a->config[$k] = $rr['v'];
 | 
			
		||||
			} else {
 | 
			
		||||
				$a->config[$family][$k] = $rr['v'];
 | 
			
		||||
				self::$cache[$family][$k] = $rr['v'];
 | 
			
		||||
				self::$in_db[$family][$k] = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($r);
 | 
			
		||||
		self::$adapter->load($family);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -84,40 +76,11 @@ class Config
 | 
			
		|||
	 */
 | 
			
		||||
	public static function get($family, $key, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		if (!$refresh) {
 | 
			
		||||
			// Do we have the cached value? Then return it
 | 
			
		||||
			if (isset(self::$cache[$family][$key])) {
 | 
			
		||||
				if (self::$cache[$family][$key] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				} else {
 | 
			
		||||
					return self::$cache[$family][$key];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$config = dba::selectFirst('config', ['v'], ['cat' => $family, 'k' => $key]);
 | 
			
		||||
		if (DBM::is_result($config)) {
 | 
			
		||||
			// manage array value
 | 
			
		||||
			$val = (preg_match("|^a:[0-9]+:{.*}$|s", $config['v']) ? unserialize($config['v']) : $config['v']);
 | 
			
		||||
 | 
			
		||||
			// Assign the value from the database to the cache
 | 
			
		||||
			self::$cache[$family][$key] = $val;
 | 
			
		||||
			self::$in_db[$family][$key] = true;
 | 
			
		||||
			return $val;
 | 
			
		||||
		} elseif (isset($a->config[$family][$key])) {
 | 
			
		||||
			// Assign the value (mostly) from the .htconfig.php to the cache
 | 
			
		||||
			self::$cache[$family][$key] = $a->config[$family][$key];
 | 
			
		||||
			self::$in_db[$family][$key] = false;
 | 
			
		||||
 | 
			
		||||
			return $a->config[$family][$key];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self::$cache[$family][$key] = '!<unset>!';
 | 
			
		||||
		self::$in_db[$family][$key] = false;
 | 
			
		||||
 | 
			
		||||
		return $default_value;
 | 
			
		||||
		return self::$adapter->get($family, $key, $default_value, $refresh);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -136,38 +99,11 @@ class Config
 | 
			
		|||
	 */
 | 
			
		||||
	public static function set($family, $key, $value)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		// We store our setting values in a string variable.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$dbvalue = (!is_array($value) ? (string)$value : $value);
 | 
			
		||||
 | 
			
		||||
		$stored = self::get($family, $key, null, true);
 | 
			
		||||
 | 
			
		||||
		if (($stored === $dbvalue) && self::$in_db[$family][$key]) {
 | 
			
		||||
			return true;
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($family === 'config') {
 | 
			
		||||
			$a->config[$key] = $dbvalue;
 | 
			
		||||
		} elseif ($family != 'system') {
 | 
			
		||||
			$a->config[$family][$key] = $dbvalue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Assign the just added value to the cache
 | 
			
		||||
		self::$cache[$family][$key] = $dbvalue;
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
 | 
			
		||||
 | 
			
		||||
		$ret = dba::update('config', ['v' => $dbvalue], ['cat' => $family, 'k' => $key], true);
 | 
			
		||||
 | 
			
		||||
		if ($ret) {
 | 
			
		||||
			self::$in_db[$family][$key] = true;
 | 
			
		||||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
		return $ret;
 | 
			
		||||
		return self::$adapter->set($family, $key, $value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -183,13 +119,10 @@ class Config
 | 
			
		|||
	 */
 | 
			
		||||
	public static function delete($family, $key)
 | 
			
		||||
	{
 | 
			
		||||
		if (isset(self::$cache[$family][$key])) {
 | 
			
		||||
			unset(self::$cache[$family][$key]);
 | 
			
		||||
			unset(self::$in_db[$family][$key]);
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$ret = dba::delete('config', ['cat' => $family, 'k' => $key]);
 | 
			
		||||
 | 
			
		||||
		return $ret;
 | 
			
		||||
		return self::$adapter->delete($family, $key);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										72
									
								
								src/Core/Config/IConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/Core/Config/IConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hypolite Petovan <mrpetovan@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
interface IConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Loads all configuration values into a cached storage.
 | 
			
		||||
	 *
 | 
			
		||||
	 * All configuration values of the system are stored in global cache
 | 
			
		||||
	 * which is available under the global variable $a->config
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string  $cat The category of the configuration values to load
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return void
 | 
			
		||||
	 */
 | 
			
		||||
	public function load($cat = "config");
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Get a particular user's config variable given the category name
 | 
			
		||||
	 * ($family) and a key.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Get a particular config value from the given category ($family)
 | 
			
		||||
	 * and the $key from a cached storage in $a->config[$uid].
 | 
			
		||||
	 * $instore is only used by the set_config function
 | 
			
		||||
	 * to determine if the key already exists in the DB
 | 
			
		||||
	 * If a key is found in the DB but doesn't exist in
 | 
			
		||||
	 * local config cache, pull it into the cache so we don't have
 | 
			
		||||
	 * to hit the DB again for this item.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string  $cat           The category of the configuration value
 | 
			
		||||
	 * @param string  $k             The configuration key to query
 | 
			
		||||
	 * @param mixed   $default_value optional, The value to return if key is not set (default: null)
 | 
			
		||||
	 * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed Stored value or null if it does not exist
 | 
			
		||||
	 */
 | 
			
		||||
	public function get($cat, $k, $default_value = null, $refresh = false);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Sets a configuration value for system config
 | 
			
		||||
	 *
 | 
			
		||||
	 * Stores a config value ($value) in the category ($family) under the key ($key)
 | 
			
		||||
	 * for the user_id $uid.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Note: Please do not store booleans - convert to 0/1 integer values!
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $family The category of the configuration value
 | 
			
		||||
	 * @param string $key    The configuration key to set
 | 
			
		||||
	 * @param mixed  $value  The value to store
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed Stored $value or false if the database update failed
 | 
			
		||||
	 */
 | 
			
		||||
	public function set($cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Deletes the given key from the system configuration.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Removes the configured value from the stored cache in $a->config
 | 
			
		||||
	 * and removes it from the database.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $cat The category of the configuration value
 | 
			
		||||
	 * @param string $k   The configuration key to delete
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed
 | 
			
		||||
	 */
 | 
			
		||||
	public function delete($cat, $k);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								src/Core/Config/IPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/Core/Config/IPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * To change this license header, choose License Headers in Project Properties.
 | 
			
		||||
 * To change this template file, choose Tools | Templates
 | 
			
		||||
 * and open the template in the editor.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author benlo
 | 
			
		||||
 */
 | 
			
		||||
interface IPConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Loads all configuration values of a user's config family into a cached storage.
 | 
			
		||||
	 *
 | 
			
		||||
	 * All configuration values of the given user are stored in global cache
 | 
			
		||||
	 * which is available under the global variable $a->config[$uid].
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $uid The user_id
 | 
			
		||||
	 * @param string $cat The category of the configuration value
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return void
 | 
			
		||||
	 */
 | 
			
		||||
	public function load($uid, $cat);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Get a particular user's config variable given the category name
 | 
			
		||||
	 * ($family) and a key.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Get a particular user's config value from the given category ($family)
 | 
			
		||||
	 * and the $key from a cached storage in $a->config[$uid].
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string  $uid           The user_id
 | 
			
		||||
	 * @param string  $cat           The category of the configuration value
 | 
			
		||||
	 * @param string  $k             The configuration key to query
 | 
			
		||||
	 * @param mixed   $default_value optional, The value to return if key is not set (default: null)
 | 
			
		||||
	 * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed Stored value or null if it does not exist
 | 
			
		||||
	 */
 | 
			
		||||
	public function get($uid, $cat, $k, $default_value = null, $refresh = false);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Sets a configuration value for a user
 | 
			
		||||
	 *
 | 
			
		||||
	 * Stores a config value ($value) in the category ($family) under the key ($key)
 | 
			
		||||
	 * for the user_id $uid.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @note Please do not store booleans - convert to 0/1 integer values!
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $uid   The user_id
 | 
			
		||||
	 * @param string $cat   The category of the configuration value
 | 
			
		||||
	 * @param string $k     The configuration key to set
 | 
			
		||||
	 * @param string $value The value to store
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed Stored $value or false
 | 
			
		||||
	 */
 | 
			
		||||
	public function set($uid, $cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Deletes the given key from the users's configuration.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Removes the configured value from the stored cache in $a->config[$uid]
 | 
			
		||||
	 * and removes it from the database.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $uid The user_id
 | 
			
		||||
	 * @param string $cat The category of the configuration value
 | 
			
		||||
	 * @param string $k   The configuration key to delete
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return mixed
 | 
			
		||||
	 */
 | 
			
		||||
	public function delete($uid, $cat, $k);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								src/Core/Config/JITConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/Core/Config/JITConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,126 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
use dba;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * JustInTime Configuration Adapter
 | 
			
		||||
 *
 | 
			
		||||
 * Default Config Adapter. Provides the best performance for pages loading few configuration variables.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hypolite Petovan <mrpetovan@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
class JITConfigAdapter extends BaseObject implements IConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	private $cache;
 | 
			
		||||
	private $in_db;
 | 
			
		||||
 | 
			
		||||
	public function load($cat = "config")
 | 
			
		||||
	{
 | 
			
		||||
		// We don't preload "system" anymore.
 | 
			
		||||
		// This reduces the number of database reads a lot.
 | 
			
		||||
		if ($cat === 'system') {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$configs = dba::select('config', ['v', 'k'], ['cat' => $cat]);
 | 
			
		||||
		while ($config = dba::fetch($configs)) {
 | 
			
		||||
			$k = $config['k'];
 | 
			
		||||
 | 
			
		||||
			self::getApp()->setConfigValue($cat, $k, $config['v']);
 | 
			
		||||
 | 
			
		||||
			if ($cat !== 'config') {
 | 
			
		||||
				$this->cache[$cat][$k] = $config['v'];
 | 
			
		||||
				$this->in_db[$cat][$k] = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($configs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function get($cat, $k, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		$a = self::getApp();
 | 
			
		||||
 | 
			
		||||
		if (!$refresh) {
 | 
			
		||||
			// Do we have the cached value? Then return it
 | 
			
		||||
			if (isset($this->cache[$cat][$k])) {
 | 
			
		||||
				if ($this->cache[$cat][$k] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				} else {
 | 
			
		||||
					return $this->cache[$cat][$k];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$config = dba::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $k]);
 | 
			
		||||
		if (DBM::is_result($config)) {
 | 
			
		||||
			// manage array value
 | 
			
		||||
			$value = (preg_match("|^a:[0-9]+:{.*}$|s", $config['v']) ? unserialize($config['v']) : $config['v']);
 | 
			
		||||
 | 
			
		||||
			// Assign the value from the database to the cache
 | 
			
		||||
			$this->cache[$cat][$k] = $value;
 | 
			
		||||
			$this->in_db[$cat][$k] = true;
 | 
			
		||||
			return $value;
 | 
			
		||||
		} elseif (isset($a->config[$cat][$k])) {
 | 
			
		||||
			// Assign the value (mostly) from the .htconfig.php to the cache
 | 
			
		||||
			$this->cache[$cat][$k] = $a->config[$cat][$k];
 | 
			
		||||
			$this->in_db[$cat][$k] = false;
 | 
			
		||||
 | 
			
		||||
			return $a->config[$cat][$k];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$this->cache[$cat][$k] = '!<unset>!';
 | 
			
		||||
		$this->in_db[$cat][$k] = false;
 | 
			
		||||
 | 
			
		||||
		return $default_value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function set($cat, $k, $value)
 | 
			
		||||
	{
 | 
			
		||||
		$a = self::getApp();
 | 
			
		||||
 | 
			
		||||
		// We store our setting values in a string variable.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$dbvalue = (!is_array($value) ? (string)$value : $value);
 | 
			
		||||
 | 
			
		||||
		$stored = $this->get($cat, $k, null, true);
 | 
			
		||||
 | 
			
		||||
		if (($stored === $dbvalue) && $this->in_db[$cat][$k]) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self::getApp()->setConfigValue($cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
		// Assign the just added value to the cache
 | 
			
		||||
		$this->cache[$cat][$k] = $dbvalue;
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
 | 
			
		||||
 | 
			
		||||
		$result = dba::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $k], true);
 | 
			
		||||
 | 
			
		||||
		if ($result) {
 | 
			
		||||
			$this->in_db[$cat][$k] = true;
 | 
			
		||||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function delete($cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		if (isset($this->cache[$cat][$k])) {
 | 
			
		||||
			unset($this->cache[$cat][$k]);
 | 
			
		||||
			unset($this->in_db[$cat][$k]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$result = dba::delete('config', ['cat' => $cat, 'k' => $k]);
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								src/Core/Config/JITPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/Core/Config/JITPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,119 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
use dba;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * JustInTime User Configuration Adapter
 | 
			
		||||
 *
 | 
			
		||||
 * Default PConfig Adapter. Provides the best performance for pages loading few configuration variables.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hypolite Petovan <mrpetovan@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	private $in_db;
 | 
			
		||||
 | 
			
		||||
	public function load($uid, $cat)
 | 
			
		||||
	{
 | 
			
		||||
		$a = self::getApp();
 | 
			
		||||
 | 
			
		||||
		$pconfigs = dba::select('pconfig', ['v', 'k'], ['cat' => $cat, 'uid' => $uid]);
 | 
			
		||||
		if (DBM::is_result($pconfigs)) {
 | 
			
		||||
			while ($pconfig = dba::fetch($pconfigs)) {
 | 
			
		||||
				$k = $pconfig['k'];
 | 
			
		||||
 | 
			
		||||
				self::getApp()->setPConfigValue($uid, $cat, $k, $pconfig['v']);
 | 
			
		||||
 | 
			
		||||
				$this->in_db[$uid][$cat][$k] = true;
 | 
			
		||||
			}
 | 
			
		||||
		} else if ($cat != 'config') {
 | 
			
		||||
			// Negative caching
 | 
			
		||||
			$a->config[$uid][$cat] = "!<unset>!";
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($pconfigs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function get($uid, $cat, $k, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		$a = self::getApp();
 | 
			
		||||
 | 
			
		||||
		if (!$refresh) {
 | 
			
		||||
			// Looking if the whole family isn't set
 | 
			
		||||
			if (isset($a->config[$uid][$cat])) {
 | 
			
		||||
				if ($a->config[$uid][$cat] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (isset($a->config[$uid][$cat][$k])) {
 | 
			
		||||
				if ($a->config[$uid][$cat][$k] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				}
 | 
			
		||||
				return $a->config[$uid][$cat][$k];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$pconfig = dba::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
 | 
			
		||||
		if (DBM::is_result($pconfig)) {
 | 
			
		||||
			$val = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']);
 | 
			
		||||
 | 
			
		||||
			self::getApp()->setPConfigValue($uid, $cat, $k, $val);
 | 
			
		||||
 | 
			
		||||
			$this->in_db[$uid][$cat][$k] = true;
 | 
			
		||||
 | 
			
		||||
			return $val;
 | 
			
		||||
		} else {
 | 
			
		||||
			self::getApp()->setPConfigValue($uid, $cat, $k, '!<unset>!');
 | 
			
		||||
 | 
			
		||||
			$this->in_db[$uid][$cat][$k] = false;
 | 
			
		||||
 | 
			
		||||
			return $default_value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function set($uid, $cat, $k, $value)
 | 
			
		||||
	{
 | 
			
		||||
		// We store our setting values in a string variable.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$dbvalue = (!is_array($value) ? (string)$value : $value);
 | 
			
		||||
 | 
			
		||||
		$stored = $this->get($uid, $cat, $k, null, true);
 | 
			
		||||
 | 
			
		||||
		if (($stored === $dbvalue) && $this->in_db[$uid][$cat][$k]) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self::getApp()->setPConfigValue($uid, $cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
 | 
			
		||||
 | 
			
		||||
		$result = dba::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $k], true);
 | 
			
		||||
 | 
			
		||||
		if ($result) {
 | 
			
		||||
			$this->in_db[$uid][$cat][$k] = true;
 | 
			
		||||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function delete($uid, $cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		self::getApp()->deletePConfigValue($uid, $cat, $k);
 | 
			
		||||
 | 
			
		||||
		if (!empty($this->in_db[$uid][$cat][$k])) {
 | 
			
		||||
			unset($this->in_db[$uid][$cat][$k]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$result = dba::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/Core/Config/PreloadConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/Core/Config/PreloadConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
use dba;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Preload Configuration Adapter
 | 
			
		||||
 *
 | 
			
		||||
 * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hypolite Petovan <mrpetovan@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
class PreloadConfigAdapter extends BaseObject implements IConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	private $config_loaded = false;
 | 
			
		||||
 | 
			
		||||
	public function __construct()
 | 
			
		||||
	{
 | 
			
		||||
		$this->load();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function load($family = 'config')
 | 
			
		||||
	{
 | 
			
		||||
		if ($this->config_loaded) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$configs = dba::select('config', ['cat', 'v', 'k']);
 | 
			
		||||
		while ($config = dba::fetch($configs)) {
 | 
			
		||||
			self::getApp()->setConfigValue($config['cat'], $config['k'], $config['v']);
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($configs);
 | 
			
		||||
 | 
			
		||||
		$this->config_loaded = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function get($cat, $k, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		if ($refresh) {
 | 
			
		||||
			$config = dba::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $k]);
 | 
			
		||||
			if (DBM::is_result($config)) {
 | 
			
		||||
				self::getApp()->setConfigValue($cat, $k, $config['v']);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$return = self::getApp()->getConfigValue($cat, $k, $default_value);
 | 
			
		||||
 | 
			
		||||
		return $return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function set($cat, $k, $value)
 | 
			
		||||
	{
 | 
			
		||||
		// We store our setting values as strings.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$compare_value = !is_array($value) ? (string)$value : $value;
 | 
			
		||||
 | 
			
		||||
		if (self::getApp()->getConfigValue($cat, $k) === $compare_value) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self::getApp()->setConfigValue($cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = is_array($value) ? serialize($value) : $value;
 | 
			
		||||
 | 
			
		||||
		$result = dba::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $k], true);
 | 
			
		||||
		if (!$result) {
 | 
			
		||||
			throw new Exception('Unable to store config value in [' . $cat . '][' . $k . ']');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function delete($cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		self::getApp()->deleteConfigValue($cat, $k);
 | 
			
		||||
 | 
			
		||||
		$result = dba::delete('config', ['cat' => $cat, 'k' => $k]);
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/Core/Config/PreloadPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/Core/Config/PreloadPConfigAdapter.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,92 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
use dba;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Preload User Configuration Adapter
 | 
			
		||||
 *
 | 
			
		||||
 * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Hypolite Petovan <mrpetovan@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
 | 
			
		||||
{
 | 
			
		||||
	private $config_loaded = false;
 | 
			
		||||
 | 
			
		||||
	public function __construct($uid)
 | 
			
		||||
	{
 | 
			
		||||
		$this->load($uid, 'config');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function load($uid, $family)
 | 
			
		||||
	{
 | 
			
		||||
		if ($this->config_loaded) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$pconfigs = dba::select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
 | 
			
		||||
		while ($pconfig = dba::fetch($pconfigs)) {
 | 
			
		||||
			self::getApp()->setPConfigValue($uid, $pconfig['cat'], $pconfig['k'], $pconfig['v']);
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($pconfigs);
 | 
			
		||||
 | 
			
		||||
		$this->config_loaded = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function get($uid, $cat, $k, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		if ($refresh) {
 | 
			
		||||
			$config = dba::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
 | 
			
		||||
			if (DBM::is_result($config)) {
 | 
			
		||||
				self::getApp()->setPConfigValue($uid, $cat, $k, $config['v']);
 | 
			
		||||
			} else {
 | 
			
		||||
				self::getApp()->deletePConfigValue($uid, $cat, $k);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$return = self::getApp()->getPConfigValue($uid, $cat, $k, $default_value);
 | 
			
		||||
 | 
			
		||||
		return $return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function set($uid, $cat, $k, $value)
 | 
			
		||||
	{
 | 
			
		||||
		// We store our setting values as strings.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$compare_value = !is_array($value) ? (string)$value : $value;
 | 
			
		||||
 | 
			
		||||
		if (self::getApp()->getPConfigValue($uid, $cat, $k) === $compare_value) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self::getApp()->setPConfigValue($uid, $cat, $k, $value);
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = is_array($value) ? serialize($value) : $value;
 | 
			
		||||
 | 
			
		||||
		$result = dba::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $k], true);
 | 
			
		||||
		if (!$result) {
 | 
			
		||||
			throw new Exception('Unable to store config value in [' . $uid . '][' . $cat . '][' . $k . ']');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function delete($uid, $cat, $k)
 | 
			
		||||
	{
 | 
			
		||||
		self::getApp()->deletePConfigValue($uid, $cat, $k);
 | 
			
		||||
 | 
			
		||||
		$result = dba::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
 | 
			
		||||
 | 
			
		||||
		return $result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +1,18 @@
 | 
			
		|||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @file src/Core/PConfig.php
 | 
			
		||||
 * User Configuration Class
 | 
			
		||||
 *
 | 
			
		||||
 * @file include/Core/PConfig.php
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Contains the class with methods for user configuration
 | 
			
		||||
 */
 | 
			
		||||
namespace Friendica\Core;
 | 
			
		||||
 | 
			
		||||
use Friendica\Database\DBM;
 | 
			
		||||
use dba;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file include/Core/PConfig.php
 | 
			
		||||
 * @brief contains the class with methods for the management
 | 
			
		||||
 * of the user configuration
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Management of user configuration storage
 | 
			
		||||
 * Note:
 | 
			
		||||
| 
						 | 
				
			
			@ -22,9 +20,23 @@ require_once 'include/dba.php';
 | 
			
		|||
 * The PConfig::get() functions return boolean false for keys that are unset,
 | 
			
		||||
 * and this could lead to subtle bugs.
 | 
			
		||||
 */
 | 
			
		||||
class PConfig
 | 
			
		||||
class PConfig extends BaseObject
 | 
			
		||||
{
 | 
			
		||||
	private static $in_db;
 | 
			
		||||
	/**
 | 
			
		||||
	 * @var Friendica\Core\Config\IPConfigAdapter
 | 
			
		||||
	 */
 | 
			
		||||
	private static $adapter = null;
 | 
			
		||||
 | 
			
		||||
	public static function init($uid)
 | 
			
		||||
	{
 | 
			
		||||
		$a = self::getApp();
 | 
			
		||||
 | 
			
		||||
		if (isset($a->config['system']['config_adapter']) && $a->config['system']['config_adapter'] == 'preload') {
 | 
			
		||||
			self::$adapter = new Config\PreloadPConfigAdapter($uid);
 | 
			
		||||
		} else {
 | 
			
		||||
			self::$adapter = new Config\JITPConfigAdapter($uid);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Loads all configuration values of a user's config family into a cached storage.
 | 
			
		||||
| 
						 | 
				
			
			@ -39,20 +51,11 @@ class PConfig
 | 
			
		|||
	 */
 | 
			
		||||
	public static function load($uid, $family)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		$r = dba::select('pconfig', ['v', 'k'], ['cat' => $family, 'uid' => $uid]);
 | 
			
		||||
		if (DBM::is_result($r)) {
 | 
			
		||||
			while ($rr = dba::fetch($r)) {
 | 
			
		||||
				$k = $rr['k'];
 | 
			
		||||
				$a->config[$uid][$family][$k] = $rr['v'];
 | 
			
		||||
				self::$in_db[$uid][$family][$k] = true;
 | 
			
		||||
			}
 | 
			
		||||
		} else if ($family != 'config') {
 | 
			
		||||
			// Negative caching
 | 
			
		||||
			$a->config[$uid][$family] = "!<unset>!";
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init($uid);
 | 
			
		||||
		}
 | 
			
		||||
		dba::close($r);
 | 
			
		||||
 | 
			
		||||
		self::$adapter->load($uid, $family);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -72,37 +75,11 @@ class PConfig
 | 
			
		|||
	 */
 | 
			
		||||
	public static function get($uid, $family, $key, $default_value = null, $refresh = false)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		if (!$refresh) {
 | 
			
		||||
			// Looking if the whole family isn't set
 | 
			
		||||
			if (isset($a->config[$uid][$family])) {
 | 
			
		||||
				if ($a->config[$uid][$family] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (isset($a->config[$uid][$family][$key])) {
 | 
			
		||||
				if ($a->config[$uid][$family][$key] === '!<unset>!') {
 | 
			
		||||
					return $default_value;
 | 
			
		||||
				}
 | 
			
		||||
				return $a->config[$uid][$family][$key];
 | 
			
		||||
			}
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init($uid);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$pconfig = dba::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $family, 'k' => $key]);
 | 
			
		||||
		if (DBM::is_result($pconfig)) {
 | 
			
		||||
			$val = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']);
 | 
			
		||||
			$a->config[$uid][$family][$key] = $val;
 | 
			
		||||
			self::$in_db[$uid][$family][$key] = true;
 | 
			
		||||
 | 
			
		||||
			return $val;
 | 
			
		||||
		} else {
 | 
			
		||||
			$a->config[$uid][$family][$key] = '!<unset>!';
 | 
			
		||||
			self::$in_db[$uid][$family][$key] = false;
 | 
			
		||||
 | 
			
		||||
			return $default_value;
 | 
			
		||||
		}
 | 
			
		||||
		return self::$adapter->get($uid, $family, $key, $default_value, $refresh);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -122,31 +99,11 @@ class PConfig
 | 
			
		|||
	 */
 | 
			
		||||
	public static function set($uid, $family, $key, $value)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		// We store our setting values in a string variable.
 | 
			
		||||
		// So we have to do the conversion here so that the compare below works.
 | 
			
		||||
		// The exception are array values.
 | 
			
		||||
		$dbvalue = (!is_array($value) ? (string)$value : $value);
 | 
			
		||||
 | 
			
		||||
		$stored = self::get($uid, $family, $key, null, true);
 | 
			
		||||
 | 
			
		||||
		if (($stored === $dbvalue) && self::$in_db[$uid][$family][$key]) {
 | 
			
		||||
			return true;
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init($uid);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$a->config[$uid][$family][$key] = $dbvalue;
 | 
			
		||||
 | 
			
		||||
		// manage array value
 | 
			
		||||
		$dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
 | 
			
		||||
 | 
			
		||||
		$ret = dba::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $family, 'k' => $key], true);
 | 
			
		||||
 | 
			
		||||
		if ($ret) {
 | 
			
		||||
			self::$in_db[$uid][$family][$key] = true;
 | 
			
		||||
			return $value;
 | 
			
		||||
		}
 | 
			
		||||
		return $ret;
 | 
			
		||||
		return self::$adapter->set($uid, $family, $key, $value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -163,15 +120,10 @@ class PConfig
 | 
			
		|||
	 */
 | 
			
		||||
	public static function delete($uid, $family, $key)
 | 
			
		||||
	{
 | 
			
		||||
		$a = get_app();
 | 
			
		||||
 | 
			
		||||
		if (x($a->config[$uid][$family], $key)) {
 | 
			
		||||
			unset($a->config[$uid][$family][$key]);
 | 
			
		||||
			unset(self::$in_db[$uid][$family][$key]);
 | 
			
		||||
		if (empty(self::$adapter)) {
 | 
			
		||||
			self::init($uid);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$ret = dba::delete('pconfig', ['uid' => $uid, 'cat' => $family, 'k' => $key]);
 | 
			
		||||
 | 
			
		||||
		return $ret;
 | 
			
		||||
		return self::$adapter->delete($uid, $family, $key);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,16 +2,17 @@
 | 
			
		|||
/**
 | 
			
		||||
 * @file util/maintenance.php
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
use Friendica\Core\Config;
 | 
			
		||||
use Friendica\Core\L10n;
 | 
			
		||||
 | 
			
		||||
require_once 'boot.php';
 | 
			
		||||
require_once 'include/dba.php';
 | 
			
		||||
 | 
			
		||||
if (empty($a)) {
 | 
			
		||||
	$a = new App(dirname(__DIR__));
 | 
			
		||||
}
 | 
			
		||||
$a = new App(dirname(__DIR__));
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
@include(".htconfig.php");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,9 @@
 | 
			
		|||
// Run this from cmdline in basedir and quickly see if we've
 | 
			
		||||
// got any parse errors in our application files.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use Friendica\App;
 | 
			
		||||
use Friendica\BaseObject;
 | 
			
		||||
 | 
			
		||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
 | 
			
		||||
ini_set('display_errors', '1');
 | 
			
		||||
| 
						 | 
				
			
			@ -13,15 +15,12 @@ ini_set('log_errors', '0');
 | 
			
		|||
 | 
			
		||||
include 'boot.php';
 | 
			
		||||
 | 
			
		||||
if (empty($a)) {
 | 
			
		||||
	$a = new App(dirname(__DIR__));
 | 
			
		||||
}
 | 
			
		||||
$a = new App(dirname(__DIR__));
 | 
			
		||||
BaseObject::setApp($a);
 | 
			
		||||
 | 
			
		||||
if (x($a->config, 'php_path')) {
 | 
			
		||||
	$phpath = $a->config['php_path'];
 | 
			
		||||
} else {
 | 
			
		||||
	$phpath = 'php';
 | 
			
		||||
}
 | 
			
		||||
@include '.htconfig.php';
 | 
			
		||||
 | 
			
		||||
$phpath = $a->getConfigValue('config', 'php_path', 'php');
 | 
			
		||||
 | 
			
		||||
echo 'Directory: src' . PHP_EOL;
 | 
			
		||||
$Iterator = new RecursiveDirectoryIterator('src');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue