]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #6600 from annando/false-notifications
authorHypolite Petovan <hypolite@mrpetovan.com>
Wed, 6 Feb 2019 21:47:08 +0000 (16:47 -0500)
committerGitHub <noreply@github.com>
Wed, 6 Feb 2019 21:47:08 +0000 (16:47 -0500)
The automatic follow request is currently deactivated

55 files changed:
bin/auth_ejabberd.php
bin/console.php
bin/daemon.php
bin/worker.php
boot.php
config/dbstructure.config.php
index.php
mod/admin.php
mod/friendica.php
src/App.php
src/BaseObject.php
src/Core/Addon.php
src/Core/Config.php
src/Core/Config/ConfigCache.php [new file with mode: 0644]
src/Core/Config/ConfigCacheLoader.php [new file with mode: 0644]
src/Core/Config/IConfigAdapter.php
src/Core/Config/IConfigCache.php [new file with mode: 0644]
src/Core/Config/IPConfigAdapter.php
src/Core/Config/IPConfigCache.php [new file with mode: 0644]
src/Core/Config/JITConfigAdapter.php
src/Core/Config/JITPConfigAdapter.php
src/Core/Config/PreloadConfigAdapter.php
src/Core/Config/PreloadPConfigAdapter.php
src/Core/Console/AutomaticInstallation.php
src/Core/Console/Config.php
src/Core/Console/DatabaseStructure.php
src/Core/Console/PostUpdate.php
src/Core/Console/Typo.php
src/Core/Installer.php
src/Core/Logger.php
src/Core/PConfig.php
src/Core/System.php
src/Core/Update.php
src/Database/DBA.php
src/Database/DBStructure.php
src/Factory/ConfigFactory.php [new file with mode: 0644]
src/Factory/LoggerFactory.php [new file with mode: 0644]
src/Model/Attach.php
src/Module/Install.php
src/Util/BasePath.php [new file with mode: 0644]
src/Util/LoggerFactory.php [deleted file]
src/Worker/DBUpdate.php
tests/DatabaseTest.php
tests/Util/AppMockTrait.php
tests/include/ApiTest.php
tests/src/BaseObjectTest.php
tests/src/Core/Cache/CacheTest.php
tests/src/Core/Console/AutomaticInstallationConsoleTest.php
tests/src/Core/Console/ConsoleTest.php
tests/src/Core/Lock/LockTest.php
tests/src/Database/DBATest.php
tests/src/Database/DBStructureTest.php
view/theme/frio/css/style.css
view/theme/frio/templates/search_item.tpl
view/theme/frio/templates/wall_thread.tpl

index a6f30d20193275192d808dc5a9f9190d7d5f5e9e..11df438952a06e96ee700a7d6345cba1c90007d8 100755 (executable)
  */
 
 use Friendica\App;
+use Friendica\Core\Config;
+use Friendica\Factory;
+use Friendica\Util\BasePath;
 use Friendica\Util\ExAuth;
