mirror of
https://github.com/friendica/friendica
synced 2024-12-22 18:40:17 +00:00
Merge pull request #6641 from nupplaphil/config_followup
Config FollowUp
This commit is contained in:
commit
256e845c5d
75 changed files with 2606 additions and 1368 deletions
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
52
composer.lock
generated
52
composer.lock
generated
|
@ -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"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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) {
|
||||
/*
|
||||
|
|
12
index.php
12
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();
|
||||
|
|
199
src/App.php
199
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 <head> 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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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('/<a(.*?)href="#/is', '<a$1href="' . ltrim($_SERVER['REQUEST_URI'], '/') . '#', $html);
|
||||
|
||||
self::getApp()->saveTimestamp($stamp1, "parser");
|
||||
self::getApp()->getProfiler()->saveTimestamp($stamp1, "parser", System::callstack());
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
abstract class AbstractDbaConfigAdapter
|
||||
{
|
||||
/** @var bool */
|
||||
protected $connected = true;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->connected = DBA::connected();
|
||||
}
|
||||
|
||||
public function isConnected()
|
||||
{
|
||||
return $this->connected;
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -9,51 +9,48 @@ namespace Friendica\Core\Config;
|
|||
interface IConfigAdapter
|
||||
{
|
||||
/**
|
||||
* Loads all configuration values into a cached storage.
|
||||
* Loads all configuration values and returns the loaded category as an array.
|
||||
*
|
||||
* @param string $cat The category of the configuration values to load
|
||||
*
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function load($cat = "config");
|
||||
|
||||
/**
|
||||
* Get a particular user's config variable given the category name
|
||||
* Get a particular system-wide config variable given the category name
|
||||
* ($family) and a key.
|
||||
*
|
||||
* @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 $cat The category of the configuration value
|
||||
* @param string $key The configuration key to query
|
||||
*
|
||||
* @return mixed Stored value or null if it does not exist
|
||||
* @return mixed Stored value or "!<unset>!" 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);
|
||||
}
|
|
@ -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 "!<unset>!" 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);
|
||||
}
|
135
src/Core/Config/Adapter/JITConfigAdapter.php
Normal file
135
src/Core/Config/Adapter/JITConfigAdapter.php
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
* JustInTime Configuration Adapter
|
||||
*
|
||||
* Default Config Adapter. Provides the best performance for pages loading few configuration variables.
|
||||
*
|
||||
* @author Hypolite Petovan <hypolite@mrpetovan.com>
|
||||
*/
|
||||
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 '!<unset>!';
|
||||
}
|
||||
|
||||
$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 '!<unset>!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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];
|
||||
}
|
||||
}
|
138
src/Core/Config/Adapter/JITPConfigAdapter.php
Normal file
138
src/Core/Config/Adapter/JITPConfigAdapter.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
* JustInTime User Configuration Adapter
|
||||
*
|
||||
* Default PConfig Adapter. Provides the best performance for pages loading few configuration variables.
|
||||
*
|
||||
* @author Hypolite Petovan <hypolite@mrpetovan.com>
|
||||
*/
|
||||
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 = "!<unset>!";
|
||||
}
|
||||
DBA::close($pconfigs);
|
||||
|
||||
return [$cat => $return];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($uid, $cat, $key)
|
||||
{
|
||||
if (!$this->isConnected()) {
|
||||
return '!<unset>!';
|
||||
}
|
||||
|
||||
$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 '!<unset>!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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];
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
use Exception;
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
|
@ -16,60 +15,28 @@ class PreloadConfigAdapter extends AbstractDbaConfigAdapter implements IConfigAd
|
|||
{
|
||||
private $config_loaded = false;
|
||||
|
||||
/**
|
||||
* @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();
|
||||
$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 '!<unset>!';
|
||||
}
|
||||
|
||||
$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 '!<unset>!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Adapter;
|
||||
|
||||
use Exception;
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
|
@ -12,23 +11,17 @@ use Friendica\Database\DBA;
|
|||
*
|
||||
* @author Hypolite Petovan <hypolite@mrpetovan.com>
|
||||
*/
|
||||
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 '!<unset>!';
|
||||
}
|
||||
|
||||
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 '!<unset>!';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Cache;
|
||||
|
||||
/**
|
||||
* The Friendica config cache for the application
|
||||
|
@ -11,6 +11,9 @@ namespace Friendica\Core\Config;
|
|||
*/
|
||||
class ConfigCache implements IConfigCache, IPConfigCache
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
|
@ -18,24 +21,28 @@ class ConfigCache implements IConfigCache, IPConfigCache
|
|||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->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 '!<unset>!';
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($cat, $key = null)
|
||||
{
|
||||
return (isset($this->config[$cat][$key]) && $this->config[$cat][$key] !== '!<unset>!') ||
|
||||
($key == null && isset($this->config[$cat]) && $this->config[$cat] !== '!<unset>!' && is_array($this->config[$cat]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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] !== '!<unset>!') ||
|
||||
($key == null && isset($this->config[$uid][$cat]) && $this->config[$uid][$cat] !== '!<unset>!' && 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 '!<unset>!';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
namespace Friendica\Core\Config\Cache;
|
||||
|
||||
use Friendica\Core\Addon;
|
||||
|
||||
|
@ -40,13 +40,13 @@ class ConfigCacheLoader
|
|||
// Setting at least the basepath we know
|
||||
$config->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);
|
||||
}
|
||||
|
||||
/**
|
65
src/Core/Config/Cache/IConfigCache.php
Normal file
65
src/Core/Config/Cache/IConfigCache.php
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config\Cache;
|
||||
|
||||
/**
|
||||
* The interface for a system-wide ConfigCache
|
||||
*/
|
||||
interface IConfigCache
|
||||
{
|
||||
/**
|
||||
* Tries to load the specified configuration array into the 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
|
||||
*/
|
||||
function load(array $config, $overwrite = false);
|
||||
|
||||
/**
|
||||
* Gets a value from the config cache.
|
||||
*
|
||||
* @param string $cat Config category
|
||||
* @param string $key Config key
|
||||
*
|
||||
* @return mixed Returns the value of the Config entry or '!<unset>!' 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();
|
||||
}
|
70
src/Core/Config/Cache/IPConfigCache.php
Normal file
70
src/Core/Config/Cache/IPConfigCache.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config\Cache;
|
||||
|
||||
/**
|
||||
* The interface for a user-specific config cache
|
||||
*/
|
||||
interface IPConfigCache
|
||||
{
|
||||
/**
|
||||
* Tries to load the specified configuration array into the user specific config array.
|
||||
* Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
|
||||
*
|
||||
* @param int $uid
|
||||
* @param array $config
|
||||
*/
|
||||
function loadP($uid, array $config);
|
||||
|
||||
/**
|
||||
* Retrieves a value from the user config cache
|
||||
*
|
||||
* @param int $uid User Id
|
||||
* @param string $cat Config category
|
||||
* @param string $key Config key
|
||||
*
|
||||
* @return string The value of the config entry or '!<unset>!' 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();
|
||||
}
|
153
src/Core/Config/Configuration.php
Normal file
153
src/Core/Config/Configuration.php
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
/**
|
||||
* This class is responsible for all system-wide configuration values in Friendica
|
||||
* There are two types of storage
|
||||
* - The Config-Files (loaded into the FileCache @see Cache\IConfigCache )
|
||||
* - The Config-DB-Table (per Config-DB-adapter @see Adapter\IConfigAdapter )
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* @var Cache\IConfigCache
|
||||
*/
|
||||
private $configCache;
|
||||
|
||||
/**
|
||||
* @var Adapter\IConfigAdapter
|
||||
*/
|
||||
private $configAdapter;
|
||||
|
||||
/**
|
||||
* @param Cache\IConfigCache $configCache The configuration cache (based on the config-files)
|
||||
* @param Adapter\IConfigAdapter $configAdapter The configuration DB-backend
|
||||
*/
|
||||
public function __construct(Cache\IConfigCache $configCache, Adapter\IConfigAdapter $configAdapter)
|
||||
{
|
||||
$this->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 !== '!<unset>!') {
|
||||
$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;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
/**
|
||||
* The interface for a system-wide ConfigCache
|
||||
*/
|
||||
interface IConfigCache
|
||||
{
|
||||
/**
|
||||
* @param string $cat Config category
|
||||
* @param string $key Config key
|
||||
* @param mixed $default Default value if it isn't set
|
||||
*
|
||||
* @return mixed Returns the value of the Config entry
|
||||
*/
|
||||
function get($cat, $key = null, $default = 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
|
||||
*/
|
||||
function delete($cat, $key);
|
||||
|
||||
function getAll();
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
/**
|
||||
* The interface for a user-specific config cache
|
||||
*/
|
||||
interface IPConfigCache
|
||||
{
|
||||
/**
|
||||
* Retrieves a value from the user config cache
|
||||
*
|
||||
* @param int $uid User Id
|
||||
* @param string $cat Config category
|
||||
* @param string $key Config key
|
||||
* @param mixed $default Default value if key isn't set
|
||||
*
|
||||
* @return string The value of the config entry
|
||||
*/
|
||||
function getP($uid, $cat, $key = null, $default = 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
|
||||
*/
|
||||
function deleteP($uid, $cat, $key);
|
||||
|
||||
function getAll();
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
<?php
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
* JustInTime Configuration Adapter
|
||||
*
|
||||
* Default Config Adapter. Provides the best performance for pages loading few configuration variables.
|
||||
*
|
||||
* @author Hypolite Petovan <hypolite@mrpetovan.com>
|
||||
*/
|
||||
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] === '!<unset>!') {
|
||||
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] = '!<unset>!';
|
||||
$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;
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
<?php
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
use Friendica\Database\DBA;
|
||||
|
||||
/**
|
||||
* JustInTime User Configuration Adapter
|
||||
*
|
||||
* Default PConfig Adapter. Provides the best performance for pages loading few configuration variables.
|
||||
*
|
||||
* @author Hypolite Petovan <hypolite@mrpetovan.com>
|
||||
*/
|
||||
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, "!<unset>!");
|
||||
}
|
||||
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) === '!<unset>!') {
|
||||
return $default_value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->configCache->getP($uid, $cat, $k) !== null) {
|
||||
if ($this->configCache->getP($uid, $cat, $k) === '!<unset>!') {
|
||||
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, '!<unset>!');
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
149
src/Core/Config/PConfiguration.php
Normal file
149
src/Core/Config/PConfiguration.php
Normal file
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Core\Config;
|
||||
|
||||
/**
|
||||
* This class is responsible for the user-specific configuration values in Friendica
|
||||
* The values are set through the Config-DB-Table (per Config-DB-adapter @see Adapter\IPConfigAdapter )
|
||||
*
|
||||
* The configuration cache (@see Cache\IPConfigCache ) is used for temporary caching of database calls. This will
|
||||
* increase the performance.
|
||||
*/
|
||||
class PConfiguration
|
||||
{
|
||||
/**
|
||||
* @var Cache\IPConfigCache
|
||||
*/
|
||||
private $configCache;
|
||||
|
||||
/**
|
||||
* @var Adapter\IPConfigAdapter
|
||||
*/
|
||||
private $configAdapter;
|
||||
|
||||
/**
|
||||
* @param Cache\IPConfigCache $configCache The configuration cache
|
||||
* @param Adapter\IPConfigAdapter $configAdapter The configuration DB-backend
|
||||
*/
|
||||
public function __construct(Cache\IPConfigCache $configCache, Adapter\IPConfigAdapter $configAdapter)
|
||||
{
|
||||
$this->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 !== '!<unset>!') {
|
||||
$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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
58
src/Factory/DBFactory.php
Normal file
58
src/Factory/DBFactory.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Factory;
|
||||
|
||||
use Friendica\Core\Config\Cache;
|
||||
use Friendica\Database;
|
||||
use Friendica\Util\Profiler;
|
||||
|
||||
class DBFactory
|
||||
{
|
||||
/**
|
||||
* Initialize the DBA connection
|
||||
*
|
||||
* @param Cache\IConfigCache $configCache The configuration cache
|
||||
* @param Profiler $profiler The profiler
|
||||
* @param array $server The $_SERVER variables
|
||||
*
|
||||
* @throws \Exception if connection went bad
|
||||
*/
|
||||
public static function init(Cache\IConfigCache $configCache, Profiler $profiler, array $server)
|
||||
{
|
||||
if (Database\DBA::connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db_host = $configCache->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);
|
||||
}
|
||||
}
|
37
src/Factory/DependencyFactory.php
Normal file
37
src/Factory/DependencyFactory.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Factory;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Cache;
|
||||
use Friendica\Factory;
|
||||
use Friendica\Util\BasePath;
|
||||
|
||||
class DependencyFactory
|
||||
{
|
||||
/**
|
||||
* Setting all default-dependencies of a friendica execution
|
||||
*
|
||||
* @param string $channel The channel of this execution
|
||||
* @param string $directory The base directory
|
||||
* @param bool $isBackend True, if it's a backend execution, otherwise false (Default true)
|
||||
*
|
||||
* @return App The application
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function setUp($channel, $directory, $isBackend = true)
|
||||
{
|
||||
$basedir = BasePath::create($directory, $_SERVER);
|
||||
$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);
|
||||
// needed to call PConfig::init()
|
||||
Factory\ConfigFactory::createPConfig($configCache);
|
||||
$logger = Factory\LoggerFactory::create($channel, $config);
|
||||
|
||||
return new App($config, $logger, $profiler, $isBackend);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace Friendica\Factory;
|
||||
|
||||
use Friendica\Core\Config\ConfigCache;
|
||||
use Friendica\Core\Config\Configuration;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
use Friendica\Util\Logger\FriendicaDevelopHandler;
|
||||
use Friendica\Util\Logger\FriendicaIntrospectionProcessor;
|
||||
use Friendica\Util\Profiler;
|
||||
use Monolog;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
@ -20,29 +22,32 @@ class LoggerFactory
|
|||
/**
|
||||
* Creates a new PSR-3 compliant logger instances
|
||||
*
|
||||
* @param string $channel The channel of the logger instance
|
||||
* @param ConfigCache $config The config
|
||||
* @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 create($channel, ConfigCache $config = null)
|
||||
public static function create($channel, Configuration $config)
|
||||
{
|
||||
$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->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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
26
src/Factory/ProfilerFactory.php
Normal file
26
src/Factory/ProfilerFactory.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Factory;
|
||||
|
||||
use Friendica\Core\Config\Cache\IConfigCache;
|
||||
use Friendica\Util\Profiler;
|
||||
|
||||
class ProfilerFactory
|
||||
{
|
||||
/**
|
||||
* Creates a Profiler for the current execution
|
||||
*
|
||||
* @param IConfigCache $configCache The configuration cache
|
||||
*
|
||||
* @return Profiler
|
||||
*/
|
||||
public static function create(IConfigCache $configCache)
|
||||
{
|
||||
$enabled = $configCache->get('system', 'profiler');
|
||||
$enabled = isset($enabled) && $enabled !== '!<unset>!';
|
||||
$renderTime = $configCache->get('rendertime', 'callstack');
|
||||
$renderTime = isset($renderTime) && $renderTime !== '!<unset>!';
|
||||
|
||||
return new Profiler($enabled, $renderTime);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
239
src/Util/Profiler.php
Normal file
239
src/Util/Profiler.php
Normal file
|
@ -0,0 +1,239 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Util;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* A class to store profiling data
|
||||
* It can handle different logging data for specific functions or global performance measures
|
||||
*
|
||||
* It stores the data as log entries (@see LoggerInterface )
|
||||
*/
|
||||
class Profiler implements ContainerInterface
|
||||
{
|
||||
/**
|
||||
* @var array The global performance array
|
||||
*/
|
||||
private $performance;
|
||||
/**
|
||||
* @var array The function specific callstack
|
||||
*/
|
||||
private $callstack;
|
||||
/**
|
||||
* @var bool True, if the Profiler is enabled
|
||||
*/
|
||||
private $enabled;
|
||||
/**
|
||||
* @var bool True, if the Profiler should measure the whole rendertime including functions
|
||||
*/
|
||||
private $rendertime;
|
||||
|
||||
/**
|
||||
* @param bool $enabled True, if the Profiler is enabled
|
||||
* @param bool $renderTime True, if the Profiler should measure the whole rendertime including functions
|
||||
*/
|
||||
public function __construct($enabled = false, $renderTime = false)
|
||||
{
|
||||
$this->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]);
|
||||
}
|
||||
}
|
|
@ -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'),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\Core\Config;
|
||||
namespace Friendica\Test\Core\Config\Cache;
|
||||
|
||||
use Friendica\Core\Config\ConfigCache;
|
||||
use Friendica\Core\Config\ConfigCacheLoader;
|
||||
use Friendica\Core\Config\Cache\ConfigCache;
|
||||
use Friendica\Core\Config\Cache\ConfigCacheLoader;
|
||||
use Friendica\Test\MockedTest;
|
||||
use Friendica\Test\Util\VFSTrait;
|
||||
use org\bovigo\vfs\vfsStream;
|
||||
|
@ -59,6 +59,7 @@ class ConfigCacheLoaderTest extends MockedTest
|
|||
$this->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 .
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\Core\Config;
|
||||
namespace Friendica\Test\Core\Config\Cache;
|
||||
|
||||
use Friendica\Core\Config\ConfigCache;
|
||||
use Friendica\Core\Config\Cache\ConfigCache;
|
||||
use Friendica\Test\MockedTest;
|
||||
|
||||
class ConfigCacheTest extends MockedTest
|
||||
|
@ -48,7 +48,7 @@ class ConfigCacheTest extends MockedTest
|
|||
public function testLoadConfigArray($data)
|
||||
{
|
||||
$configCache = new ConfigCache();
|
||||
$configCache->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('!<unset>!', $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'));
|
||||
}
|
||||
}
|
276
tests/src/Core/Config/ConfigurationTest.php
Normal file
276
tests/src/Core/Config/ConfigurationTest.php
Normal file
|
@ -0,0 +1,276 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\Core\Config;
|
||||
|
||||
use Friendica\Core\Config\Adapter\IConfigAdapter;
|
||||
use Friendica\Core\Config\Cache\ConfigCache;
|
||||
use Friendica\Core\Config\Cache\IConfigCache;
|
||||
use Friendica\Core\Config\Configuration;
|
||||
use Friendica\Test\MockedTest;
|
||||
|
||||
class ConfigurationTest extends MockedTest
|
||||
{
|
||||
public function dataTests()
|
||||
{
|
||||
return [
|
||||
'string' => ['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 '!<unset>!' and not null for a non existing value
|
||||
$this->assertEquals('!<unset>!', $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('!<unset>!')->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('!<unset>!', $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('!<unset>!')->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('!<unset>!', $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());
|
||||
}
|
||||
}
|
247
tests/src/Core/Config/PConfigurationTest.php
Normal file
247
tests/src/Core/Config/PConfigurationTest.php
Normal file
|
@ -0,0 +1,247 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\Core\Config;
|
||||
|
||||
use Friendica\Core\Config\Adapter\IPConfigAdapter;
|
||||
use Friendica\Core\Config\Cache\ConfigCache;
|
||||
use Friendica\Core\Config\PConfiguration;
|
||||
use Friendica\Test\MockedTest;
|
||||
|
||||
class PConfigurationTest extends MockedTest
|
||||
{
|
||||
public function dataTests()
|
||||
{
|
||||
return [
|
||||
'string' => ['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('!<unset>!')->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('!<unset>!')->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'));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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/');
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
181
tests/src/Util/ProfilerTest.php
Normal file
181
tests/src/Util/ProfilerTest.php
Normal file
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
namespace src\Util;
|
||||
|
||||
use Friendica\Test\MockedTest;
|
||||
use Friendica\Util\Profiler;
|
||||
use Mockery\MockInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ProfilerTest extends MockedTest
|
||||
{
|
||||
/**
|
||||
* @var LoggerInterface|MockInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->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');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue