file_put_contents($pidfile, $pid);
// We lose the database connection upon forking
- Factory\DBFactory::init($a->getConfigCache(), $a->getProfiler(), $_SERVER);
+ /// @todo refactoring during https://github.com/friendica/friendica/issues/6720
+ $basePath = \Friendica\Util\BasePath::create(dirname(__DIR__), $_SERVER);
+ Factory\DBFactory::init($basePath, $a->getConfigCache(), $a->getProfiler(), $_SERVER);
}
Config::set('system', 'worker_daemon_mode', true);
/**
* @brief App constructor.
*
+ * @param string $basePath The basedir of the app
* @param Configuration $config The Configuration
* @param LoggerInterface $logger The current app logger
* @param Profiler $profiler The profiler of this application
*
* @throws Exception if the Basepath is not usable
*/
- public function __construct(Configuration $config, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
+ public function __construct($basePath, Configuration $config, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
{
BaseObject::setApp($this);
$this->logger = $logger;
$this->config = $config;
$this->profiler = $profiler;
- $this->basePath = $this->config->get('system', 'basepath');
+ $cfgBasePath = $this->config->get('system', 'basepath');
+ $this->basePath = (isset($cfgBasePath) && $cfgBasePath !== '') ? $cfgBasePath : $basePath;
if (!Core\System::isDirectoryUsable($this->basePath, false)) {
throw new Exception('Basepath \'' . $this->basePath . '\' isn\'t usable.');
*
* Stores a config value ($value) in the category ($cat) under the key ($key)
*
- * Note: Please do not store booleans - convert to 0/1 integer values!
- *
* @param string $cat The category of the configuration value
* @param string $key The configuration key to set
* @param mixed $value The value to store
abstract class AbstractDbaConfigAdapter
{
- /** @var bool */
+ /**
+ * The connection state of the adapter
+ *
+ * @var bool
+ */
protected $connected = true;
public function __construct()
$this->connected = DBA::connected();
}
+ /**
+ * Checks if the adapter is currently connected
+ *
+ * @return bool
+ */
public function isConnected()
{
return $this->connected;
}
+
+ /**
+ * Formats a DB value to a config value
+ * - null = The db-value isn't set
+ * - bool = The db-value is either '0' or '1'
+ * - array = The db-value is a serialized array
+ * - string = The db-value is a string
+ *
+ * Keep in mind that there aren't any numeric/integer config values in the database
+ *
+ * @param null|string $value
+ *
+ * @return null|array|string
+ */
+ protected function toConfigValue($value)
+ {
+ if (!isset($value)) {
+ return null;
+ }
+
+ switch (true) {
+ // manage array value
+ case preg_match("|^a:[0-9]+:{.*}$|s", $value):
+ return unserialize($value);
+
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Formats a config value to a DB value (string)
+ *
+ * @param mixed $value
+ *
+ * @return string
+ */
+ protected function toDbValue($value)
+ {
+ // if not set, save an empty string
+ if (!isset($value)) {
+ return '';
+ }
+
+ switch (true) {
+ // manage arrays
+ case is_array($value):
+ return serialize($value);
+
+ default:
+ return (string)$value;
+ }
+ }
}
* Get a particular system-wide config variable given the category name
* ($family) and a key.
*
+ * Note: Boolean variables are defined as 0/1 in the database
+ *
* @param string $cat The category of the configuration value
* @param string $key The configuration key to query
*
- * @return mixed Stored value or "!<unset>!" if it does not exist
+ * @return null|mixed Stored value or null if it does not exist
*/
public function get($cat, $key);
* and removes it from the database.
*
* @param string $cat The category of the configuration value
- * @param string $key The configuration key to delete
+ * @param string $key The configuration key to delete
*
- * @return mixed
+ * @return bool Operation success
*/
public function delete($cat, $key);
* Get a particular user's config variable given the category name
* ($family) and a key.
*
+ * Note: Boolean variables are defined as 0/1 in the database
+ *
* @param string $uid The user_id
* @param string $cat The category of the configuration value
* @param string $key The configuration key to query
*
- * @return mixed Stored value or "!<unset>!" if it does not exist
+ * @return null|mixed Stored value or null if it does not exist
*/
public function get($uid, $cat, $key);
* @param string $cat The category of the configuration value
* @param string $key The configuration key to delete
*
- * @return bool
+ * @return bool Operation success
*/
public function delete($uid, $cat, $key);
$configs = DBA::select('config', ['v', 'k'], ['cat' => $cat]);
while ($config = DBA::fetch($configs)) {
$key = $config['k'];
- $value = $config['v'];
+ $value = $this->toConfigValue($config['v']);
- if (isset($value) && $value !== '') {
+ // The value was in the db, so don't check it again (unless you have to)
+ $this->in_db[$cat][$key] = true;
+
+ // just save it in case it is set
+ if (isset($value)) {
$return[$key] = $value;
- $this->in_db[$cat][$key] = true;
}
}
DBA::close($configs);
- return [$cat => $config];
+ return [$cat => $return];
}
/**
* {@inheritdoc}
+ *
+ * @param bool $mark if true, mark the selection of the current cat/key pair
*/
- public function get($cat, $key)
+ public function get($cat, $key, $mark = true)
{
if (!$this->isConnected()) {
- return '!<unset>!';
+ return null;
+ }
+
+ // The value got checked, so mark it to avoid checking it over and over again
+ if ($mark) {
+ $this->in_db[$cat][$key] = true;
}
$config = DBA::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $key]);
if (DBA::isResult($config)) {
// manage array value
- $value = (preg_match("|^a:[0-9]+:{.*}$|s", $config['v']) ? unserialize($config['v']) : $config['v']);
+ $value = $this->toConfigValue($config['v']);
- if (isset($value) && $value !== '') {
- $this->in_db[$cat][$key] = true;
+ // just return it in case it is set
+ if (isset($value)) {
return $value;
}
}
- $this->in_db[$cat][$key] = false;
- return '!<unset>!';
+ return null;
}
/**
// The exception are array values.
$dbvalue = (!is_array($value) ? (string)$value : $value);
- $stored = $this->get($cat, $key);
+ $stored = $this->get($cat, $key, false);
if (!isset($this->in_db[$cat])) {
$this->in_db[$cat] = [];
$this->in_db[$cat][$key] = false;
}
- if (($stored === $dbvalue) && $this->in_db[$cat][$key]) {
+ if (isset($stored) && ($stored === $dbvalue) && $this->in_db[$cat][$key]) {
return true;
}
- // manage array value
- $dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
+ $dbvalue = $this->toDbValue($dbvalue);
$result = DBA::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
if (DBA::isResult($pconfigs)) {
while ($pconfig = DBA::fetch($pconfigs)) {
$key = $pconfig['k'];
- $value = $pconfig['v'];
+ $value = $this->toConfigValue($pconfig['v']);
- if (isset($value) && $value !== '') {
+ // The value was in the db, so don't check it again (unless you have to)
+ $this->in_db[$uid][$cat][$key] = true;
+
+ if (isset($value)) {
$return[$key] = $value;
- $this->in_db[$uid][$cat][$key] = true;
}
}
} else if ($cat != 'config') {
// Negative caching
- $return = "!<unset>!";
+ $return = null;
}
DBA::close($pconfigs);
public function get($uid, $cat, $key)
{
if (!$this->isConnected()) {
- return '!<unset>!';
+ return null;
}
+ // The value was in the db, so don't check it again (unless you have to)
+ $this->in_db[$uid][$cat][$key] = true;
+
$pconfig = DBA::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
if (DBA::isResult($pconfig)) {
- // manage array value
- $value = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']);
+ $value = $this->toConfigValue($pconfig['v']);
- if (isset($value) && $value !== '') {
- $this->in_db[$uid][$cat][$key] = true;
+ if (isset($value)) {
return $value;
}
}
$this->in_db[$uid][$cat][$key] = false;
- return '!<unset>!';
+ return null;
}
/**
return false;
}
- if (!empty($this->in_db[$uid][$cat][$key])) {
+ if (isset($this->in_db[$uid][$cat][$key])) {
unset($this->in_db[$uid][$cat][$key]);
}
- $result = DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-
- return $result;
+ return DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
}
/**
$value = $config['v'];
if (isset($value) && $value !== '') {
$return[$config['cat']][$config['k']] = $value;
- } else {
- $return[$config['cat']][$config['k']] = '!<unset>!';
}
}
DBA::close($configs);
public function get($cat, $key)
{
if (!$this->isConnected()) {
- return '!<unset>!';
+ return null;
}
$config = DBA::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $key]);
}
}
- return '!<unset>!';
+ return null;
}
/**
// manage array value
$dbvalue = is_array($value) ? serialize($value) : $value;
- $result = DBA::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
-
- return $result;
+ return DBA::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
}
/**
return false;
}
- $result = DBA::delete('config', ['cat' => $cat, 'k' => $key]);
-
- return $result;
+ return DBA::delete('config', ['cat' => $cat, 'k' => $key]);
}
/**
$value = $pconfig['v'];
if (isset($value) && $value !== '') {
$return[$pconfig['cat']][$pconfig['k']] = $value;
- } else {
- $return[$pconfig['cat']][$pconfig['k']] = '!<unset>!';
}
}
DBA::close($pconfigs);
public function get($uid, $cat, $key)
{
if (!$this->isConnected()) {
- return '!<unset>!';
+ return null;
}
if (!$this->isLoaded($uid, $cat, $key)) {
return $value;
}
}
- return '!<unset>!';
+ return null;
}
/**
// manage array value
$dbvalue = is_array($value) ? serialize($value) : $value;
- $result = DBA::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
-
- return $result;
+ return DBA::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
}
/**
$this->load($uid, $cat);
}
- $result = DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-
- return $result;
+ return DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
}
/**
* The Friendica config cache for the application
* Initial, all *.config.php files are loaded into this cache with the
* ConfigCacheLoader ( @see ConfigCacheLoader )
- *
- * Is used for further caching operations too (depending on the ConfigAdapter )
*/
class ConfigCache implements IConfigCache, IPConfigCache
{
foreach ($keys as $key) {
$value = $config[$category][$key];
- if (isset($value) && $value !== '!<unset>!') {
+ if (isset($value)) {
if ($overwrite) {
$this->set($category, $key, $value);
} else {
{
if (isset($this->config[$cat][$key])) {
return $this->config[$cat][$key];
- } elseif ($key == null && isset($this->config[$cat])) {
+ } elseif (!isset($key) && isset($this->config[$cat])) {
return $this->config[$cat];
} else {
- return '!<unset>!';
+ return null;
}
}
- /**
- * {@inheritdoc}
- */
- public function has($cat, $key = null)
- {
- return (isset($this->config[$cat][$key]) && $this->config[$cat][$key] !== '!<unset>!') ||
- ($key == null && isset($this->config[$cat]) && $this->config[$cat] !== '!<unset>!' && is_array($this->config[$cat]));
- }
-
/**
* Sets a default value in the config cache. Ignores already existing keys.
*
*/
public function set($cat, $key, $value)
{
- // Only arrays are serialized in database, so we have to unserialize sparingly
- $value = is_string($value) && preg_match("|^a:[0-9]+:{.*}$|s", $value) ? unserialize($value) : $value;
-
if (!isset($this->config[$cat])) {
$this->config[$cat] = [];
}
return true;
}
- /**
- * {@inheritdoc}
- */
- public function hasP($uid, $cat, $key = null)
- {
- return (isset($this->config[$uid][$cat][$key]) && $this->config[$uid][$cat][$key] !== '!<unset>!') ||
- ($key == null && isset($this->config[$uid][$cat]) && $this->config[$uid][$cat] !== '!<unset>!' && is_array($this->config[$uid][$cat]));
- }
-
/**
* {@inheritdoc}
*/
foreach ($keys as $key) {
$value = $config[$category][$key];
- if (isset($value) && $value !== '!<unset>!') {
+ if (isset($value)) {
$this->setP($uid, $category, $key, $value);
}
}
{
if (isset($this->config[$uid][$cat][$key])) {
return $this->config[$uid][$cat][$key];
- } elseif ($key == null && isset($this->config[$uid][$cat])) {
+ } elseif (!isset($key) && isset($this->config[$uid][$cat])) {
return $this->config[$uid][$cat];
} else {
- return '!<unset>!';
+ return null;
}
}
*/
public function setP($uid, $cat, $key, $value)
{
- // Only arrays are serialized in database, so we have to unserialize sparingly
- $value = is_string($value) && preg_match("|^a:[0-9]+:{.*}$|s", $value) ? unserialize($value) : $value;
-
if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
$this->config[$uid] = [];
}
*/
public function loadConfigFiles(ConfigCache $config)
{
- // Setting at least the basepath we know
- $config->set('system', 'basepath', $this->baseDir);
-
$config->load($this->loadCoreConfig('defaults'));
$config->load($this->loadCoreConfig('settings'));
* Gets a value from the config cache.
*
* @param string $cat Config category
- * @param string $key Config key
+ * @param string $key Config key
*
- * @return mixed Returns the value of the Config entry or '!<unset>!' if not set
+ * @return null|mixed Returns the value of the Config entry or null if not set
*/
function get($cat, $key = null);
*/
function delete($cat, $key);
- /**
- * Checks if a value is set in the config cache.
- *
- * @param string $cat Config category
- * @param string $key Config key
- * @return bool
- */
- function has($cat, $key = null);
-
/**
* Returns the whole configuration cache
*
* @param string $cat Config category
* @param string $key Config key
*
- * @return string The value of the config entry or '!<unset>!' if not set
+ * @return null|string The value of the config entry or null if not set
*/
function getP($uid, $cat, $key = null);
*/
function deleteP($uid, $cat, $key);
-
- /**
- * Checks if a value is set in the user config cache.
- *
- * @param int $uid User Id
- * @param string $cat Config category
- * @param string $key Config key
- * @return bool
- */
- function hasP($uid, $cat, $key = null);
-
/**
* Returns the whole configuration cache
*
if ($this->configAdapter->isConnected() &&
(!$this->configAdapter->isLoaded($cat, $key) ||
$refresh)) {
+
$dbvalue = $this->configAdapter->get($cat, $key);
- if ($dbvalue !== '!<unset>!') {
+ if (isset($dbvalue)) {
$this->configCache->set($cat, $key, $dbvalue);
return $dbvalue;
}
}
// use the config cache for return
- if ($this->configCache->has($cat, $key)) {
- return $this->configCache->get($cat, $key);
- } else {
- return $default_value;
- }
+ $result = $this->configCache->get($cat, $key);
+
+ return (isset($result)) ? $result : $default_value;
}
/**
$refresh)) {
$dbValue = $this->configAdapter->get($uid, $cat, $key);
- if ($dbValue !== '!<unset>!') {
+ if (isset($dbValue)) {
$this->configCache->setP($uid, $cat, $key, $dbValue);
return $dbValue;
}
}
// use the config cache for return
- if ($this->configCache->hasP($uid, $cat, $key)) {
- return $this->configCache->getP($uid, $cat, $key);
- } else {
- return $default_value;
- }
+ $result = $this->configCache->getP($uid, $cat, $key);
+ return (isset($result)) ? $result : $default_value;
}
/**
/**
* @brief Sets a configuration value for a user
*
- * @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 $key The configuration key to set
* @var Profiler
*/
private static $profiler;
+ /**
+ * @var string
+ */
+ private static $basedir;
private static $server_info = '';
private static $connection;
private static $driver;
private static $db_name = '';
private static $db_charset = '';
- public static function connect(IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null)
+ public static function connect($basedir, IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null)
{
if (!is_null(self::$connection) && self::connected()) {
return true;
}
// We are storing these values for being able to perform a reconnect
+ self::$basedir = $basedir;
self::$configCache = $configCache;
self::$profiler = $profiler;
self::$db_serveraddr = $serveraddr;
* This process must only be started once, since the value is cached.
*/
private static function buildRelationData() {
- $definition = DBStructure::definition(self::$configCache->get('system', 'basepath'));
+ $definition = DBStructure::definition(self::$basedir);
foreach ($definition AS $table => $structure) {
foreach ($structure['fields'] AS $field => $field_struct) {
/**
* Initialize the DBA connection
*
+ * @param string $basePath The basepath of the application
* @param Cache\IConfigCache $configCache The configuration cache
- * @param Profiler $profiler The profiler
- * @param array $server The $_SERVER variables
+ * @param Profiler $profiler The profiler
+ * @param array $server The $_SERVER variables
*
* @throws \Exception if connection went bad
+ *
+ * @todo refactor basedir during https://github.com/friendica/friendica/issues/6720
*/
- public static function init(Cache\IConfigCache $configCache, Profiler $profiler, array $server)
+ public static function init($basePath, Cache\IConfigCache $configCache, Profiler $profiler, array $server)
{
if (Database\DBA::connected()) {
return;
$db_data = $server['MYSQL_DATABASE'];
}
- if (Database\DBA::connect($configCache, $profiler, $db_host, $db_user, $db_pass, $db_data, $charset)) {
+ if (Database\DBA::connect($basePath, $configCache, $profiler, $db_host, $db_user, $db_pass, $db_data, $charset)) {
// Loads DB_UPDATE_VERSION constant
- Database\DBStructure::definition($configCache->get('system', 'basepath'), false);
+ Database\DBStructure::definition($basePath, false);
}
unset($db_host, $db_user, $db_pass, $db_data, $charset);
*/
public static function setUp($channel, $directory, $isBackend = true)
{
- $basedir = BasePath::create($directory, $_SERVER);
- $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $basePath = BasePath::create($directory, $_SERVER);
+ $configLoader = new Cache\ConfigCacheLoader($basePath);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
- Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
// needed to call PConfig::init()
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create($channel, $config);
- return new App($config, $logger, $profiler, $isBackend);
+ return new App($basePath, $config, $logger, $profiler, $isBackend);
}
}
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\L10n;
-use Friendica\Core\System;
use Friendica\Core\StorageManager;
+use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
use Friendica\Model\Storage\IStorage;
*/
private static function getFields()
{
- $allfields = DBStructure::definition(false);
+ $allfields = DBStructure::definition(self::getApp()->getBasePath(), false);
$fields = array_keys($allfields["photo"]["fields"]);
array_splice($fields, array_search("data", $fields), 1);
return $fields;
*/
public function setUp()
{
- $basedir = BasePath::create(dirname(__DIR__) . '/../');
- $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $basePath = BasePath::create(dirname(__DIR__) . '/../');
+ $configLoader = new Cache\ConfigCacheLoader($basePath);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
- Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, $profiler, false);
+ $this->app = new App($basePath, $config, $logger, $profiler, false);
parent::setUp();
{
public function setUp()
{
- $basedir = BasePath::create(dirname(__DIR__) . '/../../');
- $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $basePath = BasePath::create(dirname(__DIR__) . '/../../');
+ $configLoader = new Cache\ConfigCacheLoader($basePath);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
- Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, $profiler, false);
+ $this->app = new App($basePath, $config, $logger, $profiler, false);
parent::setUp();
{
public function setUp()
{
- $basedir = BasePath::create(dirname(__DIR__) . '/../../');
- $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $basePath = BasePath::create(dirname(__DIR__) . '/../../');
+ $configLoader = new Cache\ConfigCacheLoader($basePath);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
- Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, $profiler, false);
+ $this->app = new App($basePath, $config, $logger, $profiler, false);
parent::setUp();
}