-use Friendica\Util\LoggerFactory;
 
 if (sizeof($_SERVER["argv"]) == 0) {
        die();
@@ -52,9 +54,12 @@ chdir($directory);
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = LoggerFactory::create('auth_ejabberd');
+$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(dirname(__DIR__), $logger);
+$a = new App($config, $logger);
 
 if ($a->getMode()->isNormal()) {
        $oAuth = new ExAuth();
index 9264e3eee46080d294ff79fd28041340ed239942..9061824d875b0be10f8f1fad8aa94c1f883c55a0 100755 (executable)
@@ -3,11 +3,16 @@
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-use Friendica\Util\LoggerFactory;
+use Friendica\Core\Config;
+use Friendica\Factory;
+use Friendica\Util\BasePath;
 
-$logger = LoggerFactory::create('console');
+$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(dirname(__DIR__), $logger);
+$a = new Friendica\App($config, $logger);
 \Friendica\BaseObject::setApp($a);
 
 (new Friendica\Core\Console($argv))->execute();
index c7b321c11c3c455ab8d31fc61b48b30ee68a0ebc..5c014a92702429d58af4dfab1ac163597d34b95d 100755 (executable)
@@ -11,7 +11,8 @@ use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
-use Friendica\Util\LoggerFactory;
+use Friendica\Factory;
+use Friendica\Util\BasePath;
 
 // Get options
 $shortopts = 'f';
@@ -32,9 +33,12 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = LoggerFactory::create('daemon');
+$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(dirname(__DIR__), $logger);
+$a = new App($config, $logger);
 
 if ($a->getMode()->isInstall()) {
        die("Friendica isn't properly installed yet.\n");
index a64b6a83305660f705bf5530141061ddcf379269..553e9849774fe307e5f1535b9c090809ce043e80 100755 (executable)
@@ -4,11 +4,13 @@
  * @file bin/worker.php
  * @brief Starts the background processing
  */
+
 use Friendica\App;
 use Friendica\Core\Config;
-use Friendica\Core\Worker;
 use Friendica\Core\Update;
-use Friendica\Util\LoggerFactory;
+use Friendica\Core\Worker;
+use Friendica\Factory;
+use Friendica\Util\BasePath;
 
 // Get options
 $shortopts = 'sn';
@@ -29,12 +31,15 @@ if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
 
 require dirname(__DIR__) . '/vendor/autoload.php';
 
-$logger = LoggerFactory::create('worker');
+$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(dirname(__DIR__), $logger);
+$a = new App($config, $logger);
 
 // Check the database structure and possibly fixes it
-Update::check(true);
+Update::check($a->getBasePath(), true);
 
 // Quit when in maintenance
 if (!$a->getMode()->has(App\Mode::MAINTENANCEDISABLED)) {
index 7dc99bbe88c3621e72babf21a08823088ad08694..318798e324c3fd693313654feb8da3c7496d6e82 100644 (file)
--- a/boot.php
+++ b/boot.php
 
 use Friendica\App;
 use Friendica\BaseObject;
-use Friendica\Core\Addon;
-use Friendica\Core\Cache;
 use Friendica\Core\Config;
-use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Core\Protocol;
 use Friendica\Core\System;
-use Friendica\Core\Update;
-use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
-use Friendica\Model\Conversation;
+use Friendica\Util\BasePath;
 use Friendica\Util\DateTimeFormat;
 
 define('FRIENDICA_PLATFORM',     'Friendica');
@@ -640,18 +635,18 @@ function get_temppath()
 
        $temppath = Config::get("system", "temppath");
 
-       if (($temppath != "") && App::isDirectoryUsable($temppath)) {
+       if (($temppath != "") && System::isDirectoryUsable($temppath)) {
                // We have a temp path and it is usable
-               return App::getRealPath($temppath);
+               return BasePath::getRealPath($temppath);
        }
 
        // We don't have a working preconfigured temp path, so we take the system path.
        $temppath = sys_get_temp_dir();
 
        // Check if it is usable
-       if (($temppath != "") && App::isDirectoryUsable($temppath)) {
+       if (($temppath != "") && System::isDirectoryUsable($temppath)) {
                // Always store the real path, not the path through symlinks
-               $temppath = App::getRealPath($temppath);
+               $temppath = BasePath::getRealPath($temppath);
 
                // To avoid any interferences with other systems we create our own directory
                $new_temppath = $temppath . "/" . $a->getHostName();
@@ -660,7 +655,7 @@ function get_temppath()
                        mkdir($new_temppath);
                }
 
-               if (App::isDirectoryUsable($new_temppath)) {
+               if (System::isDirectoryUsable($new_temppath)) {
                        // The new path is usable, we are happy
                        Config::set("system", "temppath", $new_temppath);
                        return $new_temppath;
@@ -742,8 +737,8 @@ function get_itemcachepath()
        }
 
        $itemcache = Config::get('system', 'itemcache');
-       if (($itemcache != "") && App::isDirectoryUsable($itemcache)) {
-               return App::getRealPath($itemcache);
+       if (($itemcache != "") && System::isDirectoryUsable($itemcache)) {
+               return BasePath::getRealPath($itemcache);
        }
 
        $temppath = get_temppath();
@@ -754,7 +749,7 @@ function get_itemcachepath()
                        mkdir($itemcache);
                }
 
-               if (App::isDirectoryUsable($itemcache)) {
+               if (System::isDirectoryUsable($itemcache)) {
                        Config::set("system", "itemcache", $itemcache);
                        return $itemcache;
                }
@@ -770,7 +765,7 @@ function get_itemcachepath()
 function get_spoolpath()
 {
        $spoolpath = Config::get('system', 'spoolpath');
-       if (($spoolpath != "") && App::isDirectoryUsable($spoolpath)) {
+       if (($spoolpath != "") && System::isDirectoryUsable($spoolpath)) {
                // We have a spool path and it is usable
                return $spoolpath;
        }
@@ -785,7 +780,7 @@ function get_spoolpath()
                        mkdir($spoolpath);
                }
 
-               if (App::isDirectoryUsable($spoolpath)) {
+               if (System::isDirectoryUsable($spoolpath)) {
                        // The new path is usable, we are happy
                        Config::set("system", "spoolpath", $spoolpath);
                        return $spoolpath;
index dcacce811efbe94ca69b2851e1b824bda90781e3..fdc54b0bde80586f483a63802fae68b8eefbc6e3 100644 (file)
@@ -34,7 +34,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1300);
+       define('DB_UPDATE_VERSION', 1301);
 }
 
 return [
@@ -1376,12 +1376,12 @@ return [
                ],
                "indexes" => [
                        "PRIMARY" => ["id"],
-                       "pid" => ["pid"],
-                       "parameter" => ["parameter(64)"],
-                       "priority_created_next_try" => ["priority", "created", "next_try"],
+                       "done_parameter" => ["done", "parameter(64)"],
+                       "done_pid" => ["done", "pid"],
+                       "done_priority_created_next_try" => ["done", "priority", "created", "next_try"],
                        "done_priority_executed_next_try" => ["done", "priority", "executed", "next_try"],
-                       "done_executed_next_try" => ["done", "executed", "next_try"],
                        "done_priority_next_try" => ["done", "priority", "next_try"],
+                       "done_executed_next_try" => ["done", "executed", "next_try"],
                        "done_next_try" => ["done", "next_try"]
                ]
        ],
index c2dd31bcf24289362cb4f8e223617b5275c84be1..7e7396785f5993c7b17f7a1e74870b7be5b4afcd 100644 (file)
--- a/index.php
+++ b/index.php
@@ -5,7 +5,9 @@
  */
 
 use Friendica\App;
-use Friendica\Util\LoggerFactory;
+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.');
@@ -13,10 +15,13 @@ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
 
 require __DIR__ . '/vendor/autoload.php';
 
-$logger = LoggerFactory::create('index');
+$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(__DIR__, $logger, false);
+$a = new App($config, $logger, false);
 
 $a->runFrontend();
index be28168e62275a8a3a6e5f4af3ed387af8eb1285..39f75021889c0eba414af9094bb93df9b5281942 100644 (file)
@@ -15,11 +15,11 @@ use Friendica\Core\Config;
 use Friendica\Core\L10n;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
+use Friendica\Core\StorageManager;
 use Friendica\Core\System;
 use Friendica\Core\Theme;
 use Friendica\Core\Update;
 use Friendica\Core\Worker;
-use Friendica\Core\StorageManager;
 use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\Model\Contact;
@@ -30,6 +30,7 @@ use Friendica\Module;
 use Friendica\Module\Login;
 use Friendica\Module\Tos;
 use Friendica\Util\Arrays;
+use Friendica\Util\BasePath;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
 use Friendica\Util\Strings;
@@ -915,7 +916,7 @@ function admin_page_summary(App $a)
        }
 
        if (Config::get('system', 'dbupdate', DBStructure::UPDATE_NOT_CHECKED) == DBStructure::UPDATE_NOT_CHECKED) {
-               DBStructure::update(false, true);
+               DBStructure::update($a->getBasePath(), false, true);
        }
        if (Config::get('system', 'dbupdate') == DBStructure::UPDATE_FAILED) {
                $showwarning = true;
@@ -1375,7 +1376,7 @@ function admin_page_site_post(App $a)
        Config::set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed);
 
        if ($itemcache != '') {
-               $itemcache = App::getRealPath($itemcache);
+               $itemcache = BasePath::getRealPath($itemcache);
        }
 
        Config::set('system', 'itemcache', $itemcache);
@@ -1383,13 +1384,13 @@ function admin_page_site_post(App $a)
        Config::set('system', 'max_comments', $max_comments);
 
        if ($temppath != '') {
-               $temppath = App::getRealPath($temppath);
+               $temppath = BasePath::getRealPath($temppath);
        }
 
        Config::set('system', 'temppath', $temppath);
 
        if ($basepath != '') {
-               $basepath = App::getRealPath($basepath);
+               $basepath = BasePath::getRealPath($basepath);
        }
 
        Config::set('system', 'basepath'         , $basepath);
@@ -1607,7 +1608,7 @@ function admin_page_site(App $a)
                '$hide_help'        => ['hide_help', L10n::t("Hide help entry from navigation menu"), Config::get('system', 'hide_help'), L10n::t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")],
                '$singleuser'       => ['singleuser', L10n::t("Single user instance"), Config::get('system', 'singleuser', '---'), L10n::t("Make this instance multi-user or single-user for the named user"), $user_names],
 
-               '$storagebackend'   => ['storagebackend', L10n::t("File storage backend"), $storage_current_backend, L10n::t('The backend used to store uploaded files data. If you change the storage backend, you have to manually move the existing files see <a href="/help/Settings#1_2_3_1">the settings documentation</a> for more information about the choices and the moving procedure.'), $storage_backends_choices],
+               '$storagebackend'   => ['storagebackend', L10n::t("File storage backend"), $storage_current_backend, L10n::t('The backend used to store uploaded data. If you change the storage backend, you can manually move the existing files. If you do not do so, the files uploaded before the change will still be available at the old backend. Please see <a href="/help/Settings#1_2_3_1">the settings documentation</a> for more information about the choices and the moving procedure.'), $storage_backends_choices],
                '$storageform'      => $storage_form,
                '$maximagesize'     => ['maximagesize', L10n::t("Maximum image size"), Config::get('system', 'maximagesize'), L10n::t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")],
                '$maximagelength'   => ['maximagelength', L10n::t("Maximum image length"), Config::get('system', 'max_image_length'), L10n::t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")],
@@ -1724,7 +1725,7 @@ function admin_page_dbsync(App $a)
        }
 
        if (($a->argc > 2) && (intval($a->argv[2]) || ($a->argv[2] === 'check'))) {
-               $retval = DBStructure::update(false, true);
+               $retval = DBStructure::update($a->getBasePath(), false, true);
                if ($retval === '') {
                        $o .= L10n::t("Database structure update %s was successfully applied.", DB_UPDATE_VERSION) . "<br />";
                        Config::set('database', 'last_successful_update', DB_UPDATE_VERSION);
index d10deb2e88452ce94cbdf4704b35f98053a789ea..80d5f34cc814ee0da16d24cd9d7c31a216079ff4 100644 (file)
@@ -29,7 +29,7 @@ function friendica_init(App $a)
                }
 
                $sql_extra = '';
-               if (!empty($a->config['admin_nickname'])) {
+               if (Config::get('config', 'admin_nickname') !== null) {
                        $sql_extra = sprintf(" AND `nickname` = '%s' ", DBA::escape(Config::get('config', 'admin_nickname')));
                }
                if (!empty(Config::get('config', 'admin_email'))) {
@@ -48,8 +48,9 @@ function friendica_init(App $a)
 
                Config::load('feature_lock');
                $locked_features = [];
-               if (!empty($a->config['feature_lock'])) {
-                       foreach ($a->config['feature_lock'] as $k => $v) {
+               $featureLock = Config::get('config', 'feature_lock');
+               if (isset($featureLock)) {
+                       foreach ($featureLock as $k => $v) {
                                if ($k === 'config_loaded') {
                                        continue;
                                }
index b910765e12f02c35719523d9c9393c6a2cfd86f6..8068a1530bad71a2e3c462e48c710f2751d99b68 100644 (file)
@@ -8,7 +8,10 @@ use Detection\MobileDetect;
 use DOMDocument;
 use DOMXPath;
 use Exception;
+use Friendica\Core\Config\ConfigCache;
+use Friendica\Core\Config\ConfigCacheLoader;
 use Friendica\Database\DBA;
+use Friendica\Factory\ConfigFactory;
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Psr\Log\LoggerInterface;
 
@@ -30,7 +33,6 @@ class App
        public $module_loaded = false;
        public $module_class = null;
        public $query_string = '';
-       public $config = [];
        public $page = [];
        public $profile;
        public $profile_uid;
@@ -112,6 +114,31 @@ class App
         */
        private $logger;
 
+       /**
+        * @var ConfigCache The cached config
+        */
+       private $config;
+
+       /**
+        * Returns the current config cache of this node
+        *
+        * @return ConfigCache
+        */
+       public function getConfig()
+       {
+               return $this->config;
+       }
+
+       /**
+        * The basepath of this app
+        *
+        * @return string
+        */
+       public function getBasePath()
+       {
+               return $this->basePath;
+       }
+
        /**
         * Register a stylesheet file path to be included in the <head> tag of every page.
         * Inclusion is done in App->initHead().
@@ -124,7 +151,7 @@ class App
         */
        public function registerStylesheet($path)
        {
-               $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path);
+               $url = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
 
                $this->stylesheets[] = trim($url, '/');
        }
@@ -141,7 +168,7 @@ class App
         */
        public function registerFooterScript($path)
        {
-               $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path);
+               $url = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $path);
 
                $this->footerScripts[] = trim($url, '/');
        }
@@ -154,23 +181,25 @@ class App
        /**
         * @brief App constructor.
         *
-        * @param string           $basePath  Path to the app base folder
+        * @param ConfigCache      $config    The Cached Config
         * @param LoggerInterface  $logger    Logger 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($basePath, LoggerInterface $logger, $isBackend = true)
+       public function __construct(ConfigCache $config, LoggerInterface $logger, $isBackend = true)
        {
-               $this->logger = $logger;
+               $this->config   = $config;
+               $this->logger   = $logger;
+               $this->basePath = $this->config->get('system', 'basepath');
 
-               if (!static::isDirectoryUsable($basePath, false)) {
-                       throw new Exception('Basepath ' . $basePath . ' isn\'t usable.');
+               if (!Core\System::isDirectoryUsable($this->basePath, false)) {
+                       throw new Exception('Basepath ' . $this->basePath . ' isn\'t usable.');
                }
+               $this->basePath = rtrim($this->basePath, DIRECTORY_SEPARATOR);
 
                BaseObject::setApp($this);
 
-               $this->basePath = rtrim($basePath, DIRECTORY_SEPARATOR);
                $this->checkBackend($isBackend);
                $this->checkFriendicaApp();
 
@@ -195,7 +224,7 @@ class App
                $this->callstack['rendering'] = [];
                $this->callstack['parser'] = [];
 
-               $this->mode = new App\Mode($basePath);
+               $this->mode = new App\Mode($this->basePath);
 
                $this->reload();
 
@@ -226,9 +255,9 @@ class App
 
                set_include_path(
                        get_include_path() . PATH_SEPARATOR
-                       . $this->getBasePath() . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
-                       . $this->getBasePath() . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
-                       . $this->getBasePath());
+                       . $this->basePath . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR
+                       . $this->basePath . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR
+                       . $this->basePath);
 
                if (!empty($_SERVER['QUERY_STRING']) && strpos($_SERVER['QUERY_STRING'], 'pagename=') === 0) {
                        $this->query_string = substr($_SERVER['QUERY_STRING'], 9);
@@ -332,21 +361,32 @@ class App
         */
        public function reload()
        {
-               // The order of the following calls is important to ensure proper initialization
-               $this->loadConfigFiles();
+               Core\Config::init($this->config);
+               Core\PConfig::init($this->config);
 
                $this->loadDatabase();
 
-               $this->getMode()->determine($this->getBasePath());
+               $this->getMode()->determine($this->basePath);
 
                $this->determineURLPath();
 
-               Core\Config::load();
+               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();
-
-                       $this->loadAddonConfig();
+                       $loader = new ConfigCacheLoader($this->basePath);
+                       Core\Hook::callAll('load_config', $loader);
+                       $this->config->loadConfigArray($loader->loadCoreConfig('addon'), true);
                }
 
                $this->loadDefaultTimezone();
@@ -358,158 +398,6 @@ class App
                Core\Logger::setLogger($this->logger);
        }
 
-       /**
-        * Load the configuration files
-        *
-        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
-        * expected local.config.php
-        */
-       private function loadConfigFiles()
-       {
-               $this->loadConfigFile($this->getBasePath() . '/config/defaults.config.php');
-               $this->loadConfigFile($this->getBasePath() . '/config/settings.config.php');
-
-               // Legacy .htconfig.php support
-               if (file_exists($this->getBasePath() . '/.htpreconfig.php')) {
-                       $a = $this;
-                       include $this->getBasePath() . '/.htpreconfig.php';
-               }
-
-               // Legacy .htconfig.php support
-               if (file_exists($this->getBasePath() . '/.htconfig.php')) {
-                       $a = $this;
-
-                       include $this->getBasePath() . '/.htconfig.php';
-
-                       $this->setConfigValue('database', 'hostname', $db_host);
-                       $this->setConfigValue('database', 'username', $db_user);
-                       $this->setConfigValue('database', 'password', $db_pass);
-                       $this->setConfigValue('database', 'database', $db_data);
-                       if (isset($a->config['system']['db_charset'])) {
-                               $this->setConfigValue('database', 'charset', $a->config['system']['db_charset']);
-                       }
-
-                       unset($db_host, $db_user, $db_pass, $db_data);
-
-                       if (isset($default_timezone)) {
-                               $this->setConfigValue('system', 'default_timezone', $default_timezone);
-                               unset($default_timezone);
-                       }
-
-                       if (isset($pidfile)) {
-                               $this->setConfigValue('system', 'pidfile', $pidfile);
-                               unset($pidfile);
-                       }
-
-                       if (isset($lang)) {
-                               $this->setConfigValue('system', 'language', $lang);
-                               unset($lang);
-                       }
-               }
-
-               if (file_exists($this->getBasePath() . '/config/local.config.php')) {
-                       $this->loadConfigFile($this->getBasePath() . '/config/local.config.php', true);
-               } elseif (file_exists($this->getBasePath() . '/config/local.ini.php')) {
-                       $this->loadINIConfigFile($this->getBasePath() . '/config/local.ini.php', true);
-               }
-       }
-
-       /**
-        * Tries to load the specified legacy configuration file into the App->config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * @deprecated since version 2018.12
-        * @param string $filepath
-        * @param bool $overwrite Force value overwrite if the config key already exists
-        * @throws Exception
-        */
-       public function loadINIConfigFile($filepath, $overwrite = false)
-       {
-               if (!file_exists($filepath)) {
-                       throw new Exception('Error parsing non-existent INI config file ' . $filepath);
-               }
-
-               $contents = include($filepath);
-
-               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
-
-               if ($config === false) {
-                       throw new Exception('Error parsing INI config file ' . $filepath);
-               }
-
-               $this->loadConfigArray($config, $overwrite);
-       }
-
-       /**
-        * Tries to load the specified configuration file into the App->config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * The config format is PHP array and the template for configuration files is the following:
-        *
-        * <?php return [
-        *      'section' => [
-        *          'key' => 'value',
-        *      ],
-        * ];
-        *
-        * @param string $filepath
-        * @param bool $overwrite Force value overwrite if the config key already exists
-        * @throws Exception
-        */
-       public function loadConfigFile($filepath, $overwrite = false)
-       {
-               if (!file_exists($filepath)) {
-                       throw new Exception('Error loading non-existent config file ' . $filepath);
-               }
-
-               $config = include($filepath);
-
-               if (!is_array($config)) {
-                       throw new Exception('Error loading config file ' . $filepath);
-               }
-
-               $this->loadConfigArray($config, $overwrite);
-       }
-
-       /**
-        * Loads addons configuration files
-        *
-        * First loads all activated addons default configuration through the load_config hook, then load the local.config.php
-        * again to overwrite potential local addon configuration.
-        */
-       private function loadAddonConfig()
-       {
-               // Loads addons default config
-               Core\Hook::callAll('load_config');
-
-               // Load the local addon config file to overwritten default addon config values
-               if (file_exists($this->getBasePath() . '/config/addon.config.php')) {
-                       $this->loadConfigFile($this->getBasePath() . '/config/addon.config.php', true);
-               } elseif (file_exists($this->getBasePath() . '/config/addon.ini.php')) {
-                       $this->loadINIConfigFile($this->getBasePath() . '/config/addon.ini.php', true);
-               }
-       }
-
-       /**
-        * 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
-        */
-       private function loadConfigArray(array $config, $overwrite = false)
-       {
-               foreach ($config as $category => $values) {
-                       foreach ($values as $key => $value) {
-                               if ($overwrite) {
-                                       $this->setConfigValue($category, $key, $value);
-                               } else {
-                                       $this->setDefaultConfigValue($category, $key, $value);
-                               }
-                       }
-               }
-       }
-
        /**
         * Loads the default timezone
         *
@@ -519,8 +407,8 @@ class App
         */
        private function loadDefaultTimezone()
        {
-               if ($this->getConfigValue('system', 'default_timezone')) {
-                       $this->timezone = $this->getConfigValue('system', 'default_timezone');
+               if ($this->config->get('system', 'default_timezone')) {
+                       $this->timezone = $this->config->get('system', 'default_timezone');
                } else {
                        global $default_timezone;
                        $this->timezone = !empty($default_timezone) ? $default_timezone : 'UTC';
@@ -546,7 +434,7 @@ class App
                $relative_script_path = defaults($_SERVER, 'SCRIPT_URL'         , $relative_script_path);
                $relative_script_path = defaults($_SERVER, 'REQUEST_URI'        , $relative_script_path);
 
-               $this->urlPath = $this->getConfigValue('system', 'urlpath');
+               $this->urlPath = $this->config->get('system', 'urlpath');
 
                /* $relative_script_path gives /relative/path/to/friendica/module/parameter
                 * QUERY_STRING gives pagename=module/parameter
@@ -574,11 +462,11 @@ class App
                        return;
                }
 
-               $db_host = $this->getConfigValue('database', 'hostname');
-               $db_user = $this->getConfigValue('database', 'username');
-               $db_pass = $this->getConfigValue('database', 'password');
-               $db_data = $this->getConfigValue('database', 'database');
-               $charset = $this->getConfigValue('database', 'charset');
+               $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'))
@@ -601,9 +489,9 @@ class App
 
                $stamp1 = microtime(true);
 
-               if (DBA::connect($db_host, $db_user, $db_pass, $db_data, $charset)) {
+               if (DBA::connect($this->config, $db_host, $db_user, $db_pass, $db_data, $charset)) {
                        // Loads DB_UPDATE_VERSION constant
-                       Database\DBStructure::definition(false);
+                       Database\DBStructure::definition($this->basePath, false);
                }
 
                unset($db_host, $db_user, $db_pass, $db_data, $charset);
@@ -611,55 +499,6 @@ class App
                $this->saveTimestamp($stamp1, 'network');
        }
 
-       /**
-        * @brief Returns the base filesystem path of the App
-        *
-        * It first checks for the internal variable, then for DOCUMENT_ROOT and
-        * finally for PWD
-        *
-        * @return string
-        * @throws InternalServerErrorException
-        */
-       public function getBasePath()
-       {
-               $basepath = $this->basePath;
-
-               if (!$basepath) {
-                       $basepath = Core\Config::get('system', 'basepath');
-               }
-
-               if (!$basepath && !empty($_SERVER['DOCUMENT_ROOT'])) {
-                       $basepath = $_SERVER['DOCUMENT_ROOT'];
-               }
-
-               if (!$basepath && !empty($_SERVER['PWD'])) {
-                       $basepath = $_SERVER['PWD'];
-               }
-
-               return self::getRealPath($basepath);
-       }
-
-       /**
-        * @brief Returns a normalized file path
-        *
-        * This is a wrapper for the "realpath" function.
-        * That function cannot detect the real path when some folders aren't readable.
-        * Since this could happen with some hosters we need to handle this.
-        *
-        * @param string $path The path that is about to be normalized
-        * @return string normalized path - when possible
-        */
-       public static function getRealPath($path)
-       {
-               $normalized = realpath($path);
-
-               if (!is_bool($normalized)) {
-                       return $normalized;
-               } else {
-                       return $path;
-               }
-       }
-
        public function getScheme()
        {
                return $this->scheme;
@@ -735,8 +574,8 @@ class App
                                $this->urlPath = trim($parsed['path'], '\\/');
                        }
 
-                       if (file_exists($this->getBasePath() . '/.htpreconfig.php')) {
-                               include $this->getBasePath() . '/.htpreconfig.php';
+                       if (file_exists($this->basePath . '/.htpreconfig.php')) {
+                               include $this->basePath . '/.htpreconfig.php';
                        }
 
                        if (Core\Config::get('config', 'hostname') != '') {
@@ -789,9 +628,9 @@ class App
                // compose the page title from the sitename and the
                // current module called
                if (!$this->module == '') {
-                       $this->page['title'] = $this->config['sitename'] . ' (' . $this->module . ')';
+                       $this->page['title'] = $this->config->get('config', 'sitename') . ' (' . $this->module . ')';
                } else {
-                       $this->page['title'] = $this->config['sitename'];
+                       $this->page['title'] = $this->config->get('config', 'sitename');
                }
 
                if (!empty(Core\Renderer::$theme['stylesheet'])) {
@@ -912,7 +751,9 @@ class App
         */
        public function saveTimestamp($timestamp, $value)
        {
-               if (!isset($this->config['system']['profiler']) || !$this->config['system']['profiler']) {
+               $profiler = $this->config->get('system', 'profiler');
+
+               if (!isset($profiler) || !$profiler) {
                        return;
                }
 
@@ -1150,7 +991,7 @@ class App
                        return;
                }
 
-               $cmdline = $this->getConfigValue('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
+               $cmdline = $this->config->get('config', 'php_path', 'php') . ' ' . escapeshellarg($command);
 
                foreach ($args as $key => $value) {
                        if (!is_null($value) && is_bool($value) && !$value) {
@@ -1168,9 +1009,9 @@ class App
                }
 
                if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
-                       $resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->getBasePath());
+                       $resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->basePath);
                } else {
-                       $resource = proc_open($cmdline . ' &', [], $foo, $this->getBasePath());
+                       $resource = proc_open($cmdline . ' &', [], $foo, $this->basePath);
                }
                if (!is_resource($resource)) {
                        Core\Logger::log('We got no resource for command ' . $cmdline, Core\Logger::DEBUG);
@@ -1179,203 +1020,6 @@ class App
                proc_close($resource);
        }
 
-       /**
-        * @brief Returns the system user that is executing the script
-        *
-        * This mostly returns something like "www-data".
-        *
-        * @return string system username
-        */
-       private static function getSystemUser()
-       {
-               if (!function_exists('posix_getpwuid') || !function_exists('posix_geteuid')) {
-                       return '';
-               }
-
-               $processUser = posix_getpwuid(posix_geteuid());
-               return $processUser['name'];
-       }
-
-       /**
-        * @brief Checks if a given directory is usable for the system
-        *
-        * @param      $directory
-        * @param bool $check_writable
-        * @return boolean the directory is usable
-        * @throws Exception
-        */
-       public static function isDirectoryUsable($directory, $check_writable = true)
-       {
-               if ($directory == '') {
-                       Core\Logger::log('Directory is empty. This shouldn\'t happen.', Core\Logger::DEBUG);
-                       return false;
-               }
-
-               if (!file_exists($directory)) {
-                       Core\Logger::log('Path "' . $directory . '" does not exist for user ' . self::getSystemUser(), Core\Logger::DEBUG);
-                       return false;
-               }
-
-               if (is_file($directory)) {
-                       Core\Logger::log('Path "' . $directory . '" is a file for user ' . self::getSystemUser(), Core\Logger::DEBUG);
-                       return false;
-               }
-
-               if (!is_dir($directory)) {
-                       Core\Logger::log('Path "' . $directory . '" is not a directory for user ' . self::getSystemUser(), Core\Logger::DEBUG);
-                       return false;
-               }
-
-               if ($check_writable && !is_writable($directory)) {
-                       Core\Logger::log('Path "' . $directory . '" is not writable for user ' . self::getSystemUser(), Core\Logger::DEBUG);
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * @param string $cat     Config category
-        * @param string $k       Config key
-        * @param mixed  $default Default value if it isn't set
-        *
-        * @return string Returns the value of the Config entry
-        */
-       public function getConfigValue($cat, $k, $default = null)
-       {
-               $return = $default;
-
-               if ($cat === 'config') {
-                       if (isset($this->config[$k])) {
-                               $return = $this->config[$k];
-                       }
-               } else {
-                       if (isset($this->config[$cat][$k])) {
-                               $return = $this->config[$cat][$k];
-                       }
-               }
-
-               return $return;
-       }
-
-       /**
-        * Sets a default value in the config cache. Ignores already existing keys.
-        *
-        * @param string $cat Config category
-        * @param string $k   Config key
-        * @param mixed  $v   Default value to set
-        */
-       private function setDefaultConfigValue($cat, $k, $v)
-       {
-               if (!isset($this->config[$cat][$k])) {
-                       $this->setConfigValue($cat, $k, $v);
-               }
-       }
-
-       /**
-        * Sets a value in the config cache. Accepts raw output from the config table
-        *
-        * @param string $cat Config category
-        * @param string $k   Config key
-        * @param mixed  $v   Value to set
-        */
-       public function setConfigValue($cat, $k, $v)
-       {
-               // Only arrays are serialized in database, so we have to unserialize sparingly
-               $value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
-
-               if ($cat === 'config') {
-                       $this->config[$k] = $value;
-               } else {
-                       if (!isset($this->config[$cat])) {
-                               $this->config[$cat] = [];
-                       }
-
-                       $this->config[$cat][$k] = $value;
-               }
-       }
-
-       /**
-        * Deletes a value from the config cache
-        *
-        * @param string $cat Config category
-        * @param string $k   Config key
-        */
-       public function deleteConfigValue($cat, $k)
-       {
-               if ($cat === 'config') {
-                       if (isset($this->config[$k])) {
-                               unset($this->config[$k]);
-                       }
-               } else {
-                       if (isset($this->config[$cat][$k])) {
-                               unset($this->config[$cat][$k]);
-                       }
-               }
-       }
-
-
-       /**
-        * Retrieves a value from the user config cache
-        *
-        * @param int    $uid     User Id
-        * @param string $cat     Config category
-        * @param string $k       Config key
-        * @param mixed  $default Default value if key isn't set
-        *
-        * @return string The value of the config entry
-        */
-       public function getPConfigValue($uid, $cat, $k, $default = null)
-       {
-               $return = $default;
-
-               if (isset($this->config[$uid][$cat][$k])) {
-                       $return = $this->config[$uid][$cat][$k];
-               }
-
-               return $return;
-       }
-
-       /**
-        * 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 $k   Config key
-        * @param mixed  $v   Value to set
-        */
-       public function setPConfigValue($uid, $cat, $k, $v)
-       {
-               // Only arrays are serialized in database, so we have to unserialize sparingly
-               $value = is_string($v) && preg_match("|^a:[0-9]+:{.*}$|s", $v) ? unserialize($v) : $v;
-
-               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
-                       $this->config[$uid] = [];
-               }
-
-               if (!isset($this->config[$uid][$cat]) || !is_array($this->config[$uid][$cat])) {
-                       $this->config[$uid][$cat] = [];
-               }
-
-               $this->config[$uid][$cat][$k] = $value;
-       }
-
-       /**
-        * Deletes a value from the user config cache
-        *
-        * @param int    $uid User Id
-        * @param string $cat Config category
-        * @param string $k   Config key
-        */
-       public function deletePConfigValue($uid, $cat, $k)
-       {
-               if (isset($this->config[$uid][$cat][$k])) {
-                       unset($this->config[$uid][$cat][$k]);
-               }
-       }
-
        /**
         * Generates the site's default sender email address
         *
@@ -1643,7 +1287,7 @@ class App
                        $this->module = 'maintenance';
                } else {
                        $this->checkURL();
-                       Core\Update::check(false);
+                       Core\Update::check($this->basePath, false);
                        Core\Addon::loadAddons();
                        Core\Hook::loadHooks();
                }
index 84ff193823113a1534e3e407ac2eb712f3fda5f0..4a6fa12d24b03ad18f4542114f1302d8a9e3573e 100644 (file)
@@ -6,7 +6,7 @@ namespace Friendica;
 
 require_once 'boot.php';
 
-use Friendica\Util\LoggerFactory;
+use Friendica\Network\HTTPException\InternalServerErrorException;
 
 /**
  * Basic object
@@ -28,8 +28,7 @@ class BaseObject
        public static function getApp()
        {
                if (empty(self::$app)) {
-                       $logger = $logger = LoggerFactory::create('app');
-                       self::$app = new App(dirname(__DIR__), $logger);
+                       throw new InternalServerErrorException('App isn\'t initialized.');
                }
 
                return self::$app;
index 1118280a53e4bd0ca02394394a36e1fdc173d56f..14b163f165db2c3a77fbd4c3544d5bf34d7d3447 100644 (file)
@@ -12,6 +12,12 @@ use Friendica\Database\DBA;
  */
 class Addon extends BaseObject
 {
+       /**
+        * The addon sub-directory
+        * @var string
+        */
+       const DIRECTORY = 'addon';
+
        /**
         * List of the names of enabled addons
         *
index 755dc6ebbcf50bfcc82e9f31a7877ea5d89ea8e3..6ceb637701a251506c4d32a09b9d52af2edcfa55 100644 (file)
@@ -8,8 +8,9 @@
  */
 namespace Friendica\Core;
 
-use Friendica\App;
-use Friendica\BaseObject;
+use Friendica\Core\Config\ConfigCache;
+use Friendica\Core\Config\IConfigAdapter;
+use Friendica\Core\Config\IConfigCache;
 
 /**
  * @brief Arbitrary system configuration storage
@@ -18,49 +19,53 @@ use Friendica\BaseObject;
  * If we ever would decide to return exactly the variable type as entered,
  * we will have fun with the additional features. :-)
  */
-class Config extends BaseObject
+class Config
 {
        /**
-        * @var \Friendica\Core\Config\IConfigAdapter
+        * @var Config\IConfigAdapter
         */
-       private static $adapter = null;
+       private static $adapter;
 
-       public static function init()
+       /**
+        * @var Config\IConfigCache
+        */
+       private static $cache;
+
+       /**
+        * Initialize the config with only the cache
+        *
+        * @param Config\IConfigCache $cache  The configuration cache
+        */
+       public static function init(Config\IConfigCache $cache)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return;
-               }
+               self::$cache  = $cache;
+       }
 
-               if (self::getApp()->getConfigValue('system', 'config_adapter') == 'preload') {
-                       self::$adapter = new Config\PreloadConfigAdapter();
-               } else {
-                       self::$adapter = new Config\JITConfigAdapter();
-               }
+       /**
+        * Add the adapter for DB-backend
+        *
+        * @param Config\IConfigAdapter $adapter
+        */
+       public static function setAdapter(Config\IConfigAdapter $adapter)
+       {
+               self::$adapter = $adapter;
        }
 
        /**
         * @brief Loads all configuration values of family into a cached storage.
         *
-        * All configuration values of the system are stored in global cache
-        * which is available under the global variable $a->config
+        * All configuration values of the system are stored in the cache ( @see IConfigCache )
         *
         * @param string $family The category of the configuration value
         *
         * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function load($family = "config")
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+               if (!isset(self::$adapter)) {
                        return;
                }
 
-               if (empty(self::$adapter)) {
-                       self::init();
-               }
-
                self::$adapter->load($family);
        }
 
@@ -69,12 +74,8 @@ class Config extends BaseObject
         * ($family) and a key.
         *
         * Get a particular config value from the given category ($family)
-        * and the $key from a cached storage in $a->config[$uid].
-        * $instore is only used by the set_config function
-        * to determine if the key already exists in the DB
-        * If a key is found in the DB but doesn't exist in
-        * local config cache, pull it into the cache so we don't have
-        * to hit the DB again for this item.
+        * 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  $key           The configuration key to query
@@ -82,17 +83,11 @@ class Config extends BaseObject
         * @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
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function get($family, $key, $default_value = null, $refresh = false)
        {
-               // Database isn't ready or populated yet, fallback to file config
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return self::getApp()->getConfigValue($family, $key, $default_value);
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init();
+               if (!isset(self::$adapter)) {
+                       return self::$cache->get($family, $key, $default_value);
                }
 
                return self::$adapter->get($family, $key, $default_value, $refresh);
@@ -102,7 +97,6 @@ class Config extends BaseObject
         * @brief Sets a configuration value for system config
         *
         * Stores a config value ($value) in the category ($family) under the key ($key)
-        * for the user_id $uid.
         *
         * Note: Please do not store booleans - convert to 0/1 integer values!
         *
@@ -111,17 +105,12 @@ class Config extends BaseObject
         * @param mixed  $value  The value to store
         *
         * @return bool Operation success
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function set($family, $key, $value)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return false;
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init();
+               if (!isset(self::$adapter)) {
+                       self::$cache->set($family, $key, $value);
+                       return true;
                }
 
                return self::$adapter->set($family, $key, $value);
@@ -130,24 +119,18 @@ class Config extends BaseObject
        /**
         * @brief Deletes the given key from the system configuration.
         *
-        * Removes the configured value from the stored cache in $a->config
-        * and removes it from the database.
+        * 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 $key    The configuration key to delete
         *
         * @return mixed
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function delete($family, $key)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return false;
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init();
+               if (!isset(self::$adapter)) {
+                       self::$cache->delete($family, $key);
                }
 
                return self::$adapter->delete($family, $key);
diff --git a/src/Core/Config/ConfigCache.php b/src/Core/Config/ConfigCache.php
new file mode 100644 (file)
index 0000000..e03d352
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+
+namespace Friendica\Core\Config;
+
+/**
+ * The Friendica config cache for the application
+ * Initial, all *.config.php files are loaded into this cache with the
+ * ConfigCacheLoader ( @see ConfigCacheLoader )
+ *
+ * Is used for further caching operations too (depending on the ConfigAdapter )
+ */
+class ConfigCache implements IConfigCache, IPConfigCache
+{
+       private $config;
+
+       /**
+        * @param array $config    A initial config array
+        */
+       public function __construct(array $config = [])
+       {
+               $this->config = $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
+        */
+       public function loadConfigArray(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);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function get($cat, $key = null, $default = null)
+       {
+               $return = $default;
+
+               if ($cat === 'config') {
+                       if (isset($this->config[$key])) {
+                               $return = $this->config[$key];
+                       }
+               } else {
+                       if (isset($this->config[$cat][$key])) {
+                               $return = $this->config[$cat][$key];
+                       } elseif ($key == null && isset($this->config[$cat])) {
+                               $return = $this->config[$cat];
+                       }
+               }
+
+               return $return;
+       }
+
+       /**
+        * Sets a default value in the config cache. Ignores already existing keys.
+        *
+        * @param string $cat Config category
+        * @param string $k   Config key
+        * @param mixed  $v   Default value to set
+        */
+       private function setDefault($cat, $k, $v)
+       {
+               if (!isset($this->config[$cat][$k])) {
+                       $this->set($cat, $k, $v);
+               }
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function set($cat, $key, $value)
+       {
+               // Only arrays are serialized in database, so we have to unserialize sparingly
+               $value = is_string($value) && preg_match("|^a:[0-9]+:{.*}$|s", $value) ? unserialize($value) : $value;
+
+               if ($cat === 'config') {
+                       $this->config[$key] = $value;
+               } else {
+                       if (!isset($this->config[$cat])) {
+                               $this->config[$cat] = [];
+                       }
+
+                       $this->config[$cat][$key] = $value;
+               }
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function delete($cat, $key)
+       {
+               if ($cat === 'config') {
+                       if (isset($this->config[$key])) {
+                               unset($this->config[$key]);
+                       }
+               } else {
+                       if (isset($this->config[$cat][$key])) {
+                               unset($this->config[$cat][$key]);
+                       }
+               }
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function getP($uid, $cat, $key = null, $default = 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 $return;
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function setP($uid, $cat, $key, $value)
+       {
+               // Only arrays are serialized in database, so we have to unserialize sparingly
+               $value = is_string($value) && preg_match("|^a:[0-9]+:{.*}$|s", $value) ? unserialize($value) : $value;
+
+               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
+                       $this->config[$uid] = [];
+               }
+
+               if (!isset($this->config[$uid][$cat]) || !is_array($this->config[$uid][$cat])) {
+                       $this->config[$uid][$cat] = [];
+               }
+
+               if ($key === null) {
+                       $this->config[$uid][$cat] = $value;
+               } else {
+                       $this->config[$uid][$cat][$key] = $value;
+               }
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function deleteP($uid, $cat, $key)
+       {
+               if (isset($this->config[$uid][$cat][$key])) {
+                       unset($this->config[$uid][$cat][$key]);
+               }
+       }
+
+       /**
+        * Returns the whole configuration
+        *
+        * @return array The configuration
+        */
+       public function getAll()
+       {
+               return $this->config;
+       }
+}
diff --git a/src/Core/Config/ConfigCacheLoader.php b/src/Core/Config/ConfigCacheLoader.php
new file mode 100644 (file)
index 0000000..0b87614
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+namespace Friendica\Core\Config;
+
+use Friendica\Core\Addon;
+
+/**
+ * The ConfigCacheLoader loads config-files and stores them in a ConfigCache ( @see ConfigCache )
+ *
+ * It is capable of loading the following config files:
+ * - *.config.php   (current)
+ * - *.ini.php      (deprecated)
+ * - *.htconfig.php (deprecated)
+ */
+class ConfigCacheLoader
+{
+       /**
+        * The Sub directory of the config-files
+        * @var string
+        */
+       const SUBDIRECTORY = 'config';
+
+       private $baseDir;
+       private $configDir;
+
+       public function __construct($baseDir)
+       {
+               $this->baseDir = $baseDir;
+               $this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::SUBDIRECTORY;
+       }
+
+       /**
+        * Load the configuration files
+        *
+        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
+        * expected local.config.php
+        */
+       public function loadConfigFiles(ConfigCache $config)
+       {
+               // Setting at least the basepath we know
+               $config->set('system', 'basepath', $this->baseDir);
+
+               $config->loadConfigArray($this->loadCoreConfig('defaults'));
+               $config->loadConfigArray($this->loadCoreConfig('settings'));
+
+               $config->loadConfigArray($this->loadLegacyConfig('htpreconfig'), true);
+               $config->loadConfigArray($this->loadLegacyConfig('htconfig'), true);
+
+               $config->loadConfigArray($this->loadCoreConfig('local'), true);
+       }
+
+       /**
+        * Tries to load the specified core-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws \Exception if the configuration file isn't readable
+        */
+       public function loadCoreConfig($name)
+       {
+               if (file_exists($this->configDir . DIRECTORY_SEPARATOR . $name . '.config.php')) {
+                       return $this->loadConfigFile($this->configDir . DIRECTORY_SEPARATOR . $name . '.config.php');
+               } elseif (file_exists($this->configDir . DIRECTORY_SEPARATOR . $name . '.ini.php')) {
+                       return $this->loadINIConfigFile($this->configDir . DIRECTORY_SEPARATOR . $name . '.ini.php');
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the specified addon-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws \Exception if the configuration file isn't readable
+        */
+       public function loadAddonConfig($name)
+       {
+               $filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
+                       Addon::DIRECTORY       . DIRECTORY_SEPARATOR . // addon/
+                       $name                  . DIRECTORY_SEPARATOR . // openstreetmap/
+                       self::SUBDIRECTORY     . DIRECTORY_SEPARATOR . // config/
+                       $name . ".config.php";                         // openstreetmap.config.php
+
+               if (file_exists($filepath)) {
+                       return $this->loadConfigFile($filepath);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
+        *
+        * @param string $name The name of the config file
+        *
+        * @return array The configuration array (empty if no config found)
+        *
+        * @deprecated since version 2018.09
+        */
+       private function loadLegacyConfig($name)
+       {
+               $filePath = $this->baseDir  . DIRECTORY_SEPARATOR . '.' . $name . '.php';
+
+               if (file_exists($filePath)) {
+                       $a = new \stdClass();
+                       $a->config = [];
+                       include $filePath;
+
+                       if (isset($db_host)) {
+                               $a->config['database']['hostname'] = $db_host;
+                               unset($db_host);
+                       }
+                       if (isset($db_user)) {
+                               $a->config['database']['username'] = $db_user;
+                               unset($db_user);
+                       }
+                       if (isset($db_pass)) {
+                               $a->config['database']['password'] = $db_pass;
+                               unset($db_pass);
+                       }
+                       if (isset($db_data)) {
+                               $a->config['database']['database'] = $db_data;
+                               unset($db_data);
+                       }
+                       if (isset($a->config['system']['db_charset'])) {
+                               $a->config['database']['charset'] = $a->config['system']['charset'];
+                       }
+                       if (isset($pidfile)) {
+                               $a->config['system']['pidfile'] = $pidfile;
+                               unset($pidfile);
+                       }
+                       if (isset($default_timezone)) {
+                               $a->config['system']['default_timezone'] = $default_timezone;
+                               unset($default_timezone);
+                       }
+                       if (isset($lang)) {
+                               $a->config['system']['language'] = $lang;
+                               unset($lang);
+                       }
+
+                       return $a->config;
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the specified legacy configuration file and returns the config array.
+        *
+        * @deprecated since version 2018.12
+        * @param string $filepath
+        *
+        * @return array The configuration array
+        * @throws \Exception
+        */
+       private function loadINIConfigFile($filepath)
+       {
+               if (!file_exists($filepath)) {
+                       throw new \Exception('Error parsing non-existent INI config file ' . $filepath);
+               }
+
+               $contents = include($filepath);
+
+               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
+
+               if ($config === false) {
+                       throw new \Exception('Error parsing INI config file ' . $filepath);
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified configuration file and returns the config array.
+        *
+        * The config format is PHP array and the template for configuration files is the following:
+        *
+        * <?php return [
+        *      'section' => [
+        *          'key' => 'value',
+        *      ],
+        * ];
+        *
+        * @param  string $filepath The filepath of the
+        * @return array The config array0
+        *
+        * @throws \Exception if the config cannot get loaded.
+        */
+       private function loadConfigFile($filepath)
+       {
+               if (!file_exists($filepath)) {
+                       throw new \Exception('Error loading non-existent config file ' . $filepath);
+               }
+
+               $config = include($filepath);
+
+               if (!is_array($config)) {
+                       throw new \Exception('Error loading config file ' . $filepath);
+               }
+
+               return $config;
+       }
+}
index 9d8eefd777406181afd1bfa5b95e549886abdcdc..139483de26922d9db7761e2a413d7a6218af098a 100644 (file)
@@ -9,10 +9,7 @@ namespace Friendica\Core\Config;
 interface IConfigAdapter
 {
        /**
-        * @brief Loads all configuration values into a cached storage.
-        *
-        * All configuration values of the system are stored in global cache
-        * which is available under the global variable $a->config
+        * Loads all configuration values into a cached storage.
         *
         * @param string  $cat The category of the configuration values to load
         *
@@ -21,17 +18,9 @@ interface IConfigAdapter
        public function load($cat = "config");
 
        /**
-        * @brief Get a particular user's config variable given the category name
+        * Get a particular user's config variable given the category name
         * ($family) and a key.
         *
-        * Get a particular config value from the given category ($family)
-        * and the $key from a cached storage in $a->config[$uid].
-        * $instore is only used by the set_config function
-        * to determine if the key already exists in the DB
-        * If a key is found in the DB but doesn't exist in
-        * local config cache, pull it into the cache so we don't have
-        * to hit the DB again for this item.
-        *
         * @param string  $cat           The category of the configuration value
         * @param string  $k             The configuration key to query
         * @param mixed   $default_value optional, The value to return if key is not set (default: null)
@@ -42,8 +31,6 @@ interface IConfigAdapter
        public function get($cat, $k, $default_value = null, $refresh = false);
 
        /**
-        * @brief Sets a configuration value for system config
-        *
         * Stores a config value ($value) in the category ($family) under the key ($key)
         * for the user_id $uid.
         *
@@ -58,9 +45,7 @@ interface IConfigAdapter
        public function set($cat, $k, $value);
 
        /**
-        * @brief Deletes the given key from the system configuration.
-        *
-        * Removes the configured value from the stored cache in $a->config
+        * Removes the configured value from the stored cache
         * and removes it from the database.
         *
         * @param string $cat The category of the configuration value
diff --git a/src/Core/Config/IConfigCache.php b/src/Core/Config/IConfigCache.php
new file mode 100644 (file)
index 0000000..8266cc2
--- /dev/null
@@ -0,0 +1,37 @@
+<?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
+        */
+       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();
+}
index b912418432e1eb86d15005a4da20911b3cd84bbd..e62fc9c93fb83e0a427fcc638d05839229fb2c35 100644 (file)
@@ -15,10 +15,7 @@ namespace Friendica\Core\Config;
 interface IPConfigAdapter
 {
        /**
-        * @brief Loads all configuration values of a user's config family into a cached storage.
-        *
-        * All configuration values of the given user are stored in global cache
-        * which is available under the global variable $a->config[$uid].
+        * Loads all configuration values of a user's config family into a cached storage.
         *
         * @param string $uid The user_id
         * @param string $cat The category of the configuration value
@@ -28,12 +25,9 @@ interface IPConfigAdapter
        public function load($uid, $cat);
 
        /**
-        * @brief Get a particular user's config variable given the category name
+        * Get a particular user's config variable given the category name
         * ($family) and a key.
         *
-        * Get a particular user's config value from the given category ($family)
-        * and the $key from a cached storage in $a->config[$uid].
-        *
         * @param string  $uid           The user_id
         * @param string  $cat           The category of the configuration value
         * @param string  $k             The configuration key to query
@@ -45,8 +39,6 @@ interface IPConfigAdapter
        public function get($uid, $cat, $k, $default_value = null, $refresh = false);
 
        /**
-        * @brief Sets a configuration value for a user
-        *
         * Stores a config value ($value) in the category ($family) under the key ($key)
         * for the user_id $uid.
         *
@@ -62,9 +54,7 @@ interface IPConfigAdapter
        public function set($uid, $cat, $k, $value);
 
        /**
-        * @brief Deletes the given key from the users's configuration.
-        *
-        * Removes the configured value from the stored cache in $a->config[$uid]
+        * Removes the configured value from the stored cache
         * and removes it from the database.
         *
         * @param string $uid The user_id
diff --git a/src/Core/Config/IPConfigCache.php b/src/Core/Config/IPConfigCache.php
new file mode 100644 (file)
index 0000000..6a57daf
--- /dev/null
@@ -0,0 +1,44 @@
+<?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();
+}
index ce1c13b2cae8b82b8e9e776064ac3027756dfece..e7aecb933b673af56a7a65e9f3cdccf28f596d37 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 namespace Friendica\Core\Config;
 
-use Friendica\BaseObject;
 use Friendica\Database\DBA;
 
 /**
@@ -11,11 +10,27 @@ use Friendica\Database\DBA;
  *
  * @author Hypolite Petovan <hypolite@mrpetovan.com>
  */
-class JITConfigAdapter extends BaseObject implements IConfigAdapter
+class JITConfigAdapter 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;
+       }
+
+       /**
+        * {@inheritdoc}
+        */
        public function load($cat = "config")
        {
                // We don't preload "system" anymore.
@@ -28,7 +43,7 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                while ($config = DBA::fetch($configs)) {
                        $k = $config['k'];
 
-                       self::getApp()->setConfigValue($cat, $k, $config['v']);
+                       $this->configCache->set($cat, $k, $config['v']);
 
                        if ($cat !== 'config') {
                                $this->cache[$cat][$k] = $config['v'];
@@ -38,10 +53,11 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                DBA::close($configs);
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function get($cat, $k, $default_value = null, $refresh = false)
        {
-               $a = self::getApp();
-
                if (!$refresh) {
                        // Do we have the cached value? Then return it
                        if (isset($this->cache[$cat][$k])) {
@@ -62,18 +78,18 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                        $this->cache[$cat][$k] = $value;
                        $this->in_db[$cat][$k] = true;
                        return $value;
-               } elseif (isset($a->config[$cat][$k])) {
+               } elseif ($this->configCache->get($cat, $k) !== null) {
                        // Assign the value (mostly) from config/local.config.php file to the cache
-                       $this->cache[$cat][$k] = $a->config[$cat][$k];
+                       $this->cache[$cat][$k] = $this->configCache->get($cat, $k);
                        $this->in_db[$cat][$k] = false;
 
-                       return $a->config[$cat][$k];
-               } elseif (isset($a->config[$k])) {
+                       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] = $a->config[$k];
+                       $this->cache[$k] = $this->configCache->get('config', $k);
                        $this->in_db[$k] = false;
 
-                       return $a->config[$k];
+                       return $this->configCache->get('config', $k);
                }
 
                $this->cache[$cat][$k] = '!<unset>!';
@@ -82,6 +98,9 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                return $default_value;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function set($cat, $k, $value)
        {
                // We store our setting values in a string variable.
@@ -102,7 +121,7 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                        return true;
                }
 
-               self::getApp()->setConfigValue($cat, $k, $value);
+               $this->configCache->set($cat, $k, $value);
 
                // Assign the just added value to the cache
                $this->cache[$cat][$k] = $dbvalue;
@@ -119,6 +138,9 @@ class JITConfigAdapter extends BaseObject implements IConfigAdapter
                return $result;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function delete($cat, $k)
        {
                if (isset($this->cache[$cat][$k])) {
index bdaca407ffa583f88aa0c5c36a2dcf0fb4275471..b1a15601cc4cdaa28efbd7687c7c0aeb65e65097 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 namespace Friendica\Core\Config;
 
-use Friendica\BaseObject;
 use Friendica\Database\DBA;
 
 /**
@@ -11,47 +10,63 @@ use Friendica\Database\DBA;
  *
  * @author Hypolite Petovan <hypolite@mrpetovan.com>
  */
-class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
+class JITPConfigAdapter implements IPConfigAdapter
 {
        private $in_db;
 
-       public function load($uid, $cat)
+       /**
+        * The config cache of this adapter
+        * @var IPConfigCache
+        */
+       private $configCache;
+
+       /**
+        * @param IPConfigCache $configCache The config cache of this adapter
+        */
+       public function __construct(IPConfigCache $configCache)
        {
-               $a = self::getApp();
+               $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'];
 
-                               self::getApp()->setPConfigValue($uid, $cat, $k, $pconfig['v']);
+                               $this->configCache->setP($uid, $cat, $k, $pconfig['v']);
 
                                $this->in_db[$uid][$cat][$k] = true;
                        }
                } else if ($cat != 'config') {
                        // Negative caching
-                       $a->config[$uid][$cat] = "!<unset>!";
+                       $this->configCache->setP($uid, $cat, null, "!<unset>!");
                }
                DBA::close($pconfigs);
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function get($uid, $cat, $k, $default_value = null, $refresh = false)
        {
-               $a = self::getApp();
-
                if (!$refresh) {
                        // Looking if the whole family isn't set
-                       if (isset($a->config[$uid][$cat])) {
-                               if ($a->config[$uid][$cat] === '!<unset>!') {
+                       if ($this->configCache->getP($uid, $cat) !== null) {
+                               if ($this->configCache->getP($uid, $cat) === '!<unset>!') {
                                        return $default_value;
                                }
                        }
 
-                       if (isset($a->config[$uid][$cat][$k])) {
-                               if ($a->config[$uid][$cat][$k] === '!<unset>!') {
+                       if ($this->configCache->getP($uid, $cat, $k) !== null) {
+                               if ($this->configCache->getP($uid, $cat, $k) === '!<unset>!') {
                                        return $default_value;
                                }
-                               return $a->config[$uid][$cat][$k];
+                               return $this->configCache->getP($uid, $cat, $k);
                        }
                }
 
@@ -59,13 +74,13 @@ class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
                if (DBA::isResult($pconfig)) {
                        $val = (preg_match("|^a:[0-9]+:{.*}$|s", $pconfig['v']) ? unserialize($pconfig['v']) : $pconfig['v']);
 
-                       self::getApp()->setPConfigValue($uid, $cat, $k, $val);
+                       $this->configCache->setP($uid, $cat, $k, $val);
 
                        $this->in_db[$uid][$cat][$k] = true;
 
                        return $val;
                } else {
-                       self::getApp()->setPConfigValue($uid, $cat, $k, '!<unset>!');
+                       $this->configCache->setP($uid, $cat, $k, '!<unset>!');
 
                        $this->in_db[$uid][$cat][$k] = false;
 
@@ -73,6 +88,9 @@ class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
                }
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function set($uid, $cat, $k, $value)
        {
                // We store our setting values in a string variable.
@@ -86,7 +104,7 @@ class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
                        return true;
                }
 
-               self::getApp()->setPConfigValue($uid, $cat, $k, $value);
+               $this->configCache->setP($uid, $cat, $k, $value);
 
                // manage array value
                $dbvalue = (is_array($value) ? serialize($value) : $dbvalue);
@@ -100,9 +118,12 @@ class JITPConfigAdapter extends BaseObject implements IPConfigAdapter
                return $result;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function delete($uid, $cat, $k)
        {
-               self::getApp()->deletePConfigValue($uid, $cat, $k);
+               $this->configCache->deleteP($uid, $cat, $k);
 
                if (!empty($this->in_db[$uid][$cat][$k])) {
                        unset($this->in_db[$uid][$cat][$k]);
index ac59d945580ca6d6e55ffebda4fdff8a042a5c4a..d5fbd982bf56e6f912fa5568c3168087819fdf61 100644 (file)
@@ -3,7 +3,6 @@
 namespace Friendica\Core\Config;
 
 use Exception;
-use Friendica\BaseObject;
 use Friendica\Database\DBA;
 
 /**
@@ -13,15 +12,27 @@ use Friendica\Database\DBA;
  *
  * @author Hypolite Petovan <hypolite@mrpetovan.com>
  */
-class PreloadConfigAdapter extends BaseObject implements IConfigAdapter
+class PreloadConfigAdapter implements IConfigAdapter
 {
        private $config_loaded = false;
 
-       public function __construct()
+       /**
+        * @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->load();
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function load($family = 'config')
        {
                if ($this->config_loaded) {
@@ -30,27 +41,33 @@ class PreloadConfigAdapter extends BaseObject implements IConfigAdapter
 
                $configs = DBA::select('config', ['cat', 'v', 'k']);
                while ($config = DBA::fetch($configs)) {
-                       self::getApp()->setConfigValue($config['cat'], $config['k'], $config['v']);
+                       $this->configCache->set($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 ($refresh) {
                        $config = DBA::selectFirst('config', ['v'], ['cat' => $cat, 'k' => $k]);
                        if (DBA::isResult($config)) {
-                               self::getApp()->setConfigValue($cat, $k, $config['v']);
+                               $this->configCache->set($cat, $k, $config['v']);
                        }
                }
 
-               $return = self::getApp()->getConfigValue($cat, $k, $default_value);
+               $return = $this->configCache->get($cat, $k, $default_value);
 
                return $return;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function set($cat, $k, $value)
        {
                // We store our setting values as strings.
@@ -58,11 +75,11 @@ class PreloadConfigAdapter extends BaseObject implements IConfigAdapter
                // The exception are array values.
                $compare_value = !is_array($value) ? (string)$value : $value;
 
-               if (self::getApp()->getConfigValue($cat, $k) === $compare_value) {
+               if ($this->configCache->get($cat, $k) === $compare_value) {
                        return true;
                }
 
-               self::getApp()->setConfigValue($cat, $k, $value);
+               $this->configCache->set($cat, $k, $value);
 
                // manage array value
                $dbvalue = is_array($value) ? serialize($value) : $value;
@@ -75,9 +92,12 @@ class PreloadConfigAdapter extends BaseObject implements IConfigAdapter
                return true;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function delete($cat, $k)
        {
-               self::getApp()->deleteConfigValue($cat, $k);
+               $this->configCache->delete($cat, $k);
 
                $result = DBA::delete('config', ['cat' => $cat, 'k' => $k]);
 
index 6658efa3f67f571e2d1c93f60aa17bb67392a8ba..af97815adef38d159ab6ba44f27766d10ed7ca9d 100644 (file)
@@ -3,7 +3,6 @@
 namespace Friendica\Core\Config;
 
 use Exception;
-use Friendica\BaseObject;
 use Friendica\Database\DBA;
 
 /**
@@ -13,15 +12,31 @@ use Friendica\Database\DBA;
  *
  * @author Hypolite Petovan <hypolite@mrpetovan.com>
  */
-class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
+class PreloadPConfigAdapter implements IPConfigAdapter
 {
        private $config_loaded = false;
 
-       public function __construct($uid)
+       /**
+        * The config cache of this adapter
+        * @var IPConfigCache
+        */
+       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)
        {
-               $this->load($uid, 'config');
+               $this->configCache = $configCache;
+               if (isset($uid)) {
+                       $this->load($uid, 'config');
+               }
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function load($uid, $family)
        {
                if ($this->config_loaded) {
@@ -34,13 +49,16 @@ class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
 
                $pconfigs = DBA::select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
                while ($pconfig = DBA::fetch($pconfigs)) {
-                       self::getApp()->setPConfigValue($uid, $pconfig['cat'], $pconfig['k'], $pconfig['v']);
+                       $this->configCache->setP($uid, $pconfig['cat'], $pconfig['k'], $pconfig['v']);
                }
                DBA::close($pconfigs);
 
                $this->config_loaded = true;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function get($uid, $cat, $k, $default_value = null, $refresh = false)
        {
                if (!$this->config_loaded) {
@@ -50,17 +68,18 @@ class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
                if ($refresh) {
                        $config = DBA::selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
                        if (DBA::isResult($config)) {
-                               self::getApp()->setPConfigValue($uid, $cat, $k, $config['v']);
+                               $this->configCache->setP($uid, $cat, $k, $config['v']);
                        } else {
-                               self::getApp()->deletePConfigValue($uid, $cat, $k);
+                               $this->configCache->deleteP($uid, $cat, $k);
                        }
                }
 
-               $return = self::getApp()->getPConfigValue($uid, $cat, $k, $default_value);
-
-               return $return;
+               return $this->configCache->getP($uid, $cat, $k, $default_value);;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function set($uid, $cat, $k, $value)
        {
                if (!$this->config_loaded) {
@@ -71,11 +90,11 @@ class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
                // The exception are array values.
                $compare_value = !is_array($value) ? (string)$value : $value;
 
-               if (self::getApp()->getPConfigValue($uid, $cat, $k) === $compare_value) {
+               if ($this->configCache->getP($uid, $cat, $k) === $compare_value) {
                        return true;
                }
 
-               self::getApp()->setPConfigValue($uid, $cat, $k, $value);
+               $this->configCache->setP($uid, $cat, $k, $value);
 
                // manage array value
                $dbvalue = is_array($value) ? serialize($value) : $value;
@@ -88,13 +107,16 @@ class PreloadPConfigAdapter extends BaseObject implements IPConfigAdapter
                return true;
        }
 
+       /**
+        * {@inheritdoc}
+        */
        public function delete($uid, $cat, $k)
        {
                if (!$this->config_loaded) {
                        $this->load($uid, $cat);
                }
 
-               self::getApp()->deletePConfigValue($uid, $cat, $k);
+               $this->configCache->deleteP($uid, $cat, $k);
 
                $result = DBA::delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $k]);
 
index c38dab9806b5d22a21dadcac9fc01ac73bb7e072..da078545e3eb0dd4c52c98ab0f329ca83fc1dd59 100644 (file)
@@ -100,10 +100,10 @@ HELP;
                                }
                        }
 
-                       $db_host = $a->getConfigValue('database', 'hostname');
-                       $db_user = $a->getConfigValue('database', 'username');
-                       $db_pass = $a->getConfigValue('database', 'password');
-                       $db_data = $a->getConfigValue('database', 'database');
+                       $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');
                } else {
                        // Creating config file
                        $this->out("Creating config file...\n");
@@ -158,7 +158,7 @@ HELP;
 
                $installer->resetChecks();
 
-               if (!$installer->installDatabase()) {
+               if (!$installer->installDatabase($a->getBasePath())) {
                        $errorMessage = $this->extractErrors($installer->getChecks());
                        throw new RuntimeException($errorMessage);
                }
index ce367fffbf748785c4f81dbc1c46ef341d4bdfc5..b1c3df54e024fc59738c259c9cddf0b54327292b 100644 (file)
@@ -113,7 +113,7 @@ HELP;
 
                        if (is_array($value)) {
                                foreach ($value as $k => $v) {
-                                       $this->out("{$cat}.{$key}[{$k}] => " . $v);
+                                       $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
                                }
                        } else {
                                $this->out("{$cat}.{$key} => " . $value);
@@ -124,12 +124,13 @@ HELP;
                        $cat = $this->getArgument(0);
                        Core\Config::load($cat);
 
-                       if (!is_null($a->config[$cat])) {
+                       if ($a->getConfig()->get($cat) !== null) {
                                $this->out("[{$cat}]");
-                               foreach ($a->config[$cat] as $key => $value) {
+                               $catVal = $a->getConfig()->get($cat);
+                               foreach ($catVal as $key => $value) {
                                        if (is_array($value)) {
                                                foreach ($value as $k => $v) {
-                                                       $this->out("{$key}[{$k}] => " . $v);
+                                                       $this->out("{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
                                                }
                                        } else {
                                                $this->out("{$key} => " . $value);
@@ -147,12 +148,13 @@ HELP;
                                $this->out('Warning: The JIT (Just In Time) Config adapter doesn\'t support loading the entire configuration, showing file config only');
                        }
 
-                       foreach ($a->config as $cat => $section) {
+                       $config = $a->getConfig()->getAll();
+                       foreach ($config as $cat => $section) {
                                if (is_array($section)) {
                                        foreach ($section as $key => $value) {
                                                if (is_array($value)) {
                                                        foreach ($value as $k => $v) {
-                                                               $this->out("{$cat}.{$key}[{$k}] => " . $v);
+                                                               $this->out("{$cat}.{$key}[{$k}] => " . (is_array($v) ? implode(', ', $v) : $v));
                                                        }
                                                } else {
                                                        $this->out("{$cat}.{$key} => " . $value);
index 724feea5e44f947e2178ef47915bc22ce257360c..1ec108d2e61cfd2f0d5d2fc07502b733ba3843b3 100644 (file)
@@ -61,17 +61,19 @@ HELP;
 
                Core\Config::load();
 
+               $a = get_app();
+
                switch ($this->getArgument(0)) {
                        case "dryrun":
-                               $output = DBStructure::update(true, false);
+                               $output = DBStructure::update($a->getBasePath(), true, false);
                                break;
                        case "update":
                                $force = $this->getOption(['f', 'force'], false);
-                               $output = Update::run($force, true, false);
+                               $output = Update::run($a->getBasePath(), $force, true, false);
                                break;
                        case "dumpsql":
                                ob_start();
-                               DBStructure::printStructure();
+                               DBStructure::printStructure($a->getBasePath());
                                $output = ob_get_clean();
                                break;
                        case "toinnodb":
index 17ed231f978f1d3a0e365bf738c84e472483ffc1..103d0fef7e68062928cdfd79100234a8dfd0187d 100644 (file)
@@ -2,8 +2,8 @@
 
 namespace Friendica\Core\Console;
 
-use Friendica\Core\L10n;
 use Friendica\Core\Config;
+use Friendica\Core\L10n;
 use Friendica\Core\Update;
 
 /**
@@ -56,7 +56,7 @@ HELP;
                }
 
                echo L10n::t('Check for pending update actions.') . "\n";
-               Update::run(true, true, false);
+               Update::run($a->getBasePath(), true, true, false);
                echo L10n::t('Done.') . "\n";
 
                echo L10n::t('Execute pending post updates.') . "\n";
index 82357b475397ded28ae9e41ff5794cdea5af970a..32ba6ded35186878bea79e9bf8cac456c8444172 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace Friendica\Core\Console;
 
+use Friendica\BaseObject;
+
 /**
  * Tired of chasing typos and finding them after a commit.
  * Run this and quickly see if we've got any parse errors in our application files.
@@ -41,9 +43,7 @@ HELP;
                        throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
                }
 
-               $a = \get_app();
-
-               $php_path = $a->getConfigValue('config', 'php_path', 'php');
+               $php_path = BaseObject::getApp()->getConfig()->get('config', 'php_path', 'php');
 
                if ($this->getOption('v')) {
                        $this->out('Directory: src');
index a487aec78b34ee24053c53c58d2b6e46c7999f80..7e79f29f153dd6efe81efc50993c19106c916032 100644 (file)
@@ -168,12 +168,14 @@ class Installer
        /***
         * Installs the DB-Scheme for Friendica
         *
+        * @param string $basePath The base path of this application
+        *
         * @return bool true if the installation was successful, otherwise false
         * @throws Exception
         */
-       public function installDatabase()
+       public function installDatabase($basePath)
        {
-               $result = DBStructure::update(false, true, true);
+               $result = DBStructure::update($basePath, false, true, true);
 
                if ($result) {
                        $txt = L10n::t('You may need to import the file "database.sql" manually using phpmyadmin or mysql.') . EOL;
index 277a0916417aa562bf260b7f62dad1e7a9c626ef..6b8112796f557f00dea156a9c22fef3993097584 100644 (file)
@@ -5,8 +5,8 @@
 namespace Friendica\Core;
 
 use Friendica\BaseObject;
+use Friendica\Factory\LoggerFactory;
 use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\LoggerFactory;
 use Psr\Log\LoggerInterface;
 use Psr\Log\LogLevel;
 
index 584318adbc65a4c0efa1368940d1d1961f15e649..df024f0f3426dfa84abc665789066a1c6427316a 100644 (file)
@@ -8,9 +8,6 @@
  */
 namespace Friendica\Core;
 
-use Friendica\App;
-use Friendica\BaseObject;
-
 /**
  * @brief Management of user configuration storage
  * Note:
@@ -18,52 +15,55 @@ use Friendica\BaseObject;
  * The PConfig::get() functions return boolean false for keys that are unset,
  * and this could lead to subtle bugs.
  */
-class PConfig extends BaseObject
+class PConfig
 {
        /**
-        * @var \Friendica\Core\Config\IPConfigAdapter
+        * @var Config\IPConfigAdapter
         */
-       private static $adapter = null;
+       private static $adapter;
 
-       public static function init($uid)
-       {
-               $a = self::getApp();
+       /**
+        * @var Config\IPConfigCache
+        */
+       private static $cache;
 
-               // Database isn't ready or populated yet
-               if (!$a->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return;
-               }
+       /**
+        * Initialize the config with only the cache
+        *
+        * @param Config\IPConfigCache $cache  The configuration cache
+        */
+       public static function init(Config\IPConfigCache $cache)
+       {
+               self::$cache  = $cache;
+       }
 
-               if ($a->getConfigValue('system', 'config_adapter') == 'preload') {
-                       self::$adapter = new Config\PreloadPConfigAdapter($uid);
-               } else {
-                       self::$adapter = new Config\JITPConfigAdapter();
-               }
+       /**
+        * Add the adapter for DB-backend
+        *
+        * @param Config\IPConfigAdapter $adapter
+        */
+       public static function setAdapter(Config\IPConfigAdapter $adapter)
+       {
+               self::$adapter = $adapter;
        }
 
        /**
         * @brief Loads all configuration values of a user's config family into a cached storage.
         *
-        * All configuration values of the given user are stored in global cache
-        * which is available under the global variable $a->config[$uid].
+        * 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
         *
         * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function load($uid, $family)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
+               if (!isset(self::$adapter)) {
                        return;
                }
 
-               if (empty(self::$adapter)) {
-                       self::init($uid);
-               }
-
                self::$adapter->load($uid, $family);
        }
 
@@ -72,7 +72,8 @@ class PConfig extends BaseObject
         * ($family) and a key.
         *
         * Get a particular user's config value from the given category ($family)
-        * and the $key from a cached storage in $a->config[$uid].
+        * and the $key with the $uid from a cached storage either from the self::$adapter
+        * (@see IConfigAdapter ) or from the static::$cache (@see IConfigCache ).
         *
         * @param string  $uid           The user_id
         * @param string  $family        The category of the configuration value
@@ -81,17 +82,11 @@ class PConfig extends BaseObject
         * @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
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function get($uid, $family, $key, $default_value = null, $refresh = false)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return;
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init($uid);
+               if (!isset(self::$adapter)) {
+                       return self::$cache->getP($uid, $family, $key, $default_value);
                }
 
                return self::$adapter->get($uid, $family, $key, $default_value, $refresh);
@@ -111,17 +106,11 @@ class PConfig extends BaseObject
         * @param mixed  $value  The value to store
         *
         * @return bool Operation success
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function set($uid, $family, $key, $value)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return false;
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init($uid);
+               if (!isset(self::$adapter)) {
+                       return self::$cache->setP($uid, $family, $key, $value);
                }
 
                return self::$adapter->set($uid, $family, $key, $value);
@@ -130,25 +119,20 @@ class PConfig extends BaseObject
        /**
         * @brief Deletes the given key from the users's configuration.
         *
-        * Removes the configured value from the stored cache in $a->config[$uid]
-        * and removes it from the database.
+        * 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 $family The category of the configuration value
         * @param string $key    The configuration key to delete
         *
         * @return mixed
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function delete($uid, $family, $key)
        {
-               // Database isn't ready or populated yet
-               if (!self::getApp()->getMode()->has(App\Mode::DBCONFIGAVAILABLE)) {
-                       return false;
-               }
-
-               if (empty(self::$adapter)) {
-                       self::init($uid);
+               if (!isset(self::$adapter)) {
+                       return self::$cache->deleteP($uid, $family, $key);
                }
 
                return self::$adapter->delete($uid, $family, $key);
index ba3d03e6229f283e3d0d7250366869f144e8caeb..f0ed08357359f5cc75f1d3a77652085e35ca657e 100644 (file)
@@ -286,6 +286,61 @@ class System extends BaseObject
                exit();
        }
 
+       /**
+        * @brief Returns the system user that is executing the script
+        *
+        * This mostly returns something like "www-data".
+        *
+        * @return string system username
+        */
+       public static function getUser()
+       {
+               if (!function_exists('posix_getpwuid') || !function_exists('posix_geteuid')) {
+                       return '';
+               }
+
+               $processUser = posix_getpwuid(posix_geteuid());
+               return $processUser['name'];
+       }
+
+       /**
+        * @brief Checks if a given directory is usable for the system
+        *
+        * @param      $directory
+        * @param bool $check_writable
+        *
+        * @return boolean the directory is usable
+        */
+       public static function isDirectoryUsable($directory, $check_writable = true)
+       {
+               if ($directory == '') {
+                       Logger::log('Directory is empty. This shouldn\'t happen.', Logger::DEBUG);
+                       return false;
+               }
+
+               if (!file_exists($directory)) {
+                       Logger::log('Path "' . $directory . '" does not exist for user ' . static::getUser(), Logger::DEBUG);
+                       return false;
+               }
+
+               if (is_file($directory)) {
+                       Logger::log('Path "' . $directory . '" is a file for user ' . static::getUser(), Logger::DEBUG);
+                       return false;
+               }
+
+               if (!is_dir($directory)) {
+                       Logger::log('Path "' . $directory . '" is not a directory for user ' . static::getUser(), Logger::DEBUG);
+                       return false;
+               }
+
+               if ($check_writable && !is_writable($directory)) {
+                       Logger::log('Path "' . $directory . '" is not writable for user ' . static::getUser(), Logger::DEBUG);
+                       return false;
+               }
+
+               return true;
+       }
+
        /// @todo Move the following functions from boot.php
        /*
        function killme()
index 368f5f55cc777bb28ab38f8fa440116ff50bfafa..5df0675cdaeb46cd7520468d693e79f349b034c2 100644 (file)
@@ -14,10 +14,11 @@ class Update
        /**
         * @brief Function to check if the Database structure needs an update.
         *
+        * @param string $basePath The base path of this application
         * @param boolean $via_worker boolean Is the check run via the worker?
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function check($via_worker)
+       public static function check($basePath, $via_worker)
        {
                if (!DBA::connected()) {
                        return;
@@ -38,7 +39,7 @@ class Update
                if ($build < DB_UPDATE_VERSION) {
                        // When we cannot execute the database update via the worker, we will do it directly
                        if (!Worker::add(PRIORITY_CRITICAL, 'DBUpdate') && $via_worker) {
-                               self::run();
+                               self::run($basePath);
                        }
                }
        }
@@ -46,14 +47,15 @@ class Update
        /**
         * Automatic database updates
         *
-        * @param bool $force    Force the Update-Check even if the lock is set
-        * @param bool $verbose  Run the Update-Check verbose
-        * @param bool $sendMail Sends a Mail to the administrator in case of success/failure
+        * @param string $basePath The base path of this application
+        * @param bool $force      Force the Update-Check even if the lock is set
+        * @param bool $verbose    Run the Update-Check verbose
+        * @param bool $sendMail   Sends a Mail to the administrator in case of success/failure
         *
         * @return string Empty string if the update is successful, error messages otherwise
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function run($force = false, $verbose = false, $sendMail = true)
+       public static function run($basePath, $force = false, $verbose = false, $sendMail = true)
        {
                // In force mode, we release the dbupdate lock first
                // Necessary in case of an stuck update
@@ -91,7 +93,7 @@ class Update
                                        }
 
                                        // update the structure in one call
-                                       $retval = DBStructure::update($verbose, true);
+                                       $retval = DBStructure::update($basePath, $verbose, true);
                                        if ($retval) {
                                                if ($sendMail) {
                                                        self::updateFailed(
@@ -125,7 +127,7 @@ class Update
                                }
                        }
                } elseif ($force) {
-                       DBStructure::update($verbose, true);
+                       DBStructure::update($basePath, $verbose, true);
                }
 
                return '';
index e14d94ce04fc8cb5acb7e8fae7fb6965a66ece8d..d2a739e9313aa07b9be4aaf948bab6398c1930e2 100644 (file)
@@ -2,10 +2,7 @@
 
 namespace Friendica\Database;
 
-// Do not use Core\Config in this class at risk of infinite loop.
-// Please use App->getConfigVariable() instead.
-//use Friendica\Core\Config;
-
+use Friendica\Core\Config\IConfigCache;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\Util\DateTimeFormat;
@@ -34,6 +31,10 @@ class DBA
 
        public static $connected = false;
 
+       /**
+        * @var IConfigCache
+        */
+       private static $configCache;
        private static $server_info = '';
        private static $connection;
        private static $driver;
@@ -49,13 +50,14 @@ class DBA
        private static $db_name = '';
        private static $db_charset = '';
 
-       public static function connect($serveraddr, $user, $pass, $db, $charset = null)
+       public static function connect($configCache, $serveraddr, $user, $pass, $db, $charset = null)
        {
                if (!is_null(self::$connection) && self::connected()) {
                        return true;
                }
 
                // We are storing these values for being able to perform a reconnect
+               self::$configCache = $configCache;
                self::$db_serveraddr = $serveraddr;
                self::$db_user = $user;
                self::$db_pass = $pass;
@@ -156,7 +158,7 @@ class DBA
        public static function reconnect() {
                self::disconnect();
 
-               $ret = self::connect(self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
+               $ret = self::connect(self::$configCache, self::$db_serveraddr, self::$db_user, self::$db_pass, self::$db_name, self::$db_charset);
                return $ret;
        }
 
@@ -210,9 +212,8 @@ class DBA
         * @throws \Exception
         */
        private static function logIndex($query) {
-               $a = \get_app();
 
-               if (!$a->getConfigVariable('system', 'db_log_index')) {
+               if (!self::$configCache->get('system', 'db_log_index')) {
                        return;
                }
 
@@ -231,18 +232,18 @@ class DBA
                        return;
                }
 
-               $watchlist = explode(',', $a->getConfigVariable('system', 'db_log_index_watch'));
-               $blacklist = explode(',', $a->getConfigVariable('system', 'db_log_index_blacklist'));
+               $watchlist = explode(',', self::$configCache->get('system', 'db_log_index_watch'));
+               $blacklist = explode(',', self::$configCache->get('system', 'db_log_index_blacklist'));
 
                while ($row = self::fetch($r)) {
-                       if ((intval($a->getConfigVariable('system', 'db_loglimit_index')) > 0)) {
+                       if ((intval(self::$configCache->get('system', 'db_loglimit_index')) > 0)) {
                                $log = (in_array($row['key'], $watchlist) &&
-                                       ($row['rows'] >= intval($a->getConfigVariable('system', 'db_loglimit_index'))));
+                                       ($row['rows'] >= intval(self::$configCache->get('system', 'db_loglimit_index'))));
                        } else {
                                $log = false;
                        }
 
-                       if ((intval($a->getConfigVariable('system', 'db_loglimit_index_high')) > 0) && ($row['rows'] >= intval($a->getConfigVariable('system', 'db_loglimit_index_high')))) {
+                       if ((intval(self::$configCache->get('system', 'db_loglimit_index_high')) > 0) && ($row['rows'] >= intval(self::$configCache->get('system', 'db_loglimit_index_high')))) {
                                $log = true;
                        }
 
@@ -252,7 +253,7 @@ class DBA
 
                        if ($log) {
                                $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
-                               @file_put_contents($a->getConfigVariable('system', 'db_log_index'), DateTimeFormat::utcNow()."\t".
+                               @file_put_contents(self::$configCache->get('system', 'db_log_index'), DateTimeFormat::utcNow()."\t".
                                                $row['key']."\t".$row['rows']."\t".$row['Extra']."\t".
                                                basename($backtrace[1]["file"])."\t".
                                                $backtrace[1]["line"]."\t".$backtrace[2]["function"]."\t".
@@ -422,7 +423,7 @@ class DBA
 
                $orig_sql = $sql;
 
-               if ($a->getConfigValue('system', 'db_callstack')) {
+               if (self::$configCache->get('system', 'db_callstack') !== null) {
                        $sql = "/*".System::callstack()." */ ".$sql;
                }
 
@@ -583,15 +584,15 @@ class DBA
 
                $a->saveTimestamp($stamp1, 'database');
 
-               if ($a->getConfigValue('system', 'db_log')) {
+               if (self::$configCache->get('system', 'db_log')) {
                        $stamp2 = microtime(true);
                        $duration = (float)($stamp2 - $stamp1);
 
-                       if (($duration > $a->getConfigValue('system', 'db_loglimit'))) {
+                       if (($duration > self::$configCache->get('system', 'db_loglimit'))) {
                                $duration = round($duration, 3);
                                $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
 
-                               @file_put_contents($a->getConfigValue('system', 'db_log'), DateTimeFormat::utcNow()."\t".$duration."\t".
+                               @file_put_contents(self::$configCache->get('system', 'db_log'), DateTimeFormat::utcNow()."\t".$duration."\t".
                                                basename($backtrace[1]["file"])."\t".
                                                $backtrace[1]["line"]."\t".$backtrace[2]["function"]."\t".
                                                substr(self::replaceParameters($sql, $args), 0, 2000)."\n", FILE_APPEND);
@@ -1030,7 +1031,7 @@ class DBA
         * This process must only be started once, since the value is cached.
         */
        private static function buildRelationData() {
-               $definition = DBStructure::definition();
+               $definition = DBStructure::definition(self::$configCache->get('system', 'basepath'));
 
                foreach ($definition AS $table => $structure) {
                        foreach ($structure['fields'] AS $field => $field_struct) {
index 7d52e60caec13d53a0b0b811754932c76ca121ed..75a5c86241fc63497e3c9fa4f31a73b07eed5733 100644 (file)
@@ -74,9 +74,9 @@ class DBStructure
                return L10n::t('Errors encountered performing database changes: ') . $message . EOL;
        }
 
-       public static function printStructure()
+       public static function printStructure($basePath)
        {
-               $database = self::definition(false);
+               $database = self::definition($basePath, false);
 
                echo "-- ------------------------------------------\n";
                echo "-- " . FRIENDICA_PLATFORM . " " . FRIENDICA_VERSION . " (" . FRIENDICA_CODENAME, ")\n";
@@ -98,15 +98,15 @@ class DBStructure
         *
         * @see config/dbstructure.config.php
         * @param boolean $with_addons_structure Whether to tack on addons additional tables
+        * @param string  $basePath              The base path of this application
         * @return array
         * @throws Exception
         */
-       public static function definition($with_addons_structure = true)
+       public static function definition($basePath, $with_addons_structure = true)
        {
                if (!self::$definition) {
-                       $a = \Friendica\BaseObject::getApp();
 
-                       $filename = $a->getBasePath() . '/config/dbstructure.config.php';
+                       $filename = $basePath . '/config/dbstructure.config.php';
 
                        if (!is_readable($filename)) {
                                throw new Exception('Missing database structure config file config/dbstructure.config.php');
@@ -247,15 +247,16 @@ class DBStructure
        /**
         * Updates DB structure and returns eventual errors messages
         *
-        * @param bool  $verbose
-        * @param bool  $action     Whether to actually apply the update
-        * @param bool  $install    Is this the initial update during the installation?
-        * @param array $tables     An array of the database tables
-        * @param array $definition An array of the definition tables
+        * @param string $basePath   The base path of this application
+        * @param bool   $verbose
+        * @param bool   $action     Whether to actually apply the update
+        * @param bool   $install    Is this the initial update during the installation?
+        * @param array  $tables     An array of the database tables
+        * @param array  $definition An array of the definition tables
         * @return string Empty string if the update is successful, error messages otherwise
         * @throws Exception
         */
-       public static function update($verbose, $action, $install = false, array $tables = null, array $definition = null)
+       public static function update($basePath, $verbose, $action, $install = false, array $tables = null, array $definition = null)
        {
                if ($action && !$install) {
                        Config::set('system', 'maintenance', 1);
@@ -284,7 +285,7 @@ class DBStructure
 
                // Get the definition
                if (is_null($definition)) {
-                       $definition = self::definition();
+                       $definition = self::definition($basePath);
                }
 
                // MySQL >= 5.7.4 doesn't support the IGNORE keyword in ALTER TABLE statements
diff --git a/src/Factory/ConfigFactory.php b/src/Factory/ConfigFactory.php
new file mode 100644 (file)
index 0000000..269daea
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+namespace Friendica\Factory;
+
+use Friendica\Core\Config;
+
+class ConfigFactory
+{
+       /**
+        * @param Config\ConfigCacheLoader $loader The Config Cache loader (INI/config/.htconfig)
+        *
+        * @return Config\ConfigCache
+        */
+       public static function createCache(Config\ConfigCacheLoader $loader)
+       {
+               $configCache = new Config\ConfigCache();
+               $loader->loadConfigFiles($configCache);
+
+               return $configCache;
+       }
+
+       /**
+        * @param string              $type   The adapter type
+        * @param Config\IConfigCache $config The config cache of this adapter
+        *
+        * @return Config\IConfigAdapter
+        */
+       public static function createConfig($type, Config\IConfigCache $config)
+       {
+               if ($type == 'preload') {
+                       return new Config\PreloadConfigAdapter($config);
+               } else {
+                       return new Config\JITConfigAdapter($config);
+               }
+       }
+
+       /**
+        * @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
+        *
+        * @return Config\IPConfigAdapter
+        */
+       public static function createPConfig($type, Config\IPConfigCache $config, $uid = null)
+       {
+               if ($type == 'preload') {
+                       return new Config\PreloadPConfigAdapter($config, $uid);
+               } else {
+                       return new Config\JITPConfigAdapter($config);
+               }
+       }
+}
diff --git a/src/Factory/LoggerFactory.php b/src/Factory/LoggerFactory.php
new file mode 100644 (file)
index 0000000..751a635
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+
+namespace Friendica\Factory;
+
+use Friendica\Core\Config\ConfigCache;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\Logger\FriendicaDevelopHandler;
+use Friendica\Util\Logger\FriendicaIntrospectionProcessor;
+use Monolog;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * A logger factory
+ *
+ * Currently only Monolog is supported
+ */
+class LoggerFactory
+{
+       /**
+        * Creates a new PSR-3 compliant logger instances
+        *
+        * @param string      $channel The channel of the logger instance
+        * @param ConfigCache $config  The config
+        *
+        * @return LoggerInterface The PSR-3 compliant logger instance
+        */
+       public static function create($channel, ConfigCache $config = 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']));
+
+               if (isset($config)) {
+                       $debugging = $config->get('system', 'debugging');
+                       $stream = $config->get('system', 'logfile');
+                       $level = $config->get('system', 'loglevel');
+
+                       if ($debugging) {
+                               static::addStreamHandler($logger, $stream, $level);
+                       }
+               }
+
+               return $logger;
+       }
+
+       /**
+        * Creates a new PSR-3 compliant develop logger
+        *
+        * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
+        * you'll use this logger instance for the duration of your work.
+        *
+        * 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
+        *
+        * @return LoggerInterface The PSR-3 compliant logger instance
+        */
+       public static function createDev($channel, $developerIp)
+       {
+               $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));
+
+               return $logger;
+       }
+
+       /**
+        * Adding a handler to a given logger instance
+        *
+        * @param LoggerInterface $logger  The logger instance
+        * @param mixed           $stream  The stream which handles the logger output
+        * @param string          $level   The level, for which this handler at least should handle logging
+        *
+        * @return void
+        *
+        * @throws InternalServerErrorException if the logger is incompatible to the logger factory
+        * @throws \Exception in case of general failures
+        */
+       public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
+       {
+               if ($logger instanceof Monolog\Logger) {
+                       $loglevel = Monolog\Logger::toMonologLevel($level);
+
+                       // fallback to notice if an invalid loglevel is set
+                       if (!is_int($loglevel)) {
+                               $loglevel = LogLevel::NOTICE;
+                       }
+                       $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
+
+                       $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
+                       $fileHandler->setFormatter($formatter);
+
+                       $logger->pushHandler($fileHandler);
+               } else {
+                       throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
+               }
+       }
+
+       /**
+        * 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)
+       {
+               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');
+               }
+       }
+}
index 7efb56f95a03a87fcd38dc5823aa73b5de2a5883..d65e67fe3e6a8c34adec09eb7ffca2091f8e7f2c 100644 (file)
@@ -7,15 +7,15 @@
 namespace Friendica\Model;
 
 use Friendica\BaseObject;
-use Friendica\Core\System;
 use Friendica\Core\StorageManager;
+use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\Model\Storage\IStorage;
 use Friendica\Object\Image;
-use Friendica\Util\Security;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Mimetype;
+use Friendica\Util\Security;
 
 /**
  * Class to handle attach dabatase table
@@ -31,7 +31,7 @@ class Attach extends BaseObject
         */
        private static function getFields()
        {
-               $allfields = DBStructure::definition(false);
+               $allfields = DBStructure::definition(self::getApp()->getBasePath(), false);
                $fields = array_keys($allfields['attach']['fields']);
                array_splice($fields, array_search('data', $fields), 1);
                return $fields;
index d1a35c1518597eff9e631ec1a15a6818f9ac8981..327e59422c9f97083b34ee6cf5133b3c2d03600c 100644 (file)
@@ -103,7 +103,7 @@ class Install extends BaseModule
                                        return;
                                }
 
-                               self::$installer->installDatabase();
+                               self::$installer->installDatabase($a->getBasePath());
 
                                break;
                }
diff --git a/src/Util/BasePath.php b/src/Util/BasePath.php
new file mode 100644 (file)
index 0000000..a284983
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+namespace Friendica\Util;
+
+class BasePath
+{
+       /**
+        * @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, $server = [])
+       {
+               if (!$basePath && !empty($server['DOCUMENT_ROOT'])) {
+                       $basePath = $server['DOCUMENT_ROOT'];
+               }
+
+               if (!$basePath && !empty($server['PWD'])) {
+                       $basePath = $server['PWD'];
+               }
+
+               return self::getRealPath($basePath);
+       }
+
+       /**
+        * @brief Returns a normalized file path
+        *
+        * This is a wrapper for the "realpath" function.
+        * That function cannot detect the real path when some folders aren't readable.
+        * Since this could happen with some hosters we need to handle this.
+        *
+        * @param string $path The path that is about to be normalized
+        * @return string normalized path - when possible
+        */
+       public static function getRealPath($path)
+       {
+               $normalized = realpath($path);
+
+               if (!is_bool($normalized)) {
+                       return $normalized;
+               } else {
+                       return $path;
+               }
+       }
+}
diff --git a/src/Util/LoggerFactory.php b/src/Util/LoggerFactory.php
deleted file mode 100644 (file)
index 4d3a287..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-namespace Friendica\Util;
-
-use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\Logger\FriendicaDevelopHandler;
-use Friendica\Util\Logger\FriendicaIntrospectionProcessor;
-use Monolog;
-use Psr\Log\LoggerInterface;
-use Psr\Log\LogLevel;
-
-/**
- * A logger factory
- *
- * Currently only Monolog is supported
- */
-class LoggerFactory
-{
-       /**
-        * Creates a new PSR-3 compliant logger instances
-        *
-        * @param string $channel The channel of the logger instance
-        *
-        * @return LoggerInterface The PSR-3 compliant logger instance
-        */
-       public static function create($channel)
-       {
-               $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']));
-
-               return $logger;
-       }
-
-       /**
-        * Creates a new PSR-3 compliant develop logger
-        *
-        * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
-        * you'll use this logger instance for the duration of your work.
-        *
-        * 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
-        *
-        * @return LoggerInterface The PSR-3 compliant logger instance
-        */
-       public static function createDev($channel, $developerIp)
-       {
-               $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));
-
-               return $logger;
-       }
-
-       /**
-        * Adding a handler to a given logger instance
-        *
-        * @param LoggerInterface $logger  The logger instance
-        * @param mixed           $stream  The stream which handles the logger output
-        * @param string          $level   The level, for which this handler at least should handle logging
-        *
-        * @return void
-        *
-        * @throws InternalServerErrorException if the logger is incompatible to the logger factory
-        * @throws \Exception in case of general failures
-        */
-       public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
-       {
-               if ($logger instanceof Monolog\Logger) {
-                       $loglevel = Monolog\Logger::toMonologLevel($level);
-
-                       // fallback to notice if an invalid loglevel is set
-                       if (!is_int($loglevel)) {
-                               $loglevel = LogLevel::NOTICE;
-                       }
-                       $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
-
-                       $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
-                       $fileHandler->setFormatter($formatter);
-
-                       $logger->pushHandler($fileHandler);
-               } else {
-                       throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
-               }
-       }
-
-       /**
-        * 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)
-       {
-               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');
-               }
-       }
-}
index 48c7e7ce6a20ec22fa3bb5389aea01970aeb00c8..05bace14679d3da1718d75b2df8f62066e79e110 100644 (file)
@@ -5,12 +5,13 @@
  */
 namespace Friendica\Worker;
 
+use Friendica\BaseObject;
 use Friendica\Core\Update;
 
-class DBUpdate
+class DBUpdate extends BaseObject
 {
        public static function execute()
        {
-               Update::run();
+               Update::run(self::getApp()->getBasePath());
        }
 }
index 2cb76dcad9ab39a013987026d6c4248bbe2afa56..79af5b5468a9495f86d390ceda58d1afdc4d64eb 100644 (file)
@@ -5,7 +5,10 @@
 
 namespace Friendica\Test;
 
+use Friendica\Core\Config;
 use Friendica\Database\DBA;
+use Friendica\Factory;
+use Friendica\Util\BasePath;
 use PHPUnit\DbUnit\DataSet\YamlDataSet;
 use PHPUnit\DbUnit\TestCaseTrait;
 use PHPUnit_Extensions_Database_DB_IDatabaseConnection;
@@ -36,7 +39,13 @@ abstract class DatabaseTest extends MockedTest
                        $this->markTestSkipped('Please set the MYSQL_* environment variables to your test database credentials.');
                }
 
-               DBA::connect(getenv('MYSQL_HOST'),
+               $basedir = BasePath::create(dirname(__DIR__));
+               $configLoader = new Config\ConfigCacheLoader($basedir);
+               $config = Factory\ConfigFactory::createCache($configLoader);
+
+               DBA::connect(
+                       $config,
+                       getenv('MYSQL_HOST'),
                        getenv('MYSQL_USERNAME'),
                        getenv('MYSQL_PASSWORD'),
                        getenv('MYSQL_DATABASE'));
index c6793218446cc168bc01e9628b822e98609ff108..290191cba125b6e40fca01d5d1a8f279e9e459da 100644 (file)
@@ -4,6 +4,7 @@ namespace Friendica\Test\Util;
 
 use Friendica\App;
 use Friendica\BaseObject;
+use Friendica\Core\Config\ConfigCache;
 use Friendica\Render\FriendicaSmartyEngine;
 use Mockery\MockInterface;
 use org\bovigo\vfs\vfsStreamDirectory;
@@ -24,8 +25,9 @@ trait AppMockTrait
         * Mock the App
         *
         * @param vfsStreamDirectory $root The root directory
+        * @param MockInterface|ConfigCache $config The config cache
         */
-       public function mockApp($root)
+       public function mockApp($root, $config)
        {
                $this->mockConfigGet('system', 'theme', 'testtheme');
 
@@ -35,22 +37,26 @@ trait AppMockTrait
                        ->shouldReceive('getBasePath')
                        ->andReturn($root->url());
 
-               $this->app
-                       ->shouldReceive('getConfigValue')
+               $config
+                       ->shouldReceive('get')
                        ->with('database', 'hostname')
                        ->andReturn(getenv('MYSQL_HOST'));
-               $this->app
-                       ->shouldReceive('getConfigValue')
+               $config
+                       ->shouldReceive('get')
                        ->with('database', 'username')
                        ->andReturn(getenv('MYSQL_USERNAME'));
-               $this->app
-                       ->shouldReceive('getConfigValue')
+               $config
+                       ->shouldReceive('get')
                        ->with('database', 'password')
                        ->andReturn(getenv('MYSQL_PASSWORD'));
-               $this->app
-                       ->shouldReceive('getConfigValue')
+               $config
+                       ->shouldReceive('get')
                        ->with('database', 'database')
                        ->andReturn(getenv('MYSQL_DATABASE'));
+               $this->app
+                       ->shouldReceive('getConfig')
+                       ->andReturn($config);
+
                $this->app
                        ->shouldReceive('getTemplateEngine')
                        ->andReturn(new FriendicaSmartyEngine());
index cf7571073addfdd38397aef30b4377a80948cf1b..be70d923bd4866c42e3f084cf4a543cb5ef72f2a 100644 (file)
@@ -5,13 +5,14 @@
 
 namespace Friendica\Test;
 
-use Friendica\BaseObject;
+use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\Protocol;
 use Friendica\Core\System;
+use Friendica\Factory;
 use Friendica\Network\HTTPException;
-use Friendica\Util\LoggerFactory;
+use Friendica\Util\BasePath;
 use Monolog\Handler\TestHandler;
 
 require_once __DIR__ . '/../../include/api.php';
@@ -34,10 +35,14 @@ class ApiTest extends DatabaseTest
         */
        public function setUp()
        {
-               parent::setUp();
+               $basedir = BasePath::create(dirname(__DIR__) . '/../');
+               $configLoader = new Config\ConfigCacheLoader($basedir);
+               $config = Factory\ConfigFactory::createCache($configLoader);
+               $logger = Factory\LoggerFactory::create('test', $config);
+               $this->app = new App($config, $logger, false);
+               $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
 
-               $this->app = BaseObject::getApp();
-               $this->logOutput = LoggerFactory::enableTest($this->app->getLogger());
+               parent::setUp();
 
                // User data that the test database is populated with
                $this->selfUser = [
index 2b10556af67d79885342b3f05e88f698b4294ff1..b2c73780a4499247544524f0f515636a1979f298 100644 (file)
@@ -31,9 +31,6 @@ class BaseObjectTest extends TestCase
         */
        protected function setUp()
        {
-               $this->setUpVfsDir();
-               $this->mockApp($this->root);
-
                $this->baseObject = new BaseObject();
        }
 
@@ -43,6 +40,10 @@ class BaseObjectTest extends TestCase
         */
        public function testGetApp()
        {
+               $this->setUpVfsDir();
+               $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+               $this->mockApp($this->root, $configMock);
+
                $this->assertInstanceOf(App::class, $this->baseObject->getApp());
        }
 
@@ -52,7 +53,20 @@ class BaseObjectTest extends TestCase
         */
        public function testSetApp()
        {
+               $this->setUpVfsDir();
+               $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+               $this->mockApp($this->root, $configMock);
+
                $this->assertNull($this->baseObject->setApp($this->app));
                $this->assertEquals($this->app, $this->baseObject->getApp());
        }
+
+       /**
+        * Test the getApp() function without App
+        * @expectedException Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public function testGetAppFailed()
+       {
+               BaseObject::getApp();
+       }
 }
index b9a22ee9ca375ac8c0495fa67af77e9b817cee6d..d0b357bf465dad6a77768cb9fc9ec48110b6c763 100644 (file)
@@ -69,7 +69,8 @@ abstract class CacheTest extends MockedTest
        protected function setUp()
        {
                $this->setUpVfsDir();
-               $this->mockApp($this->root);
+               $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+               $this->mockApp($this->root, $configMock);
                $this->app
                        ->shouldReceive('getHostname')
                        ->andReturn('friendica.local');
index 361608d375f3f06f0b1564c4e402768de6cc3afe..127a8bc3f87bdf38fdd4228de33925b1ec94f91f 100644 (file)
@@ -181,7 +181,7 @@ FIN;
                $this->mockConnect(true, 1);
                $this->mockConnected(true, 1);
                $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([false, true, true], null, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
 
                $config = <<<CONF
 <?php
@@ -241,7 +241,7 @@ CONF;
                $this->mockConnect(true, 1);
                $this->mockConnected(true, 1);
                $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([false, true, true], null, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
 
                $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
                $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(true), '', 1);
@@ -267,7 +267,7 @@ CONF;
                $this->mockConnect(true, 1);
                $this->mockConnected(true, 1);
                $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([false, true, true], null, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
 
                $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
                $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(false), '', 1);
@@ -292,7 +292,7 @@ CONF;
                $this->mockConnect(true, 1);
                $this->mockConnected(true, 1);
                $this->mockExistsTable('user', false, 1);
-               $this->mockUpdate([false, true, true], null, 1);
+               $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
 
                $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
                $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(true), '', 1);
index 4f7acc9c4229f62223b42cbdfca7121e46bffc81..905d214cac2b6282ceb298c5c5a391d3073d0587 100644 (file)
@@ -29,7 +29,8 @@ abstract class ConsoleTest extends MockedTest
                Intercept::setUp();
 
                $this->setUpVfsDir();
-               $this->mockApp($this->root);
+               $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+               $this->mockApp($this->root, $configMock);
        }
 
        /**
index 320beb3054e2f95638bdf6ec88f801d5124852e0..2d11a71ae18946c153d726f0c56833d881914995 100644 (file)
@@ -31,7 +31,8 @@ abstract class LockTest extends MockedTest
 
                // Reusable App object
                $this->setUpVfsDir();
-               $this->mockApp($this->root);
+               $configMock = \Mockery::mock('Friendica\Core\Config\ConfigCache');
+               $this->mockApp($this->root, $configMock);
                $this->app
                        ->shouldReceive('getHostname')
                        ->andReturn('friendica.local');
index 17ac55fd7a5bd58d031b5fdf609c09647c018aec..f2a5cc5558f7dcd853a377d2065f905fbe245331 100644 (file)
@@ -1,19 +1,25 @@
 <?php
 namespace Friendica\Test\Database;
 
-use Friendica\BaseObject;
+use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBA;
+use Friendica\Factory;
 use Friendica\Test\DatabaseTest;
+use Friendica\Util\BasePath;
 
 class DBATest extends DatabaseTest
 {
        public function setUp()
        {
-               parent::setUp();
+               $basedir = BasePath::create(dirname(__DIR__) . '/../../');
+               $configLoader = new Config\ConfigCacheLoader($basedir);
+               $config = Factory\ConfigFactory::createCache($configLoader);
+               $logger = Factory\LoggerFactory::create('test', $config);
+               $this->app = new App($config, $logger, false);
+               $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
 
-               // Reusable App object
-               $this->app = BaseObject::getApp();
+               parent::setUp();
 
                // Default config
                Config::set('config', 'hostname', 'localhost');
index 268bf8eeddcb08694b4ac18a40521982969ab232..53c4e8895b2dac1afe52cea59b6d5ffa29af7f49 100644 (file)
@@ -2,19 +2,25 @@
 
 namespace Friendica\Test\Database;
 
-use Friendica\BaseObject;
+use Friendica\App;
 use Friendica\Core\Config;
 use Friendica\Database\DBStructure;
+use Friendica\Factory;
 use Friendica\Test\DatabaseTest;
+use Friendica\Util\BasePath;
 
 class DBStructureTest extends DatabaseTest
 {
        public function setUp()
        {
-               parent::setUp();
+               $basedir = BasePath::create(dirname(__DIR__) . '/../../');
+               $configLoader = new Config\ConfigCacheLoader($basedir);
+               $config = Factory\ConfigFactory::createCache($configLoader);
+               $logger = Factory\LoggerFactory::create('test', $config);
+               $this->app = new App($config, $logger, false);
+               $this->logOutput = FActory\LoggerFactory::enableTest($this->app->getLogger());
 
-               // Reusable App object
-               $this->app = BaseObject::getApp();
+               parent::setUp();
 
                // Default config
                Config::set('config', 'hostname', 'localhost');
index b293a3f48ad173c05e4c8f9698000da88c546e68..d45d7c47a92624d105042ca8fd7adabf98356e72 100644 (file)
@@ -1819,6 +1819,10 @@ code > .hl-main {
 .wall-item-bottom .label a {
     color: #fff;
 }
+.wall-item-tags .category,
+.wall-item-tags .folder {
+    margin-right: 3px;
+}
 
 /* item social action buttons */
 .wall-item-actions {
index b668229e8af5ebb2b71017475cafabd905c8ab12..c6f90ac05d63dce6d584201d1dfb38f1e1af5c85 100644 (file)
                        {{/if}}
 
                                {{foreach $item.folders as $cat}}
-                                       <span class="folder label btn-danger sm">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+                                       <span class="folder label btn-danger sm">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
                                {{/foreach}}
 
                                {{foreach $item.categories as $cat}}
-                                       <span class="category label btn-success sm">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+                                       <span class="category label btn-success sm">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
                                {{/foreach}}
                                </div>
                                {{if $item.edited}}<div class="itemedited text-muted">{{$item.edited['label']}} (<span title="{{$item.edited['date']}}">{{$item.edited['relative']}}</span>)</div>{{/if}}
index 12e419f8a59f8562ac06fea94aa475d8171ad090..c149b58a515edabedab9fc051469d09eb653614d 100644 (file)
@@ -293,11 +293,11 @@ as the value of $top_child_total (this is done at the end of this file)
                {{/if}}
 
                        {{foreach $item.folders as $cat}}
-                               <span class="folder label btn-danger sm"><span class="p-category">{{$cat.name}}</span></a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+                               <span class="folder label btn-danger sm p-category">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
                        {{/foreach}}
 
                        {{foreach $item.categories as $cat}}
-                               <span class="category label btn-success sm"><span class="p-category">{{$cat.name}}</span></a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+                               <span class="category label btn-success sm p-category">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
                        {{/foreach}}
                        </div>
                        {{if $item.edited}}<div class="itemedited text-muted">{{$item.edited['label']}} (<span title="{{$item.edited['date']}}">{{$item.edited['relative']}}</span>)</div>{{/if}}