diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php
index 11df43895..bf6d069d1 100755
--- a/bin/auth_ejabberd.php
+++ b/bin/auth_ejabberd.php
@@ -32,10 +32,7 @@
*
*/
-use Friendica\App;
-use Friendica\Core\Config;
use Friendica\Factory;
-use Friendica\Util\BasePath;
use Friendica\Util\ExAuth;
if (sizeof($_SERVER["argv"]) == 0) {
@@ -54,12 +51,7 @@ chdir($directory);
require dirname(__DIR__) . '/vendor/autoload.php';
-$basedir = BasePath::create(dirname(__DIR__), $_SERVER);
-$configLoader = new Config\ConfigCacheLoader($basedir);
-$config = Factory\ConfigFactory::createCache($configLoader);
-$logger = Factory\LoggerFactory::create('auth_ejabberd', $config);
-
-$a = new App($config, $logger);
+$a = Factory\DependencyFactory::setUp('auth_ejabbered', dirname(__DIR__));
if ($a->getMode()->isNormal()) {
$oAuth = new ExAuth();
diff --git a/bin/console.php b/bin/console.php
index 9061824d8..410eabda0 100755
--- a/bin/console.php
+++ b/bin/console.php
@@ -3,16 +3,9 @@
require dirname(__DIR__) . '/vendor/autoload.php';
-use Friendica\Core\Config;
use Friendica\Factory;
-use Friendica\Util\BasePath;
-$basedir = BasePath::create(dirname(__DIR__), $_SERVER);
-$configLoader = new Config\ConfigCacheLoader($basedir);
-$config = Factory\ConfigFactory::createCache($configLoader);
-$logger = Factory\LoggerFactory::create('console', $config);
-
-$a = new Friendica\App($config, $logger);
+$a = Factory\DependencyFactory::setUp('console', dirname(__DIR__));
\Friendica\BaseObject::setApp($a);
(new Friendica\Core\Console($argv))->execute();
diff --git a/bin/daemon.php b/bin/daemon.php
index 5c014a927..047bf71be 100755
--- a/bin/daemon.php
+++ b/bin/daemon.php
@@ -7,12 +7,11 @@
* This script was taken from http://php.net/manual/en/function.pcntl-fork.php
*/
-use Friendica\App;
use Friendica\Core\Config;
+use Friendica\Core\Logger;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\Factory;
-use Friendica\Util\BasePath;
// Get options
$shortopts = 'f';
@@ -33,12 +32,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
require dirname(__DIR__) . '/vendor/autoload.php';
-$basedir = BasePath::create(dirname(__DIR__), $_SERVER);
-$configLoader = new Config\ConfigCacheLoader($basedir);
-$config = Factory\ConfigFactory::createCache($configLoader);
-$logger = Factory\LoggerFactory::create('daemon', $config);
-
-$a = new App($config, $logger);
+$a = Factory\DependencyFactory::setUp('daemon', dirname(__DIR__));
if ($a->getMode()->isInstall()) {
die("Friendica isn't properly installed yet.\n");
@@ -108,7 +102,7 @@ if ($mode == "stop") {
unlink($pidfile);
- $logger->notice("Worker daemon process was killed", ["pid" => $pid]);
+ Logger::notice("Worker daemon process was killed", ["pid" => $pid]);
Config::set('system', 'worker_daemon_mode', false);
die("Worker daemon process $pid was killed.\n");
@@ -118,7 +112,7 @@ if (!empty($pid) && posix_kill($pid, 0)) {
die("Daemon process $pid is already running.\n");
}
-$logger->notice('Starting worker daemon.', ["pid" => $pid]);
+Logger::notice('Starting worker daemon.', ["pid" => $pid]);
if (!$foreground) {
echo "Starting worker daemon.\n";
@@ -150,7 +144,7 @@ if (!$foreground) {
file_put_contents($pidfile, $pid);
// We lose the database connection upon forking
- $a->loadDatabase();
+ Factory\DBFactory::init($a->getConfigCache(), $a->getProfiler(), $_SERVER);
}
Config::set('system', 'worker_daemon_mode', true);
@@ -166,7 +160,7 @@ $last_cron = 0;
// Now running as a daemon.
while (true) {
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
- $logger->info('Forcing cron worker call.', ["pid" => $pid]);
+ Logger::info('Forcing cron worker call.', ["pid" => $pid]);
$do_cron = true;
}
@@ -180,7 +174,7 @@ while (true) {
$last_cron = time();
}
- $logger->info("Sleeping", ["pid" => $pid]);
+ Logger::info("Sleeping", ["pid" => $pid]);
$start = time();
do {
$seconds = (time() - $start);
@@ -197,10 +191,10 @@ while (true) {
if ($timeout) {
$do_cron = true;
- $logger->info("Woke up after $wait_interval seconds.", ["pid" => $pid, 'sleep' => $wait_interval]);
+ Logger::info("Woke up after $wait_interval seconds.", ["pid" => $pid, 'sleep' => $wait_interval]);
} else {
$do_cron = false;
- $logger->info("Worker jobs are calling to be forked.", ["pid" => $pid]);
+ Logger::info("Worker jobs are calling to be forked.", ["pid" => $pid]);
}
}
diff --git a/bin/worker.php b/bin/worker.php
index 553e98497..c7174d81e 100755
--- a/bin/worker.php
+++ b/bin/worker.php
@@ -10,7 +10,6 @@ use Friendica\Core\Config;
use Friendica\Core\Update;
use Friendica\Core\Worker;
use Friendica\Factory;
-use Friendica\Util\BasePath;
// Get options
$shortopts = 'sn';
@@ -31,12 +30,7 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
require dirname(__DIR__) . '/vendor/autoload.php';
-$basedir = BasePath::create(dirname(__DIR__), $_SERVER);
-$configLoader = new Config\ConfigCacheLoader($basedir);
-$config = Factory\ConfigFactory::createCache($configLoader);
-$logger = Factory\LoggerFactory::create('worker', $config);
-
-$a = new App($config, $logger);
+$a = Factory\DependencyFactory::setUp('worker', dirname(__DIR__));
// Check the database structure and possibly fixes it
Update::check($a->getBasePath(), true);
diff --git a/composer.json b/composer.json
index 39d935892..3638a9495 100644
--- a/composer.json
+++ b/composer.json
@@ -34,13 +34,15 @@
"lightopenid/lightopenid": "dev-master",
"michelf/php-markdown": "^1.7",
"mobiledetect/mobiledetectlib": "2.8.*",
+ "monolog/monolog": "^1.24",
"paragonie/random_compat": "^2.0",
- "pear/Text_LanguageDetect": "1.*",
+ "pear/text_languagedetect": "1.*",
+ "psr/container": "^1.0",
"seld/cli-prompt": "^1.0",
"smarty/smarty": "^3.1",
"fxp/composer-asset-plugin": "~1.3",
"bower-asset/base64": "^1.0",
- "bower-asset/Chart-js": "^2.7",
+ "bower-asset/chart-js": "^2.7",
"bower-asset/perfect-scrollbar": "^0.6",
"bower-asset/vue": "^2.5",
"npm-asset/jquery": "^2.0",
@@ -49,8 +51,7 @@
"npm-asset/jgrowl": "^1.4",
"npm-asset/fullcalendar": "^3.0.1",
"npm-asset/cropperjs": "1.2.2",
- "npm-asset/imagesloaded": "4.1.4",
- "monolog/monolog": "^1.24"
+ "npm-asset/imagesloaded": "4.1.4"
},
"repositories": [
{
@@ -96,7 +97,7 @@
"phpunit/dbunit": "^2.0",
"phpdocumentor/reflection-docblock": "^3.0.2",
"phpunit/php-token-stream": "^1.4.2",
- "mikey179/vfsStream": "^1.6",
+ "mikey179/vfsstream": "^1.6",
"mockery/mockery": "^1.2",
"johnkary/phpunit-speedtrap": "1.1"
},
diff --git a/composer.lock b/composer.lock
index f91b833de..e554b1199 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b944adfb6ede89430ba3b7e9ebb45acb",
+ "content-hash": "19fabb14e0dd5d806ef841e51d5f6a0b",
"packages": [
{
"name": "asika/simple-console",
@@ -1882,6 +1882,55 @@
],
"time": "2016-08-06T20:24:11+00:00"
},
+ {
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "time": "2017-02-14T16:28:37+00:00"
+ },
{
"name": "psr/http-message",
"version": "1.0.1",
@@ -2650,6 +2699,7 @@
"testing",
"xunit"
],
+ "abandoned": true,
"time": "2016-12-02T14:39:14+00:00"
},
{
diff --git a/include/api.php b/include/api.php
index 052d32b17..13ff75bdb 100644
--- a/include/api.php
+++ b/include/api.php
@@ -326,69 +326,7 @@ function api_call(App $a)
Logger::info(API_LOG_PREFIX . 'username {username}', ['module' => 'api', 'action' => 'call', 'username' => $a->user['username'], 'duration' => round($duration, 2)]);
- if (Config::get("system", "profiler")) {
- $duration = microtime(true)-$a->performance["start"];
-
- /// @TODO round() really everywhere?
- Logger::debug(
- API_LOG_PREFIX . 'performance',
- [
- 'module' => 'api',
- 'action' => 'call',
- 'database_read' => round($a->performance["database"] - $a->performance["database_write"], 3),
- 'database_write' => round($a->performance["database_write"], 3),
- 'cache_read' => round($a->performance["cache"], 3),
- 'cache_write' => round($a->performance["cache_write"], 3),
- 'network_io' => round($a->performance["network"], 2),
- 'file_io' => round($a->performance["file"], 2),
- 'other_io' => round($duration - ($a->performance["database"]
- + $a->performance["cache"] + $a->performance["cache_write"]
- + $a->performance["network"] + $a->performance["file"]), 2),
- 'total' => round($duration, 2)
- ]
- );
-
- if (Config::get("rendertime", "callstack")) {
- $o = "Database Read:\n";
- foreach ($a->callstack["database"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func . ": " . $time . "\n";
- }
- }
- $o .= "\nDatabase Write:\n";
- foreach ($a->callstack["database_write"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func . ": " . $time . "\n";
- }
- }
-
- $o = "Cache Read:\n";
- foreach ($a->callstack["cache"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func . ": " . $time . "\n";
- }
- }
- $o .= "\nCache Write:\n";
- foreach ($a->callstack["cache_write"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func . ": " . $time . "\n";
- }
- }
-
- $o .= "\nNetwork:\n";
- foreach ($a->callstack["network"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func . ": " . $time . "\n";
- }
- }
- Logger::debug(API_LOG_PREFIX . $o, ['module' => 'api', 'action' => 'call']);
- }
- }
+ $a->getProfiler()->saveLog($a->getLogger(), API_LOG_PREFIX . 'performance');
if (false === $return) {
/*
diff --git a/index.php b/index.php
index 7e7396785..47264362c 100644
--- a/index.php
+++ b/index.php
@@ -4,10 +4,7 @@
* Friendica
*/
-use Friendica\App;
-use Friendica\Core\Config;
use Friendica\Factory;
-use Friendica\Util\BasePath;
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
die('Vendor path not found. Please execute "bin/composer.phar --no-dev install" on the command line in the web root.');
@@ -15,13 +12,6 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
require __DIR__ . '/vendor/autoload.php';
-$basedir = BasePath::create(__DIR__, $_SERVER);
-$configLoader = new Config\ConfigCacheLoader($basedir);
-$config = Factory\ConfigFactory::createCache($configLoader);
-$logger = Factory\LoggerFactory::create('index', $config);
-
-// We assume that the index.php is called by a frontend process
-// The value is set to "true" by default in App
-$a = new App($config, $logger, false);
+$a = Factory\DependencyFactory::setUp('index', __DIR__, true);
$a->runFrontend();
diff --git a/src/App.php b/src/App.php
index b9e22dd1b..ca2b6dfc2 100644
--- a/src/App.php
+++ b/src/App.php
@@ -8,11 +8,12 @@ use Detection\MobileDetect;
use DOMDocument;
use DOMXPath;
use Exception;
-use Friendica\Core\Config\ConfigCache;
-use Friendica\Core\Config\ConfigCacheLoader;
+use Friendica\Core\Config\Cache\ConfigCacheLoader;
+use Friendica\Core\Config\Cache\IConfigCache;
+use Friendica\Core\Config\Configuration;
use Friendica\Database\DBA;
-use Friendica\Factory\ConfigFactory;
use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
/**
@@ -53,8 +54,6 @@ class App
public $identities;
public $is_mobile = false;
public $is_tablet = false;
- public $performance = [];
- public $callstack = [];
public $theme_info = [];
public $category;
// Allow themes to control internal parameters
@@ -110,23 +109,28 @@ class App
public $mobileDetect;
/**
- * @var LoggerInterface The current logger of this App
- */
- private $logger;
-
- /**
- * @var ConfigCache The cached config
+ * @var Configuration The config
*/
private $config;
+ /**
+ * @var LoggerInterface The logger
+ */
+ private $logger;
+
+ /**
+ * @var Profiler The profiler of this app
+ */
+ private $profiler;
+
/**
* Returns the current config cache of this node
*
- * @return ConfigCache
+ * @return IConfigCache
*/
- public function getConfig()
+ public function getConfigCache()
{
- return $this->config;
+ return $this->config->getCache();
}
/**
@@ -139,6 +143,26 @@ class App
return $this->basePath;
}
+ /**
+ * The Logger of this app
+ *
+ * @return LoggerInterface
+ */
+ public function getLogger()
+ {
+ return $this->logger;
+ }
+
+ /**
+ * The profiler of this app
+ *
+ * @return Profiler
+ */
+ public function getProfiler()
+ {
+ return $this->profiler;
+ }
+
/**
* Register a stylesheet file path to be included in the
tag of every page.
* Inclusion is done in App->initHead().
@@ -181,16 +205,18 @@ class App
/**
* @brief App constructor.
*
- * @param ConfigCache $config The Cached Config
- * @param LoggerInterface $logger Logger of this application
+ * @param Configuration $config The Configuration
+ * @param LoggerInterface $logger The current app logger
+ * @param Profiler $profiler The profiler of this application
* @param bool $isBackend Whether it is used for backend or frontend (Default true=backend)
*
* @throws Exception if the Basepath is not usable
*/
- public function __construct(ConfigCache $config, LoggerInterface $logger, $isBackend = true)
+ public function __construct(Configuration $config, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
{
- $this->config = $config;
$this->logger = $logger;
+ $this->config = $config;
+ $this->profiler = $profiler;
$this->basePath = $this->config->get('system', 'basepath');
if (!Core\System::isDirectoryUsable($this->basePath, false)) {
@@ -203,26 +229,7 @@ class App
$this->checkBackend($isBackend);
$this->checkFriendicaApp();
- $this->performance['start'] = microtime(true);
- $this->performance['database'] = 0;
- $this->performance['database_write'] = 0;
- $this->performance['cache'] = 0;
- $this->performance['cache_write'] = 0;
- $this->performance['network'] = 0;
- $this->performance['file'] = 0;
- $this->performance['rendering'] = 0;
- $this->performance['parser'] = 0;
- $this->performance['marktime'] = 0;
- $this->performance['markstart'] = microtime(true);
-
- $this->callstack['database'] = [];
- $this->callstack['database_write'] = [];
- $this->callstack['cache'] = [];
- $this->callstack['cache_write'] = [];
- $this->callstack['network'] = [];
- $this->callstack['file'] = [];
- $this->callstack['rendering'] = [];
- $this->callstack['parser'] = [];
+ $this->profiler->reset();
$this->mode = new App\Mode($this->basePath);
@@ -341,52 +348,20 @@ class App
return $this->mode;
}
- /**
- * Returns the Logger of the Application
- *
- * @return LoggerInterface The Logger
- * @throws InternalServerErrorException when the logger isn't created
- */
- public function getLogger()
- {
- if (empty($this->logger)) {
- throw new InternalServerErrorException('Logger of the Application is not defined');
- }
-
- return $this->logger;
- }
-
/**
* Reloads the whole app instance
*/
public function reload()
{
- Core\Config::init($this->config);
- Core\PConfig::init($this->config);
-
- $this->loadDatabase();
-
- $this->getMode()->determine($this->basePath);
-
$this->determineURLPath();
- if ($this->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
- $adapterType = $this->config->get('system', 'config_adapter');
- $adapter = ConfigFactory::createConfig($adapterType, $this->config);
- Core\Config::setAdapter($adapter);
- $adapterP = ConfigFactory::createPConfig($adapterType, $this->config);
- Core\PConfig::setAdapter($adapterP);
- Core\Config::load();
- }
-
- // again because DB-config could change the config
$this->getMode()->determine($this->basePath);
if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
Core\Hook::loadHooks();
$loader = new ConfigCacheLoader($this->basePath);
Core\Hook::callAll('load_config', $loader);
- $this->config->loadConfigArray($loader->loadCoreConfig('addon'), true);
+ $this->config->getCache()->load($loader->loadCoreConfig('addon'), true);
}
$this->loadDefaultTimezone();
@@ -394,8 +369,6 @@ class App
Core\L10n::init();
$this->process_id = Core\System::processID('log');
-
- Core\Logger::setLogger($this->logger);
}
/**
@@ -456,49 +429,6 @@ class App
}
}
- public function loadDatabase()
- {
- if (DBA::connected()) {
- return;
- }
-
- $db_host = $this->config->get('database', 'hostname');
- $db_user = $this->config->get('database', 'username');
- $db_pass = $this->config->get('database', 'password');
- $db_data = $this->config->get('database', 'database');
- $charset = $this->config->get('database', 'charset');
-
- // Use environment variables for mysql if they are set beforehand
- if (!empty(getenv('MYSQL_HOST'))
- && !empty(getenv('MYSQL_USERNAME') || !empty(getenv('MYSQL_USER')))
- && getenv('MYSQL_PASSWORD') !== false
- && !empty(getenv('MYSQL_DATABASE')))
- {
- $db_host = getenv('MYSQL_HOST');
- if (!empty(getenv('MYSQL_PORT'))) {
- $db_host .= ':' . getenv('MYSQL_PORT');
- }
- if (!empty(getenv('MYSQL_USERNAME'))) {
- $db_user = getenv('MYSQL_USERNAME');
- } else {
- $db_user = getenv('MYSQL_USER');
- }
- $db_pass = (string) getenv('MYSQL_PASSWORD');
- $db_data = getenv('MYSQL_DATABASE');
- }
-
- $stamp1 = microtime(true);
-
- if (DBA::connect($this->config, $db_host, $db_user, $db_pass, $db_data, $charset)) {
- // Loads DB_UPDATE_VERSION constant
- Database\DBStructure::definition($this->basePath, false);
- }
-
- unset($db_host, $db_user, $db_pass, $db_data, $charset);
-
- $this->saveTimestamp($stamp1, 'network');
- }
-
public function getScheme()
{
return $this->scheme;
@@ -740,41 +670,6 @@ class App
}
}
- /**
- * Saves a timestamp for a value - f.e. a call
- * Necessary for profiling Friendica
- *
- * @param int $timestamp the Timestamp
- * @param string $value A value to profile
- */
- public function saveTimestamp($timestamp, $value)
- {
- $profiler = $this->config->get('system', 'profiler');
-
- if (!isset($profiler) || !$profiler) {
- return;
- }
-
- $duration = (float) (microtime(true) - $timestamp);
-
- if (!isset($this->performance[$value])) {
- // Prevent ugly E_NOTICE
- $this->performance[$value] = 0;
- }
-
- $this->performance[$value] += (float) $duration;
- $this->performance['marktime'] += (float) $duration;
-
- $callstack = Core\System::callstack();
-
- if (!isset($this->callstack[$value][$callstack])) {
- // Prevent ugly E_NOTICE
- $this->callstack[$value][$callstack] = 0;
- }
-
- $this->callstack[$value][$callstack] += (float) $duration;
- }
-
/**
* Returns the current UserAgent as a String
*
@@ -1225,7 +1120,7 @@ class App
if (!$this->isBackend()) {
$stamp1 = microtime(true);
session_start();
- $this->saveTimestamp($stamp1, 'parser');
+ $this->profiler->saveTimestamp($stamp1, 'parser', Core\System::callstack());
Core\L10n::setSessionVariable();
Core\L10n::setLangFromSession();
} else {
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index a8b5ec202..e9b5f98d0 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -1027,7 +1027,7 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
if (substr($curl_info["content_type"], 0, 6) == "image/") {
$text = "[url=" . $match[1] . "]" . $match[1] . "[/url]";
@@ -1086,7 +1086,7 @@ class BBCode extends BaseObject
@curl_exec($ch);
$curl_info = @curl_getinfo($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
// if its a link to a picture then embed this picture
if (substr($curl_info["content_type"], 0, 6) == "image/") {
@@ -1915,7 +1915,7 @@ class BBCode extends BaseObject
// unmask the special chars back to HTML
$text = str_replace(['&\_lt\_;', '&\_gt\_;', '&\_amp\_;'], ['<', '>', '&'], $text);
- $a->saveTimestamp($stamp1, "parser");
+ $a->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
// Libertree has a problem with escaped hashtags.
$text = str_replace(['\#'], ['#'], $text);
diff --git a/src/Content/Text/Markdown.php b/src/Content/Text/Markdown.php
index ceb5b043b..e3e2cd3ac 100644
--- a/src/Content/Text/Markdown.php
+++ b/src/Content/Text/Markdown.php
@@ -7,6 +7,7 @@
namespace Friendica\Content\Text;
use Friendica\BaseObject;
+use Friendica\Core\System;
use Friendica\Model\Contact;
use Michelf\MarkdownExtra;
@@ -36,7 +37,7 @@ class Markdown extends BaseObject
$html = $MarkdownParser->transform($text);
$html = preg_replace('/saveTimestamp($stamp1, "parser");
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
return $html;
}
diff --git a/src/Core/Addon.php b/src/Core/Addon.php
index 6697a44ae..7957e0835 100644
--- a/src/Core/Addon.php
+++ b/src/Core/Addon.php
@@ -219,7 +219,7 @@ class Addon extends BaseObject
$stamp1 = microtime(true);
$f = file_get_contents("addon/$addon/$addon.php");
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$r = preg_match("|/\*.*\*/|msU", $f, $m);
diff --git a/src/Core/Cache.php b/src/Core/Cache.php
index 39c29566d..cadb2444b 100644
--- a/src/Core/Cache.php
+++ b/src/Core/Cache.php
@@ -63,7 +63,7 @@ class Cache extends \Friendica\BaseObject
$return = self::getDriver()->getAllKeys($prefix);
- self::getApp()->saveTimestamp($time, 'cache');
+ self::getApp()->getProfiler()->saveTimestamp($time, 'cache', System::callstack());
return $return;
}
@@ -82,7 +82,7 @@ class Cache extends \Friendica\BaseObject
$return = self::getDriver()->get($key);
- self::getApp()->saveTimestamp($time, 'cache');
+ self::getApp()->getProfiler()->saveTimestamp($time, 'cache', System::callstack());
return $return;
}
@@ -105,7 +105,7 @@ class Cache extends \Friendica\BaseObject
$return = self::getDriver()->set($key, $value, $duration);
- self::getApp()->saveTimestamp($time, 'cache_write');
+ self::getApp()->getProfiler()->saveTimestamp($time, 'cache_write', System::callstack());
return $return;
}
@@ -124,7 +124,7 @@ class Cache extends \Friendica\BaseObject
$return = self::getDriver()->delete($key);
- self::getApp()->saveTimestamp($time, 'cache_write');
+ self::getApp()->getProfiler()->saveTimestamp($time, 'cache_write', System::callstack());
return $return;
}
diff --git a/src/Core/Config.php b/src/Core/Config.php
index 559ee83ec..4bf9c5b11 100644
--- a/src/Core/Config.php
+++ b/src/Core/Config.php
@@ -8,10 +8,6 @@
*/
namespace Friendica\Core;
-use Friendica\Core\Config\ConfigCache;
-use Friendica\Core\Config\IConfigAdapter;
-use Friendica\Core\Config\IConfigCache;
-
/**
* @brief Arbitrary system configuration storage
*
@@ -22,116 +18,76 @@ use Friendica\Core\Config\IConfigCache;
class Config
{
/**
- * @var Config\IConfigAdapter|null
+ * @var Config\Configuration
*/
- private static $adapter;
+ private static $config;
/**
- * @var Config\IConfigCache
- */
- private static $cache;
-
- /**
- * Initialize the config with only the cache
+ * Initialize the config
*
- * @param Config\IConfigCache $cache The configuration cache
+ * @param Config\Configuration $config
*/
- public static function init(Config\IConfigCache $cache)
+ public static function init(Config\Configuration $config)
{
- self::$cache = $cache;
- }
-
- /**
- * Add the adapter for DB-backend
- *
- * @param Config\IConfigAdapter $adapter
- */
- public static function setAdapter(Config\IConfigAdapter $adapter)
- {
- self::$adapter = $adapter;
+ self::$config = $config;
}
/**
* @brief Loads all configuration values of family into a cached storage.
*
- * All configuration values of the system are stored in the cache ( @see IConfigCache )
- *
- * @param string $family The category of the configuration value
+ * @param string $cat The category of the configuration value
*
* @return void
*/
- public static function load($family = "config")
+ public static function load($cat = "config")
{
- if (!isset(self::$adapter) || !self::$adapter->isConnected()) {
- return;
- }
-
- self::$adapter->load($family);
+ self::$config->load($cat);
}
/**
* @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 either from the self::$adapter
- * (@see IConfigAdapter ) or from the static::$cache (@see IConfigCache ).
- *
- * @param string $family The category of the configuration value
+ * @param string $cat The category of the configuration value
* @param string $key 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 static function get($family, $key, $default_value = null, $refresh = false)
+ public static function get($cat, $key, $default_value = null, $refresh = false)
{
- if (!isset(self::$adapter) || !self::$adapter->isConnected()) {
- return self::$cache->get($family, $key, $default_value);
- }
-
- return self::$adapter->get($family, $key, $default_value, $refresh);
+ return self::$config->get($cat, $key, $default_value, $refresh);
}
/**
* @brief Sets a configuration value for system config
*
- * Stores a config value ($value) in the category ($family) under the key ($key)
+ * 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 $family The category of the configuration value
+ * @param string $cat The category of the configuration value
* @param string $key The configuration key to set
* @param mixed $value The value to store
*
* @return bool Operation success
*/
- public static function set($family, $key, $value)
+ public static function set($cat, $key, $value)
{
- if (!isset(self::$adapter) || !self::$adapter->isConnected()) {
- return self::$cache->set($family, $key, $value);
- }
-
- return self::$adapter->set($family, $key, $value);
+ return self::$config->set($cat, $key, $value);
}
/**
* @brief Deletes the given key from the system configuration.
*
- * Removes the configured value from the stored cache in self::$config
- * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter ).
- *
- * @param string $family The category of the configuration value
+ * @param string $cat The category of the configuration value
* @param string $key The configuration key to delete
*
- * @return mixed
+ * @return bool
*/
- public static function delete($family, $key)
+ public static function delete($cat, $key)
{
- if (!isset(self::$adapter) || !self::$adapter->isConnected()) {
- self::$cache->delete($family, $key);
- }
-
- return self::$adapter->delete($family, $key);
+ return self::$config->delete($cat, $key);
}
}
diff --git a/src/Core/Config/AbstractDbaConfigAdapter.php b/src/Core/Config/Adapter/AbstractDbaConfigAdapter.php
similarity index 52%
rename from src/Core/Config/AbstractDbaConfigAdapter.php
rename to src/Core/Config/Adapter/AbstractDbaConfigAdapter.php
index bae75122a..770dfd2c9 100644
--- a/src/Core/Config/AbstractDbaConfigAdapter.php
+++ b/src/Core/Config/Adapter/AbstractDbaConfigAdapter.php
@@ -1,12 +1,19 @@
connected = DBA::connected();
+ }
+
public function isConnected()
{
return $this->connected;
diff --git a/src/Core/Config/IConfigAdapter.php b/src/Core/Config/Adapter/IConfigAdapter.php
similarity index 50%
rename from src/Core/Config/IConfigAdapter.php
rename to src/Core/Config/Adapter/IConfigAdapter.php
index 70e141484..21cd9a4b2 100644
--- a/src/Core/Config/IConfigAdapter.php
+++ b/src/Core/Config/Adapter/IConfigAdapter.php
@@ -1,6 +1,6 @@
!" if it does not exist
*/
- public function get($cat, $k, $default_value = null, $refresh = false);
+ public function get($cat, $key);
/**
- * Stores a config value ($value) in the category ($family) under the key ($key)
- * for the user_id $uid.
+ * Stores a config value ($value) in the category ($family) 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 $k The configuration key to set
+ * @param string $key The configuration key to set
* @param mixed $value The value to store
*
* @return bool Operation success
*/
- public function set($cat, $k, $value);
+ public function set($cat, $key, $value);
/**
* Removes the configured value from the stored cache
* and removes it from the database.
*
* @param string $cat The category of the configuration value
- * @param string $k The configuration key to delete
+ * @param string $key The configuration key to delete
*
* @return mixed
*/
- public function delete($cat, $k);
+ public function delete($cat, $key);
/**
* Checks, if the current adapter is connected to the backend
@@ -61,4 +58,14 @@ interface IConfigAdapter
* @return bool
*/
public function isConnected();
+
+ /**
+ * Checks, if a config key ($key) in the category ($cat) is already loaded.
+ *
+ * @param string $cat The configuration category
+ * @param string $key The configuration key
+ *
+ * @return bool
+ */
+ public function isLoaded($cat, $key);
}
diff --git a/src/Core/Config/IPConfigAdapter.php b/src/Core/Config/Adapter/IPConfigAdapter.php
similarity index 55%
rename from src/Core/Config/IPConfigAdapter.php
rename to src/Core/Config/Adapter/IPConfigAdapter.php
index e62fc9c93..8e6c050b2 100644
--- a/src/Core/Config/IPConfigAdapter.php
+++ b/src/Core/Config/Adapter/IPConfigAdapter.php
@@ -6,7 +6,7 @@
* and open the template in the editor.
*/
-namespace Friendica\Core\Config;
+namespace Friendica\Core\Config\Adapter;
/**
*
@@ -15,12 +15,12 @@ namespace Friendica\Core\Config;
interface IPConfigAdapter
{
/**
- * Loads all configuration values of a user's config family into a cached storage.
+ * Loads all configuration values of a user's config family and returns the loaded category as an array.
*
* @param string $uid The user_id
* @param string $cat The category of the configuration value
*
- * @return void
+ * @return array
*/
public function load($uid, $cat);
@@ -30,13 +30,11 @@ interface IPConfigAdapter
*
* @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)
+ * @param string $key The configuration key to query
*
- * @return mixed Stored value or null if it does not exist
+ * @return mixed Stored value or "!!" if it does not exist
*/
- public function get($uid, $cat, $k, $default_value = null, $refresh = false);
+ public function get($uid, $cat, $key);
/**
* Stores a config value ($value) in the category ($family) under the key ($key)
@@ -46,12 +44,12 @@ interface IPConfigAdapter
*
* @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 $key The configuration key to set
* @param string $value The value to store
*
* @return bool Operation success
*/
- public function set($uid, $cat, $k, $value);
+ public function set($uid, $cat, $key, $value);
/**
* Removes the configured value from the stored cache
@@ -59,9 +57,27 @@ interface IPConfigAdapter
*
* @param string $uid The user_id
* @param string $cat The category of the configuration value
- * @param string $k The configuration key to delete
+ * @param string $key The configuration key to delete
*
- * @return mixed
+ * @return bool
*/
- public function delete($uid, $cat, $k);
+ public function delete($uid, $cat, $key);
+
+ /**
+ * Checks, if the current adapter is connected to the backend
+ *
+ * @return bool
+ */
+ public function isConnected();
+
+ /**
+ * Checks, if a config key ($key) in the category ($cat) is already loaded for the user_id $uid.
+ *
+ * @param string $uid The user_id
+ * @param string $cat The configuration category
+ * @param string $key The configuration key
+ *
+ * @return bool
+ */
+ public function isLoaded($uid, $cat, $key);
}
diff --git a/src/Core/Config/Adapter/JITConfigAdapter.php b/src/Core/Config/Adapter/JITConfigAdapter.php
new file mode 100644
index 000000000..95211777f
--- /dev/null
+++ b/src/Core/Config/Adapter/JITConfigAdapter.php
@@ -0,0 +1,135 @@
+
+ */
+class JITConfigAdapter extends AbstractDbaConfigAdapter implements IConfigAdapter
+{
+ private $in_db;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load($cat = "config")
+ {
+ $return = [];
+
+ if (!$this->isConnected()) {
+ return $return;
+ }
+
+ // We don't preload "system" anymore.
+ // This reduces the number of database reads a lot.
+ if ($cat === 'system') {
+ return $return;
+ }
+
+ $configs = DBA::select('config', ['v', 'k'], ['cat' => $cat]);
+ while ($config = DBA::fetch($configs)) {
+ $key = $config['k'];
+
+ $return[$key] = $config['v'];
+ $this->in_db[$cat][$key] = true;
+ }
+ DBA::close($configs);
+
+ return [$cat => $config];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return '!!';
+ }
+
+ $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']);
+
+ $this->in_db[$cat][$key] = true;
+ return $value;
+ } else {
+
+ $this->in_db[$cat][$key] = false;
+ return '!!';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($cat, $key, $value)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ // 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, $key);
+
+ if (!isset($this->in_db[$cat])) {
+ $this->in_db[$cat] = [];
+ }
+ if (!isset($this->in_db[$cat][$key])) {
+ $this->in_db[$cat][$key] = false;
+ }
+
+ if (($stored === $dbvalue) && $this->in_db[$cat][$key]) {
+ return true;
+ }
+
+ // manage array value
+ $dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
+
+ $result = DBA::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
+
+ $this->in_db[$cat][$key] = $result;
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ if (isset($this->cache[$cat][$key])) {
+ unset($this->in_db[$cat][$key]);
+ }
+
+ $result = DBA::delete('config', ['cat' => $cat, 'k' => $key]);
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLoaded($cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ return (isset($this->in_db[$cat][$key])) && $this->in_db[$cat][$key];
+ }
+}
diff --git a/src/Core/Config/Adapter/JITPConfigAdapter.php b/src/Core/Config/Adapter/JITPConfigAdapter.php
new file mode 100644
index 000000000..c5f3a381e
--- /dev/null
+++ b/src/Core/Config/Adapter/JITPConfigAdapter.php
@@ -0,0 +1,138 @@
+
+ */
+class JITPConfigAdapter extends AbstractDbaConfigAdapter implements IPConfigAdapter
+{
+ private $in_db;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load($uid, $cat)
+ {
+ $return = [];
+
+ if (!$this->isConnected()) {
+ return $return;
+ }
+
+ $pconfigs = DBA::select('pconfig', ['v', 'k'], ['cat' => $cat, 'uid' => $uid]);
+ if (DBA::isResult($pconfigs)) {
+ while ($pconfig = DBA::fetch($pconfigs)) {
+ $key = $pconfig['k'];
+
+ $return[$key] = $pconfig['v'];
+
+ $this->in_db[$uid][$cat][$key] = true;
+ }
+ } else if ($cat != 'config') {
+ // Negative caching
+ $return = "!!";
+ }
+ DBA::close($pconfigs);
+
+ return [$cat => $return];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($uid, $cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return '!!';
+ }
+
+ $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']);
+
+ $this->in_db[$uid][$cat][$key] = true;
+ return $value;
+ } else {
+
+ $this->in_db[$uid][$cat][$key] = false;
+ return '!!';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($uid, $cat, $key, $value)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ // 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, $key);
+
+ if (!isset($this->in_db[$uid])) {
+ $this->in_db[$uid] = [];
+ }
+ if (!isset($this->in_db[$uid][$cat])) {
+ $this->in_db[$uid][$cat] = [];
+ }
+ if (!isset($this->in_db[$uid][$cat][$key])) {
+ $this->in_db[$uid][$cat][$key] = false;
+ }
+
+ if (($stored === $dbvalue) && $this->in_db[$uid][$cat][$key]) {
+ return true;
+ }
+
+ // manage array value
+ $dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
+
+ $result = DBA::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
+
+ $this->in_db[$uid][$cat][$key] = $result;
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($uid, $cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ if (!empty($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;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLoaded($uid, $cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ return (isset($this->in_db[$uid][$cat][$key])) && $this->in_db[$uid][$cat][$key];
+ }
+}
diff --git a/src/Core/Config/PreloadConfigAdapter.php b/src/Core/Config/Adapter/PreloadConfigAdapter.php
similarity index 51%
rename from src/Core/Config/PreloadConfigAdapter.php
rename to src/Core/Config/Adapter/PreloadConfigAdapter.php
index 96331e7a2..fa691a16d 100644
--- a/src/Core/Config/PreloadConfigAdapter.php
+++ b/src/Core/Config/Adapter/PreloadConfigAdapter.php
@@ -1,8 +1,7 @@
configCache = $configCache;
- $this->connected = DBA::connected();
- $this->load();
- }
-
/**
* {@inheritdoc}
*/
- public function load($family = 'config')
+ public function load($cat = 'config')
{
+ $return = [];
+
if (!$this->isConnected()) {
- return;
+ return $return;
}
if ($this->config_loaded) {
- return;
+ return $return;
}
$configs = DBA::select('config', ['cat', 'v', 'k']);
while ($config = DBA::fetch($configs)) {
- $this->configCache->set($config['cat'], $config['k'], $config['v']);
+ $return[$config['cat']][$config['k']] = $config['v'];
}
DBA::close($configs);
$this->config_loaded = true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function get($cat, $k, $default_value = null, $refresh = false)
- {
- if (!$this->isConnected()) {
- return $default_value;
- }
-
- if ($refresh) {
- $config = DBA::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $k]);
- if (DBA::isResult($config)) {
- $this->configCache->set($cat, $k, $config['v']);
- }
- }
-
- $return = $this->configCache->get($cat, $k, $default_value);
return $return;
}
@@ -77,7 +44,28 @@ class PreloadConfigAdapter extends AbstractDbaConfigAdapter implements IConfigAd
/**
* {@inheritdoc}
*/
- public function set($cat, $k, $value)
+ public function get($cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return '!!';
+ }
+
+ $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']);
+
+ return $value;
+ } else {
+
+ return '!!';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($cat, $key, $value)
{
if (!$this->isConnected()) {
return false;
@@ -88,36 +76,41 @@ class PreloadConfigAdapter extends AbstractDbaConfigAdapter implements IConfigAd
// The exception are array values.
$compare_value = !is_array($value) ? (string)$value : $value;
- if ($this->configCache->get($cat, $k) === $compare_value) {
+ if ($this->get($cat, $key) === $compare_value) {
return true;
}
- $this->configCache->set($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 . ']');
- }
+ $result = DBA::update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
- return true;
+ return $result;
}
/**
* {@inheritdoc}
*/
- public function delete($cat, $k)
+ public function delete($cat, $key)
{
if (!$this->isConnected()) {
return false;
}
- $this->configCache->delete($cat, $k);
-
- $result = DBA::delete('config', ['cat' => $cat, 'k' => $k]);
+ $result = DBA::delete('config', ['cat' => $cat, 'k' => $key]);
return $result;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLoaded($cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ return $this->config_loaded;
+ }
}
diff --git a/src/Core/Config/PreloadPConfigAdapter.php b/src/Core/Config/Adapter/PreloadPConfigAdapter.php
similarity index 50%
rename from src/Core/Config/PreloadPConfigAdapter.php
rename to src/Core/Config/Adapter/PreloadPConfigAdapter.php
index af97815ad..e79a4a1e3 100644
--- a/src/Core/Config/PreloadPConfigAdapter.php
+++ b/src/Core/Config/Adapter/PreloadPConfigAdapter.php
@@ -1,8 +1,7 @@
*/
-class PreloadPConfigAdapter implements IPConfigAdapter
+class PreloadPConfigAdapter extends AbstractDbaConfigAdapter implements IPConfigAdapter
{
private $config_loaded = false;
/**
- * The config cache of this adapter
- * @var IPConfigCache
+ * @param int $uid The UID of the current user
*/
- private $configCache;
-
- /**
- * @param IPConfigCache $configCache The config cache of this adapter
- * @param int $uid The UID of the current user
- */
- public function __construct(IPConfigCache $configCache, $uid = null)
+ public function __construct($uid = null)
{
- $this->configCache = $configCache;
+ parent::__construct();
+
if (isset($uid)) {
$this->load($uid, 'config');
}
@@ -37,51 +30,62 @@ class PreloadPConfigAdapter implements IPConfigAdapter
/**
* {@inheritdoc}
*/
- public function load($uid, $family)
+ public function load($uid, $cat)
{
+ $return = [];
+
if ($this->config_loaded) {
- return;
+ return $return;
}
if (empty($uid)) {
- return;
+ return $return;
}
$pconfigs = DBA::select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
while ($pconfig = DBA::fetch($pconfigs)) {
- $this->configCache->setP($uid, $pconfig['cat'], $pconfig['k'], $pconfig['v']);
+ $return[$pconfig['cat']][$pconfig['k']] = $pconfig['v'];
}
DBA::close($pconfigs);
$this->config_loaded = true;
+
+ return $return;
}
/**
* {@inheritdoc}
*/
- public function get($uid, $cat, $k, $default_value = null, $refresh = false)
+ public function get($uid, $cat, $key)
{
+ if (!$this->isConnected()) {
+ return '!!';
+ }
+
if (!$this->config_loaded) {
$this->load($uid, $cat);
}
- if ($refresh) {
- $config = DBA::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
- if (DBA::isResult($config)) {
- $this->configCache->setP($uid, $cat, $k, $config['v']);
- } else {
- $this->configCache->deleteP($uid, $cat, $k);
- }
- }
+ $config = DBA::selectFirst('pconfig', ['v'], ['uid' => $uid, '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']);
- return $this->configCache->getP($uid, $cat, $k, $default_value);;
+ return $value;
+ } else {
+ return '!!';
+ }
}
/**
* {@inheritdoc}
*/
- public function set($uid, $cat, $k, $value)
+ public function set($uid, $cat, $key, $value)
{
+ if (!$this->isConnected()) {
+ return false;
+ }
+
if (!$this->config_loaded) {
$this->load($uid, $cat);
}
@@ -90,36 +94,45 @@ class PreloadPConfigAdapter implements IPConfigAdapter
// The exception are array values.
$compare_value = !is_array($value) ? (string)$value : $value;
- if ($this->configCache->getP($uid, $cat, $k) === $compare_value) {
+ if ($this->get($uid, $cat, $key) === $compare_value) {
return true;
}
- $this->configCache->setP($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 . ']');
- }
+ $result = DBA::update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
- return true;
+ return $result;
}
/**
* {@inheritdoc}
*/
- public function delete($uid, $cat, $k)
+ public function delete($uid, $cat, $key)
{
+ if (!$this->isConnected()) {
+ return false;
+ }
+
if (!$this->config_loaded) {
$this->load($uid, $cat);
}
- $this->configCache->deleteP($uid, $cat, $k);
-
- $result = DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
+ $result = DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
return $result;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLoaded($uid, $cat, $key)
+ {
+ if (!$this->isConnected()) {
+ return false;
+ }
+
+ return $this->config_loaded;
+ }
}
diff --git a/src/Core/Config/ConfigCache.php b/src/Core/Config/Cache/ConfigCache.php
similarity index 51%
rename from src/Core/Config/ConfigCache.php
rename to src/Core/Config/Cache/ConfigCache.php
index b86ec3860..54da327db 100644
--- a/src/Core/Config/ConfigCache.php
+++ b/src/Core/Config/Cache/ConfigCache.php
@@ -1,6 +1,6 @@
loadConfigArray($config);
+ $this->load($config);
}
/**
- * Tries to load the specified configuration array into the App->config array.
- * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
- *
- * @param array $config
- * @param bool $overwrite Force value overwrite if the config key already exists
+ * {@inheritdoc}
*/
- public function loadConfigArray(array $config, $overwrite = false)
+ public function load(array $config, $overwrite = false)
{
- foreach ($config as $category => $values) {
- foreach ($values as $key => $value) {
- if ($overwrite) {
- $this->set($category, $key, $value);
- } else {
- $this->setDefault($category, $key, $value);
+ $categories = array_keys($config);
+
+ foreach ($categories as $category) {
+ if (isset($config[$category]) && is_array($config[$category])) {
+ $keys = array_keys($config[$category]);
+
+ foreach ($keys as $key) {
+ if (isset($config[$category][$key])) {
+ if ($overwrite) {
+ $this->set($category, $key, $config[$category][$key]);
+ } else {
+ $this->setDefault($category, $key, $config[$category][$key]);
+ }
+ }
}
}
}
@@ -44,23 +51,24 @@ class ConfigCache implements IConfigCache, IPConfigCache
/**
* {@inheritdoc}
*/
- public function get($cat, $key = null, $default = null)
+ public function get($cat, $key = null)
{
- $return = $default;
-
- if ($cat === 'config') {
- if (isset($this->config[$key])) {
- $return = $this->config[$key];
- }
+ if (isset($this->config[$cat][$key])) {
+ return $this->config[$cat][$key];
+ } elseif ($key == null && isset($this->config[$cat])) {
+ return $this->config[$cat];
} else {
- if (isset($this->config[$cat][$key])) {
- $return = $this->config[$cat][$key];
- } elseif ($key == null && isset($this->config[$cat])) {
- $return = $this->config[$cat];
- }
+ return '!!';
}
+ }
- return $return;
+ /**
+ * {@inheritdoc}
+ */
+ public function has($cat, $key = null)
+ {
+ return (isset($this->config[$cat][$key]) && $this->config[$cat][$key] !== '!!') ||
+ ($key == null && isset($this->config[$cat]) && $this->config[$cat] !== '!!' && is_array($this->config[$cat]));
}
/**
@@ -85,34 +93,48 @@ class ConfigCache implements IConfigCache, IPConfigCache
// 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 ($cat === 'config') {
- $this->config[$key] = $value;
- } else {
- if (!isset($this->config[$cat])) {
- $this->config[$cat] = [];
- }
-
- $this->config[$cat][$key] = $value;
+ if (!isset($this->config[$cat])) {
+ $this->config[$cat] = [];
}
+ $this->config[$cat][$key] = $value;
+
return true;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function hasP($uid, $cat, $key = null)
+ {
+ return (isset($this->config[$uid][$cat][$key]) && $this->config[$uid][$cat][$key] !== '!!') ||
+ ($key == null && isset($this->config[$uid][$cat]) && $this->config[$uid][$cat] !== '!!' && is_array($this->config[$uid][$cat]));
+ }
+
/**
* {@inheritdoc}
*/
public function delete($cat, $key)
{
- if ($cat === 'config') {
- if (isset($this->config[$key])) {
- unset($this->config[$key]);
+ if (isset($this->config[$cat][$key])) {
+ unset($this->config[$cat][$key]);
+ if (count($this->config[$cat]) == 0) {
+ unset($this->config[$cat]);
}
+ return true;
} else {
- if (isset($this->config[$cat][$key])) {
- unset($this->config[$cat][$key]);
- if (count($this->config[$cat]) == 0) {
- unset($this->config[$cat]);
- }
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function loadP($uid, array $config)
+ {
+ foreach ($config as $category => $values) {
+ foreach ($values as $key => $value) {
+ $this->setP($uid, $category, $key, $value);
}
}
}
@@ -120,17 +142,15 @@ class ConfigCache implements IConfigCache, IPConfigCache
/**
* {@inheritdoc}
*/
- public function getP($uid, $cat, $key = null, $default = null)
+ public function getP($uid, $cat, $key = null)
{
- $return = $default;
-
if (isset($this->config[$uid][$cat][$key])) {
- $return = $this->config[$uid][$cat][$key];
- } elseif ($key === null && isset($this->config[$uid][$cat])) {
- $return = $this->config[$uid][$cat];
+ return $this->config[$uid][$cat][$key];
+ } elseif ($key == null && isset($this->config[$uid][$cat])) {
+ return $this->config[$uid][$cat];
+ } else {
+ return '!!';
}
-
- return $return;
}
/**
@@ -145,15 +165,13 @@ class ConfigCache implements IConfigCache, IPConfigCache
$this->config[$uid] = [];
}
- if (!isset($this->config[$uid][$cat]) || !is_array($this->config[$uid][$cat])) {
+ if (!isset($this->config[$uid][$cat])) {
$this->config[$uid][$cat] = [];
}
- if ($key === null) {
- $this->config[$uid][$cat] = $value;
- } else {
- $this->config[$uid][$cat][$key] = $value;
- }
+ $this->config[$uid][$cat][$key] = $value;
+
+ return true;
}
/**
@@ -169,6 +187,10 @@ class ConfigCache implements IConfigCache, IPConfigCache
unset($this->config[$uid]);
}
}
+
+ return true;
+ } else {
+ return false;
}
}
diff --git a/src/Core/Config/ConfigCacheLoader.php b/src/Core/Config/Cache/ConfigCacheLoader.php
similarity index 93%
rename from src/Core/Config/ConfigCacheLoader.php
rename to src/Core/Config/Cache/ConfigCacheLoader.php
index 3a6a3c803..b728d1082 100644
--- a/src/Core/Config/ConfigCacheLoader.php
+++ b/src/Core/Config/Cache/ConfigCacheLoader.php
@@ -1,6 +1,6 @@
set('system', 'basepath', $this->baseDir);
- $config->loadConfigArray($this->loadCoreConfig('defaults'));
- $config->loadConfigArray($this->loadCoreConfig('settings'));
+ $config->load($this->loadCoreConfig('defaults'));
+ $config->load($this->loadCoreConfig('settings'));
- $config->loadConfigArray($this->loadLegacyConfig('htpreconfig'), true);
- $config->loadConfigArray($this->loadLegacyConfig('htconfig'), true);
+ $config->load($this->loadLegacyConfig('htpreconfig'), true);
+ $config->load($this->loadLegacyConfig('htconfig'), true);
- $config->loadConfigArray($this->loadCoreConfig('local'), true);
+ $config->load($this->loadCoreConfig('local'), true);
}
/**
diff --git a/src/Core/Config/Cache/IConfigCache.php b/src/Core/Config/Cache/IConfigCache.php
new file mode 100644
index 000000000..9d948527d
--- /dev/null
+++ b/src/Core/Config/Cache/IConfigCache.php
@@ -0,0 +1,65 @@
+!' if not set
+ */
+ function get($cat, $key = null);
+
+ /**
+ * Sets a value in the config cache. Accepts raw output from the config table
+ *
+ * @param string $cat Config category
+ * @param string $key Config key
+ * @param mixed $value Value to set
+ *
+ * @return bool True, if the value is set
+ */
+ function set($cat, $key, $value);
+
+ /**
+ * Deletes a value from the config cache.
+ *
+ * @param string $cat Config category
+ * @param string $key Config key
+ *
+ * @return bool true, if deleted
+ */
+ 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
+ *
+ * @return array
+ */
+ function getAll();
+}
diff --git a/src/Core/Config/Cache/IPConfigCache.php b/src/Core/Config/Cache/IPConfigCache.php
new file mode 100644
index 000000000..4ac21481a
--- /dev/null
+++ b/src/Core/Config/Cache/IPConfigCache.php
@@ -0,0 +1,70 @@
+!' if not set
+ */
+ function getP($uid, $cat, $key = null);
+
+ /**
+ * 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 $key Config key
+ * @param mixed $value Value to set
+ */
+ function setP($uid, $cat, $key, $value);
+
+ /**
+ * Deletes a value from the user config cache
+ *
+ * @param int $uid User Id
+ * @param string $cat Config category
+ * @param string $key Config key
+ *
+ * @return bool true, if deleted
+ */
+ 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
+ *
+ * @return array
+ */
+ function getAll();
+}
diff --git a/src/Core/Config/Configuration.php b/src/Core/Config/Configuration.php
new file mode 100644
index 000000000..2ac0da0ad
--- /dev/null
+++ b/src/Core/Config/Configuration.php
@@ -0,0 +1,153 @@
+configCache = $configCache;
+ $this->configAdapter = $configAdapter;
+
+ $this->load();
+ }
+
+ /**
+ * Returns the Config Cache
+ *
+ * @return Cache\IConfigCache
+ */
+ public function getCache()
+ {
+ return $this->configCache;
+ }
+
+ /**
+ * @brief Loads all configuration values of family into a cached storage.
+ *
+ * All configuration values of the system are stored in the cache ( @see IConfigCache )
+ *
+ * @param string $cat The category of the configuration value
+ *
+ * @return void
+ */
+ public function load($cat = 'config')
+ {
+ // If not connected, do nothing
+ if (!$this->configAdapter->isConnected()) {
+ return;
+ }
+
+ // load the whole category out of the DB into the cache
+ $this->configCache->load($this->configAdapter->load($cat), true);
+ }
+
+ /**
+ * @brief Get a particular user's config variable given the category name
+ * ($cat) and a $key.
+ *
+ * Get a particular config value from the given category ($cat)
+ * and the $key from a cached storage either from the $this->configAdapter
+ * (@see IConfigAdapter ) or from the $this->configCache (@see IConfigCache ).
+ *
+ * @param string $cat The category of the configuration value
+ * @param string $key 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, $key, $default_value = null, $refresh = false)
+ {
+ // if the value isn't loaded or refresh is needed, load it to the cache
+ if ($this->configAdapter->isConnected() &&
+ (!$this->configAdapter->isLoaded($cat, $key) ||
+ $refresh)) {
+ $dbvalue = $this->configAdapter->get($cat, $key);
+
+ if ($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;
+ }
+ }
+
+ /**
+ * @brief Sets a configuration value for system config
+ *
+ * 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
+ *
+ * @return bool Operation success
+ */
+ public function set($cat, $key, $value)
+ {
+ // set the cache first
+ $cached = $this->configCache->set($cat, $key, $value);
+
+ // If there is no connected adapter, we're finished
+ if (!$this->configAdapter->isConnected()) {
+ return $cached;
+ }
+
+ $stored = $this->configAdapter->set($cat, $key, $value);
+
+ return $cached && $stored;
+ }
+
+ /**
+ * @brief Deletes the given key from the system configuration.
+ *
+ * Removes the configured value from the stored cache in $this->configCache
+ * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter ).
+ *
+ * @param string $cat The category of the configuration value
+ * @param string $key The configuration key to delete
+ *
+ * @return bool
+ */
+ public function delete($cat, $key)
+ {
+ $cacheRemoved = $this->configCache->delete($cat, $key);
+
+ if (!$this->configAdapter->isConnected()) {
+ return $cacheRemoved;
+ }
+
+ $storeRemoved = $this->configAdapter->delete($cat, $key);
+
+ return $cacheRemoved || $storeRemoved;
+ }
+}
diff --git a/src/Core/Config/IConfigCache.php b/src/Core/Config/IConfigCache.php
deleted file mode 100644
index 898e3c0f8..000000000
--- a/src/Core/Config/IConfigCache.php
+++ /dev/null
@@ -1,39 +0,0 @@
-
- */
-class JITConfigAdapter extends AbstractDbaConfigAdapter implements IConfigAdapter
-{
- private $cache;
- private $in_db;
-
- /**
- * @var IConfigCache The config cache of this driver
- */
- private $configCache;
-
- /**
- * @param IConfigCache $configCache The config cache of this driver
- */
- public function __construct(IConfigCache $configCache)
- {
- $this->configCache = $configCache;
- $this->connected = DBA::connected();
- }
-
- /**
- * {@inheritdoc}
- */
- public function load($cat = "config")
- {
- if (!$this->isConnected()) {
- return;
- }
-
- // 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'];
-
- $this->configCache->set($cat, $k, $config['v']);
-
- if ($cat !== 'config') {
- $this->cache[$cat][$k] = $config['v'];
- $this->in_db[$cat][$k] = true;
- }
- }
- DBA::close($configs);
- }
-
- /**
- * {@inheritdoc}
- */
- public function get($cat, $k, $default_value = null, $refresh = false)
- {
- if (!$this->isConnected()) {
- return $default_value;
- }
-
- if (!$refresh) {
- // Do we have the cached value? Then return it
- if (isset($this->cache[$cat][$k])) {
- if ($this->cache[$cat][$k] === '!!') {
- return $default_value;
- } else {
- return $this->cache[$cat][$k];
- }
- }
- }
-
- $config = DBA::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $k]);
- if (DBA::isResult($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 ($this->configCache->get($cat, $k) !== null) {
- // Assign the value (mostly) from config/local.config.php file to the cache
- $this->cache[$cat][$k] = $this->configCache->get($cat, $k);
- $this->in_db[$cat][$k] = false;
-
- return $this->configCache->get($cat, $k);
- } elseif ($this->configCache->get('config', $k) !== null) {
- // Assign the value (mostly) from config/local.config.php file to the cache
- $this->cache[$k] = $this->configCache->get('config', $k);
- $this->in_db[$k] = false;
-
- return $this->configCache->get('config', $k);
- }
-
- $this->cache[$cat][$k] = '!!';
- $this->in_db[$cat][$k] = false;
-
- return $default_value;
- }
-
- /**
- * {@inheritdoc}
- */
- public function set($cat, $k, $value)
- {
- if (!$this->isConnected()) {
- return false;
- }
-
- // 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 (!isset($this->in_db[$cat])) {
- $this->in_db[$cat] = [];
- }
- if (!isset($this->in_db[$cat][$k])) {
- $this->in_db[$cat] = false;
- }
-
- if (($stored === $dbvalue) && $this->in_db[$cat][$k]) {
- return true;
- }
-
- $this->configCache->set($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 $result;
- }
-
- /**
- * {@inheritdoc}
- */
- public function delete($cat, $k)
- {
- if (!$this->isConnected()) {
- return false;
- }
-
- 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;
- }
-}
diff --git a/src/Core/Config/JITPConfigAdapter.php b/src/Core/Config/JITPConfigAdapter.php
deleted file mode 100644
index b1a15601c..000000000
--- a/src/Core/Config/JITPConfigAdapter.php
+++ /dev/null
@@ -1,136 +0,0 @@
-
- */
-class JITPConfigAdapter implements IPConfigAdapter
-{
- private $in_db;
-
- /**
- * The config cache of this adapter
- * @var IPConfigCache
- */
- private $configCache;
-
- /**
- * @param IPConfigCache $configCache The config cache of this adapter
- */
- public function __construct(IPConfigCache $configCache)
- {
- $this->configCache = $configCache;
- }
-
- /**
- * {@inheritdoc}
- */
- public function load($uid, $cat)
- {
- $pconfigs = DBA::select('pconfig', ['v', 'k'], ['cat' => $cat, 'uid' => $uid]);
- if (DBA::isResult($pconfigs)) {
- while ($pconfig = DBA::fetch($pconfigs)) {
- $k = $pconfig['k'];
-
- $this->configCache->setP($uid, $cat, $k, $pconfig['v']);
-
- $this->in_db[$uid][$cat][$k] = true;
- }
- } else if ($cat != 'config') {
- // Negative caching
- $this->configCache->setP($uid, $cat, null, "!!");
- }
- DBA::close($pconfigs);
- }
-
- /**
- * {@inheritdoc}
- */
- public function get($uid, $cat, $k, $default_value = null, $refresh = false)
- {
- if (!$refresh) {
- // Looking if the whole family isn't set
- if ($this->configCache->getP($uid, $cat) !== null) {
- if ($this->configCache->getP($uid, $cat) === '!!') {
- return $default_value;
- }
- }
-
- if ($this->configCache->getP($uid, $cat, $k) !== null) {
- if ($this->configCache->getP($uid, $cat, $k) === '!!') {
- return $default_value;
- }
- return $this->configCache->getP($uid, $cat, $k);
- }
- }
-
- $pconfig = DBA::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
- if (DBA::isResult($pconfig)) {
- $val = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']);
-
- $this->configCache->setP($uid, $cat, $k, $val);
-
- $this->in_db[$uid][$cat][$k] = true;
-
- return $val;
- } else {
- $this->configCache->setP($uid, $cat, $k, '!!');
-
- $this->in_db[$uid][$cat][$k] = false;
-
- return $default_value;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- 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;
- }
-
- $this->configCache->setP($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 $result;
- }
-
- /**
- * {@inheritdoc}
- */
- public function delete($uid, $cat, $k)
- {
- $this->configCache->deleteP($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;
- }
-}
diff --git a/src/Core/Config/PConfiguration.php b/src/Core/Config/PConfiguration.php
new file mode 100644
index 000000000..99b1aa146
--- /dev/null
+++ b/src/Core/Config/PConfiguration.php
@@ -0,0 +1,149 @@
+configCache = $configCache;
+ $this->configAdapter = $configAdapter;
+ }
+
+ /**
+ * @brief Loads all configuration values of a user's config family into a cached storage.
+ *
+ * All configuration values of the given user are stored with the $uid in
+ * the cache ( @see IPConfigCache )
+ *
+ * @param string $uid The user_id
+ * @param string $cat The category of the configuration value
+ *
+ * @return void
+ */
+ public function load($uid, $cat = 'config')
+ {
+ // If not connected, do nothing
+ if (!$this->configAdapter->isConnected()) {
+ return;
+ }
+
+ // load the whole category out of the DB into the cache
+ $this->configCache->loadP($uid, $this->configAdapter->load($uid, $cat));
+ }
+
+ /**
+ * @brief Get a particular user's config variable given the category name
+ * ($cat) and a key.
+ *
+ * Get a particular user's config value from the given category ($cat)
+ * and the $key with the $uid from a cached storage either from the $this->configAdapter
+ * (@see IConfigAdapter ) or from the $this->configCache (@see IConfigCache ).
+ *
+ * @param string $uid The user_id
+ * @param string $cat The category of the configuration value
+ * @param string $key 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, $key, $default_value = null, $refresh = false)
+ {
+ // if the value isn't loaded or refresh is needed, load it to the cache
+ if ($this->configAdapter->isConnected() &&
+ (!$this->configAdapter->isLoaded($uid, $cat, $key) ||
+ $refresh)) {
+ $dbValue = $this->configAdapter->get($uid, $cat, $key);
+
+ if ($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;
+ }
+ }
+
+ /**
+ * @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 $key The configuration key to set
+ * @param mixed $value The value to store
+ *
+ * @return bool Operation success
+ */
+ public function set($uid, $cat, $key, $value)
+ {
+ // set the cache first
+ $cached = $this->configCache->setP($uid, $cat, $key, $value);
+
+ // If there is no connected adapter, we're finished
+ if (!$this->configAdapter->isConnected()) {
+ return $cached;
+ }
+
+ $stored = $this->configAdapter->set($uid, $cat, $key, $value);
+
+ return $cached && $stored;
+ }
+
+ /**
+ * @brief Deletes the given key from the users's configuration.
+ *
+ * Removes the configured value from the stored cache in $this->configCache
+ * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter )
+ * with the given $uid.
+ *
+ * @param string $uid The user_id
+ * @param string $cat The category of the configuration value
+ * @param string $key The configuration key to delete
+ *
+ * @return bool
+ */
+ public function delete($uid, $cat, $key)
+ {
+ $cacheRemoved = $this->configCache->deleteP($uid, $cat, $key);
+
+ if (!$this->configAdapter->isConnected()) {
+ return $cacheRemoved;
+ }
+
+ $storeRemoved = $this->configAdapter->delete($uid, $cat, $key);
+
+ return $cacheRemoved || $storeRemoved;
+ }
+}
diff --git a/src/Core/Console/AutomaticInstallation.php b/src/Core/Console/AutomaticInstallation.php
index 7f2585e63..682d10971 100644
--- a/src/Core/Console/AutomaticInstallation.php
+++ b/src/Core/Console/AutomaticInstallation.php
@@ -100,10 +100,10 @@ HELP;
}
}
- $db_host = $a->getConfig()->get('database', 'hostname');
- $db_user = $a->getConfig()->get('database', 'username');
- $db_pass = $a->getConfig()->get('database', 'password');
- $db_data = $a->getConfig()->get('database', 'database');
+ $db_host = $a->getConfigCache()->get('database', 'hostname');
+ $db_user = $a->getConfigCache()->get('database', 'username');
+ $db_pass = $a->getConfigCache()->get('database', 'password');
+ $db_data = $a->getConfigCache()->get('database', 'database');
} else {
// Creating config file
$this->out("Creating config file...\n");
@@ -146,7 +146,7 @@ HELP;
$installer->resetChecks();
- if (!$installer->checkDB($a->getConfig(), $db_host, $db_user, $db_pass, $db_data)) {
+ if (!$installer->checkDB($a->getConfigCache(), $a->getProfiler(), $db_host, $db_user, $db_pass, $db_data)) {
$errorMessage = $this->extractErrors($installer->getChecks());
throw new RuntimeException($errorMessage);
}
diff --git a/src/Core/Console/Config.php b/src/Core/Console/Config.php
index b1c3df54e..cf5c09fc0 100644
--- a/src/Core/Console/Config.php
+++ b/src/Core/Console/Config.php
@@ -124,9 +124,9 @@ HELP;
$cat = $this->getArgument(0);
Core\Config::load($cat);
- if ($a->getConfig()->get($cat) !== null) {
+ if ($a->getConfigCache()->get($cat) !== null) {
$this->out("[{$cat}]");
- $catVal = $a->getConfig()->get($cat);
+ $catVal = $a->getConfigCache()->get($cat);
foreach ($catVal as $key => $value) {
if (is_array($value)) {
foreach ($value as $k => $v) {
@@ -148,7 +148,7 @@ HELP;
$this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only');
}
- $config = $a->getConfig()->getAll();
+ $config = $a->getConfigCache()->getAll();
foreach ($config as $cat => $section) {
if (is_array($section)) {
foreach ($section as $key => $value) {
diff --git a/src/Core/Console/Typo.php b/src/Core/Console/Typo.php
index 32ba6ded3..8d07051e8 100644
--- a/src/Core/Console/Typo.php
+++ b/src/Core/Console/Typo.php
@@ -43,7 +43,7 @@ HELP;
throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
}
- $php_path = BaseObject::getApp()->getConfig()->get('config', 'php_path', 'php');
+ $php_path = BaseObject::getApp()->getConfigCache()->get('config', 'php_path', 'php');
if ($this->getOption('v')) {
$this->out('Directory: src');
diff --git a/src/Core/Installer.php b/src/Core/Installer.php
index fdeb940a2..ed4721014 100644
--- a/src/Core/Installer.php
+++ b/src/Core/Installer.php
@@ -6,11 +6,12 @@ namespace Friendica\Core;
use DOMDocument;
use Exception;
-use Friendica\Core\Config\ConfigCache;
+use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
use Friendica\Object\Image;
use Friendica\Util\Network;
+use Friendica\Util\Profiler;
use Friendica\Util\Strings;
/**
@@ -590,7 +591,8 @@ class Installer
/**
* Checking the Database connection and if it is available for the current installation
*
- * @param ConfigCache $configCache The configuration cache
+ * @param IConfigCache $configCache The configuration cache
+ * @param Profiler $profiler The profiler of this app
* @param string $dbhost Hostname/IP of the Friendica Database
* @param string $dbuser Username of the Database connection credentials
* @param string $dbpass Password of the Database connection credentials
@@ -599,9 +601,9 @@ class Installer
* @return bool true if the check was successful, otherwise false
* @throws Exception
*/
- public function checkDB(ConfigCache $configCache, $dbhost, $dbuser, $dbpass, $dbdata)
+ public function checkDB(IConfigCache $configCache, Profiler $profiler, $dbhost, $dbuser, $dbpass, $dbdata)
{
- if (!DBA::connect($configCache, $dbhost, $dbuser, $dbpass, $dbdata)) {
+ if (!DBA::connect($configCache, $profiler, $dbhost, $dbuser, $dbpass, $dbdata)) {
$this->addCheck(L10n::t('Could not connect to database.'), false, true, '');
return false;
diff --git a/src/Core/Logger.php b/src/Core/Logger.php
index 6b8112796..3cb22e1e4 100644
--- a/src/Core/Logger.php
+++ b/src/Core/Logger.php
@@ -5,8 +5,6 @@
namespace Friendica\Core;
use Friendica\BaseObject;
-use Friendica\Factory\LoggerFactory;
-use Friendica\Network\HTTPException\InternalServerErrorException;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
@@ -67,73 +65,22 @@ class Logger extends BaseObject
/**
* Sets the default logging handler for Friendica.
- * @todo Can be combined with other handlers too if necessary, could be configurable.
*
* @param LoggerInterface $logger The Logger instance of this Application
- *
- * @throws InternalServerErrorException if the logger factory is incompatible to this logger
*/
- public static function setLogger($logger)
+ public static function init(LoggerInterface $logger)
{
- $debugging = Config::get('system', 'debugging');
- $logfile = Config::get('system', 'logfile');
- $loglevel = Config::get('system', 'loglevel');
-
- if (!$debugging || !$logfile) {
- return;
- }
-
- $loglevel = self::mapLegacyConfigDebugLevel((string)$loglevel);
-
- LoggerFactory::addStreamHandler($logger, $logfile, $loglevel);
-
self::$logger = $logger;
-
- $logfile = Config::get('system', 'dlogfile');
-
- if (!$logfile) {
- return;
- }
-
- $developIp = Config::get('system', 'dlogip');
-
- self::$devLogger = LoggerFactory::createDev('develop', $developIp);
- LoggerFactory::addStreamHandler(self::$devLogger, $logfile, LogLevel::DEBUG);
}
/**
- * Mapping a legacy level to the PSR-3 compliant levels
- * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
+ * Sets the default dev-logging handler for Friendica.
*
- * @param string $level the level to be mapped
- *
- * @return string the PSR-3 compliant level
+ * @param LoggerInterface $logger The Logger instance of this Application
*/
- private static function mapLegacyConfigDebugLevel($level)
+ public static function setDevLogger(LoggerInterface $logger)
{
- switch ($level) {
- // legacy WARNING
- case "0":
- return LogLevel::ERROR;
- // legacy INFO
- case "1":
- return LogLevel::WARNING;
- // legacy TRACE
- case "2":
- return LogLevel::NOTICE;
- // legacy DEBUG
- case "3":
- return LogLevel::INFO;
- // legacy DATA
- case "4":
- return LogLevel::DEBUG;
- // legacy ALL
- case "5":
- return LogLevel::DEBUG;
- // default if nothing set
- default:
- return $level;
- }
+ self::$devLogger = $logger;
}
/**
@@ -155,7 +102,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->emergency($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->GetProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -179,7 +126,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->alert($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -202,7 +149,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->critical($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -225,7 +172,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->error($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -249,7 +196,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->warning($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -270,7 +217,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->notice($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -293,7 +240,7 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->info($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
/**
@@ -314,28 +261,28 @@ class Logger extends BaseObject
$stamp1 = microtime(true);
self::$logger->debug($message, $context);
- self::getApp()->saveTimestamp($stamp1, 'file');
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, 'file', System::callstack());
}
- /**
- * @brief Logs the given message at the given log level
- *
- * @param string $msg
- * @param string $level
+ /**
+ * @brief Logs the given message at the given log level
+ *
+ * @param string $msg
+ * @param string $level
*
* @throws \Exception
* @deprecated since 2019.03 Use Logger::debug() Logger::info() , ... instead
- */
- public static function log($msg, $level = LogLevel::INFO)
- {
+ */
+ public static function log($msg, $level = LogLevel::INFO)
+ {
if (!isset(self::$logger)) {
return;
}
- $stamp1 = microtime(true);
+ $stamp1 = microtime(true);
self::$logger->log($level, $msg);
- self::getApp()->saveTimestamp($stamp1, "file");
- }
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
+ }
/**
* @brief An alternative logger for development.
@@ -347,14 +294,14 @@ class Logger extends BaseObject
* @param string $level
* @throws \Exception
*/
- public static function devLog($msg, $level = LogLevel::DEBUG)
- {
+ public static function devLog($msg, $level = LogLevel::DEBUG)
+ {
if (!isset(self::$logger)) {
return;
}
- $stamp1 = microtime(true);
- self::$devLogger->log($level, $msg);
- self::getApp()->saveTimestamp($stamp1, "file");
- }
+ $stamp1 = microtime(true);
+ self::$devLogger->log($level, $msg);
+ self::getApp()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
+ }
}
diff --git a/src/Core/PConfig.php b/src/Core/PConfig.php
index df024f0f3..f62b59f47 100644
--- a/src/Core/PConfig.php
+++ b/src/Core/PConfig.php
@@ -18,123 +18,78 @@ namespace Friendica\Core;
class PConfig
{
/**
- * @var Config\IPConfigAdapter
+ * @var Config\PConfiguration
*/
- private static $adapter;
-
- /**
- * @var Config\IPConfigCache
- */
- private static $cache;
+ private static $config;
/**
* Initialize the config with only the cache
*
- * @param Config\IPConfigCache $cache The configuration cache
+ * @param Config\PConfiguration $config The configuration cache
*/
- public static function init(Config\IPConfigCache $cache)
+ public static function init(Config\PConfiguration $config)
{
- self::$cache = $cache;
- }
-
- /**
- * Add the adapter for DB-backend
- *
- * @param Config\IPConfigAdapter $adapter
- */
- public static function setAdapter(Config\IPConfigAdapter $adapter)
- {
- self::$adapter = $adapter;
+ self::$config = $config;
}
/**
* @brief Loads all configuration values of a user's config family into a cached storage.
*
- * All configuration values of the given user are stored with the $uid in
- * the cache ( @see IPConfigCache )
- *
- * @param string $uid The user_id
- * @param string $family The category of the configuration value
+ * @param string $uid The user_id
+ * @param string $cat The category of the configuration value
*
* @return void
*/
- public static function load($uid, $family)
+ public static function load($uid, $cat)
{
- if (!isset(self::$adapter)) {
- return;
- }
-
- self::$adapter->load($uid, $family);
+ self::$config->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 with the $uid from a cached storage either from the self::$adapter
- * (@see IConfigAdapter ) or from the static::$cache (@see IConfigCache ).
+ * ($cat) and a key.
*
* @param string $uid The user_id
- * @param string $family The category of the configuration value
+ * @param string $cat The category of the configuration value
* @param string $key 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 static function get($uid, $family, $key, $default_value = null, $refresh = false)
+ public static function get($uid, $cat, $key, $default_value = null, $refresh = false)
{
- if (!isset(self::$adapter)) {
- return self::$cache->getP($uid, $family, $key, $default_value);
- }
-
- return self::$adapter->get($uid, $family, $key, $default_value, $refresh);
+ return self::$config->get($uid, $cat, $key, $default_value, $refresh);
}
/**
* @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 $family The category of the configuration value
+ * @param string $cat The category of the configuration value
* @param string $key The configuration key to set
* @param mixed $value The value to store
*
* @return bool Operation success
*/
- public static function set($uid, $family, $key, $value)
+ public static function set($uid, $cat, $key, $value)
{
- if (!isset(self::$adapter)) {
- return self::$cache->setP($uid, $family, $key, $value);
- }
-
- return self::$adapter->set($uid, $family, $key, $value);
+ return self::$config->set($uid, $cat, $key, $value);
}
/**
* @brief Deletes the given key from the users's configuration.
*
- * Removes the configured value from the stored cache in self::$config
- * (@see ConfigCache ) and removes it from the database (@see IConfigAdapter )
- * with the given $uid.
+ * @param string $uid The user_id
+ * @param string $cat The category of the configuration value
+ * @param string $key The configuration key to delete
*
- * @param string $uid The user_id
- * @param string $family The category of the configuration value
- * @param string $key The configuration key to delete
- *
- * @return mixed
+ * @return bool
*/
- public static function delete($uid, $family, $key)
+ public static function delete($uid, $cat, $key)
{
- if (!isset(self::$adapter)) {
- return self::$cache->deleteP($uid, $family, $key);
- }
-
- return self::$adapter->delete($uid, $family, $key);
+ return self::$config->delete($uid, $cat, $key);
}
}
diff --git a/src/Core/Renderer.php b/src/Core/Renderer.php
index 67bc5e3ba..8844f2688 100644
--- a/src/Core/Renderer.php
+++ b/src/Core/Renderer.php
@@ -74,7 +74,7 @@ class Renderer extends BaseObject
exit();
}
- $a->saveTimestamp($stamp1, "rendering");
+ $a->getProfiler()->saveTimestamp($stamp1, "rendering", System::callstack());
return $output;
}
@@ -101,7 +101,7 @@ class Renderer extends BaseObject
exit();
}
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
return $template;
}
diff --git a/src/Core/Theme.php b/src/Core/Theme.php
index 62dfaa51f..5479f8f46 100644
--- a/src/Core/Theme.php
+++ b/src/Core/Theme.php
@@ -51,7 +51,7 @@ class Theme
$a = \get_app();
$stamp1 = microtime(true);
$theme_file = file_get_contents("view/theme/$theme/theme.php");
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$result = preg_match("|/\*.*\*/|msU", $theme_file, $matches);
diff --git a/src/Core/Worker.php b/src/Core/Worker.php
index 75d4e4874..dff60e9fa 100644
--- a/src/Core/Worker.php
+++ b/src/Core/Worker.php
@@ -380,20 +380,7 @@ class Worker
// We use the callstack here to analyze the performance of executed worker entries.
// For this reason the variables have to be initialized.
- if (Config::get("system", "profiler")) {
- $a->performance["start"] = microtime(true);
- $a->performance["database"] = 0;
- $a->performance["database_write"] = 0;
- $a->performance["cache"] = 0;
- $a->performance["cache_write"] = 0;
- $a->performance["network"] = 0;
- $a->performance["file"] = 0;
- $a->performance["rendering"] = 0;
- $a->performance["parser"] = 0;
- $a->performance["marktime"] = 0;
- $a->performance["markstart"] = microtime(true);
- $a->callstack = [];
- }
+ $a->getProfiler()->reset();
// For better logging create a new process id for every worker call
// But preserve the old one for the worker
@@ -452,76 +439,7 @@ class Worker
Logger::log("Process ".$mypid." - Prio ".$queue["priority"]." - ID ".$queue["id"].": ".$funcname." - done in ".number_format($duration, 4)." seconds. Process PID: ".$new_process_id);
- // Write down the performance values into the log
- if (Config::get("system", "profiler")) {
- $duration = microtime(true)-$a->performance["start"];
-
- $o = '';
- if (Config::get("rendertime", "callstack")) {
- if (isset($a->callstack["database"])) {
- $o .= "\nDatabase Read:\n";
- foreach ($a->callstack["database"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func.": ".$time."\n";
- }
- }
- }
- if (isset($a->callstack["database_write"])) {
- $o .= "\nDatabase Write:\n";
- foreach ($a->callstack["database_write"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func.": ".$time."\n";
- }
- }
- }
- if (isset($a->callstack["dache"])) {
- $o .= "\nCache Read:\n";
- foreach ($a->callstack["dache"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func.": ".$time."\n";
- }
- }
- }
- if (isset($a->callstack["dache_write"])) {
- $o .= "\nCache Write:\n";
- foreach ($a->callstack["dache_write"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func.": ".$time."\n";
- }
- }
- }
- if (isset($a->callstack["network"])) {
- $o .= "\nNetwork:\n";
- foreach ($a->callstack["network"] as $func => $time) {
- $time = round($time, 3);
- if ($time > 0) {
- $o .= $func.": ".$time."\n";
- }
- }
- }
- }
-
- Logger::log(
- "ID ".$queue["id"].": ".$funcname.": ".sprintf(
- "DB: %s/%s, Cache: %s/%s, Net: %s, I/O: %s, Other: %s, Total: %s".$o,
- number_format($a->performance["database"] - $a->performance["database_write"], 2),
- number_format($a->performance["database_write"], 2),
- number_format($a->performance["cache"], 2),
- number_format($a->performance["cache_write"], 2),
- number_format($a->performance["network"], 2),
- number_format($a->performance["file"], 2),
- number_format($duration - ($a->performance["database"]
- + $a->performance["cache"] + $a->performance["cache_write"]
- + $a->performance["network"] + $a->performance["file"]), 2),
- number_format($duration, 2)
- ),
- Logger::DEBUG
- );
- }
+ $a->getProfiler()->saveLog("ID " . $queue["id"] . ": " . $funcname);
$cooldown = Config::get("system", "worker_cooldown", 0);
diff --git a/src/Database/DBA.php b/src/Database/DBA.php
index d2a739e93..1c17d9aca 100644
--- a/src/Database/DBA.php
+++ b/src/Database/DBA.php
@@ -2,10 +2,11 @@
namespace Friendica\Database;
-use Friendica\Core\Config\IConfigCache;
+use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Core\Logger;
use Friendica\Core\System;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Profiler;
use mysqli;
use mysqli_result;
use mysqli_stmt;
@@ -35,6 +36,10 @@ class DBA
* @var IConfigCache
*/
private static $configCache;
+ /**
+ * @var Profiler
+ */
+ private static $profiler;
private static $server_info = '';
private static $connection;
private static $driver;
@@ -50,7 +55,7 @@ class DBA
private static $db_name = '';
private static $db_charset = '';
- public static function connect($configCache, $serveraddr, $user, $pass, $db, $charset = null)
+ public static function connect(IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null)
{
if (!is_null(self::$connection) && self::connected()) {
return true;
@@ -58,6 +63,7 @@ class DBA
// We are storing these values for being able to perform a reconnect
self::$configCache = $configCache;
+ self::$profiler = $profiler;
self::$db_serveraddr = $serveraddr;
self::$db_user = $user;
self::$db_pass = $pass;
@@ -158,7 +164,7 @@ class DBA
public static function reconnect() {
self::disconnect();
- $ret = self::connect(self::$configCache, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
+ $ret = self::connect(self::$configCache, self::$profiler, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
return $ret;
}
@@ -392,7 +398,6 @@ class DBA
* @throws \Exception
*/
public static function p($sql) {
- $a = \get_app();
$stamp1 = microtime(true);
@@ -582,7 +587,7 @@ class DBA
self::$errorno = $errorno;
}
- $a->saveTimestamp($stamp1, 'database');
+ self::$profiler->saveTimestamp($stamp1, 'database', System::callstack());
if (self::$configCache->get('system', 'db_log')) {
$stamp2 = microtime(true);
@@ -611,7 +616,6 @@ class DBA
* @throws \Exception
*/
public static function e($sql) {
- $a = \get_app();
$stamp = microtime(true);
@@ -654,7 +658,7 @@ class DBA
self::$errorno = $errorno;
}
- $a->saveTimestamp($stamp, "database_write");
+ self::$profiler->saveTimestamp($stamp, "database_write", System::callstack());
return $retval;
}
@@ -777,7 +781,6 @@ class DBA
* @return array current row
*/
public static function fetch($stmt) {
- $a = \get_app();
$stamp1 = microtime(true);
@@ -824,7 +827,7 @@ class DBA
}
}
- $a->saveTimestamp($stamp1, 'database');
+ self::$profiler->saveTimestamp($stamp1, 'database', System::callstack());
return $columns;
}
@@ -1534,7 +1537,6 @@ class DBA
* @return boolean was the close successful?
*/
public static function close($stmt) {
- $a = \get_app();
$stamp1 = microtime(true);
@@ -1562,7 +1564,7 @@ class DBA
break;
}
- $a->saveTimestamp($stamp1, 'database');
+ self::$profiler->saveTimestamp($stamp1, 'database', System::callstack());
return $ret;
}
diff --git a/src/Factory/ConfigFactory.php b/src/Factory/ConfigFactory.php
index 269daea8b..6a30cf0e0 100644
--- a/src/Factory/ConfigFactory.php
+++ b/src/Factory/ConfigFactory.php
@@ -2,51 +2,66 @@
namespace Friendica\Factory;
+use Friendica\Core;
use Friendica\Core\Config;
+use Friendica\Core\Config\Adapter;
+use Friendica\Core\Config\Cache;
class ConfigFactory
{
/**
- * @param Config\ConfigCacheLoader $loader The Config Cache loader (INI/config/.htconfig)
+ * @param Cache\ConfigCacheLoader $loader The Config Cache loader (INI/config/.htconfig)
*
- * @return Config\ConfigCache
+ * @return Cache\ConfigCache
*/
- public static function createCache(Config\ConfigCacheLoader $loader)
+ public static function createCache(Cache\ConfigCacheLoader $loader)
{
- $configCache = new Config\ConfigCache();
+ $configCache = new Cache\ConfigCache();
$loader->loadConfigFiles($configCache);
return $configCache;
}
/**
- * @param string $type The adapter type
- * @param Config\IConfigCache $config The config cache of this adapter
+ * @param Cache\ConfigCache $configCache The config cache of this adapter
*
- * @return Config\IConfigAdapter
+ * @return Config\Configuration
*/
- public static function createConfig($type, Config\IConfigCache $config)
+ public static function createConfig(Cache\ConfigCache $configCache)
{
- if ($type == 'preload') {
- return new Config\PreloadConfigAdapter($config);
+ if ($configCache->get('system', 'config_adapter') === 'preload') {
+ $configAdapter = new Adapter\PreloadConfigAdapter();
} else {
- return new Config\JITConfigAdapter($config);
+ $configAdapter = new Adapter\JITConfigAdapter();
}
+
+ $configuration = new Config\Configuration($configCache, $configAdapter);
+
+ // Set the config in the static container for legacy usage
+ Core\Config::init($configuration);
+
+ return $configuration;
}
/**
- * @param string $type The adapter type
- * @param Config\IPConfigCache $config The config cache of this adapter
- * @param int $uid The UID of the current user
+ * @param Cache\ConfigCache $configCache The config cache of this adapter
+ * @param int $uid The UID of the current user
*
- * @return Config\IPConfigAdapter
+ * @return Config\PConfiguration
*/
- public static function createPConfig($type, Config\IPConfigCache $config, $uid = null)
+ public static function createPConfig(Cache\ConfigCache $configCache, $uid = null)
{
- if ($type == 'preload') {
- return new Config\PreloadPConfigAdapter($config, $uid);
+ if ($configCache->get('system', 'config_adapter') === 'preload') {
+ $configAdapter = new Adapter\PreloadPConfigAdapter($uid);
} else {
- return new Config\JITPConfigAdapter($config);
+ $configAdapter = new Adapter\JITPConfigAdapter();
}
+
+ $configuration = new Config\PConfiguration($configCache, $configAdapter);
+
+ // Set the config in the static container for legacy usage
+ Core\PConfig::init($configuration);
+
+ return $configuration;
}
}
diff --git a/src/Factory/DBFactory.php b/src/Factory/DBFactory.php
new file mode 100644
index 000000000..c1a796501
--- /dev/null
+++ b/src/Factory/DBFactory.php
@@ -0,0 +1,58 @@
+get('database', 'hostname');
+ $db_user = $configCache->get('database', 'username');
+ $db_pass = $configCache->get('database', 'password');
+ $db_data = $configCache->get('database', 'database');
+ $charset = $configCache->get('database', 'charset');
+
+ // Use environment variables for mysql if they are set beforehand
+ if (!empty($server['MYSQL_HOST'])
+ && !empty($server['MYSQL_USERNAME'] || !empty($server['MYSQL_USER']))
+ && $server['MYSQL_PASSWORD'] !== false
+ && !empty($server['MYSQL_DATABASE']))
+ {
+ $db_host = $server['MYSQL_HOST'];
+ if (!empty($server['MYSQL_PORT'])) {
+ $db_host .= ':' . $server['MYSQL_PORT'];
+ }
+ if (!empty($server['MYSQL_USERNAME'])) {
+ $db_user = $server['MYSQL_USERNAME'];
+ } else {
+ $db_user = $server['MYSQL_USER'];
+ }
+ $db_pass = (string) $server['MYSQL_PASSWORD'];
+ $db_data = $server['MYSQL_DATABASE'];
+ }
+
+ if (Database\DBA::connect($configCache, $profiler, $db_host, $db_user, $db_pass, $db_data, $charset)) {
+ // Loads DB_UPDATE_VERSION constant
+ Database\DBStructure::definition($configCache->get('system', 'basepath'), false);
+ }
+
+ unset($db_host, $db_user, $db_pass, $db_data, $charset);
+ }
+}
diff --git a/src/Factory/DependencyFactory.php b/src/Factory/DependencyFactory.php
new file mode 100644
index 000000000..acbf4bfaf
--- /dev/null
+++ b/src/Factory/DependencyFactory.php
@@ -0,0 +1,37 @@
+pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
- $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, ['Friendica\\Core\\Logger']));
+ $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, [Logger::class, Profiler::class]));
- if (isset($config)) {
- $debugging = $config->get('system', 'debugging');
- $stream = $config->get('system', 'logfile');
- $level = $config->get('system', 'loglevel');
+ $debugging = $config->get('system', 'debugging');
+ $stream = $config->get('system', 'logfile');
+ $level = $config->get('system', 'loglevel');
- if ($debugging) {
- static::addStreamHandler($logger, $stream, $level);
- }
+ if ($debugging) {
+ $loglevel = self::mapLegacyConfigDebugLevel((string)$level);
+ static::addStreamHandler($logger, $stream, $loglevel);
+ } else {
+ static::addVoidHandler($logger);
}
+ Logger::init($logger);
+
return $logger;
}
@@ -54,25 +59,71 @@ class LoggerFactory
*
* It should never get filled during normal usage of Friendica
*
- * @param string $channel The channel of the logger instance
- * @param string $developerIp The IP of the developer who wants to use the logger
+ * @param string $channel The channel of the logger instance
+ * @param Configuration $config The config
*
* @return LoggerInterface The PSR-3 compliant logger instance
*/
- public static function createDev($channel, $developerIp)
+ public static function createDev($channel, Configuration $config)
{
+ $debugging = $config->get('system', 'debugging');
+ $stream = $config->get('system', 'dlogfile');
+ $developerIp = $config->get('system', 'dlogip');
+
+ if (!isset($developerIp) || !$debugging) {
+ return null;
+ }
+
$logger = new Monolog\Logger($channel);
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
$logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, ['Friendica\\Core\\Logger']));
-
$logger->pushHandler(new FriendicaDevelopHandler($developerIp));
+ static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
+
+ Logger::setDevLogger($logger);
+
return $logger;
}
+ /**
+ * Mapping a legacy level to the PSR-3 compliant levels
+ * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
+ *
+ * @param string $level the level to be mapped
+ *
+ * @return string the PSR-3 compliant level
+ */
+ private static function mapLegacyConfigDebugLevel($level)
+ {
+ switch ($level) {
+ // legacy WARNING
+ case "0":
+ return LogLevel::ERROR;
+ // legacy INFO
+ case "1":
+ return LogLevel::WARNING;
+ // legacy TRACE
+ case "2":
+ return LogLevel::NOTICE;
+ // legacy DEBUG
+ case "3":
+ return LogLevel::INFO;
+ // legacy DATA
+ case "4":
+ return LogLevel::DEBUG;
+ // legacy ALL
+ case "5":
+ return LogLevel::DEBUG;
+ // default if nothing set
+ default:
+ return $level;
+ }
+ }
+
/**
* Adding a handler to a given logger instance
*
@@ -105,31 +156,10 @@ class LoggerFactory
}
}
- /**
- * This method enables the test mode of a given logger
- *
- * @param LoggerInterface $logger The logger
- *
- * @return Monolog\Handler\TestHandler the Handling for tests
- *
- * @throws InternalServerErrorException if the logger is incompatible to the logger factory
- */
- public static function enableTest($logger)
+ public static function addVoidHandler($logger)
{
if ($logger instanceof Monolog\Logger) {
- // disable every handler so far
$logger->pushHandler(new Monolog\Handler\NullHandler());
-
- // enable the test handler
- $fileHandler = new Monolog\Handler\TestHandler();
- $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
- $fileHandler->setFormatter($formatter);
-
- $logger->pushHandler($fileHandler);
-
- return $fileHandler;
- } else {
- throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
}
}
}
diff --git a/src/Factory/ProfilerFactory.php b/src/Factory/ProfilerFactory.php
new file mode 100644
index 000000000..26a156639
--- /dev/null
+++ b/src/Factory/ProfilerFactory.php
@@ -0,0 +1,26 @@
+get('system', 'profiler');
+ $enabled = isset($enabled) && $enabled !== '!!';
+ $renderTime = $configCache->get('rendertime', 'callstack');
+ $renderTime = isset($renderTime) && $renderTime !== '!!';
+
+ return new Profiler($enabled, $renderTime);
+ }
+}
diff --git a/src/Module/Install.php b/src/Module/Install.php
index 6948dee6e..3414e887f 100644
--- a/src/Module/Install.php
+++ b/src/Module/Install.php
@@ -75,7 +75,7 @@ class Install extends BaseModule
$dbdata = Strings::escapeTags(trim(defaults($_POST, 'dbdata', '')));
// If we cannot connect to the database, return to the previous step
- if (!self::$installer->checkDB($a->getConfig(), $dbhost, $dbuser, $dbpass, $dbdata)) {
+ if (!self::$installer->checkDB($a->getConfigCache(), $a->getProfiler(), $dbhost, $dbuser, $dbpass, $dbdata)) {
self::$currentWizardStep = self::DATABASE_CONFIG;
}
@@ -92,7 +92,7 @@ class Install extends BaseModule
$adminmail = Strings::escapeTags(trim(defaults($_POST, 'adminmail', '')));
// If we cannot connect to the database, return to the Database config wizard
- if (!self::$installer->checkDB($a->getConfig(), $dbhost, $dbuser, $dbpass, $dbdata)) {
+ if (!self::$installer->checkDB($a->getConfigCache(), $a->getProfiler(), $dbhost, $dbuser, $dbpass, $dbdata)) {
self::$currentWizardStep = self::DATABASE_CONFIG;
return;
}
diff --git a/src/Object/Image.php b/src/Object/Image.php
index 9143c23c1..45c8bedea 100644
--- a/src/Object/Image.php
+++ b/src/Object/Image.php
@@ -5,6 +5,7 @@
*/
namespace Friendica\Object;
+use Exception;
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
@@ -14,7 +15,6 @@ use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Photo;
use Friendica\Util\Network;
-use Exception;
use Imagick;
use ImagickPixel;
@@ -656,7 +656,7 @@ class Image
$stamp1 = microtime(true);
file_put_contents($path, $string);
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
}
/**
@@ -802,7 +802,7 @@ class Image
$a = \get_app();
$stamp1 = microtime(true);
file_put_contents($tempfile, $img_str);
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$data = getimagesize($tempfile);
unlink($tempfile);
@@ -910,7 +910,7 @@ class Image
$stamp1 = microtime(true);
$imagedata = @file_get_contents($url);
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
}
$maximagesize = Config::get('system', 'maximagesize');
@@ -924,7 +924,7 @@ class Image
$stamp1 = microtime(true);
file_put_contents($tempfile, $imagedata);
- $a->saveTimestamp($stamp1, "file");
+ $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
$data = getimagesize($tempfile);
diff --git a/src/Util/Network.php b/src/Util/Network.php
index de4b45da9..cda8c9a71 100644
--- a/src/Util/Network.php
+++ b/src/Util/Network.php
@@ -4,13 +4,13 @@
*/
namespace Friendica\Util;
+use DOMDocument;
+use DomXPath;
+use Friendica\Core\Config;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\System;
-use Friendica\Core\Config;
use Friendica\Network\CurlResult;
-use DOMDocument;
-use DomXPath;
class Network
{
@@ -232,7 +232,7 @@ class Network
@curl_close($ch);
- $a->saveTimestamp($stamp1, 'network');
+ $a->getProfiler()->saveTimestamp($stamp1, 'network', System::callstack());
return $curlResponse;
}
@@ -334,7 +334,7 @@ class Network
curl_close($ch);
- $a->saveTimestamp($stamp1, 'network');
+ $a->getProfiler()->saveTimestamp($stamp1, 'network', System::callstack());
Logger::log('post_url: end ' . $url, Logger::DATA);
@@ -641,7 +641,7 @@ class Network
$http_code = $curl_info['http_code'];
curl_close($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
if ($http_code == 0) {
return $url;
@@ -683,7 +683,7 @@ class Network
$body = curl_exec($ch);
curl_close($ch);
- $a->saveTimestamp($stamp1, "network");
+ $a->getProfiler()->saveTimestamp($stamp1, "network", System::callstack());
if (trim($body) == "") {
return $url;
diff --git a/src/Util/Profiler.php b/src/Util/Profiler.php
new file mode 100644
index 000000000..2d3da3a9c
--- /dev/null
+++ b/src/Util/Profiler.php
@@ -0,0 +1,239 @@
+enabled = $enabled;
+ $this->rendertime = $renderTime;
+ $this->reset();
+ }
+
+ /**
+ * Saves a timestamp for a value - f.e. a call
+ * Necessary for profiling Friendica
+ *
+ * @param int $timestamp the Timestamp
+ * @param string $value A value to profile
+ * @param string $callstack The callstack of the current profiling data
+ */
+ public function saveTimestamp($timestamp, $value, $callstack = '')
+ {
+ if (!$this->enabled) {
+ return;
+ }
+
+ $duration = (float) (microtime(true) - $timestamp);
+
+ if (!isset($this->performance[$value])) {
+ // Prevent ugly E_NOTICE
+ $this->performance[$value] = 0;
+ }
+
+ $this->performance[$value] += (float) $duration;
+ $this->performance['marktime'] += (float) $duration;
+
+ if (!isset($this->callstack[$value][$callstack])) {
+ // Prevent ugly E_NOTICE
+ $this->callstack[$value][$callstack] = 0;
+ }
+
+ $this->callstack[$value][$callstack] += (float) $duration;
+ }
+
+ /**
+ * Resets the performance and callstack profiling
+ */
+ public function reset()
+ {
+ $this->resetPerformance();
+ $this->resetCallstack();
+ }
+
+ /**
+ * Resets the performance profiling data
+ */
+ public function resetPerformance()
+ {
+ $this->performance = [];
+ $this->performance['start'] = microtime(true);
+ $this->performance['database'] = 0;
+ $this->performance['database_write'] = 0;
+ $this->performance['cache'] = 0;
+ $this->performance['cache_write'] = 0;
+ $this->performance['network'] = 0;
+ $this->performance['file'] = 0;
+ $this->performance['rendering'] = 0;
+ $this->performance['parser'] = 0;
+ $this->performance['marktime'] = 0;
+ $this->performance['marktime'] = microtime(true);
+ }
+
+ /**
+ * Resets the callstack profiling data
+ */
+ public function resetCallstack()
+ {
+ $this->callstack = [];
+ $this->callstack['database'] = [];
+ $this->callstack['database_write'] = [];
+ $this->callstack['cache'] = [];
+ $this->callstack['cache_write'] = [];
+ $this->callstack['network'] = [];
+ $this->callstack['file'] = [];
+ $this->callstack['rendering'] = [];
+ $this->callstack['parser'] = [];
+ }
+
+ /**
+ * Save the current profiling data to a log entry
+ *
+ * @param LoggerInterface $logger The logger to save the current log
+ * @param string $message Additional message for the log
+ */
+ public function saveLog(LoggerInterface $logger, $message = '')
+ {
+ // Write down the performance values into the log
+ if (!$this->enabled) {
+ return;
+ }
+ $duration = microtime(true) - $this->get('start');
+ $logger->info(
+ $message,
+ [
+ 'action' => 'profiling',
+ 'database_read' => round($this->get('database') - $this->get('database_write'), 3),
+ 'database_write' => round($this->get('database_write'), 3),
+ 'cache_read' => round($this->get('cache'), 3),
+ 'cache_write' => round($this->get('cache_write'), 3),
+ 'network_io' => round($this->get('network'), 2),
+ 'file_io' => round($this->get('file'), 2),
+ 'other_io' => round($duration - ($this->get('database')
+ + $this->get('cache') + $this->get('cache_write')
+ + $this->get('network') + $this->get('file')), 2),
+ 'total' => round($duration, 2)
+ ]
+ );
+
+ if (!$this->rendertime) {
+ return;
+ }
+
+ $o = '';
+ if (isset($this->callstack["database"])) {
+ $o .= "\nDatabase Read:\n";
+ foreach ($this->callstack["database"] as $func => $time) {
+ $time = round($time, 3);
+ if ($time > 0) {
+ $o .= $func . ": " . $time . "\n";
+ }
+ }
+ }
+ if (isset($this->callstack["database_write"])) {
+ $o .= "\nDatabase Write:\n";
+ foreach ($this->callstack["database_write"] as $func => $time) {
+ $time = round($time, 3);
+ if ($time > 0) {
+ $o .= $func . ": " . $time . "\n";
+ }
+ }
+ }
+ if (isset($this->callstack["cache"])) {
+ $o .= "\nCache Read:\n";
+ foreach ($this->callstack["cache"] as $func => $time) {
+ $time = round($time, 3);
+ if ($time > 0) {
+ $o .= $func . ": " . $time . "\n";
+ }
+ }
+ }
+ if (isset($this->callstack["cache_write"])) {
+ $o .= "\nCache Write:\n";
+ foreach ($this->callstack["cache_write"] as $func => $time) {
+ $time = round($time, 3);
+ if ($time > 0) {
+ $o .= $func . ": " . $time . "\n";
+ }
+ }
+ }
+ if (isset($this->callstack["network"])) {
+ $o .= "\nNetwork:\n";
+ foreach ($this->callstack["network"] as $func => $time) {
+ $time = round($time, 3);
+ if ($time > 0) {
+ $o .= $func . ": " . $time . "\n";
+ }
+ }
+ }
+ $logger->info($message . ": " . $o, ['action' => 'profiling']);
+ }
+
+ /**
+ * Finds an entry of the container by its identifier and returns it.
+ *
+ * @param string $id Identifier of the entry to look for.
+ *
+ * @throws NotFoundExceptionInterface No entry was found for **this** identifier.
+ * @throws ContainerExceptionInterface Error while retrieving the entry.
+ *
+ * @return int Entry.
+ */
+ public function get($id)
+ {
+ if (!$this->has($id)) {
+ return 0;
+ } else {
+ return $this->performance[$id];
+ }
+ }
+
+ /**
+ * Returns true if the container can return an entry for the given identifier.
+ * Returns false otherwise.
+ *
+ * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+ * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
+ *
+ * @param string $id Identifier of the entry to look for.
+ *
+ * @return bool
+ */
+ public function has($id)
+ {
+ return isset($this->performance[$id]);
+ }
+}
diff --git a/tests/DatabaseTest.php b/tests/DatabaseTest.php
index 79af5b546..dde61e856 100644
--- a/tests/DatabaseTest.php
+++ b/tests/DatabaseTest.php
@@ -5,10 +5,11 @@
namespace Friendica\Test;
-use Friendica\Core\Config;
+use Friendica\Core\Config\Cache;
use Friendica\Database\DBA;
use Friendica\Factory;
use Friendica\Util\BasePath;
+use Friendica\Util\Profiler;
use PHPUnit\DbUnit\DataSet\YamlDataSet;
use PHPUnit\DbUnit\TestCaseTrait;
use PHPUnit_Extensions_Database_DB_IDatabaseConnection;
@@ -40,11 +41,14 @@ abstract class DatabaseTest extends MockedTest
}
$basedir = BasePath::create(dirname(__DIR__));
- $configLoader = new Config\ConfigCacheLoader($basedir);
+ $configLoader = new Cache\ConfigCacheLoader($basedir);
$config = Factory\ConfigFactory::createCache($configLoader);
+ $profiler = \Mockery::mock(Profiler::class);
+
DBA::connect(
$config,
+ $profiler,
getenv('MYSQL_HOST'),
getenv('MYSQL_USERNAME'),
getenv('MYSQL_PASSWORD'),
diff --git a/tests/Util/AppMockTrait.php b/tests/Util/AppMockTrait.php
index 18188239f..817570dd5 100644
--- a/tests/Util/AppMockTrait.php
+++ b/tests/Util/AppMockTrait.php
@@ -5,8 +5,8 @@ namespace Friendica\Test\Util;
use Friendica\App;
use Friendica\BaseObject;
use Friendica\Core\Config;
-use Friendica\Core\Config\ConfigCache;
use Friendica\Render\FriendicaSmartyEngine;
+use Friendica\Util\Profiler;
use Mockery\MockInterface;
use org\bovigo\vfs\vfsStreamDirectory;
@@ -21,74 +21,83 @@ trait AppMockTrait
protected $app;
/**
- * @var MockInterface|ConfigCache The mocked Config Cache
+ * @var MockInterface|Config\Configuration The mocked Config Cache
*/
- protected $configCache;
+ protected $configMock;
+
+ /**
+ * @var MockInterface|Profiler The mocked profiler
+ */
+ protected $profilerMock;
/**
* Mock the App
*
* @param vfsStreamDirectory $root The root directory
- * @param MockInterface|ConfigCache $config The config cache
*/
- public function mockApp($root, $config)
+ public function mockApp($root)
{
- $this->configCache = $config;
+ $this->configMock = \Mockery::mock(Config\Cache\IConfigCache::class);
+ $configAdapterMock = \Mockery::mock(Config\Adapter\IConfigAdapter::class);
+ // Disable the adapter
+ $configAdapterMock->shouldReceive('isConnected')->andReturn(false);
+
+ $config = new Config\Configuration($this->configMock, $configAdapterMock);
+ // Initialize empty Config
+ Config::init($config);
+
// Mocking App and most used functions
$this->app = \Mockery::mock(App::class);
$this->app
->shouldReceive('getBasePath')
->andReturn($root->url());
- $config
+ $this->configMock
+ ->shouldReceive('has')
+ ->andReturn(true);
+ $this->configMock
->shouldReceive('get')
->with('database', 'hostname')
->andReturn(getenv('MYSQL_HOST'));
- $config
+ $this->configMock
->shouldReceive('get')
->with('database', 'username')
->andReturn(getenv('MYSQL_USERNAME'));
- $config
+ $this->configMock
->shouldReceive('get')
->with('database', 'password')
->andReturn(getenv('MYSQL_PASSWORD'));
- $config
+ $this->configMock
->shouldReceive('get')
->with('database', 'database')
->andReturn(getenv('MYSQL_DATABASE'));
- $config
+ $this->configMock
->shouldReceive('get')
->with('config', 'hostname')
->andReturn('localhost');
- $config
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'theme', NULL)
+ ->with('system', 'theme')
->andReturn('system_theme');
- $this->app
- ->shouldReceive('getConfig')
- ->andReturn($config);
+ $this->profilerMock = \Mockery::mock(Profiler::class);
+ $this->profilerMock->shouldReceive('saveTimestamp');
+ $this->app
+ ->shouldReceive('getConfigCache')
+ ->andReturn($this->configMock);
$this->app
->shouldReceive('getTemplateEngine')
->andReturn(new FriendicaSmartyEngine());
$this->app
->shouldReceive('getCurrentTheme')
->andReturn('Smarty3');
- $this->app
- ->shouldReceive('saveTimestamp')
- ->andReturn(true);
$this->app
->shouldReceive('getBaseUrl')
->andReturn('http://friendica.local');
-
- // Initialize empty Config
- Config::init($config);
- $configAdapter = \Mockery::mock('Friendica\Core\Config\IConfigAdapter');
- $configAdapter
- ->shouldReceive('isConnected')
- ->andReturn(false);
- Config::setAdapter($configAdapter);
+ $this->app
+ ->shouldReceive('getProfiler')
+ ->andReturn($this->profilerMock);
BaseObject::setApp($this->app);
}
diff --git a/tests/Util/DBStructureMockTrait.php b/tests/Util/DBStructureMockTrait.php
index 87c120d3f..92ec412cb 100644
--- a/tests/Util/DBStructureMockTrait.php
+++ b/tests/Util/DBStructureMockTrait.php
@@ -2,6 +2,7 @@
namespace Friendica\Test\Util;
+use Friendica\Database\DBStructure;
use Mockery\MockInterface;
/**
@@ -16,6 +17,7 @@ trait DBStructureMockTrait
/**
* Mocking DBStructure::update()
+ * @see DBStructure::update();
*
* @param array $args The arguments for the update call
* @param bool $return True, if the connect was successful, otherwise false
diff --git a/tests/include/ApiTest.php b/tests/include/ApiTest.php
index be70d923b..289b3fcea 100644
--- a/tests/include/ApiTest.php
+++ b/tests/include/ApiTest.php
@@ -7,6 +7,7 @@ namespace Friendica\Test;
use Friendica\App;
use Friendica\Core\Config;
+use Friendica\Core\Config\Cache;
use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\System;
@@ -36,11 +37,14 @@ class ApiTest extends DatabaseTest
public function setUp()
{
$basedir = BasePath::create(dirname(__DIR__) . '/../');
- $configLoader = new Config\ConfigCacheLoader($basedir);
- $config = Factory\ConfigFactory::createCache($configLoader);
+ $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $configCache = Factory\ConfigFactory::createCache($configLoader);
+ $profiler = Factory\ProfilerFactory::create($configCache);
+ Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ $config = Factory\ConfigFactory::createConfig($configCache);
+ Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, false);
- $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
+ $this->app = new App($config, $logger, $profiler, false);
parent::setUp();
diff --git a/tests/src/App/ModeTest.php b/tests/src/App/ModeTest.php
index 19dad07cd..9059e8beb 100644
--- a/tests/src/App/ModeTest.php
+++ b/tests/src/App/ModeTest.php
@@ -90,19 +90,14 @@ class ModeTest extends MockedTest
$this->mockConnected(true, 1);
$this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1);
- $config = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+ $config = \Mockery::mock(Config\Configuration::class);
$config
->shouldReceive('get')
- ->with('system', 'maintenance', null)
+ ->with('system', 'maintenance', null, false)
->andReturn(true)
->once();
// Initialize empty Config
Config::init($config);
- $configAdapter = \Mockery::mock('Friendica\Core\Config\IConfigAdapter');
- $configAdapter
- ->shouldReceive('isConnected')
- ->andReturn(false);
- Config::setAdapter($configAdapter);
$mode = new Mode($this->root->url());
$mode->determine();
@@ -123,19 +118,14 @@ class ModeTest extends MockedTest
$this->mockConnected(true, 1);
$this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1);
- $config = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+ $config = \Mockery::mock(Config\Configuration::class);
$config
->shouldReceive('get')
- ->with('system', 'maintenance', null)
+ ->with('system', 'maintenance', null, false)
->andReturn(false)
->once();
// Initialize empty Config
Config::init($config);
- $configAdapter = \Mockery::mock('Friendica\Core\Config\IConfigAdapter');
- $configAdapter
- ->shouldReceive('isConnected')
- ->andReturn(false);
- Config::setAdapter($configAdapter);
$mode = new Mode($this->root->url());
$mode->determine();
diff --git a/tests/src/BaseObjectTest.php b/tests/src/BaseObjectTest.php
index 784944c3a..334150391 100644
--- a/tests/src/BaseObjectTest.php
+++ b/tests/src/BaseObjectTest.php
@@ -31,8 +31,7 @@ class BaseObjectTest extends TestCase
{
$baseObject = new BaseObject();
$this->setUpVfsDir();
- $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
- $this->mockApp($this->root, $configMock);
+ $this->mockApp($this->root);
$this->assertNull($baseObject->setApp($this->app));
$this->assertEquals($this->app, $baseObject->getApp());
diff --git a/tests/src/Core/Cache/CacheTest.php b/tests/src/Core/Cache/CacheTest.php
index e8bd65cbf..ef97f5a17 100644
--- a/tests/src/Core/Cache/CacheTest.php
+++ b/tests/src/Core/Cache/CacheTest.php
@@ -67,8 +67,7 @@ abstract class CacheTest extends MockedTest
protected function setUp()
{
$this->setUpVfsDir();
- $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
- $this->mockApp($this->root, $configMock);
+ $this->mockApp($this->root);
$this->app
->shouldReceive('getHostname')
->andReturn('friendica.local');
diff --git a/tests/src/Core/Cache/MemcacheCacheDriverTest.php b/tests/src/Core/Cache/MemcacheCacheDriverTest.php
index 7832344a8..f9df9eaba 100644
--- a/tests/src/Core/Cache/MemcacheCacheDriverTest.php
+++ b/tests/src/Core/Cache/MemcacheCacheDriverTest.php
@@ -12,14 +12,14 @@ class MemcacheCacheDriverTest extends MemoryCacheTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcache_host', NULL)
+ ->with('system', 'memcache_host')
->andReturn('localhost');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcache_port', NULL)
+ ->with('system', 'memcache_port')
->andReturn(11211);
$this->cache = CacheDriverFactory::create('memcache');
diff --git a/tests/src/Core/Cache/MemcachedCacheDriverTest.php b/tests/src/Core/Cache/MemcachedCacheDriverTest.php
index fe401f97d..4e16ef947 100644
--- a/tests/src/Core/Cache/MemcachedCacheDriverTest.php
+++ b/tests/src/Core/Cache/MemcachedCacheDriverTest.php
@@ -12,9 +12,9 @@ class MemcachedCacheDriverTest extends MemoryCacheTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcached_hosts', NULL)
+ ->with('system', 'memcached_hosts')
->andReturn([0 => 'localhost, 11211']);
$this->cache = CacheDriverFactory::create('memcached');
diff --git a/tests/src/Core/Cache/RedisCacheDriverTest.php b/tests/src/Core/Cache/RedisCacheDriverTest.php
index 0a3dba439..20fe7eb53 100644
--- a/tests/src/Core/Cache/RedisCacheDriverTest.php
+++ b/tests/src/Core/Cache/RedisCacheDriverTest.php
@@ -12,14 +12,14 @@ class RedisCacheDriverTest extends MemoryCacheTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'redis_host', NULL)
+ ->with('system', 'redis_host')
->andReturn('localhost');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'redis_port', NULL)
+ ->with('system', 'redis_port')
->andReturn(null);
$this->cache = CacheDriverFactory::create('redis');
diff --git a/tests/src/Core/Config/ConfigCacheLoaderTest.php b/tests/src/Core/Config/Cache/ConfigCacheLoaderTest.php
similarity index 95%
rename from tests/src/Core/Config/ConfigCacheLoaderTest.php
rename to tests/src/Core/Config/Cache/ConfigCacheLoaderTest.php
index 6be89bc40..f91f267c7 100644
--- a/tests/src/Core/Config/ConfigCacheLoaderTest.php
+++ b/tests/src/Core/Config/Cache/ConfigCacheLoaderTest.php
@@ -1,9 +1,9 @@
delConfigFile('local.config.php');
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+ '..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'datasets' . DIRECTORY_SEPARATOR .
@@ -91,6 +92,7 @@ class ConfigCacheLoaderTest extends MockedTest
$this->delConfigFile('local.config.php');
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+ '..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'datasets' . DIRECTORY_SEPARATOR .
@@ -122,6 +124,7 @@ class ConfigCacheLoaderTest extends MockedTest
$this->delConfigFile('local.config.php');
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+ '..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'datasets' . DIRECTORY_SEPARATOR .
@@ -160,6 +163,7 @@ class ConfigCacheLoaderTest extends MockedTest
vfsStream::create($structure, $this->root);
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+ '..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'datasets' . DIRECTORY_SEPARATOR .
diff --git a/tests/src/Core/Config/ConfigCacheTest.php b/tests/src/Core/Config/Cache/ConfigCacheTest.php
similarity index 55%
rename from tests/src/Core/Config/ConfigCacheTest.php
rename to tests/src/Core/Config/Cache/ConfigCacheTest.php
index 25ea6030f..ac9fae540 100644
--- a/tests/src/Core/Config/ConfigCacheTest.php
+++ b/tests/src/Core/Config/Cache/ConfigCacheTest.php
@@ -1,8 +1,8 @@
loadConfigArray($data);
+ $configCache->load($data);
$this->assertConfigValues($data, $configCache);
}
@@ -67,18 +67,38 @@ class ConfigCacheTest extends MockedTest
];
$configCache = new ConfigCache();
- $configCache->loadConfigArray($data);
- $configCache->loadConfigArray($override);
+ $configCache->load($data);
+ $configCache->load($override);
$this->assertConfigValues($data, $configCache);
// override the value
- $configCache->loadConfigArray($override, true);
+ $configCache->load($override, true);
$this->assertEquals($override['system']['test'], $configCache->get('system', 'test'));
$this->assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
}
+ /**
+ * Test the loadConfigArray() method with wrong/empty datasets
+ */
+ public function testLoadConfigArrayWrong()
+ {
+ $configCache = new ConfigCache();
+
+ // empty dataset
+ $configCache->load([]);
+ $this->assertEmpty($configCache->getAll());
+
+ // wrong dataset
+ $configCache->load(['system' => 'not_array']);
+ $this->assertEmpty($configCache->getAll());
+
+ // incomplete dataset (key is integer ID of the array)
+ $configCache->load(['system' => ['value']]);
+ $this->assertEquals('value', $configCache->get('system', 0));
+ }
+
/**
* Test the getAll() method
* @dataProvider dataTests
@@ -86,14 +106,12 @@ class ConfigCacheTest extends MockedTest
public function testGetAll($data)
{
$configCache = new ConfigCache();
- $configCache->loadConfigArray($data);
+ $configCache->load($data);
$all = $configCache->getAll();
$this->assertContains($data['system'], $all);
-
- // config values are stored directly in the array base
- $this->assertEquals($data['config']['a'], $all['a']);
+ $this->assertContains($data['config'], $all);
}
/**
@@ -113,6 +131,54 @@ class ConfigCacheTest extends MockedTest
$this->assertConfigValues($data, $configCache);
}
+ /**
+ * Test the get() method without a value
+ */
+ public function testGetEmpty()
+ {
+ $configCache = new ConfigCache();
+
+ $this->assertEquals('!!', $configCache->get('something', 'value'));
+ }
+
+ /**
+ * Test the has() method
+ */
+ public function testHas()
+ {
+ $configCache = new ConfigCache();
+
+ $this->assertFalse($configCache->has('system', 'test'));
+ $this->assertFalse($configCache->has('system'));
+
+ $configCache->set('system', 'test', 'it');
+ $this->assertTrue($configCache->has('system', 'test'));
+ $this->assertTrue($configCache->has('system'));
+ }
+
+ /**
+ * Test the get() method with a category
+ */
+ public function testGetCat()
+ {
+ $configCache = new ConfigCache([
+ 'system' => [
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ],
+ 'config' => [
+ 'key3' => 'value3',
+ ],
+ ]);
+
+ $this->assertTrue($configCache->has('system'));
+
+ $this->assertEquals([
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ], $configCache->get('system'));
+ }
+
/**
* Test the delete() method
* @dataProvider dataTests
@@ -149,6 +215,32 @@ class ConfigCacheTest extends MockedTest
}
+ /**
+ * Test the getP() method with a category
+ */
+ public function testGetPCat()
+ {
+ $configCache = new ConfigCache();
+ $uid = 345;
+
+ $configCache->loadP($uid, [
+ 'system' => [
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ],
+ 'config' => [
+ 'key3' => 'value3',
+ ],
+ ]);
+
+ $this->assertTrue($configCache->hasP($uid,'system'));
+
+ $this->assertEquals([
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ], $configCache->get($uid, 'system'));
+ }
+
/**
* Test the deleteP() method
* @dataProvider dataTests
@@ -172,4 +264,20 @@ class ConfigCacheTest extends MockedTest
$this->assertEmpty($configCache->getAll());
}
+
+ /**
+ * Test the hasP() method
+ */
+ public function testHasP()
+ {
+ $configCache = new ConfigCache();
+ $uid = 345;
+
+ $this->assertFalse($configCache->hasP($uid, 'system', 'test'));
+ $this->assertFalse($configCache->hasP($uid, 'system'));
+
+ $configCache->setP($uid, 'system', 'test', 'it');
+ $this->assertTrue($configCache->hasP($uid, 'system', 'test'));
+ $this->assertTrue($configCache->hasP($uid, 'system'));
+ }
}
diff --git a/tests/src/Core/Config/ConfigurationTest.php b/tests/src/Core/Config/ConfigurationTest.php
new file mode 100644
index 000000000..2e4fcd4f5
--- /dev/null
+++ b/tests/src/Core/Config/ConfigurationTest.php
@@ -0,0 +1,276 @@
+ ['data' => 'it'],
+ 'boolTrue' => ['data' => true],
+ 'boolFalse' => ['data' => false],
+ 'integer' => ['data' => 235],
+ 'decimal' => ['data' => 2.456],
+ 'array' => ['data' => ['1', 2, '3', true, false]],
+ 'boolIntTrue' => ['data' => 1],
+ 'boolIntFalse' => ['Data' => 0],
+ ];
+ }
+
+ /**
+ * Test the configuration initialization
+ */
+ public function testSetUp()
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ $this->assertInstanceOf(IConfigCache::class, $configuration->getCache());
+ }
+
+ /**
+ * Test the configuration load() method
+ */
+ public function testCacheLoad()
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(3);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+ // expected loading
+ $configAdapter->shouldReceive('load')->andReturn(['testing' => ['test' => 'it']])->once();
+ $configAdapter->shouldReceive('isLoaded')->with('testing', 'test')->andReturn(true)->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+ $configuration->load('testing');
+
+ $this->assertEquals('it', $configuration->get('testing', 'test'));
+ $this->assertEquals('it', $configuration->getCache()->get('testing', 'test'));
+ }
+
+ /**
+ * Test the configuration load() method with overwrite
+ */
+ public function testCacheLoadDouble()
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(5);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+ // expected loading
+ $configAdapter->shouldReceive('load')->andReturn(['testing' => ['test' => 'it']])->once();
+ $configAdapter->shouldReceive('isLoaded')->with('testing', 'test')->andReturn(true)->twice();
+ // expected next loading
+ $configAdapter->shouldReceive('load')->andReturn(['testing' => ['test' => 'again']])->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+ $configuration->load('testing');
+
+ $this->assertEquals('it', $configuration->get('testing', 'test'));
+ $this->assertEquals('it', $configuration->getCache()->get('testing', 'test'));
+
+ $configuration->load('testing');
+
+ $this->assertEquals('again', $configuration->get('testing', 'test'));
+ $this->assertEquals('again', $configuration->getCache()->get('testing', 'test'));
+ }
+
+ /**
+ * Test the configuration get() and set() methods without adapter
+ * @dataProvider dataTests
+ */
+ public function testSetGetWithoutDB($data)
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(3);
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ $this->assertTrue($configuration->set('test', 'it', $data));
+
+ $this->assertEquals($data, $configuration->get('test', 'it'));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+ }
+
+ /**
+ * Test the configuration get() and set() methods with adapter
+ * @dataProvider dataTests
+ */
+ public function testSetGetWithDB($data)
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(3);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(true)->once();
+ $configAdapter->shouldReceive('set')->with('test', 'it', $data)->andReturn(true)->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ $this->assertTrue($configuration->set('test', 'it', $data));
+
+ $this->assertEquals($data, $configuration->get('test', 'it'));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+ }
+
+ /**
+ * Test the configuration get() method with wrong value and no db
+ */
+ public function testGetWrongWithoutDB()
+ {
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(4);
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ // without refresh
+ $this->assertNull($configuration->get('test', 'it'));
+
+ /// beware that the cache returns '!!' and not null for a non existing value
+ $this->assertEquals('!!', $configuration->getCache()->get('test', 'it'));
+
+ // with default value
+ $this->assertEquals('default', $configuration->get('test', 'it', 'default'));
+
+ // with default value and refresh
+ $this->assertEquals('default', $configuration->get('test', 'it', 'default', true));
+ }
+
+ /**
+ * Test the configuration get() method with refresh
+ * @dataProvider dataTests
+ */
+ public function testGetWithRefresh($data)
+ {
+ $configCache = new ConfigCache(['test' => ['it' => 'now']]);
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(4);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(true)->twice();
+ $configAdapter->shouldReceive('get')->with('test', 'it')->andReturn($data)->once();
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'not')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with('test', 'not')->andReturn('!!')->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ // without refresh
+ $this->assertEquals('now', $configuration->get('test', 'it'));
+ $this->assertEquals('now', $configuration->getCache()->get('test', 'it'));
+
+ // with refresh
+ $this->assertEquals($data, $configuration->get('test', 'it', null, true));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+
+ // without refresh and wrong value and default
+ $this->assertEquals('default', $configuration->get('test', 'not', 'default'));
+ $this->assertEquals('!!', $configuration->getCache()->get('test', 'not'));
+ }
+
+ /**
+ * Test the configuration get() method with different isLoaded settings
+ * @dataProvider dataTests
+ */
+ public function testGetWithoutLoaded($data)
+ {
+ $configCache = new ConfigCache(['test' => ['it' => 'now']]);
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(4);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with('test', 'it')->andReturn('!!')->once();
+
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with('test', 'it')->andReturn($data)->once();
+
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(true)->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ // first run is not loaded and no data is found in the DB
+ $this->assertEquals('now', $configuration->get('test', 'it'));
+ $this->assertEquals('now', $configuration->getCache()->get('test', 'it'));
+
+ // second run is not loaded, but now data is found in the db (overwrote cache)
+ $this->assertEquals($data, $configuration->get('test', 'it'));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+
+ // third run is loaded and therefore cache is used
+ $this->assertEquals($data, $configuration->get('test', 'it'));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+ }
+
+ /**
+ * Test the configuration delete() method without adapter
+ * @dataProvider dataTests
+ */
+ public function testDeleteWithoutDB($data)
+ {
+ $configCache = new ConfigCache(['test' => ['it' => $data]]);
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(4);
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ $this->assertEquals($data, $configuration->get('test', 'it'));
+ $this->assertEquals($data, $configuration->getCache()->get('test', 'it'));
+
+ $this->assertTrue($configuration->delete('test', 'it'));
+ $this->assertNull($configuration->get('test', 'it'));
+ $this->assertEquals('!!', $configuration->getCache()->get('test', 'it'));
+
+ $this->assertEmpty($configuration->getCache()->getAll());
+ }
+
+ /**
+ * Test the configuration delete() method with adapter
+ */
+ public function testDeleteWithDB()
+ {
+ $configCache = new ConfigCache(['test' => ['it' => 'now', 'quarter' => 'true']]);
+ $configAdapter = \Mockery::mock(IConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(6);
+ // constructor loading
+ $configAdapter->shouldReceive('load')->andReturn([])->once();
+ $configAdapter->shouldReceive('isLoaded')->with('test', 'it')->andReturn(true)->once();
+
+ $configAdapter->shouldReceive('delete')->with('test', 'it')->andReturn(false)->once();
+
+ $configAdapter->shouldReceive('delete')->with('test', 'second')->andReturn(true)->once();
+ $configAdapter->shouldReceive('delete')->with('test', 'third')->andReturn(false)->once();
+ $configAdapter->shouldReceive('delete')->with('test', 'quarter')->andReturn(true)->once();
+
+ $configuration = new Configuration($configCache, $configAdapter);
+
+ $this->assertEquals('now', $configuration->get('test', 'it'));
+ $this->assertEquals('now', $configuration->getCache()->get('test', 'it'));
+
+ // delete from cache only
+ $this->assertTrue($configuration->delete('test', 'it'));
+ // delete from db only
+ $this->assertTrue($configuration->delete('test', 'second'));
+ // no delete
+ $this->assertFalse($configuration->delete('test', 'third'));
+ // delete both
+ $this->assertTrue($configuration->delete('test', 'quarter'));
+
+ $this->assertEmpty($configuration->getCache()->getAll());
+ }
+}
diff --git a/tests/src/Core/Config/PConfigurationTest.php b/tests/src/Core/Config/PConfigurationTest.php
new file mode 100644
index 000000000..025994414
--- /dev/null
+++ b/tests/src/Core/Config/PConfigurationTest.php
@@ -0,0 +1,247 @@
+ ['data' => 'it'],
+ 'boolTrue' => ['data' => true],
+ 'boolFalse' => ['data' => false],
+ 'integer' => ['data' => 235],
+ 'decimal' => ['data' => 2.456],
+ 'array' => ['data' => ['1', 2, '3', true, false]],
+ 'boolIntTrue' => ['data' => 1],
+ 'boolIntFalse' => ['Data' => 0],
+ ];
+ }
+
+ /**
+ * Test the configuration load() method
+ */
+ public function testCacheLoad()
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->twice();
+ // expected loading
+ $configAdapter->shouldReceive('load')
+ ->with($uid, 'testing')
+ ->andReturn(['testing' => ['test' => 'it']])
+ ->once();
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'testing', 'test')->andReturn(true)->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+ $configuration->load($uid, 'testing');
+
+ $this->assertEquals('it', $configuration->get($uid, 'testing', 'test'));
+ }
+
+ /**
+ * Test the configuration load() method with overwrite
+ */
+ public function testCacheLoadDouble()
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(4);
+ // expected loading
+ $configAdapter->shouldReceive('load')->with($uid, 'testing')->andReturn(['testing' => ['test' => 'it']])->once();
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'testing', 'test')->andReturn(true)->twice();
+ // expected next loading
+ $configAdapter->shouldReceive('load')->andReturn(['testing' => ['test' => 'again']])->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+ $configuration->load($uid, 'testing');
+
+ $this->assertEquals('it', $configuration->get($uid, 'testing', 'test'));
+
+ $configuration->load($uid, 'testing');
+
+ $this->assertEquals('again', $configuration->get($uid, 'testing', 'test'));
+ }
+
+ /**
+ * Test the configuration get() and set() methods without adapter
+ * @dataProvider dataTests
+ */
+ public function testSetGetWithoutDB($data)
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(2);
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ $this->assertTrue($configuration->set($uid, 'test', 'it', $data));
+
+ $this->assertEquals($data, $configuration->get($uid, 'test', 'it'));
+ }
+
+ /**
+ * Test the configuration get() and set() methods with adapter
+ * @dataProvider dataTests
+ */
+ public function testSetGetWithDB($data)
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(2);
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(true)->once();
+ $configAdapter->shouldReceive('set')->with($uid, 'test', 'it', $data)->andReturn(true)->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ $this->assertTrue($configuration->set($uid, 'test', 'it', $data));
+
+ $this->assertEquals($data, $configuration->get($uid, 'test', 'it'));
+ }
+
+ /**
+ * Test the configuration get() method with wrong value and no db
+ */
+ public function testGetWrongWithoutDB()
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(3);
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ // without refresh
+ $this->assertNull($configuration->get($uid, 'test', 'it'));
+
+ // with default value
+ $this->assertEquals('default', $configuration->get($uid, 'test', 'it', 'default'));
+
+ // with default value and refresh
+ $this->assertEquals('default', $configuration->get($uid, 'test', 'it', 'default', true));
+ }
+
+ /**
+ * Test the configuration get() method with refresh
+ * @dataProvider dataTests
+ */
+ public function testGetWithRefresh($data)
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(4);
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with($uid, 'test', 'it')->andReturn('now')->once();
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(true)->twice();
+ $configAdapter->shouldReceive('get')->with($uid, 'test', 'it')->andReturn($data)->once();
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'not')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with($uid, 'test', 'not')->andReturn('!!')->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ // without refresh
+ $this->assertEquals('now', $configuration->get($uid, 'test', 'it'));
+ // use the cache again
+ $this->assertEquals('now', $configuration->get($uid, 'test', 'it'));
+
+ // with refresh (and load the second value out of the db)
+ $this->assertEquals($data, $configuration->get($uid, 'test', 'it', null, true));
+
+ // without refresh and wrong value and default
+ $this->assertEquals('default', $configuration->get($uid, 'test', 'not', 'default'));
+ }
+
+ /**
+ * Test the configuration get() method with different isLoaded settings
+ * @dataProvider dataTests
+ */
+ public function testGetWithoutLoaded($data)
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(3);
+
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with($uid, 'test', 'it')->andReturn('!!')->once();
+
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(false)->once();
+ $configAdapter->shouldReceive('get')->with($uid, 'test', 'it')->andReturn($data)->once();
+
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(true)->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ // first run is not loaded and no data is found in the DB
+ $this->assertNull($configuration->get($uid, 'test', 'it'));
+
+ // second run is not loaded, but now data is found in the db (overwrote cache)
+ $this->assertEquals($data, $configuration->get($uid,'test', 'it'));
+
+ // third run is loaded and therefore cache is used
+ $this->assertEquals($data, $configuration->get($uid,'test', 'it'));
+ }
+
+ /**
+ * Test the configuration delete() method without adapter
+ * @dataProvider dataTests
+ */
+ public function testDeleteWithoutDB($data)
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(false)->times(4);
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ $this->assertTrue($configuration->set($uid, 'test', 'it', $data));
+ $this->assertEquals($data, $configuration->get($uid, 'test', 'it'));
+
+ $this->assertTrue($configuration->delete($uid, 'test', 'it'));
+ $this->assertNull($configuration->get($uid, 'test', 'it'));
+ }
+
+ /**
+ * Test the configuration delete() method with adapter
+ */
+ public function testDeleteWithDB()
+ {
+ $uid = 234;
+ $configCache = new ConfigCache();
+ $configAdapter = \Mockery::mock(IPConfigAdapter::class);
+ $configAdapter->shouldReceive('isConnected')->andReturn(true)->times(6);
+ $configAdapter->shouldReceive('set')->with($uid, 'test', 'it', 'now')->andReturn(false)->once();
+ $configAdapter->shouldReceive('isLoaded')->with($uid, 'test', 'it')->andReturn(true)->once();
+
+ $configAdapter->shouldReceive('delete')->with($uid, 'test', 'it')->andReturn(false)->once();
+
+ $configAdapter->shouldReceive('delete')->with($uid, 'test', 'second')->andReturn(true)->once();
+ $configAdapter->shouldReceive('delete')->with($uid, 'test', 'third')->andReturn(false)->once();
+ $configAdapter->shouldReceive('delete')->with($uid, 'test', 'quarter')->andReturn(true)->once();
+
+ $configuration = new PConfiguration($configCache, $configAdapter);
+
+ $this->assertFalse($configuration->set($uid, 'test', 'it', 'now'));
+ $this->assertEquals('now', $configuration->get($uid, 'test', 'it'));
+
+ // delete from set
+ $this->assertTrue($configuration->delete($uid, 'test', 'it'));
+ // delete from db only
+ $this->assertTrue($configuration->delete($uid, 'test', 'second'));
+ // no delete
+ $this->assertFalse($configuration->delete($uid, 'test', 'third'));
+ // delete both
+ $this->assertTrue($configuration->delete($uid, 'test', 'quarter'));
+ }
+}
diff --git a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
index 41ccce0b2..73b6835fb 100644
--- a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
+++ b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
@@ -52,9 +52,9 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
$this->db_user = getenv('MYSQL_USERNAME') . getenv('MYSQL_USER');
$this->db_pass = getenv('MYSQL_PASSWORD');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('config', 'php_path', NULL)
+ ->with('config', 'php_path')
->andReturn(false);
$this->mockL10nT();
diff --git a/tests/src/Core/Console/ConfigConsoleTest.php b/tests/src/Core/Console/ConfigConsoleTest.php
index 505c4f794..579b28e02 100644
--- a/tests/src/Core/Console/ConfigConsoleTest.php
+++ b/tests/src/Core/Console/ConfigConsoleTest.php
@@ -32,14 +32,14 @@ class ConfigConsoleTest extends ConsoleTest
}
function testSetGetKeyValue() {
- $this->configCache
+ $this->configMock
->shouldReceive('set')
->with('config', 'test', 'now')
->andReturn(true)
->once();
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('config', 'test', NULL)
+ ->with('config', 'test')
->andReturn('now')
->twice();
@@ -50,9 +50,9 @@ class ConfigConsoleTest extends ConsoleTest
$txt = $this->dumpExecute($console);
$this->assertEquals("config.test <= now\n", $txt);
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('config', 'test', null)
+ ->with('config', 'test')
->andReturn('now')
->once();
@@ -62,9 +62,9 @@ class ConfigConsoleTest extends ConsoleTest
$txt = $this->dumpExecute($console);
$this->assertEquals("config.test => now\n", $txt);
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('config', 'test', null)
+ ->with('config', 'test')
->andReturn(null)
->once();
@@ -77,9 +77,9 @@ class ConfigConsoleTest extends ConsoleTest
function testSetArrayValue() {
$testArray = [1, 2, 3];
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('config', 'test', null)
+ ->with('config', 'test')
->andReturn($testArray)
->once();
@@ -105,9 +105,9 @@ class ConfigConsoleTest extends ConsoleTest
}
function testVerbose() {
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('test', 'it', null)
+ ->with('test', 'it')
->andReturn('now')
->once();
$console = new Config($this->consoleArgv);
@@ -133,14 +133,14 @@ CONF;
}
function testUnableToSet() {
- $this->configCache
+ $this->configMock
->shouldReceive('set')
->with('test', 'it', 'now')
->andReturn(false)
->once();
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('test', 'it', NULL)
+ ->with('test', 'it')
->andReturn(NULL)
->once();
$console = new Config();
diff --git a/tests/src/Core/Console/ConsoleTest.php b/tests/src/Core/Console/ConsoleTest.php
index 905d214ca..4f7acc9c4 100644
--- a/tests/src/Core/Console/ConsoleTest.php
+++ b/tests/src/Core/Console/ConsoleTest.php
@@ -29,8 +29,7 @@ abstract class ConsoleTest extends MockedTest
Intercept::setUp();
$this->setUpVfsDir();
- $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
- $this->mockApp($this->root, $configMock);
+ $this->mockApp($this->root);
}
/**
diff --git a/tests/src/Core/Lock/LockTest.php b/tests/src/Core/Lock/LockTest.php
index ab8e1b2f2..6dc170e51 100644
--- a/tests/src/Core/Lock/LockTest.php
+++ b/tests/src/Core/Lock/LockTest.php
@@ -27,8 +27,7 @@ abstract class LockTest extends MockedTest
{
// Reusable App object
$this->setUpVfsDir();
- $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
- $this->mockApp($this->root, $configMock);
+ $this->mockApp($this->root);
$this->app
->shouldReceive('getHostname')
->andReturn('friendica.local');
diff --git a/tests/src/Core/Lock/MemcacheCacheLockDriverTest.php b/tests/src/Core/Lock/MemcacheCacheLockDriverTest.php
index 46f29f52e..ad20f5bfd 100644
--- a/tests/src/Core/Lock/MemcacheCacheLockDriverTest.php
+++ b/tests/src/Core/Lock/MemcacheCacheLockDriverTest.php
@@ -13,14 +13,14 @@ class MemcacheCacheLockDriverTest extends LockTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcache_host', NULL)
+ ->with('system', 'memcache_host')
->andReturn('localhost');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcache_port', NULL)
+ ->with('system', 'memcache_port')
->andReturn(11211);
return new CacheLockDriver(CacheDriverFactory::create('memcache'));
diff --git a/tests/src/Core/Lock/MemcachedCacheLockDriverTest.php b/tests/src/Core/Lock/MemcachedCacheLockDriverTest.php
index 72271c98b..a5bdeaedb 100644
--- a/tests/src/Core/Lock/MemcachedCacheLockDriverTest.php
+++ b/tests/src/Core/Lock/MemcachedCacheLockDriverTest.php
@@ -13,9 +13,9 @@ class MemcachedCacheLockDriverTest extends LockTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'memcached_hosts', NULL)
+ ->with('system', 'memcached_hosts')
->andReturn([0 => 'localhost, 11211']);
return new CacheLockDriver(CacheDriverFactory::create('memcached'));
diff --git a/tests/src/Core/Lock/RedisCacheLockDriverTest.php b/tests/src/Core/Lock/RedisCacheLockDriverTest.php
index 0c9deea16..5f047bc66 100644
--- a/tests/src/Core/Lock/RedisCacheLockDriverTest.php
+++ b/tests/src/Core/Lock/RedisCacheLockDriverTest.php
@@ -13,14 +13,14 @@ class RedisCacheLockDriverTest extends LockTest
{
protected function getInstance()
{
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'redis_host', NULL)
+ ->with('system', 'redis_host')
->andReturn('localhost');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'redis_port', NULL)
+ ->with('system', 'redis_port')
->andReturn(null);
return new CacheLockDriver(CacheDriverFactory::create('redis'));
diff --git a/tests/src/Core/Lock/SemaphoreLockDriverTest.php b/tests/src/Core/Lock/SemaphoreLockDriverTest.php
index c2b941457..a37fbffbe 100644
--- a/tests/src/Core/Lock/SemaphoreLockDriverTest.php
+++ b/tests/src/Core/Lock/SemaphoreLockDriverTest.php
@@ -12,9 +12,9 @@ class SemaphoreLockDriverTest extends LockTest
$this->app->shouldReceive('getHostname')->andReturn('friendica.local');
- $this->configCache
+ $this->configMock
->shouldReceive('get')
- ->with('system', 'temppath', NULL)
+ ->with('system', 'temppath')
->andReturn('/tmp/');
}
diff --git a/tests/src/Database/DBATest.php b/tests/src/Database/DBATest.php
index f2a5cc555..e8b9c68b1 100644
--- a/tests/src/Database/DBATest.php
+++ b/tests/src/Database/DBATest.php
@@ -3,6 +3,7 @@ namespace Friendica\Test\Database;
use Friendica\App;
use Friendica\Core\Config;
+use Friendica\Core\Config\Cache;
use Friendica\Database\DBA;
use Friendica\Factory;
use Friendica\Test\DatabaseTest;
@@ -13,11 +14,14 @@ class DBATest extends DatabaseTest
public function setUp()
{
$basedir = BasePath::create(dirname(__DIR__) . '/../../');
- $configLoader = new Config\ConfigCacheLoader($basedir);
- $config = Factory\ConfigFactory::createCache($configLoader);
+ $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $configCache = Factory\ConfigFactory::createCache($configLoader);
+ $profiler = Factory\ProfilerFactory::create($configCache);
+ Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ $config = Factory\ConfigFactory::createConfig($configCache);
+ Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, false);
- $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
+ $this->app = new App($config, $logger, $profiler, false);
parent::setUp();
diff --git a/tests/src/Database/DBStructureTest.php b/tests/src/Database/DBStructureTest.php
index bc50a0a69..325ad4e5e 100644
--- a/tests/src/Database/DBStructureTest.php
+++ b/tests/src/Database/DBStructureTest.php
@@ -3,7 +3,7 @@
namespace Friendica\Test\Database;
use Friendica\App;
-use Friendica\Core\Config;
+use Friendica\Core\Config\Cache;
use Friendica\Database\DBStructure;
use Friendica\Factory;
use Friendica\Test\DatabaseTest;
@@ -14,11 +14,14 @@ class DBStructureTest extends DatabaseTest
public function setUp()
{
$basedir = BasePath::create(dirname(__DIR__) . '/../../');
- $configLoader = new Config\ConfigCacheLoader($basedir);
- $config = Factory\ConfigFactory::createCache($configLoader);
+ $configLoader = new Cache\ConfigCacheLoader($basedir);
+ $configCache = Factory\ConfigFactory::createCache($configLoader);
+ $profiler = Factory\ProfilerFactory::create($configCache);
+ Factory\DBFactory::init($configCache, $profiler, $_SERVER);
+ $config = Factory\ConfigFactory::createConfig($configCache);
+ Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create('test', $config);
- $this->app = new App($config, $logger, false);
- $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
+ $this->app = new App($config, $logger, $profiler, false);
parent::setUp();
}
diff --git a/tests/src/Util/ProfilerTest.php b/tests/src/Util/ProfilerTest.php
new file mode 100644
index 000000000..f242fd43c
--- /dev/null
+++ b/tests/src/Util/ProfilerTest.php
@@ -0,0 +1,181 @@
+logger = \Mockery::mock('Psr\Log\LoggerInterface');
+ }
+
+ /**
+ * Test the Profiler setup
+ */
+ public function testSetUp()
+ {
+ $profiler = new Profiler(true, true);
+ }
+
+ /**
+ * A dataset for different profiling settings
+ * @return array
+ */
+ public function dataPerformance()
+ {
+ return [
+ 'database' => [
+ 'timestamp' => time(),
+ 'name' => 'database',
+ 'functions' => ['test', 'it'],
+ ],
+ 'database_write' => [
+ 'timestamp' => time(),
+ 'name' => 'database_write',
+ 'functions' => ['test', 'it2'],
+ ],
+ 'cache' => [
+ 'timestamp' => time(),
+ 'name' => 'cache',
+ 'functions' => ['test', 'it3'],
+ ],
+ 'cache_write' => [
+ 'timestamp' => time(),
+ 'name' => 'cache_write',
+ 'functions' => ['test', 'it4'],
+ ],
+ 'network' => [
+ 'timestamp' => time(),
+ 'name' => 'network',
+ 'functions' => ['test', 'it5'],
+ ],
+ 'file' => [
+ 'timestamp' => time(),
+ 'name' => 'file',
+ 'functions' => [],
+ ],
+ 'rendering' => [
+ 'timestamp' => time(),
+ 'name' => 'rendering',
+ 'functions' => ['test', 'it7'],
+ ],
+ 'parser' => [
+ 'timestamp' => time(),
+ 'name' => 'parser',
+ 'functions' => ['test', 'it8'],
+ ],
+ 'marktime' => [
+ 'timestamp' => time(),
+ 'name' => 'parser',
+ 'functions' => ['test'],
+ ],
+ // This one isn't set during reset
+ 'unknown' => [
+ 'timestamp' => time(),
+ 'name' => 'unknown',
+ 'functions' => ['test'],
+ ],
+ ];
+ }
+
+ /**
+ * Test the Profiler savetimestamp
+ * @dataProvider dataPerformance
+ */
+ public function testSaveTimestamp($timestamp, $name, array $functions)
+ {
+ $profiler = new Profiler(true, true);
+
+ foreach ($functions as $function) {
+ $profiler->saveTimestamp($timestamp, $name, $function);
+ }
+
+ $this->assertGreaterThanOrEqual(0, $profiler->get($name));
+ }
+
+ /**
+ * Test the Profiler reset
+ * @dataProvider dataPerformance
+ */
+ public function testReset($timestamp, $name, array $functions)
+ {
+ $profiler = new Profiler(true, true);
+
+ $profiler->saveTimestamp($timestamp, $name);
+ $profiler->reset();
+
+ $this->assertEquals(0, $profiler->get($name));
+ }
+
+ public function dataBig()
+ {
+ return [
+ 'big' => [
+ 'data' => [
+ 'database' => [
+ 'timestamp' => time(),
+ 'name' => 'database',
+ 'functions' => ['test', 'it'],
+ ],
+ 'database_write' => [
+ 'timestamp' => time(),
+ 'name' => 'database_write',
+ 'functions' => ['test', 'it2'],
+ ],
+ 'cache' => [
+ 'timestamp' => time(),
+ 'name' => 'cache',
+ 'functions' => ['test', 'it3'],
+ ],
+ 'cache_write' => [
+ 'timestamp' => time(),
+ 'name' => 'cache_write',
+ 'functions' => ['test', 'it4'],
+ ],
+ 'network' => [
+ 'timestamp' => time(),
+ 'name' => 'network',
+ 'functions' => ['test', 'it5'],
+ ],
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Test the output of the Profiler
+ * @dataProvider dataBig
+ */
+ public function testSaveLog($data)
+ {
+ $this->logger
+ ->shouldReceive('info')
+ ->with('test', \Mockery::any())
+ ->once();
+ $this->logger
+ ->shouldReceive('info')
+ ->once();
+
+ $profiler = new Profiler(true, true);
+
+ foreach ($data as $perf => $items) {
+ foreach ($items['functions'] as $function) {
+ $profiler->saveTimestamp($items['timestamp'], $items['name'], $function);
+ }
+ }
+
+ $profiler->saveLog($this->logger, 'test');
+ }
+}