diff --git a/bin/auth_ejabberd.php b/bin/auth_ejabberd.php index bf6d069d12..ba3a9b8dd1 100755 --- a/bin/auth_ejabberd.php +++ b/bin/auth_ejabberd.php @@ -51,7 +51,10 @@ chdir($directory); require dirname(__DIR__) . '/vendor/autoload.php'; -$a = Factory\DependencyFactory::setUp('auth_ejabbered', dirname(__DIR__)); +$dice = new \Dice\Dice(); +$dice = $dice->addRules(include __DIR__ . '/../static/dependencies.config.php'); + +$a = Factory\DependencyFactory::setUp('auth_ejabbered', $dice); if ($a->getMode()->isNormal()) { $oAuth = new ExAuth(); diff --git a/bin/console.php b/bin/console.php index 410eabda09..6fa804fb98 100755 --- a/bin/console.php +++ b/bin/console.php @@ -5,7 +5,10 @@ require dirname(__DIR__) . '/vendor/autoload.php'; use Friendica\Factory; -$a = Factory\DependencyFactory::setUp('console', dirname(__DIR__)); +$dice = new \Dice\Dice(); +$dice = $dice->addRules(include __DIR__ . '/../static/dependencies.config.php'); + +$a = Factory\DependencyFactory::setUp('console', $dice); \Friendica\BaseObject::setApp($a); (new Friendica\Core\Console($argv))->execute(); diff --git a/bin/daemon.php b/bin/daemon.php index 9051e0e6c3..1b0a7edb3c 100755 --- a/bin/daemon.php +++ b/bin/daemon.php @@ -32,7 +32,10 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) { require dirname(__DIR__) . '/vendor/autoload.php'; -$a = Factory\DependencyFactory::setUp('daemon', dirname(__DIR__)); +$dice = new \Dice\Dice(); +$dice = $dice->addRules(include __DIR__ . '/../static/dependencies.config.php'); + +$a = Factory\DependencyFactory::setUp('daemon', $dice); if ($a->getMode()->isInstall()) { die("Friendica isn't properly installed yet.\n"); diff --git a/bin/worker.php b/bin/worker.php index 2b5915f471..f4b0120268 100755 --- a/bin/worker.php +++ b/bin/worker.php @@ -30,7 +30,10 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) { require dirname(__DIR__) . '/vendor/autoload.php'; -$a = Factory\DependencyFactory::setUp('worker', dirname(__DIR__)); +$dice = new \Dice\Dice(); +$dice = $dice->addRules(include __DIR__ . '/../static/dependencies.config.php'); + +$a = Factory\DependencyFactory::setUp('worker', $dice); // Check the database structure and possibly fixes it Update::check($a->getBasePath(), true, $a->getMode()); diff --git a/index.php b/index.php index ddc851cd4e..7b7146aeb2 100644 --- a/index.php +++ b/index.php @@ -12,7 +12,9 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) { require __DIR__ . '/vendor/autoload.php'; -$a = Factory\DependencyFactory::setUp('index', __DIR__, false); +$dice = new \Dice\Dice(); +$dice = $dice->addRules(include __DIR__ . '/static/dependencies.config.php'); + +$a = Factory\DependencyFactory::setUp('index', $dice, false); $a->runFrontend(); - diff --git a/src/App.php b/src/App.php index 1475d60df8..58ab451b37 100644 --- a/src/App.php +++ b/src/App.php @@ -376,12 +376,10 @@ class App $this->getMode()->determine($this->getBasePath()); if ($this->getMode()->has(App\Mode::DBAVAILABLE)) { - $this->profiler->update( - $this->config->get('system', 'profiler', false), - $this->config->get('rendertime', 'callstack', false)); + $this->profiler->update($this->config); Core\Hook::loadHooks(); - $loader = new ConfigFileLoader($this->getBasePath(), $this->mode); + $loader = new ConfigFileLoader($this->getBasePath()); Core\Hook::callAll('load_config', $loader); } diff --git a/src/App/Mode.php b/src/App/Mode.php index 8d82ffc0b4..7f5c31c4bb 100644 --- a/src/App/Mode.php +++ b/src/App/Mode.php @@ -2,8 +2,9 @@ namespace Friendica\App; -use Friendica\Core\Config; -use Friendica\Database\DBA; +use Friendica\Core\Config\Cache\ConfigCache; +use Friendica\Database\Database; +use Friendica\Util\BasePath; /** * Mode of the current Friendica Node @@ -28,10 +29,22 @@ class Mode */ private $basepath; - public function __construct($basepath = '') + /** + * @var Database + */ + private $database; + + /** + * @var ConfigCache + */ + private $configCache; + + public function __construct(BasePath $basepath, Database $database, ConfigCache $configCache) { - $this->basepath = $basepath; - $this->mode = 0; + $this->basepath = $basepath->getPath(); + $this->database = $database; + $this->configCache = $configCache; + $this->mode = 0; } /** @@ -41,42 +54,48 @@ class Mode * - App::MODE_MAINTENANCE: The maintenance mode has been set * - App::MODE_NORMAL : Normal run with all features enabled * - * @param string $basepath the Basepath of the Application + * @param string $basePath the Basepath of the Application + * + * @return Mode returns itself + * * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function determine($basepath = null) + public function determine($basePath = null) { - if (!empty($basepath)) { - $this->basepath = $basepath; + if (!empty($basePath)) { + $this->basepath = $basePath; } $this->mode = 0; if (!file_exists($this->basepath . '/config/local.config.php') - && !file_exists($this->basepath . '/config/local.ini.php') - && !file_exists($this->basepath . '/.htconfig.php')) { - return; + && !file_exists($this->basepath . '/config/local.ini.php') + && !file_exists($this->basepath . '/.htconfig.php')) { + return $this; } $this->mode |= Mode::LOCALCONFIGPRESENT; - if (!DBA::connected()) { - return; + if (!$this->database->connected()) { + return $this; } $this->mode |= Mode::DBAVAILABLE; - if (DBA::fetchFirst("SHOW TABLES LIKE 'config'") === false) { - return; + if ($this->database->fetchFirst("SHOW TABLES LIKE 'config'") === false) { + return $this; } $this->mode |= Mode::DBCONFIGAVAILABLE; - if (Config::get('system', 'maintenance')) { - return; + if ($this->configCache->get('system', 'maintenance') || + $this->database->selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'maintenance'])) { + return $this; } $this->mode |= Mode::MAINTENANCEDISABLED; + + return $this; } /** @@ -100,7 +119,7 @@ class Mode public function isInstall() { return !$this->has(Mode::LOCALCONFIGPRESENT) || - !$this->has(MODE::DBCONFIGAVAILABLE); + !$this->has(MODE::DBCONFIGAVAILABLE); } /** @@ -111,8 +130,8 @@ class Mode public function isNormal() { return $this->has(Mode::LOCALCONFIGPRESENT) && - $this->has(Mode::DBAVAILABLE) && - $this->has(Mode::DBCONFIGAVAILABLE) && - $this->has(Mode::MAINTENANCEDISABLED); + $this->has(Mode::DBAVAILABLE) && + $this->has(Mode::DBCONFIGAVAILABLE) && + $this->has(Mode::MAINTENANCEDISABLED); } -} +} \ No newline at end of file diff --git a/src/App/Router.php b/src/App/Router.php index 6720f54437..9e30ed3516 100644 --- a/src/App/Router.php +++ b/src/App/Router.php @@ -220,13 +220,9 @@ class Router $this->routeCollector->addRoute(['GET'], '/xrd', Module\Xrd::class); } - public function __construct(RouteCollector $routeCollector = null) + public function __construct() { - if (!$routeCollector) { - $routeCollector = new RouteCollector(new Std(), new GroupCountBased()); - } - - $this->routeCollector = $routeCollector; + $this->routeCollector = new RouteCollector(new Std(), new GroupCountBased()); } public function getRouteCollector() diff --git a/src/Core/L10n/L10n.php b/src/Core/L10n/L10n.php index a7bbed9af7..355f4c6ed4 100644 --- a/src/Core/L10n/L10n.php +++ b/src/Core/L10n/L10n.php @@ -2,6 +2,7 @@ namespace Friendica\Core\L10n; +use Friendica\Core\Config\Configuration; use Friendica\Core\Hook; use Friendica\Core\Session; use Friendica\Database\Database; @@ -52,12 +53,12 @@ class L10n */ private $logger; - public function __construct(string $lang, Database $dba, LoggerInterface $logger) + public function __construct(Configuration $config, Database $dba, LoggerInterface $logger) { $this->dba = $dba; $this->logger = $logger; - $this->loadTranslationTable($lang); + $this->loadTranslationTable(L10n::detectLanguage($config->get('system', 'language', 'en'))); \Friendica\Core\L10n::init($this); } diff --git a/src/Database/Database.php b/src/Database/Database.php index 0d1540f7cd..cdd5a357ab 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -9,7 +9,6 @@ use Friendica\Util\Profiler; use mysqli; use mysqli_result; use mysqli_stmt; -use ParagonIE\HiddenString\HiddenString; use PDO; use PDOException; use PDOStatement; @@ -46,32 +45,44 @@ class Database private $in_transaction = false; private $in_retrial = false; private $relation = []; - private $db_serveraddr; - private $db_user; - /** - * @var HiddenString - */ - private $db_pass; - private $db_name; - private $db_charset; - public function __construct(ConfigCache $configCache, Profiler $profiler, LoggerInterface $logger, $serveraddr, $user, HiddenString $pass, $db, $charset = null) + public function __construct(ConfigCache $configCache, Profiler $profiler, LoggerInterface $logger, array $server) { // We are storing these values for being able to perform a reconnect $this->configCache = $configCache; $this->profiler = $profiler; $this->logger = $logger; - $this->db_serveraddr = $serveraddr; - $this->db_user = $user; - $this->db_pass = $pass; - $this->db_name = $db; - $this->db_charset = $charset; + $this->readServerVariables($server); $this->connect(); DBA::init($this); } + private function readServerVariables(array $server) + { + // 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']; + } + $this->configCache->set('database', 'hostname', $db_host); + unset($db_host); + if (!empty($server['MYSQL_USERNAME'])) { + $this->configCache->set('database', 'username', $server['MYSQL_USERNAME']); + } else { + $this->configCache->set('database', 'username', $server['MYSQL_USER']); + } + $this->configCache->set('database', 'password', (string) $server['MYSQL_PASSWORD']); + $this->configCache->set('database', 'database', $server['MYSQL_DATABASE']); + } + } + public function connect() { if (!is_null($this->connection) && $this->connected()) { @@ -79,20 +90,17 @@ class Database } $port = 0; - $serveraddr = trim($this->db_serveraddr); - + $serveraddr = trim($this->configCache->get('database', 'hostname')); $serverdata = explode(':', $serveraddr); $server = $serverdata[0]; - if (count($serverdata) > 1) { $port = trim($serverdata[1]); } - $server = trim($server); - $user = trim($this->db_user); - $pass = trim($this->db_pass); - $db = trim($this->db_name); - $charset = trim($this->db_charset); + $user = trim($this->configCache->get('database', 'username')); + $pass = trim($this->configCache->get('database', 'password')); + $db = trim($this->configCache->get('database', 'database')); + $charset = trim($this->configCache->get('database', 'charset')); if (!(strlen($server) && strlen($user))) { return false; diff --git a/src/Factory/ConfigFactory.php b/src/Factory/ConfigFactory.php index 1aba8fc824..08fcddacea 100644 --- a/src/Factory/ConfigFactory.php +++ b/src/Factory/ConfigFactory.php @@ -5,9 +5,9 @@ namespace Friendica\Factory; use Friendica\Core; use Friendica\Core\Config; use Friendica\Core\Config\Cache; -use Friendica\Util\ConfigFileLoader; use Friendica\Model\Config\Config as ConfigModel; use Friendica\Model\Config\PConfig as PConfigModel; +use Friendica\Util\ConfigFileLoader; class ConfigFactory { @@ -16,7 +16,7 @@ class ConfigFactory * * @return Cache\ConfigCache */ - public static function createCache(ConfigFileLoader $loader) + public function createCache(ConfigFileLoader $loader) { $configCache = new Cache\ConfigCache(); $loader->setupCache($configCache); @@ -26,11 +26,11 @@ class ConfigFactory /** * @param Cache\ConfigCache $configCache The config cache of this adapter - * @param ConfigModel $configModel The configuration model + * @param ConfigModel $configModel The configuration model * * @return Config\Configuration */ - public static function createConfig(Cache\ConfigCache $configCache, ConfigModel $configModel) + public function createConfig(Cache\ConfigCache $configCache, ConfigModel $configModel) { if ($configCache->get('system', 'config_adapter') === 'preload') { $configuration = new Config\PreloadConfiguration($configCache, $configModel); @@ -46,13 +46,13 @@ class ConfigFactory } /** - * @param Cache\ConfigCache $configCache The config cache - * @param Cache\PConfigCache $pConfigCache The personal config cache - * @param PConfigModel $configModel The configuration model + * @param Cache\ConfigCache $configCache The config cache + * @param Cache\PConfigCache $pConfigCache The personal config cache + * @param PConfigModel $configModel The configuration model * * @return Config\PConfiguration */ - public static function createPConfig(Cache\ConfigCache $configCache, Cache\PConfigCache $pConfigCache, PConfigModel $configModel) + public function createPConfig(Cache\ConfigCache $configCache, Cache\PConfigCache $pConfigCache, PConfigModel $configModel) { if ($configCache->get('system', 'config_adapter') === 'preload') { $configuration = new Config\PreloadPConfiguration($pConfigCache, $configModel); diff --git a/src/Factory/DBFactory.php b/src/Factory/DBFactory.php deleted file mode 100644 index f24961c3f2..0000000000 --- a/src/Factory/DBFactory.php +++ /dev/null @@ -1,61 +0,0 @@ -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 = new HiddenString((string) $server['MYSQL_PASSWORD']); - $db_data = $server['MYSQL_DATABASE']; - } - - $database = new Database\Database($configCache, $profiler, new VoidLogger(), $db_host, $db_user, $db_pass, $db_data, $charset); - - if ($database->connected()) { - // Loads DB_UPDATE_VERSION constant - Database\DBStructure::definition($configCache->get('system', 'basepath'), false); - } - - unset($db_host, $db_user, $db_pass, $db_data, $charset); - - return $database; - } -} diff --git a/src/Factory/DependencyFactory.php b/src/Factory/DependencyFactory.php index 9d1af15a0f..8ead2f6156 100644 --- a/src/Factory/DependencyFactory.php +++ b/src/Factory/DependencyFactory.php @@ -2,13 +2,10 @@ namespace Friendica\Factory; +use Dice\Dice; use Friendica\App; -use Friendica\Core\Config\Cache\PConfigCache; -use Friendica\Core\L10n\L10n; -use Friendica\Factory; -use Friendica\Util\BasePath; -use Friendica\Util\BaseURL; -use Friendica\Util\ConfigFileLoader; +use Friendica\Core\Config\PConfiguration; +use Psr\Log\LoggerInterface; class DependencyFactory { @@ -16,34 +13,18 @@ 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) + public static function setUp($channel, Dice $dice, $isBackend = true) { - $basePath = BasePath::create($directory, $_SERVER); - $mode = new App\Mode($basePath); - $router = new App\Router(); - $configLoader = new ConfigFileLoader($basePath, $mode); - $configCache = Factory\ConfigFactory::createCache($configLoader); - $profiler = Factory\ProfilerFactory::create($configCache); - $database = Factory\DBFactory::init($configCache, $profiler, $_SERVER); - $configModel = new \Friendica\Model\Config\Config($database); - $config = Factory\ConfigFactory::createConfig($configCache, $configModel); - // needed to call PConfig::init() - $pconfigModel = new \Friendica\Model\Config\PConfig($database); - Factory\ConfigFactory::createPConfig($configCache, new PConfigCache(), $pconfigModel); - $logger = Factory\LoggerFactory::create($channel, $database, $config, $profiler); - Factory\LoggerFactory::createDev($channel, $config, $profiler); - $baseURL = new BaseURL($config, $_SERVER); - $l10n = new L10n(L10n::detectLanguage($config->get('system', 'language')), - $database, - $logger); + $pConfig = $dice->create(PConfiguration::class); + $logger = $dice->create(LoggerInterface::class, [$channel]); + $devLogger = $dice->create('$devLogger', [$channel]); - return new App($database, $config, $mode, $router, $baseURL, $logger, $profiler, $l10n, $isBackend); + return $dice->create(App::class, [$isBackend]); } } diff --git a/src/Factory/LoggerFactory.php b/src/Factory/LoggerFactory.php index 67829546e9..2a054607ca 100644 --- a/src/Factory/LoggerFactory.php +++ b/src/Factory/LoggerFactory.php @@ -48,7 +48,7 @@ class LoggerFactory * @throws \Exception * @throws InternalServerErrorException */ - public static function create($channel, Database $database, Configuration $config, Profiler $profiler) + public function create($channel, Database $database, Configuration $config, Profiler $profiler) { if (empty($config->get('system', 'debugging', false))) { $logger = new VoidLogger(); diff --git a/src/Factory/ProfilerFactory.php b/src/Factory/ProfilerFactory.php deleted file mode 100644 index 522e8fee09..0000000000 --- a/src/Factory/ProfilerFactory.php +++ /dev/null @@ -1,26 +0,0 @@ -get('system', 'profiler'); - $enabled = isset($enabled) && $enabled !== '0'; - $renderTime = $configCache->get('rendertime', 'callstack'); - $renderTime = isset($renderTime) && $renderTime !== '0'; - - return new Profiler($enabled, $renderTime); - } -} diff --git a/src/Util/BasePath.php b/src/Util/BasePath.php index f29c2e864e..06fa524679 100644 --- a/src/Util/BasePath.php +++ b/src/Util/BasePath.php @@ -4,36 +4,55 @@ namespace Friendica\Util; class BasePath { + /** + * @var string + */ + private $baseDir; + /** + * @var array + */ + private $server; + + /** + * @param string|null $baseDir The default base path + * @param array $server server arguments + */ + public function __construct(string $baseDir, array $server = []) + { + $this->baseDir = $baseDir; + $this->server = $server; + } + /** * @brief Returns the base filesystem path of the App * * It first checks for the internal variable, then for DOCUMENT_ROOT and * finally for PWD * - * @param string|null $basePath The default base path - * @param array $server server arguments - * * @return string * * @throws \Exception if directory isn't usable */ - public static function create($basePath, array $server = []) + public function getPath() { - if ((!$basePath || !is_dir($basePath)) && !empty($server['DOCUMENT_ROOT'])) { - $basePath = $server['DOCUMENT_ROOT']; + $baseDir = $this->baseDir; + $server = $this->server; + + if ((!$baseDir || !is_dir($baseDir)) && !empty($server['DOCUMENT_ROOT'])) { + $baseDir = $server['DOCUMENT_ROOT']; } - if ((!$basePath || !is_dir($basePath)) && !empty($server['PWD'])) { - $basePath = $server['PWD']; + if ((!$baseDir || !is_dir($baseDir)) && !empty($server['PWD'])) { + $baseDir = $server['PWD']; } - $basePath = self::getRealPath($basePath); + $baseDir = self::getRealPath($baseDir); - if (!is_dir($basePath)) { - throw new \Exception(sprintf('\'%s\' is not a valid basepath', $basePath)); + if (!is_dir($baseDir)) { + throw new \Exception(sprintf('\'%s\' is not a valid basepath', $baseDir)); } - return $basePath; + return $baseDir; } /** diff --git a/src/Util/ConfigFileLoader.php b/src/Util/ConfigFileLoader.php index 8ca76f79c1..80da4018c0 100644 --- a/src/Util/ConfigFileLoader.php +++ b/src/Util/ConfigFileLoader.php @@ -3,7 +3,6 @@ namespace Friendica\Util; use Exception; -use Friendica\App; use Friendica\Core\Addon; use Friendica\Core\Config\Cache\ConfigCache; @@ -52,10 +51,6 @@ class ConfigFileLoader */ const SAMPLE_END = '-sample'; - /** - * @var App\Mode - */ - private $appMode; /** * @var string */ @@ -69,12 +64,11 @@ class ConfigFileLoader */ private $staticDir; - public function __construct($baseDir, App\Mode $mode) + public function __construct(string $basePath) { - $this->baseDir = $baseDir; - $this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::CONFIG_DIR; - $this->staticDir = $baseDir . DIRECTORY_SEPARATOR . self::STATIC_DIR; - $this->appMode = $mode; + $this->baseDir = $basePath; + $this->configDir = $this->baseDir . DIRECTORY_SEPARATOR . self::CONFIG_DIR; + $this->staticDir = $this->baseDir . DIRECTORY_SEPARATOR . self::STATIC_DIR; } /** @@ -102,7 +96,7 @@ class ConfigFileLoader $this->loadCoreConfig($config); // In case of install mode, add the found basepath (because there isn't a basepath set yet - if (!$raw && ($this->appMode->isInstall() || empty($config->get('system', 'basepath')))) { + if (!$raw && empty($config->get('system', 'basepath'))) { // Setting at least the basepath we know $config->set('system', 'basepath', $this->baseDir); } diff --git a/src/Util/Profiler.php b/src/Util/Profiler.php index fe72efce40..dc140469c6 100644 --- a/src/Util/Profiler.php +++ b/src/Util/Profiler.php @@ -2,6 +2,8 @@ namespace Friendica\Util; +use Friendica\Core\Config\Cache\ConfigCache; +use Friendica\Core\Config\Configuration; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; @@ -45,23 +47,21 @@ class Profiler implements ContainerInterface /** * Updates the enabling of the current profiler * - * @param bool $enabled - * @param bool $renderTime + * @param Configuration $config */ - public function update($enabled = false, $renderTime = false) + public function update(Configuration $config) { - $this->enabled = $enabled; - $this->rendertime = $renderTime; + $this->enabled = $config->get('system', 'profiler'); + $this->rendertime = $config->get('rendertime', 'callstack'); } /** - * @param bool $enabled True, if the Profiler is enabled - * @param bool $renderTime True, if the Profiler should measure the whole rendertime including functions + * @param ConfigCache $configCache The configuration cache */ - public function __construct($enabled = false, $renderTime = false) + public function __construct(ConfigCache $configCache) { - $this->enabled = $enabled; - $this->rendertime = $renderTime; + $this->enabled = $configCache->get('system', 'profiler'); + $this->rendertime = $configCache->get('rendertime', 'callstack'); $this->reset(); } diff --git a/static/dependencies.config.php b/static/dependencies.config.php new file mode 100644 index 0000000000..c1ce4f3b56 --- /dev/null +++ b/static/dependencies.config.php @@ -0,0 +1,125 @@ +create(); + * + * - $a = new ClassA($creationPassedVariable); + * + */ +return [ + '$basepath' => [ + 'instanceOf' => Util\BasePath::class, + 'call' => [ + ['getPath', [], Dice::CHAIN_CALL], + ], + 'constructParams' => [ + dirname(__FILE__, 2), + $_SERVER + ] + ], + Util\BasePath::class => [ + 'shared' => true, + 'constructParams' => [ + dirname(__FILE__, 2), + $_SERVER + ] + ], + Util\ConfigFileLoader::class => [ + 'shared' => true, + 'constructParams' => [ + [Dice::INSTANCE => '$basepath'], + ], + ], + Config\Cache\ConfigCache::class => [ + 'instanceOf' => Factory\ConfigFactory::class, + 'call' => [ + ['createCache', [], Dice::CHAIN_CALL], + ], + 'shared' => true, + ], + App\Mode::class => [ + 'call' => [ + ['determine', [], Dice::CHAIN_CALL], + ], + // marks the result as shared for other creations, so there's just + // one instance for the whole execution + 'shared' => true, + ], + Config\Configuration::class => [ + 'shared' => true, + 'instanceOf' => Factory\ConfigFactory::class, + 'call' => [ + ['createConfig', [], Dice::CHAIN_CALL], + ], + ], + Config\PConfiguration::class => [ + 'shared' => true, + 'instanceOf' => Factory\ConfigFactory::class, + 'call' => [ + ['createPConfig', [], Dice::CHAIN_CALL], + ] + ], + Database::class => [ + 'shared' => true, + 'constructParams' => [ + [DICE::INSTANCE => \Psr\Log\NullLogger::class], + $_SERVER, + ], + ], + /** + * Creates the Util\BaseURL + * + * Same as: + * $baseURL = new Util\BaseURL($configuration, $_SERVER); + */ + Util\BaseURL::class => [ + 'shared' => true, + 'constructParams' => [ + $_SERVER, + ], + ], + /** + * Create a Logger, which implements the LoggerInterface + * + * Same as: + * $loggerFactory = new Factory\LoggerFactory(); + * $logger = $loggerFactory->create($channel, $configuration, $profiler); + * + * Attention1: We can use DICE for detecting dependencies inside "chained" calls too + * Attention2: The variable "$channel" is passed inside the creation of the dependencies per: + * $app = $dice->create(App::class, [], ['$channel' => 'index']); + * and is automatically passed as an argument with the same name + */ + LoggerInterface::class => [ + 'shared' => true, + 'instanceOf' => Factory\LoggerFactory::class, + 'call' => [ + ['create', [], Dice::CHAIN_CALL], + ], + ], + '$devLogger' => [ + 'shared' => true, + 'instanceOf' => Factory\LoggerFactory::class, + 'call' => [ + ['createDev', [], Dice::CHAIN_CALL], + ] + ] +]; diff --git a/tests/DatabaseTest.php b/tests/DatabaseTest.php index 950da5af6f..4dffc56878 100644 --- a/tests/DatabaseTest.php +++ b/tests/DatabaseTest.php @@ -17,6 +17,7 @@ use Friendica\Util\Profiler; use PHPUnit\DbUnit\DataSet\YamlDataSet; use PHPUnit\DbUnit\TestCaseTrait; use PHPUnit_Extensions_Database_DB_IDatabaseConnection; +use Psr\Log\NullLogger; require_once __DIR__ . '/../boot.php'; @@ -46,12 +47,13 @@ abstract class DatabaseTest extends MockedTest { parent::setUpBeforeClass(); - self::$basePath = BasePath::create(dirname(__DIR__)); - self::$mode = new Mode(self::$basePath); - $configLoader = new ConfigFileLoader(self::$basePath, self::$mode); - self::$configCache = ConfigFactory::createCache($configLoader); - self::$profiler = ProfilerFactory::create(self::$configCache); - self::$dba = DBFactory::init(self::$configCache, self::$profiler, $_SERVER); + self::$basePath = new BasePath(dirname(__DIR__)); + $configLoader = new ConfigFileLoader(self::$basePath->getPath()); + $configFactory = new ConfigFactory(); + self::$configCache = $configFactory->createCache($configLoader); + self::$profiler = new Profiler(self::$configCache); + self::$dba = new Database(self::$configCache, self::$profiler, new NullLogger(), $_SERVER); + self::$mode = new Mode(self::$basePath, self::$dba, self::$configCache); } /** diff --git a/tests/functional/DependencyCheckTest.php b/tests/functional/DependencyCheckTest.php new file mode 100644 index 0000000000..4a1ab5afde --- /dev/null +++ b/tests/functional/DependencyCheckTest.php @@ -0,0 +1,136 @@ +setUpVfsDir(); + + $this->dice = new Dice(); + $this->dice = $this->dice->addRules(include __DIR__ . '/../../static/dependencies.config.php'); + } + + /** + * Test the creation of the BasePath + */ + public function testBasePath() + { + /** @var BasePath $basePath */ + $basePath = $this->dice->create(BasePath::class, [$this->root->url()]); + + $this->assertInstanceOf(BasePath::class, $basePath); + $this->assertEquals($this->root->url(), $basePath->getPath()); + } + + /** + * Test the initial config cache + * Should not need any other files + */ + public function testConfigFileLoader() + { + /** @var ConfigFileLoader $configFileLoader */ + $configFileLoader = $this->dice->create(ConfigFileLoader::class); + + $this->assertInstanceOf(ConfigFileLoader::class, $configFileLoader); + + $configCache = new ConfigCache(); + $configFileLoader->setupCache($configCache); + + $this->assertNotEmpty($configCache->getAll()); + $this->assertArrayHasKey('database', $configCache->getAll()); + $this->assertArrayHasKey('system', $configCache->getAll()); + } + + /** + * Test the construction of a profiler class with DI + */ + public function testProfiler() + { + /** @var Profiler $profiler */ + $profiler = $this->dice->create(Profiler::class); + + $this->assertInstanceOf(Profiler::class, $profiler); + + $configCache = new ConfigCache([ + 'system' => [ + 'profiler' => true, + ], + 'rendertime' => [ + 'callstack' => true, + ] + ]); + + $profiler = $this->dice->create(Profiler::class, [$configCache]); + + $this->assertInstanceOf(Profiler::class, $profiler); + $this->assertTrue($profiler->isRendertime()); + } + + public function testDatabase() + { + /** @var Database $database */ + $database = $this->dice->create(Database::class); + + $this->assertInstanceOf(Database::class, $database); + $this->assertTrue($database->connected()); + } + + public function testAppMode() + { + /** @var App\Mode $mode */ + $mode = $this->dice->create(App\Mode::class); + + $this->assertInstanceOf(App\Mode::class, $mode); + + $this->assertTrue($mode->isNormal()); + } + + public function testConfiguration() + { + /** @var Configuration $config */ + $config = $this->dice->create(Configuration::class); + + $this->assertInstanceOf(Configuration::class, $config); + + $this->assertNotEmpty($config->get('database', 'username')); + } + + public function testLogger() + { + /** @var LoggerInterface $logger */ + $logger = $this->dice->create(LoggerInterface::class, ['test']); + + $this->assertInstanceOf(LoggerInterface::class, $logger); + } + + public function testDevLogger() + { + /** @var LoggerInterface $logger */ + $logger = $this->dice->create('$devLogger', ['dev']); + + self::assertInstanceOf(LoggerInterface::class, $logger); + } +} diff --git a/tests/include/ApiTest.php b/tests/include/ApiTest.php index 801857a453..a7193c8872 100644 --- a/tests/include/ApiTest.php +++ b/tests/include/ApiTest.php @@ -15,7 +15,6 @@ use Friendica\Core\System; use Friendica\Factory; use Friendica\Network\HTTPException; use Friendica\Util\BaseURL; -use Friendica\Util\ConfigFileLoader; use Monolog\Handler\TestHandler; require_once __DIR__ . '/../../include/api.php'; @@ -51,13 +50,15 @@ class ApiTest extends DatabaseTest public function setUp() { $configModel = new \Friendica\Model\Config\Config(self::$dba); - $config = Factory\ConfigFactory::createConfig(self::$configCache, $configModel); + $configFactory = new Factory\ConfigFactory(); + $config = $configFactory->createConfig(self::$configCache, $configModel); $pconfigModel = new \Friendica\Model\Config\PConfig(self::$dba); - Factory\ConfigFactory::createPConfig(self::$configCache, new PConfigCache(), $pconfigModel); - $logger = Factory\LoggerFactory::create('test', self::$dba, $config, self::$profiler); + $configFactory->createPConfig(self::$configCache, new PConfigCache(), $pconfigModel); + $loggerFactory = new Factory\LoggerFactory(); + $logger = $loggerFactory->create('test', self::$dba, $config, self::$profiler); $baseUrl = new BaseURL($config, $_SERVER); $router = new App\Router(); - $l10n = new L10n(L10n::detectLanguage($config->get('system', 'language')), + $l10n = new L10n($config, self::$dba, $logger); $this->app = new App(self::$dba, $config, self::$mode, $router, $baseUrl, $logger, self::$profiler, $l10n, false); diff --git a/tests/src/App/ModeTest.php b/tests/src/App/ModeTest.php index 9059e8bebf..b8d2e5136b 100644 --- a/tests/src/App/ModeTest.php +++ b/tests/src/App/ModeTest.php @@ -4,32 +4,56 @@ namespace Friendica\Test\src\App; use Friendica\App\Mode; use Friendica\Core\Config; +use Friendica\Database\Database; use Friendica\Test\MockedTest; use Friendica\Test\Util\DBAMockTrait; use Friendica\Test\Util\VFSTrait; +use Friendica\Util\BasePath; +use Mockery\MockInterface; class ModeTest extends MockedTest { use VFSTrait; use DBAMockTrait; + /** + * @var BasePath|MockInterface + */ + private $basePathMock; + + /** + * @var Database|MockInterface + */ + private $databaseMock; + + /** + * @var Config\Cache\ConfigCache|MockInterface + */ + private $configCacheMock; + public function setUp() { parent::setUp(); $this->setUpVfsDir(); + + $this->basePathMock = \Mockery::mock(BasePath::class); + $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once(); + + $this->databaseMock = \Mockery::mock(Database::class); + $this->configCacheMock = \Mockery::mock(Config\Cache\ConfigCache::class); } public function testItEmpty() { - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $this->assertTrue($mode->isInstall()); $this->assertFalse($mode->isNormal()); } public function testWithoutConfig() { - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $this->assertTrue($this->root->hasChild('config/local.config.php')); @@ -45,15 +69,11 @@ class ModeTest extends MockedTest $this->assertFalse($mode->has(Mode::LOCALCONFIGPRESENT)); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ public function testWithoutDatabase() { - $this->mockConnected(false, 1); + $this->databaseMock->shouldReceive('connected')->andReturn(false)->once(); - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $mode->determine(); $this->assertFalse($mode->isNormal()); @@ -63,16 +83,13 @@ class ModeTest extends MockedTest $this->assertFalse($mode->has(Mode::DBAVAILABLE)); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ public function testWithoutDatabaseSetup() { - $this->mockConnected(true, 1); - $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', false, 1); + $this->databaseMock->shouldReceive('connected')->andReturn(true)->once(); + $this->databaseMock->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'')->andReturn(false)->once(); - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $mode->determine(); $this->assertFalse($mode->isNormal()); @@ -81,25 +98,15 @@ class ModeTest extends MockedTest $this->assertTrue($mode->has(Mode::LOCALCONFIGPRESENT)); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ public function testWithMaintenanceMode() { - $this->mockConnected(true, 1); - $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1); + $this->databaseMock->shouldReceive('connected')->andReturn(true)->once(); + $this->databaseMock->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once(); + $this->configCacheMock->shouldReceive('get')->with('system', 'maintenance') + ->andReturn(true)->once(); - $config = \Mockery::mock(Config\Configuration::class); - $config - ->shouldReceive('get') - ->with('system', 'maintenance', null, false) - ->andReturn(true) - ->once(); - // Initialize empty Config - Config::init($config); - - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $mode->determine(); $this->assertFalse($mode->isNormal()); @@ -109,25 +116,18 @@ class ModeTest extends MockedTest $this->assertFalse($mode->has(Mode::MAINTENANCEDISABLED)); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ public function testNormalMode() { - $this->mockConnected(true, 1); - $this->mockFetchFirst('SHOW TABLES LIKE \'config\'', true, 1); + $this->databaseMock->shouldReceive('connected')->andReturn(true)->once(); + $this->databaseMock->shouldReceive('fetchFirst') + ->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once(); + $this->configCacheMock->shouldReceive('get')->with('system', 'maintenance') + ->andReturn(false)->once(); + $this->databaseMock->shouldReceive('selectFirst') + ->with('config', ['v'], ['cat' => 'system', 'k' => 'maintenance']) + ->andReturn(false)->once(); - $config = \Mockery::mock(Config\Configuration::class); - $config - ->shouldReceive('get') - ->with('system', 'maintenance', null, false) - ->andReturn(false) - ->once(); - // Initialize empty Config - Config::init($config); - - $mode = new Mode($this->root->url()); + $mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock); $mode->determine(); $this->assertTrue($mode->isNormal()); diff --git a/tests/src/Database/DBATest.php b/tests/src/Database/DBATest.php index cc25373e1a..1ca5cd8bcf 100644 --- a/tests/src/Database/DBATest.php +++ b/tests/src/Database/DBATest.php @@ -21,7 +21,7 @@ class DBATest extends DatabaseTest $logger = Factory\LoggerFactory::create('test', self::$dba, $config, self::$profiler); $baseUrl = new BaseURL($config, $_SERVER); $router = new App\Router(); - $l10n = new L10n(L10n::detectLanguage($config->get('system', 'language')), + $l10n = new L10n($config, self::$dba, $logger); $this->app = new App(self::$dba, $config, self::$mode, $router, $baseUrl, $logger, self::$profiler, $l10n, false); diff --git a/tests/src/Database/DBStructureTest.php b/tests/src/Database/DBStructureTest.php index 3cecec62a9..ef777b30e8 100644 --- a/tests/src/Database/DBStructureTest.php +++ b/tests/src/Database/DBStructureTest.php @@ -25,7 +25,7 @@ class DBStructureTest extends DatabaseTest $logger = Factory\LoggerFactory::create('test', self::$dba, $config, self::$profiler); $baseUrl = new BaseURL($config, $_SERVER); $router = new App\Router(); - $l10n = new L10n(L10n::detectLanguage($config->get('system', 'language')), + $l10n = new L10n($config, self::$dba, $logger); $this->app = new App(self::$dba, $config, self::$mode, $router, $baseUrl, $logger, self::$profiler, $l10n, false); diff --git a/tests/src/Util/BasePathTest.php b/tests/src/Util/BasePathTest.php index 3c619255cf..c9c7b079f9 100644 --- a/tests/src/Util/BasePathTest.php +++ b/tests/src/Util/BasePathTest.php @@ -58,7 +58,8 @@ class BasePathTest extends MockedTest */ public function testDetermineBasePath(array $server, $input, $output) { - $this->assertEquals($output, BasePath::create($input, $server)); + $basepath = new BasePath($input, $server); + $this->assertEquals($output, $basepath->getPath()); } /** @@ -68,6 +69,7 @@ class BasePathTest extends MockedTest */ public function testFailedBasePath() { - BasePath::create('/now23452sgfgas', []); + $basepath = new BasePath('/now23452sgfgas', []); + $basepath->getPath(); } } diff --git a/tests/src/Util/Config/ConfigFileLoaderTest.php b/tests/src/Util/Config/ConfigFileLoaderTest.php index 1680f2fdb6..aa9a11cb08 100644 --- a/tests/src/Util/Config/ConfigFileLoaderTest.php +++ b/tests/src/Util/Config/ConfigFileLoaderTest.php @@ -2,31 +2,21 @@ namespace Friendica\Test\src\Util\Config; -use Friendica\App; use Friendica\Core\Config\Cache\ConfigCache; use Friendica\Test\MockedTest; use Friendica\Test\Util\VFSTrait; use Friendica\Util\ConfigFileLoader; -use Mockery\MockInterface; use org\bovigo\vfs\vfsStream; class ConfigFileLoaderTest extends MockedTest { use VFSTrait; - /** - * @var App\Mode|MockInterface - */ - private $mode; - protected function setUp() { parent::setUp(); $this->setUpVfsDir(); - - $this->mode = \Mockery::mock(App\Mode::class); - $this->mode->shouldReceive('isInstall')->andReturn(true); } /** @@ -34,7 +24,9 @@ class ConfigFileLoaderTest extends MockedTest */ public function testLoadConfigFiles() { - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $this->delConfigFile('local.config.php'); + + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -55,7 +47,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent('root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -79,7 +71,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent(file_get_contents($file)); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -111,7 +103,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent(file_get_contents($file)); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -142,7 +134,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root) ->setContent(file_get_contents($file)); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -191,7 +183,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('addon')->getChild('test')->getChild('config')) ->setContent(file_get_contents($file)); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $conf = $configFileLoader->loadAddonConfig('test'); @@ -223,7 +215,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent(file_get_contents($fileDir . 'B.config.php')); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -252,7 +244,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent(file_get_contents($fileDir . 'B.ini.php')); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); @@ -281,7 +273,7 @@ class ConfigFileLoaderTest extends MockedTest ->at($this->root->getChild('config')) ->setContent(file_get_contents($fileDir . 'B.ini.php')); - $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode); + $configFileLoader = new ConfigFileLoader($this->root->url()); $configCache = new ConfigCache(); $configFileLoader->setupCache($configCache); diff --git a/tests/src/Util/ProfilerTest.php b/tests/src/Util/ProfilerTest.php index 1dbf36f38b..0790bc30ac 100644 --- a/tests/src/Util/ProfilerTest.php +++ b/tests/src/Util/ProfilerTest.php @@ -2,6 +2,8 @@ namespace Friendica\Test\src\Util; +use Friendica\Core\Config\Cache\ConfigCache; +use Friendica\Core\Config\Configuration; use Friendica\Test\MockedTest; use Friendica\Util\Profiler; use Mockery\MockInterface; @@ -26,7 +28,12 @@ class ProfilerTest extends MockedTest */ public function testSetUp() { - $profiler = new Profiler(true, true); + $configCache = \Mockery::mock(ConfigCache::class); + $configCache->shouldReceive('get') + ->withAnyArgs() + ->andReturn(true) + ->twice(); + $profiler = new Profiler($configCache); } /** @@ -96,7 +103,13 @@ class ProfilerTest extends MockedTest */ public function testSaveTimestamp($timestamp, $name, array $functions) { - $profiler = new Profiler(true, true); + $configCache = \Mockery::mock(ConfigCache::class); + $configCache->shouldReceive('get') + ->withAnyArgs() + ->andReturn(true) + ->twice(); + + $profiler = new Profiler($configCache); foreach ($functions as $function) { $profiler->saveTimestamp($timestamp, $name, $function); @@ -111,7 +124,13 @@ class ProfilerTest extends MockedTest */ public function testReset($timestamp, $name, array $functions) { - $profiler = new Profiler(true, true); + $configCache = \Mockery::mock(ConfigCache::class); + $configCache->shouldReceive('get') + ->withAnyArgs() + ->andReturn(true) + ->twice(); + + $profiler = new Profiler($configCache); $profiler->saveTimestamp($timestamp, $name); $profiler->reset(); @@ -168,7 +187,13 @@ class ProfilerTest extends MockedTest ->shouldReceive('info') ->once(); - $profiler = new Profiler(true, true); + $configCache = \Mockery::mock(ConfigCache::class); + $configCache->shouldReceive('get') + ->withAnyArgs() + ->andReturn(true) + ->twice(); + + $profiler = new Profiler($configCache); foreach ($data as $perf => $items) { foreach ($items['functions'] as $function) { @@ -193,19 +218,48 @@ class ProfilerTest extends MockedTest */ public function testEnableDisable() { - $profiler = new Profiler(true, false); + $configCache = \Mockery::mock(ConfigCache::class); + $configCache->shouldReceive('get') + ->with('system', 'profiler') + ->andReturn(true) + ->once(); + $configCache->shouldReceive('get') + ->with('rendertime', 'callstack') + ->andReturn(false) + ->once(); + + $profiler = new Profiler($configCache); $this->assertFalse($profiler->isRendertime()); $this->assertEmpty($profiler->getRendertimeString()); $profiler->saveTimestamp(time(), 'network', 'test1'); - $profiler->update(false, false); + $config = \Mockery::mock(Configuration::class); + $config->shouldReceive('get') + ->with('system', 'profiler') + ->andReturn(false) + ->once(); + $config->shouldReceive('get') + ->with('rendertime', 'callstack') + ->andReturn(false) + ->once(); + + $profiler->update($config); $this->assertFalse($profiler->isRendertime()); $this->assertEmpty($profiler->getRendertimeString()); - $profiler->update(true, true); + $config->shouldReceive('get') + ->with('system', 'profiler') + ->andReturn(true) + ->once(); + $config->shouldReceive('get') + ->with('rendertime', 'callstack') + ->andReturn(true) + ->once(); + + $profiler->update($config); $profiler->saveTimestamp(time(), 'database', 'test2');