@ -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); | |||
} |
@ -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); | |||
} |
@ -0,0 +1,132 @@ | |||
<?php | |||
namespace Friendica\Core\Config; | |||
use dba; | |||
use Friendica\BaseObject; | |||
use Friendica\Database\DBM; | |||
require_once 'include/dba.php'; | |||
/** | |||
* JustInTime ConfigAdapter | |||
* | |||
* 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; | |||
} | |||
$a = self::getApp(); | |||
$configs = dba::select('config', ['v', 'k'], ['cat' => $cat]); | |||
while ($config = dba::fetch($configs)) { | |||
$k = $config['k']; | |||
if ($cat === 'config') { | |||
$a->config[$k] = $config['v']; | |||
} else { | |||
$a->config[$cat][$k] = $config['v']; | |||
self::$cache[$cat][$k] = $config['v']; | |||
self::$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; | |||
} | |||
if ($cat === 'config') { | |||
$a->config[$k] = $dbvalue; | |||
} elseif ($cat != 'system') { | |||
$a->config[$cat][$k] = $dbvalue; | |||
} | |||
// 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; | |||
} | |||
} |
@ -0,0 +1,117 @@ | |||
<?php | |||
namespace Friendica\Core\Config; | |||
use dba; | |||
use Friendica\BaseObject; | |||
use Friendica\Database\DBM; | |||
require_once 'include/dba.php'; | |||
/** | |||
* JustInTime PConfigAdapter | |||
* | |||
* 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']; | |||
$a->config[$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']); | |||
$a->config[$uid][$cat][$k] = $val; | |||
$this->in_db[$uid][$cat][$k] = true; | |||
return $val; | |||
} else { | |||
$a->config[$uid][$cat][$k] = '!<unset>!'; | |||
$this->in_db[$uid][$cat][$k] = false; | |||
return $default_value; | |||
} | |||
} | |||
public function set($uid, $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($uid, $cat, $k, null, true); | |||
if (($stored === $dbvalue) && $this->in_db[$uid][$cat][$k]) { | |||
return true; | |||
} | |||
$a->config[$uid][$cat][$k] = $dbvalue; | |||
// 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) | |||
{ | |||
$a = self::getApp(); | |||
if (!empty($a->config[$uid][$cat][$k])) { | |||
unset($a->config[$uid][$cat][$k]); | |||
unset($this->in_db[$uid][$cat][$k]); | |||
} | |||
$result = dba::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]); | |||
return $result; | |||
} | |||
} |
@ -0,0 +1,119 @@ | |||
<?php | |||
namespace Friendica\Core\Config; | |||
use dba; | |||
use Exception; | |||
use Friendica\BaseObject; | |||
require_once 'include/dba.php'; | |||
/** | |||
* Preload ConfigAdapter | |||
* | |||
* Minimize 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; | |||
} | |||
$a = self::getApp(); | |||
$configs = dba::select('config', ['cat', 'v', 'k']); | |||
while ($config = dba::fetch($configs)) { | |||
$cat = $config['cat']; | |||
$k = $config['k']; | |||
$value = (preg_match("|^a:[0-9]+:{.*}$|s", $config['v']) ? unserialize($config['v']) : $config['v']); | |||
if ($cat === 'config') { | |||
$a->config[$k] = $value; | |||
} else { | |||
$a->config[$cat][$k] = $value; | |||
} | |||
} | |||
dba::close($configs); | |||
$this->config_loaded = true; | |||
} | |||
public function get($cat, $k, $default_value = null, $refresh = false) | |||
{ | |||
$a = self::getApp(); | |||
$return = $default_value; | |||
if ($cat === 'config') { | |||
if (isset($a->config[$k])) { | |||
$return = $a->config[$k]; | |||
} | |||
} else { | |||
if (isset($a->config[$cat][$k])) { | |||
$return = $a->config[$cat][$k]; | |||
} | |||
} | |||
return $return; | |||
} | |||
public function set($cat, $k, $value) | |||
{ | |||
$a = self::getApp(); | |||
// 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 ($this->get($cat, $k) === $compare_value) { | |||
return true; | |||
} | |||
if ($cat === 'config') { | |||
$a->config[$k] = $value; | |||
} else { | |||
$a->config[$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) | |||
{ | |||
$a = self::getApp(); | |||
if ($cat === 'config') { | |||
if (isset($a->config[$k])) { | |||
unset($a->config[$k]); | |||
} | |||
} else { | |||
if (isset($a->config[$cat][$k])) { | |||
unset($a->config[$cat][$k]); | |||
} | |||
} | |||
$result = dba::delete('config', ['cat' => $cat, 'k' => $k]); | |||
return $result; | |||
} | |||
} |
@ -0,0 +1,102 @@ | |||
<?php | |||
namespace Friendica\Core\Config; | |||
use dba; | |||
use Exception; | |||
use Friendica\BaseObject; | |||
require_once 'include/dba.php'; | |||
/** | |||
* Preload PConfigAdapter | |||
* | |||
* Minimize 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; | |||
} | |||
$a = self::getApp(); | |||
$pconfigs = dba::select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]); | |||
while ($pconfig = dba::fetch($pconfigs)) { | |||
$cat = $pconfig['cat']; | |||
$k = $pconfig['k']; | |||
$value = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']); | |||
$a->config[$uid][$cat][$k] = $value; | |||
} | |||
dba::close($pconfigs); | |||
$this->config_loaded = true; | |||
} | |||
public function get($uid, $cat, $k, $default_value = null, $refresh = false) | |||
{ | |||
$a = self::getApp(); | |||
$return = $default_value; | |||
if (isset($a->config[$uid][$cat][$k])) { | |||
$return = $a->config[$uid][$cat][$k]; | |||
} | |||
return $return; | |||
} | |||
public function set($uid, $cat, $k, $value) | |||
{ | |||
$a = self::getApp(); | |||
// 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 ($this->get($uid, $cat, $k) === $compare_value) { | |||
return true; | |||
} | |||
$a->config[$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) | |||
{ | |||
$a = self::getApp(); | |||
if (!isset($a->config[$uid][$cat][$k])) { | |||
return true; | |||
} | |||
unset($a->config[$uid][$cat][$k]); | |||
$result = dba::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]); | |||
return $result; | |||
} | |||
} |