]> git.mxchange.org Git - friendica.git/commitdiff
Refactoring Core class structures ...
authorPhilipp <admin@philipp.info>
Tue, 26 Oct 2021 19:44:29 +0000 (21:44 +0200)
committerPhilipp <admin@philipp.info>
Tue, 26 Oct 2021 20:11:09 +0000 (22:11 +0200)
155 files changed:
doc/AddonStorageBackend.md
index.php
src/App.php
src/App/BaseURL.php
src/App/Mode.php
src/App/Module.php
src/App/Page.php
src/App/Router.php
src/Console/AutomaticInstallation.php
src/Console/Cache.php
src/Console/Config.php
src/Console/DatabaseStructure.php
src/Console/Lock.php
src/Console/Maintenance.php
src/Console/PostUpdate.php
src/Console/ServerBlock.php
src/Console/Typo.php
src/Console/User.php
src/Content/Conversation.php
src/Core/Cache/Capability/ICanCache.php [new file with mode: 0644]
src/Core/Cache/Capability/ICanCacheInMemory.php [new file with mode: 0644]
src/Core/Cache/Exception/CachePersistenceException.php [new file with mode: 0644]
src/Core/Cache/Exception/InvalidCacheDriverException.php [new file with mode: 0644]
src/Core/Cache/Factory/Cache.php [new file with mode: 0644]
src/Core/Cache/Factory/CacheFactory.php [deleted file]
src/Core/Cache/ICache.php [deleted file]
src/Core/Cache/IMemoryCache.php [deleted file]
src/Core/Cache/Type/APCuCache.php
src/Core/Cache/Type/AbstractCache.php [new file with mode: 0644]
src/Core/Cache/Type/ArrayCache.php
src/Core/Cache/Type/BaseCache.php [deleted file]
src/Core/Cache/Type/CompareDeleteTrait.php [new file with mode: 0644]
src/Core/Cache/Type/CompareSetTrait.php [new file with mode: 0644]
src/Core/Cache/Type/DatabaseCache.php
src/Core/Cache/Type/MemcacheCache.php
src/Core/Cache/Type/MemcacheCommandTrait.php [new file with mode: 0644]
src/Core/Cache/Type/MemcachedCache.php
src/Core/Cache/Type/ProfilerCache.php [deleted file]
src/Core/Cache/Type/ProfilerCacheDecorator.php [new file with mode: 0644]
src/Core/Cache/Type/RedisCache.php
src/Core/Cache/Type/TraitCompareDelete.php [deleted file]
src/Core/Cache/Type/TraitCompareSet.php [deleted file]
src/Core/Cache/Type/TraitMemcacheCommand.php [deleted file]
src/Core/Config/Cache/Cache.php [deleted file]
src/Core/Config/Cache/ConfigFileLoader.php [deleted file]
src/Core/Config/Capability/IManageConfigValues.php [new file with mode: 0644]
src/Core/Config/Exception/ConfigFileException.php [new file with mode: 0644]
src/Core/Config/Exception/ConfigPersistenceException.php [new file with mode: 0644]
src/Core/Config/Factory/Config.php [new file with mode: 0644]
src/Core/Config/Factory/ConfigFactory.php [deleted file]
src/Core/Config/IConfig.php [deleted file]
src/Core/Config/Model/Config.php [deleted file]
src/Core/Config/Model/DbaUtils.php [deleted file]
src/Core/Config/Repository/Config.php [new file with mode: 0644]
src/Core/Config/Type/AbstractConfig.php [new file with mode: 0644]
src/Core/Config/Type/BaseConfig.php [deleted file]
src/Core/Config/Type/JitConfig.php
src/Core/Config/Type/PreloadConfig.php
src/Core/Config/Util/ConfigFileLoader.php [new file with mode: 0644]
src/Core/Config/Util/ValueConversion.php [new file with mode: 0644]
src/Core/Config/ValueObject/Cache.php [new file with mode: 0644]
src/Core/Installer.php
src/Core/L10n.php
src/Core/Lock/Capability/ICanLock.php [new file with mode: 0644]
src/Core/Lock/Exception/InvalidLockDriverException.php [new file with mode: 0644]
src/Core/Lock/Exception/LockPersistenceException.php [new file with mode: 0644]
src/Core/Lock/Factory/Lock.php [new file with mode: 0644]
src/Core/Lock/Factory/LockFactory.php [deleted file]
src/Core/Lock/ILock.php [deleted file]
src/Core/Lock/Type/AbstractLock.php [new file with mode: 0644]
src/Core/Lock/Type/BaseLock.php [deleted file]
src/Core/Lock/Type/CacheLock.php
src/Core/Lock/Type/DatabaseLock.php
src/Core/Lock/Type/SemaphoreLock.php
src/Core/PConfig/Cache/Cache.php [deleted file]
src/Core/PConfig/Capability/IManagePersonalConfigValues.php [new file with mode: 0644]
src/Core/PConfig/Exception/PConfigPersistenceException.php [new file with mode: 0644]
src/Core/PConfig/Factory/PConfig.php [new file with mode: 0644]
src/Core/PConfig/Factory/PConfigFactory.php [deleted file]
src/Core/PConfig/IPConfig.php [deleted file]
src/Core/PConfig/Model/PConfig.php [deleted file]
src/Core/PConfig/Repository/PConfig.php [new file with mode: 0644]
src/Core/PConfig/Type/AbstractPConfigValues.php [new file with mode: 0644]
src/Core/PConfig/Type/BasePConfig.php [deleted file]
src/Core/PConfig/Type/JitPConfig.php
src/Core/PConfig/Type/PreloadPConfig.php
src/Core/PConfig/ValueObject/Cache.php [new file with mode: 0644]
src/Core/Process.php
src/Core/Session/Capability/IHandleSessions.php [new file with mode: 0644]
src/Core/Session/Factory/Session.php [new file with mode: 0644]
src/Core/Session/Factory/SessionFactory.php [deleted file]
src/Core/Session/Handler/Cache.php
src/Core/Session/Handler/Database.php
src/Core/Session/ISession.php [deleted file]
src/Core/Session/Type/AbstractSession.php
src/Core/Session/Type/Memory.php
src/Core/Session/Type/Native.php
src/Core/StorageManager.php
src/DI.php
src/Database/Database.php
src/Factory/HTTPClientFactory.php
src/Factory/LoggerFactory.php
src/Model/Storage/FilesystemConfig.php
src/Model/User/Cookie.php
src/Module/Admin/Summary.php
src/Module/Install.php
src/Navigation/Notifications/Factory/Introduction.php
src/Navigation/Notifications/Repository/Notify.php
src/Security/Authentication.php
src/Security/ExAuth.php
src/Util/EMailer/MailBuilder.php
src/Util/EMailer/NotifyMailBuilder.php
src/Util/EMailer/SystemMailBuilder.php
src/Util/Emailer.php
src/Util/Profiler.php
static/dependencies.config.php
tests/FixtureTest.php
tests/Util/AppMockTrait.php
tests/functional/DependencyCheckTest.php
tests/legacy/ApiTest.php
tests/src/App/ModeTest.php
tests/src/App/ModuleTest.php
tests/src/App/RouterTest.php
tests/src/Console/AutomaticInstallationConsoleTest.php
tests/src/Console/ConfigConsoleTest.php
tests/src/Console/LockConsoleTest.php
tests/src/Console/ServerBlockConsoleTest.php
tests/src/Core/Cache/CacheTest.php
tests/src/Core/Cache/DatabaseCacheTest.php
tests/src/Core/Cache/MemcacheCacheTest.php
tests/src/Core/Cache/MemcachedCacheTest.php
tests/src/Core/Cache/MemoryCacheTest.php
tests/src/Core/Cache/RedisCacheTest.php
tests/src/Core/Config/Cache/CacheTest.php
tests/src/Core/Config/Cache/ConfigFileLoaderTest.php
tests/src/Core/Config/ConfigTest.php
tests/src/Core/InstallerTest.php
tests/src/Core/Lock/DatabaseLockDriverTest.php
tests/src/Core/Lock/LockTest.php
tests/src/Core/Lock/MemcacheCacheLockTest.php
tests/src/Core/Lock/MemcachedCacheLockTest.php
tests/src/Core/Lock/RedisCacheLockTest.php
tests/src/Core/Lock/SemaphoreLockTest.php
tests/src/Core/PConfig/Cache/CacheTest.php
tests/src/Core/PConfig/PConfigTest.php
tests/src/Core/StorageManagerTest.php
tests/src/Model/ProcessTest.php
tests/src/Model/Storage/DatabaseStorageTest.php
tests/src/Model/Storage/FilesystemStorageConfigTest.php
tests/src/Model/User/CookieTest.php
tests/src/Util/BaseURLTest.php
tests/src/Util/EMailerTest.php
tests/src/Util/Emailer/MailBuilderTest.php
tests/src/Util/Emailer/SystemMailBuilderTest.php
tests/src/Util/ProfilerTest.php

index f4773acb89b81376eb4c53984d36d65789d3c3b0..0b067237659260b4ff56f44eb9428c25ff4ec298 100644 (file)
@@ -188,7 +188,7 @@ namespace Friendica\Addon\samplestorage;
 
 use Friendica\Model\Storage\IWritableStorage;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 
 class SampleStorageBackend implements IWritableStorage
@@ -249,12 +249,12 @@ namespace Friendica\Addon\samplestorage;
 
 use Friendica\Model\Storage\IStorageConfiguration;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 
 class SampleStorageBackendConfig implements IStorageConfiguration
 {
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        private $config;
        /** @var L10n */
        private $l10n;
@@ -265,7 +265,7 @@ class SampleStorageBackendConfig implements IStorageConfiguration
          * You can add here every dynamic class as dependency you like and add them to a private field
          * Friendica automatically creates these classes and passes them as argument to the constructor                                                                           
          */
-       public function __construct(IConfig $config, L10n $l10n) 
+       public function __construct(IManageConfigValues $config, L10n $l10n) 
        {
                $this->config = $config;
                $this->l10n   = $l10n;
index 011b9d7f90079533ae5ffa1a1fe7b54a1e842ade..4f690ed5185cd3ad2eecc5a56600a31a27b836b8 100644 (file)
--- a/index.php
+++ b/index.php
@@ -43,7 +43,7 @@ $a = \Friendica\DI::app();
 $a->runFrontend(
        $dice->create(\Friendica\App\Module::class),
        $dice->create(\Friendica\App\Router::class),
-       $dice->create(\Friendica\Core\PConfig\IPConfig::class),
+       $dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class),
        $dice->create(\Friendica\Security\Authentication::class),
        $dice->create(\Friendica\App\Page::class),
        $start_time
index cd217c34e7ec715212962b6ed530e759b43d5a71..9c0699a182bbf86a0fa7893d315d3841edecd178 100644 (file)
@@ -25,12 +25,12 @@ use Exception;
 use Friendica\App\Arguments;
 use Friendica\App\BaseURL;
 use Friendica\App\Module;
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Module\Maintenance;
 use Friendica\Security\Authentication;
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Core\System;
 use Friendica\Core\Theme;
@@ -88,7 +88,7 @@ class App
        private $currentMobileTheme;
 
        /**
-        * @var IConfig The config
+        * @var IManageConfigValues The config
         */
        private $config;
 
@@ -123,7 +123,7 @@ class App
        private $process;
 
        /**
-        * @var IPConfig
+        * @var IManagePersonalConfigValues
         */
        private $pConfig;
 
@@ -305,18 +305,18 @@ class App
        }
 
        /**
-        * @param Database        $database The Friendica Database
-        * @param IConfig         $config   The Configuration
-        * @param App\Mode        $mode     The mode of this Friendica app
-        * @param BaseURL         $baseURL  The full base URL of this Friendica app
-        * @param LoggerInterface $logger   The current app logger
-        * @param Profiler        $profiler The profiler of this application
-        * @param L10n            $l10n     The translator instance
-        * @param App\Arguments   $args     The Friendica Arguments of the call
-        * @param Core\Process    $process  The process methods
-        * @param IPConfig        $pConfig  Personal configuration
+        * @param Database                                                       $database The Friendica Database
+        * @param IManageConfigValues                                            $config   The Configuration
+        * @param App\Mode                                                       $mode     The mode of this Friendica app
+        * @param BaseURL                                                        $baseURL  The full base URL of this Friendica app
+        * @param LoggerInterface                                                $logger   The current app logger
+        * @param Profiler                                                       $profiler The profiler of this application
+        * @param L10n                                                           $l10n     The translator instance
+        * @param App\Arguments                                                  $args     The Friendica Arguments of the call
+        * @param Core\Process                                                   $process  The process methods
+        * @param \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues $pConfig  Personal configuration
         */
-       public function __construct(Database $database, IConfig $config, App\Mode $mode, BaseURL $baseURL, LoggerInterface $logger, Profiler $profiler, L10n $l10n, Arguments $args, Core\Process $process, IPConfig $pConfig)
+       public function __construct(Database $database, IManageConfigValues $config, App\Mode $mode, BaseURL $baseURL, LoggerInterface $logger, Profiler $profiler, L10n $l10n, Arguments $args, Core\Process $process, IManagePersonalConfigValues $pConfig)
        {
                $this->database = $database;
                $this->config   = $config;
@@ -357,7 +357,7 @@ class App
                        $this->profiler->update($this->config);
 
                        Core\Hook::loadHooks();
-                       $loader = (new ConfigFactory())->createConfigFileLoader($this->getBasePath(), $_SERVER);
+                       $loader = (new Config())->createConfigFileLoader($this->getBasePath(), $_SERVER);
                        Core\Hook::callAll('load_config', $loader);
                }
 
@@ -552,16 +552,16 @@ class App
         *
         * This probably should change to limit the size of this monster method.
         *
-        * @param App\Module     $module The determined module
-        * @param App\Router     $router
-        * @param IPConfig       $pconfig
-        * @param Authentication $auth The Authentication backend of the node
-        * @param App\Page       $page The Friendica page printing container
+        * @param App\Module                  $module The determined module
+        * @param App\Router                  $router
+        * @param IManagePersonalConfigValues $pconfig
+        * @param Authentication              $auth The Authentication backend of the node
+        * @param App\Page                    $page The Friendica page printing container
         *
         * @throws HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public function runFrontend(App\Module $module, App\Router $router, IPConfig $pconfig, Authentication $auth, App\Page $page, float $start_time)
+       public function runFrontend(App\Module $module, App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, float $start_time)
        {
                $this->profiler->set($start_time, 'start');
                $this->profiler->set(microtime(true), 'classinit');
index a7bfce2b1875c7ac99dd1ae1cf93605d01f9be4e..40ed7941687a6f0cf22a15de3ee4f6c8af204875 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\App;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\System;
 use Friendica\Util\Network;
 use Friendica\Util\Strings;
@@ -56,7 +56,7 @@ class BaseURL
        /**
         * The Friendica Config
         *
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -272,10 +272,10 @@ class BaseURL
        }
 
        /**
-        * @param IConfig $config The Friendica IConfiguration
-        * @param array   $server The $_SERVER array
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config The Friendica IConfiguration
+        * @param array                                                 $server The $_SERVER array
         */
-       public function __construct(IConfig $config, array $server)
+       public function __construct(IManageConfigValues $config, array $server)
        {
                $this->config = $config;
                $this->server = $server;
index 9f7a34a53eda466cd6c94d44cfdfed80a5cc3a56..1087b08a053a2ece02640f61434179b16580ae51 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\App;
 
 use Detection\MobileDetect;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Database\Database;
 use Friendica\Util\BasePath;
 
index f15b1236e81042708e97a56e0834026da05e1656..ce7cc98f06f7b734bcd46502af2da9e076de7049 100644 (file)
@@ -168,15 +168,15 @@ class Module
        /**
         * Determine the class of the current module
         *
-        * @param Arguments           $args   The Friendica execution arguments
-        * @param Router              $router The Friendica routing instance
-        * @param Core\Config\IConfig $config The Friendica Configuration
+        * @param Arguments                                             $args   The Friendica execution arguments
+        * @param Router                                                $router The Friendica routing instance
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config The Friendica Configuration
         *
         * @return Module The determined module of this call
         *
         * @throws \Exception
         */
-       public function determineClass(Arguments $args, Router $router, Core\Config\IConfig $config)
+       public function determineClass(Arguments $args, Router $router, Core\Config\Capability\IManageConfigValues $config)
        {
                $printNotAllowedAddon = false;
 
index 766dd4ebef59dc4fa9ed1a59656778bf5e8480ed..abc84b0e99f77f8c70cc0ac1c88627cf346d09ba 100644 (file)
@@ -26,8 +26,8 @@ use DOMDocument;
 use DOMXPath;
 use Friendica\App;
 use Friendica\Content\Nav;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
@@ -190,15 +190,15 @@ class Page implements ArrayAccess
         * - Infinite scroll data
         * - head.tpl template
         *
-        * @param App      $app     The Friendica App instance
-        * @param Module   $module  The loaded Friendica module
-        * @param L10n     $l10n    The l10n language instance
-        * @param IConfig  $config  The Friendica configuration
-        * @param IPConfig $pConfig The Friendica personal configuration (for user)
+        * @param App                                                            $app     The Friendica App instance
+        * @param Module                                                         $module  The loaded Friendica module
+        * @param L10n                                                           $l10n    The l10n language instance
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues          $config  The Friendica configuration
+        * @param \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues $pConfig The Friendica personal configuration (for user)
         *
         * @throws HTTPException\InternalServerErrorException
         */
-       private function initHead(App $app, Module $module, L10n $l10n, IConfig $config, IPConfig $pConfig)
+       private function initHead(App $app, Module $module, L10n $l10n, IManageConfigValues $config, IManagePersonalConfigValues $pConfig)
        {
                $interval = ((local_user()) ? $pConfig->get(local_user(), 'system', 'update_interval') : 40000);
 
@@ -367,17 +367,17 @@ class Page implements ArrayAccess
        /**
         * Executes the creation of the current page and prints it to the screen
         *
-        * @param App      $app     The Friendica App
-        * @param BaseURL  $baseURL The Friendica Base URL
-        * @param Mode     $mode    The current node mode
-        * @param Module   $module  The loaded Friendica module
-        * @param L10n     $l10n    The l10n language class
-        * @param IConfig  $config  The Configuration of this node
-        * @param IPConfig $pconfig The personal/user configuration
+        * @param App                         $app     The Friendica App
+        * @param BaseURL                     $baseURL The Friendica Base URL
+        * @param Mode                        $mode    The current node mode
+        * @param Module                      $module  The loaded Friendica module
+        * @param L10n                        $l10n    The l10n language class
+        * @param IManageConfigValues         $config  The Configuration of this node
+        * @param IManagePersonalConfigValues $pconfig The personal/user configuration
         *
         * @throws HTTPException\InternalServerErrorException
         */
-       public function run(App $app, BaseURL $baseURL, Mode $mode, Module $module, L10n $l10n, Profiler $profiler, IConfig $config, IPConfig $pconfig)
+       public function run(App $app, BaseURL $baseURL, Mode $mode, Module $module, L10n $l10n, Profiler $profiler, IManageConfigValues $config, IManagePersonalConfigValues $pconfig)
        {
                $moduleName = $module->getName();
 
index 50768395303555625ac21efbad6516b5af5135b7..181f5368d51de5668a9f5d77bb419166330c7ade 100644 (file)
@@ -27,10 +27,10 @@ use FastRoute\Dispatcher;
 use FastRoute\RouteCollector;
 use FastRoute\RouteParser\Std;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\ICache;
+use Friendica\Core\Cache\Capability\ICanCache;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Friendica\Network\HTTPException;
 
 /**
@@ -77,10 +77,10 @@ class Router
        /** @var L10n */
        private $l10n;
 
-       /** @var ICache */
+       /** @var ICanCache */
        private $cache;
 
-       /** @var ILock */
+       /** @var ICanLock */
        private $lock;
 
        /** @var string */
@@ -90,10 +90,10 @@ class Router
         * @param array               $server             The $_SERVER variable
         * @param string              $baseRoutesFilepath The path to a base routes file to leverage cache, can be empty
         * @param L10n                $l10n
-        * @param ICache              $cache
+        * @param ICanCache           $cache
         * @param RouteCollector|null $routeCollector
         */
-       public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICache $cache, ILock $lock, RouteCollector $routeCollector = null)
+       public function __construct(array $server, string $baseRoutesFilepath, L10n $l10n, ICanCache $cache, ICanLock $lock, RouteCollector $routeCollector = null)
        {
                $this->baseRoutesFilepath = $baseRoutesFilepath;
                $this->l10n = $l10n;
index 9ef82524aab835f5e8a51f1e2a3c20f0eed39751..8be1b34cf973f3565e3b30a258ffe40c1a82feeb 100644 (file)
@@ -24,8 +24,8 @@ namespace Friendica\Console;
 use Asika\SimpleConsole\Console;
 use Friendica\App;
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\Installer;
 use Friendica\Core\Theme;
 use Friendica\Database\Database;
@@ -36,9 +36,9 @@ class AutomaticInstallation extends Console
 {
        /** @var App\Mode */
        private $appMode;
-       /** @var \Friendica\Core\Config\Cache\Cache */
+       /** @var \Friendica\Core\Config\ValueObject\Cache */
        private $configCache;
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var Database */
        private $dba;
@@ -98,7 +98,7 @@ Examples
 HELP;
        }
 
-       public function __construct(App\Mode $appMode, Cache $configCache, IConfig $config, Database $dba, array $argv = null)
+       public function __construct(App\Mode $appMode, Cache $configCache, IManageConfigValues $config, Database $dba, array $argv = null)
        {
                parent::__construct($argv);
 
@@ -252,8 +252,8 @@ HELP;
        }
 
        /**
-        * @param Installer $installer   The Installer instance
-        * @param Cache     $configCache The config cache
+        * @param Installer                                $installer   The Installer instance
+        * @param \Friendica\Core\Config\ValueObject\Cache $configCache The config cache
         *
         * @return bool true if checks were successfully, otherwise false
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
index a9452435eb89c6170fed98abe1c794d945e89a74..560832c9ce17f0305d45b7216b42699369739989 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Console;
 use Asika\SimpleConsole\CommandArgsException;
 use Friendica\App;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\ICache;
+use Friendica\Core\Cache\Capability\ICanCache;
 use RuntimeException;
 
 /**
@@ -44,7 +44,7 @@ class Cache extends \Asika\SimpleConsole\Console
        private $appMode;
 
        /**
-        * @var ICache
+        * @var ICanCache
         */
        private $cache;
 
@@ -82,7 +82,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, ICache $cache, array $argv = null)
+       public function __construct(App\Mode $appMode, ICanCache $cache, array $argv = null)
        {
                parent::__construct($argv);
 
index 3c775d43292053a58cc7ba7e580b249a3ab1584b..9b2d251973090824fbb1ba8e4500340170f2b2a7 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Console;
 
 use Asika\SimpleConsole\CommandArgsException;
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use RuntimeException;
 
 /**
@@ -56,7 +56,7 @@ class Config extends \Asika\SimpleConsole\Console
         */
        private $appMode;
        /**
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -94,7 +94,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, IConfig $config, array $argv = null)
+       public function __construct(App\Mode $appMode, IManageConfigValues $config, array $argv = null)
        {
                parent::__construct($argv);
 
index 1083a512d44f7a6128a600c3daaf6b59f3007bea..be301746c1ac3a3512cb2cb2a84b1dee796d49ed 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Console;
 
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\Update;
 use Friendica\Database\Database;
 use Friendica\Database\DBStructure;
index 7ac1cdd241fe2bdf97b860b21da0b3c2785b6f67..3b73837b6e41e7cbd8d1bb87f8c087a499681866 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Console;
 
 use Asika\SimpleConsole\CommandArgsException;
 use Friendica\App;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use RuntimeException;
 
 /**
@@ -42,7 +42,7 @@ class Lock extends \Asika\SimpleConsole\Console
        private $appMode;
 
        /**
-        * @var ILock
+        * @var \Friendica\Core\Lock\Capability\ICanLock
         */
        private $lock;
 
@@ -76,7 +76,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, ILock $lock, array $argv = null)
+       public function __construct(App\Mode $appMode, ICanLock $lock, array $argv = null)
        {
                parent::__construct($argv);
 
index 647d1910f468999e8c936f2969e624553afab1e8..29ae120f7d88f4b9f050fc87798f840dbfefcdf6 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Console;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 
 /**
  * Sets maintenance mode for this node
@@ -36,7 +36,7 @@ class Maintenance extends \Asika\SimpleConsole\Console
         */
        private $appMode;
        /**
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -69,7 +69,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, IConfig $config, $argv = null)
+       public function __construct(App\Mode $appMode, IManageConfigValues $config, $argv = null)
        {
                parent::__construct($argv);
 
index 35b57fb7aab9c23f4773a2aa4c3f7cc9e27c159c..4c047e502469c33a1a91d1377a3d3d65709cb7fe 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Console;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Core\Update;
 
@@ -38,7 +38,7 @@ class PostUpdate extends \Asika\SimpleConsole\Console
         */
        private $appMode;
        /**
-        * @var IConfig
+        * @var \Friendica\Core\Config\Capability\IManageConfigValues
         */
        private $config;
        /**
@@ -60,7 +60,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, IConfig $config, L10n $l10n, array $argv = null)
+       public function __construct(App\Mode $appMode, IManageConfigValues $config, L10n $l10n, array $argv = null)
        {
                parent::__construct($argv);
 
index bba37c617c69b8c20be9a1e05b5c57f7165f510b..2bf5fe1ab1b0c5224c2d7f2c98d0a176abaaa024 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Console;
 use Asika\SimpleConsole\CommandArgsException;
 use Asika\SimpleConsole\Console;
 use Console_Table;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 
 /**
  * Manage blocked servers
@@ -39,7 +39,7 @@ class ServerBlock extends Console
        protected $helpOptions = ['h', 'help', '?'];
 
        /**
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -72,7 +72,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(IConfig $config, $argv = null)
+       public function __construct(IManageConfigValues $config, $argv = null)
        {
                parent::__construct($argv);
 
@@ -105,9 +105,9 @@ HELP;
         * Exports the list of blocked domains including the reason for the
         * block to a CSV file.
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         */
-       private function exportBlockedServers(IConfig $config)
+       private function exportBlockedServers(IManageConfigValues $config)
        {
                $filename = $this->getArgument(1);
                $blocklist = $config->get('system', 'blocklist', []);
@@ -123,9 +123,9 @@ HELP;
         * Imports a list of domains and a reason for the block from a CSV
         * file, e.g. created with the export function.
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         */
-       private function importBlockedServers(IConfig $config)
+       private function importBlockedServers(IManageConfigValues $config)
        {
                $filename = $this->getArgument(1);
                $currBlockList = $config->get('system', 'blocklist', []);
@@ -167,9 +167,9 @@ HELP;
        /**
         * Prints the whole list of blocked domains including the reason
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         */
-       private function printBlockedServers(IConfig $config)
+       private function printBlockedServers(IManageConfigValues $config)
        {
                $table = new Console_Table();
                $table->setHeaders(['Domain', 'Reason']);
@@ -183,11 +183,11 @@ HELP;
        /**
         * Adds a server to the blocked list
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         *
         * @return int The return code (0 = success, 1 = failed)
         */
-       private function addBlockedServer(IConfig $config)
+       private function addBlockedServer(IManageConfigValues $config)
        {
                if (count($this->args) < 2 || count($this->args) > 3) {
                        throw new CommandArgsException('Add needs a domain and optional a reason.');
@@ -235,11 +235,11 @@ HELP;
        /**
         * Removes a server from the blocked list
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         *
         * @return int The return code (0 = success, 1 = failed)
         */
-       private function removeBlockedServer(IConfig $config)
+       private function removeBlockedServer(IManageConfigValues $config)
        {
                if (count($this->args) !== 2) {
                        throw new CommandArgsException('Remove needs a second parameter.');
index 633ec1ec38bf539b2cbb326d665349b4f63dd7e8..488e362aaf83ec573314019a37c749e4dc6ea2cf 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Console;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 
 /**
  * Tired of chasing typos and finding them after a commit.
@@ -32,7 +32,7 @@ class Typo extends \Asika\SimpleConsole\Console
        protected $helpOptions = ['h', 'help', '?'];
 
        /**
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -53,7 +53,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(IConfig $config, array $argv = null)
+       public function __construct(IManageConfigValues $config, array $argv = null)
        {
                parent::__construct($argv);
 
index bb0748d6f6f705bfcdb79568e64a3505a7f58d96..5cf15747e223be8165fb0851166f7ca4e9e79485 100644 (file)
@@ -25,7 +25,7 @@ use Console_Table;
 use Friendica\App;
 use Friendica\Content\Pager;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Model\Register;
 use Friendica\Model\User as UserModel;
 use Friendica\Util\Temporal;
@@ -48,7 +48,7 @@ class User extends \Asika\SimpleConsole\Console
         */
        private $l10n;
        /**
-        * @var IPConfig
+        * @var IManagePersonalConfigValues
         */
        private $pConfig;
 
@@ -88,7 +88,7 @@ HELP;
                return $help;
        }
 
-       public function __construct(App\Mode $appMode, L10n $l10n, IPConfig $pConfig, array $argv = null)
+       public function __construct(App\Mode $appMode, L10n $l10n, IManagePersonalConfigValues $pConfig, array $argv = null)
        {
                parent::__construct($argv);
 
index 879e47c24d3e1762a7c11fdeb8e80a7ca8fb229c..7bd7ea69fbb436d909832ea5946c232933dd4b97 100644 (file)
@@ -26,10 +26,10 @@ use Friendica\App\Arguments;
 use Friendica\App\BaseURL;
 use Friendica\BaseModule;
 use Friendica\Core\ACL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
 use Friendica\Core\Session;
@@ -66,11 +66,11 @@ class Conversation
        private $item;
        /** @var App\Arguments */
        private $args;
-       /** @var IPConfig */
+       /** @var IManagePersonalConfigValues */
        private $pConfig;
        /** @var BaseURL */
        private $baseURL;
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var App */
        private $app;
@@ -79,7 +79,7 @@ class Conversation
        /** @var App\Mode */
        private $mode;
 
-       public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IConfig $config, IPConfig $pConfig, App\Page $page, App\Mode $mode, App $app)
+       public function __construct(LoggerInterface $logger, Profiler $profiler, Activity $activity, L10n $l10n, Item $item, Arguments $args, BaseURL $baseURL, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\Page $page, App\Mode $mode, App $app)
        {
                $this->activity = $activity;
                $this->item     = $item;
@@ -629,7 +629,7 @@ class Conversation
 
                                        $body_html = ItemModel::prepareBody($item, true, $preview);
 
-                                       list($categories, $folders) = $this->item->determineCategoriesTerms($item, local_user());
+                                       [$categories, $folders] = $this->item->determineCategoriesTerms($item, local_user());
 
                                        if (!empty($item['content-warning']) && $this->pConfig->get(local_user(), 'system', 'disable_cw', false)) {
                                                $title = ucfirst($item['content-warning']);
diff --git a/src/Core/Cache/Capability/ICanCache.php b/src/Core/Cache/Capability/ICanCache.php
new file mode 100644 (file)
index 0000000..46d1df4
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Capability;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+
+/**
+ * Interface for caches
+ */
+interface ICanCache
+{
+       /**
+        * Lists all cache keys
+        *
+        * @param string|null prefix optional a prefix to search
+        *
+        * @return array Empty if it isn't supported by the cache driver
+        */
+       public function getAllKeys(?string $prefix = null): array;
+
+       /**
+        * Fetches cached data according to the key
+        *
+        * @param string $key The key to the cached data
+        *
+        * @return mixed Cached $value or "null" if not found
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function get(string $key);
+
+       /**
+        * Stores data in the cache identified by the key. The input $value can have multiple formats.
+        *
+        * @param string  $key   The cache key
+        * @param mixed   $value The value to store
+        * @param integer $ttl   The cache lifespan, must be one of the Cache constants
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool;
+
+       /**
+        * Delete a key from the cache
+        *
+        * @param string $key The cache key
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function delete(string $key): bool;
+
+       /**
+        * Remove outdated data from the cache
+        *
+        * @param boolean $outdated just remove outdated values
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function clear(bool $outdated = true): bool;
+
+       /**
+        * Returns the name of the current cache
+        *
+        * @return string
+        */
+       public function getName(): string;
+}
diff --git a/src/Core/Cache/Capability/ICanCacheInMemory.php b/src/Core/Cache/Capability/ICanCacheInMemory.php
new file mode 100644 (file)
index 0000000..96e47ad
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Capability;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+
+/**
+ * This interface defines methods for Memory-Caches only
+ */
+interface ICanCacheInMemory extends ICanCache
+{
+       /**
+        * Sets a value if it's not already stored
+        *
+        * @param string $key   The cache key
+        * @param mixed  $value The old value we know from the cache
+        * @param int    $ttl   The cache lifespan, must be one of the Cache constants
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool;
+
+       /**
+        * Compares if the old value is set and sets the new value
+        *
+        * @param string $key      The cache key
+        * @param mixed  $oldValue The old value we know from the cache
+        * @param mixed  $newValue The new value we want to set
+        * @param int    $ttl      The cache lifespan, must be one of the Cache constants
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function compareSet(string $key, $oldValue, $newValue, int $ttl = Duration::FIVE_MINUTES): bool;
+
+       /**
+        * Compares if the old value is set and removes it
+        *
+        * @param string $key   The cache key
+        * @param mixed  $value The old value we know and want to delete
+        *
+        * @return bool
+        *
+        * @throws CachePersistenceException In case the underlying cache driver has errors during persistence
+        */
+       public function compareDelete(string $key, $value): bool;
+}
diff --git a/src/Core/Cache/Exception/CachePersistenceException.php b/src/Core/Cache/Exception/CachePersistenceException.php
new file mode 100644 (file)
index 0000000..d50221a
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Cache\Exception;
+
+use Throwable;
+
+class CachePersistenceException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Cache/Exception/InvalidCacheDriverException.php b/src/Core/Cache/Exception/InvalidCacheDriverException.php
new file mode 100644 (file)
index 0000000..290f620
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Cache\Exception;
+
+use Throwable;
+
+class InvalidCacheDriverException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Cache/Factory/Cache.php b/src/Core/Cache/Factory/Cache.php
new file mode 100644 (file)
index 0000000..2a49dfa
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Factory;
+
+use Friendica\App\BaseURL;
+use Friendica\Core\Cache\Enum;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
+use Friendica\Core\Cache\Type;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Database\Database;
+use Friendica\Util\Profiler;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class CacheFactory
+ *
+ * @package Friendica\Core\Cache
+ *
+ * A basic class to generate a CacheDriver
+ */
+class Cache
+{
+       /**
+        * @var string The default cache if nothing set
+        */
+       const DEFAULT_TYPE = Enum\Type::DATABASE;
+
+       /**
+        * @var IManageConfigValues The IConfiguration to read parameters out of the config
+        */
+       private $config;
+
+       /**
+        * @var Database The database connection in case that the cache is used the dba connection
+        */
+       private $dba;
+
+       /**
+        * @var string The hostname, used as Prefix for Caching
+        */
+       private $hostname;
+
+       /**
+        * @var Profiler The optional profiler if the cached should be profiled
+        */
+       private $profiler;
+
+       /**
+        * @var LoggerInterface The Friendica Logger
+        */
+       private $logger;
+
+       public function __construct(BaseURL $baseURL, IManageConfigValues $config, Database $dba, Profiler $profiler, LoggerInterface $logger)
+       {
+               $this->hostname = $baseURL->getHostname();
+               $this->config   = $config;
+               $this->dba      = $dba;
+               $this->profiler = $profiler;
+               $this->logger   = $logger;
+       }
+
+       /**
+        * This method creates a CacheDriver for the given cache driver name
+        *
+        * @param string|null $type The cache type to create (default is per config)
+        *
+        * @return ICanCache  The instance of the CacheDriver
+        *
+        * @throws InvalidCacheDriverException In case the underlying cache driver isn't valid or not configured properly
+        * @throws CachePersistenceException In case the underlying cache has errors during persistence
+        */
+       public function create(string $type = null): ICanCache
+       {
+               if (empty($type)) {
+                       $type = $this->config->get('system', 'cache_driver', self::DEFAULT_TYPE);
+               }
+
+               switch ($type) {
+                       case Enum\Type::MEMCACHE:
+                               $cache = new Type\MemcacheCache($this->hostname, $this->config);
+                               break;
+                       case Enum\Type::MEMCACHED:
+                               $cache = new Type\MemcachedCache($this->hostname, $this->config, $this->logger);
+                               break;
+                       case Enum\Type::REDIS:
+                               $cache = new Type\RedisCache($this->hostname, $this->config);
+                               break;
+                       case Enum\Type::APCU:
+                               $cache = new Type\APCuCache($this->hostname);
+                               break;
+                       default:
+                               $cache = new Type\DatabaseCache($this->hostname, $this->dba);
+               }
+
+               $profiling = $this->config->get('system', 'profiling', false);
+
+               // In case profiling is enabled, wrap the ProfilerCache around the current cache
+               if (isset($profiling) && $profiling !== false) {
+                       return new Type\ProfilerCacheDecorator($cache, $this->profiler);
+               } else {
+                       return $cache;
+               }
+       }
+}
diff --git a/src/Core/Cache/Factory/CacheFactory.php b/src/Core/Cache/Factory/CacheFactory.php
deleted file mode 100644 (file)
index 2e99180..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Factory;
-
-use Friendica\App\BaseURL;
-use Friendica\Core\Cache;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Database\Database;
-use Friendica\Util\Profiler;
-use Psr\Log\LoggerInterface;
-
-/**
- * Class CacheFactory
- *
- * @package Friendica\Core\Cache
- *
- * A basic class to generate a CacheDriver
- */
-class CacheFactory
-{
-       /**
-        * @var string The default cache if nothing set
-        */
-       const DEFAULT_TYPE = Cache\Enum\Type::DATABASE;
-
-       /**
-        * @var IConfig The IConfiguration to read parameters out of the config
-        */
-       private $config;
-
-       /**
-        * @var Database The database connection in case that the cache is used the dba connection
-        */
-       private $dba;
-
-       /**
-        * @var string The hostname, used as Prefix for Caching
-        */
-       private $hostname;
-
-       /**
-        * @var Profiler The optional profiler if the cached should be profiled
-        */
-       private $profiler;
-
-       /**
-        * @var LoggerInterface The Friendica Logger
-        */
-       private $logger;
-
-       public function __construct(BaseURL $baseURL, IConfig $config, Database $dba, Profiler $profiler, LoggerInterface $logger)
-       {
-               $this->hostname = $baseURL->getHostname();
-               $this->config   = $config;
-               $this->dba      = $dba;
-               $this->profiler = $profiler;
-               $this->logger   = $logger;
-       }
-
-       /**
-        * This method creates a CacheDriver for the given cache driver name
-        *
-        * @param string $type The cache type to create (default is per config)
-        *
-        * @return ICache  The instance of the CacheDriver
-        * @throws \Exception    The exception if something went wrong during the CacheDriver creation
-        */
-       public function create(string $type = null)
-       {
-               if (empty($type)) {
-                       $type = $this->config->get('system', 'cache_driver', self::DEFAULT_TYPE);
-               }
-
-               switch ($type) {
-                       case Cache\Enum\Type::MEMCACHE:
-                               $cache = new Cache\Type\MemcacheCache($this->hostname, $this->config);
-                               break;
-                       case Cache\Enum\Type::MEMCACHED:
-                               $cache = new Cache\Type\MemcachedCache($this->hostname, $this->config, $this->logger);
-                               break;
-                       case Cache\Enum\Type::REDIS:
-                               $cache = new Cache\Type\RedisCache($this->hostname, $this->config);
-                               break;
-                       case Cache\Enum\Type::APCU:
-                               $cache = new Cache\Type\APCuCache($this->hostname);
-                               break;
-                       default:
-                               $cache = new Cache\Type\DatabaseCache($this->hostname, $this->dba);
-               }
-
-               $profiling = $this->config->get('system', 'profiling', false);
-
-               // In case profiling is enabled, wrap the ProfilerCache around the current cache
-               if (isset($profiling) && $profiling !== false) {
-                       return new Cache\Type\ProfilerCache($cache, $this->profiler);
-               } else {
-                       return $cache;
-               }
-       }
-}
diff --git a/src/Core/Cache/ICache.php b/src/Core/Cache/ICache.php
deleted file mode 100644 (file)
index 3918b00..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache;
-
-use Friendica\Core\Cache\Enum\Duration;
-
-/**
- * Cache Interface
- */
-interface ICache
-{
-       /**
-        * Lists all cache keys
-        *
-        * @param string prefix optional a prefix to search
-        *
-        * @return array Empty if it isn't supported by the cache driver
-        */
-       public function getAllKeys($prefix = null);
-
-       /**
-        * Fetches cached data according to the key
-        *
-        * @param string $key The key to the cached data
-        *
-        * @return mixed Cached $value or "null" if not found
-        */
-       public function get($key);
-
-       /**
-        * Stores data in the cache identified by the key. The input $value can have multiple formats.
-        *
-        * @param string  $key      The cache key
-        * @param mixed   $value    The value to store
-        * @param integer $ttl      The cache lifespan, must be one of the Cache constants
-        *
-        * @return bool
-        */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * Delete a key from the cache
-        *
-        * @param string $key      The cache key
-        *
-        * @return bool
-        */
-       public function delete($key);
-
-       /**
-        * Remove outdated data from the cache
-        * @param  boolean $outdated just remove outdated values
-        *
-        * @return bool
-        */
-       public function clear($outdated = true);
-
-       /**
-        * Returns the name of the current cache
-        *
-        * @return string
-        */
-       public function getName();
-}
diff --git a/src/Core/Cache/IMemoryCache.php b/src/Core/Cache/IMemoryCache.php
deleted file mode 100644 (file)
index a46db0b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache;
-
-use Friendica\Core\Cache\Enum\Duration;
-
-/**
- * This interface defines methods for Memory-Caches only
- */
-interface IMemoryCache extends ICache
-{
-       /**
-        * Sets a value if it's not already stored
-        *
-        * @param string $key      The cache key
-        * @param mixed  $value    The old value we know from the cache
-        * @param int    $ttl      The cache lifespan, must be one of the Cache constants
-        * @return bool
-        */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * Compares if the old value is set and sets the new value
-        *
-        * @param string $key         The cache key
-        * @param mixed  $oldValue    The old value we know from the cache
-        * @param mixed  $newValue    The new value we want to set
-        * @param int    $ttl             The cache lifespan, must be one of the Cache constants
-        *
-        * @return bool
-        */
-       public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * Compares if the old value is set and removes it
-        *
-        * @param string $key          The cache key
-        * @param mixed  $value        The old value we know and want to delete
-        * @return bool
-        */
-       public function compareDelete($key, $value);
-}
index b473f68030af17503c5019acf5c3158fe6d527a4..b315a5cc03d3bcffae963e18e57d2c376a09f1f2 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Exception;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Type\TraitCompareDelete;
-use Friendica\Core\Cache\Type\TraitCompareSet;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Core\Cache\Enum\Type;
+use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
 
 /**
  * APCu Cache.
  */
-class APCuCache extends BaseCache implements IMemoryCache
+class APCuCache extends AbstractCache implements ICanCacheInMemory
 {
-       use TraitCompareSet;
-       use TraitCompareDelete;
+       use CompareSetTrait;
+       use CompareDeleteTrait;
 
        /**
-        * @throws Exception
+        * @param string $hostname
+        *
+        * @throws InvalidCacheDriverException
         */
        public function __construct(string $hostname)
        {
                if (!self::isAvailable()) {
-                       throw new Exception('APCu is not available.');
+                       throw new InvalidCacheDriverException('APCu is not available.');
                }
 
                parent::__construct($hostname);
@@ -51,9 +51,9 @@ class APCuCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
-               $ns = $this->getCacheKey($prefix);
+               $ns = $this->getCacheKey($prefix ?? '');
                $ns = preg_quote($ns, '/');
 
                if (class_exists('\APCIterator')) {
@@ -73,12 +73,11 @@ class APCuCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
-               $return = null;
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
-               $cached = apcu_fetch($cachekey, $success);
+               $cached = apcu_fetch($cacheKey, $success);
                if (!$success) {
                        return null;
                }
@@ -89,30 +88,30 @@ class APCuCache extends BaseCache implements IMemoryCache
                // We also check if the db entry is a serialized
                // boolean 'false' value (which we want to return).
                if ($cached === serialize(false) || $value !== false) {
-                       $return = $value;
+                       return $value;
                }
 
-               return $return;
+               return null;
        }
 
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                $cached = serialize($value);
 
                if ($ttl > 0) {
                        return apcu_store(
-                               $cachekey,
+                               $cacheKey,
                                $cached,
                                $ttl
                        );
                } else {
                        return apcu_store(
-                               $cachekey,
+                               $cacheKey,
                                $cached
                        );
                }
@@ -121,16 +120,16 @@ class APCuCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               return apcu_delete($cachekey);
+               $cacheKey = $this->getCacheKey($key);
+               return apcu_delete($cacheKey);
        }
 
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
                if ($outdated) {
                        return true;
@@ -151,15 +150,15 @@ class APCuCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               $cached = serialize($value);
+               $cacheKey = $this->getCacheKey($key);
+               $cached   = serialize($value);
 
-               return apcu_add($cachekey, $cached);
+               return apcu_add($cacheKey, $cached);
        }
 
-       public static function isAvailable()
+       public static function isAvailable(): bool
        {
                if (!extension_loaded('apcu')) {
                        return false;
@@ -178,7 +177,7 @@ class APCuCache extends BaseCache implements IMemoryCache
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::APCU;
        }
diff --git a/src/Core/Cache/Type/AbstractCache.php b/src/Core/Cache/Type/AbstractCache.php
new file mode 100644 (file)
index 0000000..f4d2e92
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Type;
+
+use Friendica\Core\Cache\Capability\ICanCache;
+
+/**
+ * Abstract class for common used functions
+ */
+abstract class AbstractCache implements ICanCache
+{
+       /**
+        * @var string The hostname
+        */
+       private $hostName;
+
+       public function __construct(string $hostName)
+       {
+               $this->hostName = $hostName;
+       }
+
+       /**
+        * Returns the prefix (to avoid namespace conflicts)
+        *
+        * @return string
+        */
+       protected function getPrefix(): string
+       {
+               // We fetch with the hostname as key to avoid problems with other applications
+               return $this->hostName;
+       }
+
+       /**
+        * @param string $key The original key
+        *
+        * @return string        The cache key used for the cache
+        */
+       protected function getCacheKey(string $key): string
+       {
+               return $this->getPrefix() . ":" . $key;
+       }
+
+       /**
+        * @param string[] $keys A list of cached keys
+        *
+        * @return string[] A list of original keys
+        */
+       protected function getOriginalKeys(array $keys): array
+       {
+               if (empty($keys)) {
+                       return [];
+               } else {
+                       // Keys are prefixed with the node hostname, let's remove it
+                       array_walk($keys, function (&$value) {
+                               $value = preg_replace('/^' . $this->hostName . ':/', '', $value);
+                       });
+
+                       sort($keys);
+
+                       return $keys;
+               }
+       }
+
+       /**
+        * Filters the keys of an array with a given prefix
+        * Returns the filtered keys as an new array
+        *
+        * @param string[]    $keys   The keys, which should get filtered
+        * @param string|null $prefix The prefix (if null, all keys will get returned)
+        *
+        * @return string[] The filtered array with just the keys
+        */
+       protected function filterArrayKeysByPrefix(array $keys, string $prefix = null): array
+       {
+               if (empty($prefix)) {
+                       return $keys;
+               } else {
+                       $result = [];
+
+                       foreach ($keys as $key) {
+                               if (strpos($key, $prefix) === 0) {
+                                       array_push($result, $key);
+                               }
+                       }
+
+                       return $result;
+               }
+       }
+}
index dd0985a9785c350c422360867c24e45bc7707f21..879128deed3291a6a6be9cedf864675746a21284 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Type\TraitCompareDelete;
-use Friendica\Core\Cache\Enum\Type;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
+use Friendica\Core\Cache\Enum;
 
 /**
  * Implementation of the IMemoryCache mainly for testing purpose
  */
-class ArrayCache extends BaseCache implements IMemoryCache
+class ArrayCache extends AbstractCache implements ICanCacheInMemory
 {
-       use TraitCompareDelete;
+       use CompareDeleteTrait;
 
        /** @var array Array with the cached data */
-       protected $cachedData = array();
+       protected $cachedData = [];
 
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
                return $this->filterArrayKeysByPrefix(array_keys($this->cachedData), $prefix);
        }
@@ -47,7 +45,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
                if (isset($this->cachedData[$key])) {
                        return $this->cachedData[$key];
@@ -58,7 +56,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Enum\Duration::FIVE_MINUTES): bool
        {
                $this->cachedData[$key] = $value;
                return true;
@@ -67,7 +65,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
                unset($this->cachedData[$key]);
                return true;
@@ -76,7 +74,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
                // Array doesn't support TTL so just don't delete something
                if ($outdated) {
@@ -90,7 +88,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function add(string $key, $value, int $ttl = Enum\Duration::FIVE_MINUTES): bool
        {
                if (isset($this->cachedData[$key])) {
                        return false;
@@ -102,7 +100,7 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES)
+       public function compareSet(string $key, $oldValue, $newValue, int $ttl = Enum\Duration::FIVE_MINUTES): bool
        {
                if ($this->get($key) === $oldValue) {
                        return $this->set($key, $newValue);
@@ -114,8 +112,8 @@ class ArrayCache extends BaseCache implements IMemoryCache
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
-               return Type::ARRAY;
+               return Enum\Type::ARRAY;
        }
 }
diff --git a/src/Core/Cache/Type/BaseCache.php b/src/Core/Cache/Type/BaseCache.php
deleted file mode 100644 (file)
index a52f1e9..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Type;
-
-use Friendica\Core\Cache\ICache;
-
-/**
- * Abstract class for common used functions
- */
-abstract class BaseCache implements ICache
-{
-       /**
-        * @var string The hostname
-        */
-       private $hostName;
-
-       public function __construct(string $hostName)
-       {
-               $this->hostName = $hostName;
-       }
-
-       /**
-        * Returns the prefix (to avoid namespace conflicts)
-        *
-        * @return string
-        * @throws \Exception
-        */
-       protected function getPrefix()
-       {
-               // We fetch with the hostname as key to avoid problems with other applications
-               return $this->hostName;
-       }
-
-       /**
-        * @param string $key The original key
-        * @return string        The cache key used for the cache
-        * @throws \Exception
-        */
-       protected function getCacheKey($key)
-       {
-               return $this->getPrefix() . ":" . $key;
-       }
-
-       /**
-        * @param array $keys   A list of cached keys
-        * @return array        A list of original keys
-        */
-       protected function getOriginalKeys($keys)
-       {
-               if (empty($keys)) {
-                       return [];
-               } else {
-                       // Keys are prefixed with the node hostname, let's remove it
-                       array_walk($keys, function (&$value) {
-                               $value = preg_replace('/^' . $this->hostName . ':/', '', $value);
-                       });
-
-                       sort($keys);
-
-                       return $keys;
-               }
-       }
-
-       /**
-        * Filters the keys of an array with a given prefix
-        * Returns the filtered keys as an new array
-        *
-        * @param array $keys The keys, which should get filtered
-        * @param string|null $prefix The prefix (if null, all keys will get returned)
-        *
-        * @return array The filtered array with just the keys
-        */
-       protected function filterArrayKeysByPrefix(array $keys, string $prefix = null)
-       {
-               if (empty($prefix)) {
-                       return $keys;
-               } else {
-                       $result = [];
-
-                       foreach ($keys as $key) {
-                               if (strpos($key, $prefix) === 0) {
-                                       array_push($result, $key);
-                               }
-                       }
-
-                       return $result;
-               }
-       }
-}
diff --git a/src/Core/Cache/Type/CompareDeleteTrait.php b/src/Core/Cache/Type/CompareDeleteTrait.php
new file mode 100644 (file)
index 0000000..5dffb30
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+
+/**
+ * This Trait is to compensate nonnative "exclusive" sets/deletes in caches
+ */
+trait CompareDeleteTrait
+{
+       abstract public function get(string $key);
+
+       abstract public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES);
+
+       abstract public function delete(string $key);
+
+       abstract public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES);
+
+       /**
+        * NonNative - Compares if the old value is set and removes it
+        *
+        * @param string $key   The cache key
+        * @param mixed  $value The old value we know and want to delete
+        *
+        * @return bool
+        */
+       public function compareDelete(string $key, $value): bool
+       {
+               if ($this->add($key . "_lock", true)) {
+                       if ($this->get($key) === $value) {
+                               $this->delete($key);
+                               $this->delete($key . "_lock");
+                               return true;
+                       } else {
+                               $this->delete($key . "_lock");
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+       }
+}
diff --git a/src/Core/Cache/Type/CompareSetTrait.php b/src/Core/Cache/Type/CompareSetTrait.php
new file mode 100644 (file)
index 0000000..6f0eeb2
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+
+/**
+ * This Trait is to compensate nonnative "exclusive" sets/deletes in caches
+ */
+trait CompareSetTrait
+{
+       abstract public function get(string $key);
+
+       abstract public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES);
+
+       abstract public function delete(string $key);
+
+       abstract public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES);
+
+       /**
+        * NonNative - Compares if the old value is set and sets the new value
+        *
+        * @param string $key      The cache key
+        * @param mixed  $oldValue The old value we know from the cache
+        * @param mixed  $newValue The new value we want to set
+        * @param int    $ttl      The cache lifespan, must be one of the Cache constants
+        *
+        * @return bool
+        */
+       public function compareSet(string $key, $oldValue, $newValue, int $ttl = Duration::FIVE_MINUTES): bool
+       {
+               if ($this->add($key . "_lock", true)) {
+                       if ($this->get($key) === $oldValue) {
+                               $this->set($key, $newValue, $ttl);
+                               $this->delete($key . "_lock");
+                               return true;
+                       } else {
+                               $this->delete($key . "_lock");
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+       }
+}
index a3c83c8dfe301d5af6dd52ae10d0f0adf74e6cd0..ef6a30afeb80725eae13ad3acef2c4a7577dd0a3 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Cache\Enum\Type;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Enum;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Database\Database;
 use Friendica\Util\DateTimeFormat;
 
 /**
  * Database Cache
  */
-class DatabaseCache extends BaseCache implements ICache
+class DatabaseCache extends AbstractCache implements ICanCache
 {
        /**
         * @var Database
@@ -46,22 +46,29 @@ class DatabaseCache extends BaseCache implements ICache
 
        /**
         * (@inheritdoc)
+        *
+        * @throws CachePersistenceException
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
-               if (empty($prefix)) {
-                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
-               } else {
-                       $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
-               }
+               try {
+                       if (empty($prefix)) {
+                               $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+                       } else {
+                               $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+                       }
 
-               $stmt = $this->dba->select('cache', ['k'], $where);
+                       $stmt = $this->dba->select('cache', ['k'], $where);
 
-               $keys = [];
-               while ($key = $this->dba->fetch($stmt)) {
-                       array_push($keys, $key['k']);
+                       $keys = [];
+                       while ($key = $this->dba->fetch($stmt)) {
+                               array_push($keys, $key['k']);
+                       }
+               } catch (\Exception $exception) {
+                       throw new CachePersistenceException(sprintf('Cannot fetch all keys with prefix %s', $prefix), $exception);
+               } finally {
+                       $this->dba->close($stmt);
                }
-               $this->dba->close($stmt);
 
                return $keys;
        }
@@ -69,20 +76,26 @@ class DatabaseCache extends BaseCache implements ICache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
-               $cache = $this->dba->selectFirst('cache', ['v'], ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()]);
-
-               if ($this->dba->isResult($cache)) {
-                       $cached = $cache['v'];
-                       $value = @unserialize($cached);
-
-                       // Only return a value if the serialized value is valid.
-                       // We also check if the db entry is a serialized
-                       // boolean 'false' value (which we want to return).
-                       if ($cached === serialize(false) || $value !== false) {
-                               return $value;
+               try {
+                       $cache = $this->dba->selectFirst('cache', ['v'], [
+                               '`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()
+                       ]);
+
+                       if ($this->dba->isResult($cache)) {
+                               $cached = $cache['v'];
+                               $value  = @unserialize($cached);
+
+                               // Only return a value if the serialized value is valid.
+                               // We also check if the db entry is a serialized
+                               // boolean 'false' value (which we want to return).
+                               if ($cached === serialize(false) || $value !== false) {
+                                       return $value;
+                               }
                        }
+               } catch (\Exception $exception) {
+                       throw new CachePersistenceException(sprintf('Cannot get cache entry with key %s', $key), $exception);
                }
 
                return null;
@@ -91,50 +104,62 @@ class DatabaseCache extends BaseCache implements ICache
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Enum\Duration::FIVE_MINUTES): bool
        {
-               if ($ttl > 0) {
-                       $fields = [
-                               'v' => serialize($value),
-                               'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
-                               'updated' => DateTimeFormat::utcNow()
-                       ];
-               } else {
-                       $fields = [
-                               'v' => serialize($value),
-                               'expires' => -1,
-                               'updated' => DateTimeFormat::utcNow()
-                       ];
-               }
+               try {
+                       if ($ttl > 0) {
+                               $fields = [
+                                       'v'       => serialize($value),
+                                       'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
+                                       'updated' => DateTimeFormat::utcNow()
+                               ];
+                       } else {
+                               $fields = [
+                                       'v'       => serialize($value),
+                                       'expires' => -1,
+                                       'updated' => DateTimeFormat::utcNow()
+                               ];
+                       }
 
-               return $this->dba->update('cache', $fields, ['k' => $key], true);
+                       return $this->dba->update('cache', $fields, ['k' => $key], true);
+               } catch (\Exception $exception) {
+                       throw new CachePersistenceException(sprintf('Cannot set cache entry with key %s', $key), $exception);
+               }
        }
 
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
-               return $this->dba->delete('cache', ['k' => $key]);
+               try {
+                       return $this->dba->delete('cache', ['k' => $key]);
+               } catch (\Exception $exception) {
+                       throw new CachePersistenceException(sprintf('Cannot delete cache entry with key %s', $key), $exception);
+               }
        }
 
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
-               if ($outdated) {
-                       return $this->dba->delete('cache', ['`expires` < NOW()']);
-               } else {
-                       return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
+               try {
+                       if ($outdated) {
+                               return $this->dba->delete('cache', ['`expires` < NOW()']);
+                       } else {
+                               return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
+                       }
+               } catch (\Exception $exception) {
+                       throw new CachePersistenceException('Cannot clear cache', $exception);
                }
        }
 
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
-               return Type::DATABASE;
+               return Enum\Type::DATABASE;
        }
 }
index f991517fcca016f84d48a8446d84888d60ae1bbb..a8a183daab9d55c2c90bdb581355bd4823571d24 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Exception;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Type\TraitCompareDelete;
-use Friendica\Core\Cache\Type\TraitCompareSet;
-use Friendica\Core\Cache\Type\TraitMemcacheCommand;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Memcache;
 
 /**
  * Memcache Cache
  */
-class MemcacheCache extends BaseCache implements IMemoryCache
+class MemcacheCache extends AbstractCache implements ICanCacheInMemory
 {
-       use TraitCompareSet;
-       use TraitCompareDelete;
-       use TraitMemcacheCommand;
+       use CompareSetTrait;
+       use CompareDeleteTrait;
+       use MemcacheCommandTrait;
 
        /**
         * @var Memcache
@@ -46,30 +44,34 @@ class MemcacheCache extends BaseCache implements IMemoryCache
        private $memcache;
 
        /**
-        * @throws Exception
+        * @param string              $hostname
+        * @param IManageConfigValues $config
+        *
+        * @throws InvalidCacheDriverException
+        * @throws CachePersistenceException
         */
-       public function __construct(string $hostname, IConfig $config)
+       public function __construct(string $hostname, IManageConfigValues $config)
        {
                if (!class_exists('Memcache', false)) {
-                       throw new Exception('Memcache class isn\'t available');
+                       throw new InvalidCacheDriverException('Memcache class isn\'t available');
                }
 
                parent::__construct($hostname);
 
                $this->memcache = new Memcache();
 
-               $this->server = $config->get('system', 'memcache_host');;
-               $this->port = $config->get('system', 'memcache_port');
+               $this->server = $config->get('system', 'memcache_host');
+               $this->port   = $config->get('system', 'memcache_port');
 
                if (!@$this->memcache->connect($this->server, $this->port)) {
-                       throw new Exception('Expected Memcache server at ' . $this->server . ':' . $this->port . ' isn\'t available');
+                       throw new CachePersistenceException('Expected Memcache server at ' . $this->server . ':' . $this->port . ' isn\'t available');
                }
        }
 
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
                $keys = $this->getOriginalKeys($this->getMemcacheKeys());
 
@@ -79,17 +81,16 @@ class MemcacheCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
-               $return   = null;
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                // We fetch with the hostname as key to avoid problems with other applications
-               $cached = $this->memcache->get($cachekey);
+               $cached = $this->memcache->get($cacheKey);
 
                // @see http://php.net/manual/en/memcache.get.php#84275
                if (is_bool($cached) || is_double($cached) || is_long($cached)) {
-                       return $return;
+                       return null;
                }
 
                $value = @unserialize($cached);
@@ -98,30 +99,30 @@ class MemcacheCache extends BaseCache implements IMemoryCache
                // We also check if the db entry is a serialized
                // boolean 'false' value (which we want to return).
                if ($cached === serialize(false) || $value !== false) {
-                       $return = $value;
+                       return $value;
                }
 
-               return $return;
+               return null;
        }
 
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                // We store with the hostname as key to avoid problems with other applications
                if ($ttl > 0) {
                        return $this->memcache->set(
-                               $cachekey,
+                               $cacheKey,
                                serialize($value),
                                MEMCACHE_COMPRESSED,
                                time() + $ttl
                        );
                } else {
                        return $this->memcache->set(
-                               $cachekey,
+                               $cacheKey,
                                serialize($value),
                                MEMCACHE_COMPRESSED
                        );
@@ -131,16 +132,16 @@ class MemcacheCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               return $this->memcache->delete($cachekey);
+               $cacheKey = $this->getCacheKey($key);
+               return $this->memcache->delete($cacheKey);
        }
 
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
                if ($outdated) {
                        return true;
@@ -152,16 +153,16 @@ class MemcacheCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
+               $cacheKey = $this->getCacheKey($key);
+               return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
        }
 
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::MEMCACHE;
        }
diff --git a/src/Core/Cache/Type/MemcacheCommandTrait.php b/src/Core/Cache/Type/MemcacheCommandTrait.php
new file mode 100644 (file)
index 0000000..10315d6
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Type;
+
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+
+/**
+ * Trait for Memcache to add a custom version of the
+ * method getAllKeys() since this isn't working anymore
+ *
+ * Adds the possibility to directly communicate with the memcache too
+ */
+trait MemcacheCommandTrait
+{
+       /**
+        * @var string server address
+        */
+       protected $server;
+
+       /**
+        * @var int server port
+        */
+       protected $port;
+
+       /**
+        * Retrieves the stored keys of the memcache instance
+        * Uses custom commands, which aren't bound to the used instance of the class
+        *
+        * @todo Due the fact that we use a custom command, there are race conditions possible:
+        *       - $this->memcache(d) adds a key
+        *       - $this->getMemcacheKeys is called directly "after"
+        *       - But $this->memcache(d) isn't finished adding the key, so getMemcacheKeys doesn't find it
+        *
+        * @return array All keys of the memcache instance
+        *
+        * @throws CachePersistenceException
+        */
+       protected function getMemcacheKeys(): array
+       {
+               $string = $this->sendMemcacheCommand("stats items");
+               $lines  = explode("\r\n", $string);
+               $keys   = [];
+
+               foreach ($lines as $line) {
+                       if (preg_match("/STAT items:([\d]+):number ([\d]+)/", $line, $matches) &&
+                               isset($matches[1]) &&
+                               !in_array($matches[1], $keys)) {
+                               $string = $this->sendMemcacheCommand("stats cachedump " . $matches[1] . " " . $matches[2]);
+                               preg_match_all("/ITEM (.*?) /", $string, $matches);
+                               $keys = array_merge($keys, $matches[1]);
+                       }
+               }
+
+               return $keys;
+       }
+
+       /**
+        * Taken directly from memcache PECL source
+        * Sends a command to the memcache instance and returns the result
+        * as a string
+        *
+        * http://pecl.php.net/package/memcache
+        *
+        * @param string $command The command to send to the Memcache server
+        *
+        * @return string The returned buffer result
+        *
+        * @throws CachePersistenceException In case the memcache server isn't available (anymore)
+        */
+       protected function sendMemcacheCommand(string $command): string
+       {
+               $s = @fsockopen($this->server, $this->port);
+               if (!$s) {
+                       throw new CachePersistenceException("Cant connect to:" . $this->server . ':' . $this->port);
+               }
+
+               fwrite($s, $command . "\r\n");
+               $buf = '';
+
+               while (!feof($s)) {
+                       $buf .= fgets($s, 256);
+
+                       if (strpos($buf, "END\r\n") !== false) { // stat says end
+                               break;
+                       }
+
+                       if (strpos($buf, "DELETED\r\n") !== false || strpos($buf, "NOT_FOUND\r\n") !== false) { // delete says these
+                               break;
+                       }
+
+                       if (strpos($buf, "OK\r\n") !== false) { // flush_all says ok
+                               break;
+                       }
+               }
+
+               fclose($s);
+               return ($buf);
+       }
+}
index ded53ee9779d3dad0b75320bdd0fa6c2569c547e..7aff735cedb45a3afa7ff2f4daf5dab56b140755 100644 (file)
 
 namespace Friendica\Core\Cache\Type;
 
-use Exception;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Type\TraitCompareDelete;
-use Friendica\Core\Cache\Type\TraitCompareSet;
-use Friendica\Core\Cache\Type\TraitMemcacheCommand;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Memcached;
 use Psr\Log\LoggerInterface;
 
 /**
  * Memcached Cache
  */
-class MemcachedCache extends BaseCache implements IMemoryCache
+class MemcachedCache extends AbstractCache implements ICanCacheInMemory
 {
-       use TraitCompareSet;
-       use TraitCompareDelete;
-       use TraitMemcacheCommand;
+       use CompareSetTrait;
+       use CompareDeleteTrait;
+       use MemcacheCommandTrait;
 
        /**
         * @var \Memcached
@@ -58,14 +56,17 @@ class MemcachedCache extends BaseCache implements IMemoryCache
         *   1 => ...
         * }
         *
-        * @param array $memcached_hosts
+        * @param string              $hostname
+        * @param IManageConfigValues $config
+        * @param LoggerInterface     $logger
         *
-        * @throws \Exception
+        * @throws InvalidCacheDriverException
+        * @throws CachePersistenceException
         */
-       public function __construct(string $hostname, IConfig $config, LoggerInterface $logger)
+       public function __construct(string $hostname, IManageConfigValues $config, LoggerInterface $logger)
        {
                if (!class_exists('Memcached', false)) {
-                       throw new Exception('Memcached class isn\'t available');
+                       throw new InvalidCacheDriverException('Memcached class isn\'t available');
                }
 
                parent::__construct($hostname);
@@ -83,19 +84,19 @@ class MemcachedCache extends BaseCache implements IMemoryCache
                });
 
                $this->server = $memcached_hosts[0][0] ?? 'localhost';
-               $this->port = $memcached_hosts[0][1] ?? 11211;
+               $this->port   = $memcached_hosts[0][1] ?? 11211;
 
                $this->memcached->addServers($memcached_hosts);
 
                if (count($this->memcached->getServerList()) == 0) {
-                       throw new Exception('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
+                       throw new CachePersistenceException('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
                }
        }
 
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
                $keys = $this->getOriginalKeys($this->getMemcacheKeys());
 
@@ -105,40 +106,40 @@ class MemcachedCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
-               $return   = null;
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                // We fetch with the hostname as key to avoid problems with other applications
-               $value = $this->memcached->get($cachekey);
+               $value = $this->memcached->get($cacheKey);
 
                if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
-                       $return = $value;
+                       return $value;
+               } elseif ($this->memcached->getResultCode() === Memcached::RES_NOTFOUND) {
+                       $this->logger->notice('Try to use unknown key.', ['key' => $key]);
+                       return null;
                } else {
-                       $this->logger->debug('Memcached \'get\' failed', ['result' => $this->memcached->getResultMessage()]);
+                       throw new CachePersistenceException(sprintf('Cannot get cache entry with key %s', $key), new \MemcachedException($this->memcached->getResultMessage(), $this->memcached->getResultCode()));
                }
-
-               return $return;
        }
 
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                // We store with the hostname as key to avoid problems with other applications
                if ($ttl > 0) {
                        return $this->memcached->set(
-                               $cachekey,
+                               $cacheKey,
                                $value,
                                $ttl
                        );
                } else {
                        return $this->memcached->set(
-                               $cachekey,
+                               $cacheKey,
                                $value
                        );
                }
@@ -147,16 +148,16 @@ class MemcachedCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               return $this->memcached->delete($cachekey);
+               $cacheKey = $this->getCacheKey($key);
+               return $this->memcached->delete($cacheKey);
        }
 
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
                if ($outdated) {
                        return true;
@@ -168,16 +169,16 @@ class MemcachedCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               return $this->memcached->add($cachekey, $value, $ttl);
+               $cacheKey = $this->getCacheKey($key);
+               return $this->memcached->add($cacheKey, $value, $ttl);
        }
 
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::MEMCACHED;
        }
diff --git a/src/Core/Cache/Type/ProfilerCache.php b/src/Core/Cache/Type/ProfilerCache.php
deleted file mode 100644 (file)
index fd00385..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Type;
-
-use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Util\Profiler;
-
-/**
- * This class wraps cache driver so they can get profiled - in case the profiler is enabled
- *
- * It is using the decorator pattern (@see
- */
-class ProfilerCache implements ICache, IMemoryCache
-{
-       /**
-        * @var ICache The original cache driver
-        */
-       private $cache;
-
-       /**
-        * @var Profiler The profiler of Friendica
-        */
-       private $profiler;
-
-       public function __construct(ICache $cache, Profiler $profiler)
-       {
-               $this->cache    = $cache;
-               $this->profiler = $profiler;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getAllKeys($prefix = null)
-       {
-               $this->profiler->startRecording('cache');
-
-               $return = $this->cache->getAllKeys($prefix);
-
-               $this->profiler->stopRecording();
-
-               return $return;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function get($key)
-       {
-               $this->profiler->startRecording('cache');
-
-               $return = $this->cache->get($key);
-
-               $this->profiler->stopRecording();
-
-               return $return;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
-       {
-               $this->profiler->startRecording('cache');
-
-               $return = $this->cache->set($key, $value, $ttl);
-
-               $this->profiler->stopRecording();
-
-               return $return;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function delete($key)
-       {
-               $this->profiler->startRecording('cache');
-
-               $return = $this->cache->delete($key);
-
-               $this->profiler->stopRecording();
-
-               return $return;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function clear($outdated = true)
-       {
-               $this->profiler->startRecording('cache');
-
-               $return = $this->cache->clear($outdated);
-
-               $this->profiler->stopRecording();
-
-               return $return;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
-       {
-               if ($this->cache instanceof IMemoryCache) {
-                       $this->profiler->startRecording('cache');
-
-                       $return = $this->cache->add($key, $value, $ttl);
-
-                       $this->profiler->stopRecording();
-
-                       return $return;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES)
-       {
-               if ($this->cache instanceof IMemoryCache) {
-                       $this->profiler->startRecording('cache');
-
-                       $return = $this->cache->compareSet($key, $oldValue, $newValue, $ttl);
-
-                       $this->profiler->stopRecording();
-
-                       return $return;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function compareDelete($key, $value)
-       {
-               if ($this->cache instanceof IMemoryCache) {
-                       $this->profiler->startRecording('cache');
-
-                       $return = $this->cache->compareDelete($key, $value);
-
-                       $this->profiler->stopRecording();
-
-                       return $return;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function GetName()
-       {
-               return $this->cache->getName() . ' (with profiler)';
-       }
-}
diff --git a/src/Core/Cache/Type/ProfilerCacheDecorator.php b/src/Core/Cache/Type/ProfilerCacheDecorator.php
new file mode 100644 (file)
index 0000000..11b1755
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Cache\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
+use Friendica\Util\Profiler;
+
+/**
+ * This class wraps cache driver, so they can get profiled - in case the profiler is enabled
+ *
+ * It is using the decorator pattern (@see https://en.wikipedia.org/wiki/Decorator_pattern )
+ */
+class ProfilerCacheDecorator implements ICanCache, ICanCacheInMemory
+{
+       /**
+        * @var ICanCache The original cache driver
+        */
+       private $cache;
+
+       /**
+        * @var Profiler The profiler of Friendica
+        */
+       private $profiler;
+
+       public function __construct(ICanCache $cache, Profiler $profiler)
+       {
+               $this->cache    = $cache;
+               $this->profiler = $profiler;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getAllKeys(?string $prefix = null): array
+       {
+               $this->profiler->startRecording('cache');
+
+               $return = $this->cache->getAllKeys($prefix);
+
+               $this->profiler->stopRecording();
+
+               return $return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function get(string $key)
+       {
+               $this->profiler->startRecording('cache');
+
+               $return = $this->cache->get($key);
+
+               $this->profiler->stopRecording();
+
+               return $return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
+       {
+               $this->profiler->startRecording('cache');
+
+               $return = $this->cache->set($key, $value, $ttl);
+
+               $this->profiler->stopRecording();
+
+               return $return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function delete(string $key): bool
+       {
+               $this->profiler->startRecording('cache');
+
+               $return = $this->cache->delete($key);
+
+               $this->profiler->stopRecording();
+
+               return $return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function clear(bool $outdated = true): bool
+       {
+               $this->profiler->startRecording('cache');
+
+               $return = $this->cache->clear($outdated);
+
+               $this->profiler->stopRecording();
+
+               return $return;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
+       {
+               if ($this->cache instanceof ICanCacheInMemory) {
+                       $this->profiler->startRecording('cache');
+
+                       $return = $this->cache->add($key, $value, $ttl);
+
+                       $this->profiler->stopRecording();
+
+                       return $return;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function compareSet(string $key, $oldValue, $newValue, int $ttl = Duration::FIVE_MINUTES): bool
+       {
+               if ($this->cache instanceof ICanCacheInMemory) {
+                       $this->profiler->startRecording('cache');
+
+                       $return = $this->cache->compareSet($key, $oldValue, $newValue, $ttl);
+
+                       $this->profiler->stopRecording();
+
+                       return $return;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function compareDelete(string $key, $value): bool
+       {
+               if ($this->cache instanceof ICanCacheInMemory) {
+                       $this->profiler->startRecording('cache');
+
+                       $return = $this->cache->compareDelete($key, $value);
+
+                       $this->profiler->stopRecording();
+
+                       return $return;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function GetName(): string
+       {
+               return $this->cache->getName() . ' (with profiler)';
+       }
+}
index a4cc4197277ad9728ff137787990ca0c2ea556d2..494bd83d3fe4b718e8a181a10fb940507380b532 100644 (file)
@@ -23,15 +23,17 @@ namespace Friendica\Core\Cache\Type;
 
 use Exception;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Redis;
 
 /**
  * Redis Cache. This driver is based on Memcache driver
  */
-class RedisCache extends BaseCache implements IMemoryCache
+class RedisCache extends AbstractCache implements ICanCacheInMemory
 {
        /**
         * @var Redis
@@ -39,12 +41,13 @@ class RedisCache extends BaseCache implements IMemoryCache
        private $redis;
 
        /**
-        * @throws Exception
+        * @throws InvalidCacheDriverException
+        * @throws CachePersistenceException
         */
-       public function __construct(string $hostname, IConfig $config)
+       public function __construct(string $hostname, IManageConfigValues $config)
        {
                if (!class_exists('Redis', false)) {
-                       throw new Exception('Redis class isn\'t available');
+                       throw new InvalidCacheDriverException('Redis class isn\'t available');
                }
 
                parent::__construct($hostname);
@@ -57,24 +60,24 @@ class RedisCache extends BaseCache implements IMemoryCache
                $redis_db   = $config->get('system', 'redis_db', 0);
 
                if (isset($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) {
-                       throw new Exception('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
+                       throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
                } elseif (!@$this->redis->connect($redis_host)) {
-                       throw new Exception('Expected Redis server at ' . $redis_host . ' isn\'t available');
+                       throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available');
                }
 
                if (isset($redis_pw) && !$this->redis->auth($redis_pw)) {
-                       throw new Exception('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
+                       throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
                }
 
                if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
-                       throw new Exception('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+                       throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
                }
        }
 
        /**
         * (@inheritdoc)
         */
-       public function getAllKeys($prefix = null)
+       public function getAllKeys(?string $prefix = null): array
        {
                if (empty($prefix)) {
                        $search = '*';
@@ -90,13 +93,13 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function get($key)
+       public function get(string $key)
        {
-               $return = null;
-               $cachekey = $this->getCacheKey($key);
+               $return   = null;
+               $cacheKey = $this->getCacheKey($key);
 
-               $cached = $this->redis->get($cachekey);
-               if ($cached === false && !$this->redis->exists($cachekey)) {
+               $cached = $this->redis->get($cacheKey);
+               if ($cached === false && !$this->redis->exists($cacheKey)) {
                        return null;
                }
 
@@ -115,21 +118,21 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function set(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                $cached = serialize($value);
 
                if ($ttl > 0) {
                        return $this->redis->setex(
-                               $cachekey,
+                               $cacheKey,
                                $ttl,
                                $cached
                        );
                } else {
                        return $this->redis->set(
-                               $cachekey,
+                               $cacheKey,
                                $cached
                        );
                }
@@ -138,10 +141,10 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function delete($key)
+       public function delete(string $key): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               $this->redis->del($cachekey);
+               $cacheKey = $this->getCacheKey($key);
+               $this->redis->del($cacheKey);
                // Redis doesn't have an error state for del()
                return true;
        }
@@ -149,7 +152,7 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function clear($outdated = true)
+       public function clear(bool $outdated = true): bool
        {
                if ($outdated) {
                        return true;
@@ -161,34 +164,30 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
+       public function add(string $key, $value, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
-               $cached = serialize($value);
+               $cacheKey = $this->getCacheKey($key);
+               $cached   = serialize($value);
 
-               return $this->redis->setnx($cachekey, $cached);
+               return $this->redis->setnx($cacheKey, $cached);
        }
 
        /**
         * (@inheritdoc)
         */
-       public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES)
+       public function compareSet(string $key, $oldValue, $newValue, int $ttl = Duration::FIVE_MINUTES): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
                $newCached = serialize($newValue);
 
-               $this->redis->watch($cachekey);
+               $this->redis->watch($cacheKey);
                // If the old value isn't what we expected, somebody else changed the key meanwhile
                if ($this->get($key) === $oldValue) {
                        if ($ttl > 0) {
-                               $result = $this->redis->multi()
-                                       ->setex($cachekey, $ttl, $newCached)
-                                       ->exec();
+                               $result = $this->redis->multi()->setex($cacheKey, $ttl, $newCached)->exec();
                        } else {
-                               $result = $this->redis->multi()
-                                       ->set($cachekey, $newCached)
-                                       ->exec();
+                               $result = $this->redis->multi()->set($cacheKey, $newCached)->exec();
                        }
                        return $result !== false;
                }
@@ -199,17 +198,15 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * (@inheritdoc)
         */
-       public function compareDelete($key, $value)
+       public function compareDelete(string $key, $value): bool
        {
-               $cachekey = $this->getCacheKey($key);
+               $cacheKey = $this->getCacheKey($key);
 
-               $this->redis->watch($cachekey);
+               $this->redis->watch($cacheKey);
                // If the old value isn't what we expected, somebody else changed the key meanwhile
                if ($this->get($key) === $value) {
-                       $result = $this->redis->multi()
-                               ->del($cachekey)
-                               ->exec();
-                       return $result !== false;
+                       $this->redis->multi()->del($cacheKey)->exec();
+                       return true;
                }
                $this->redis->unwatch();
                return false;
@@ -218,7 +215,7 @@ class RedisCache extends BaseCache implements IMemoryCache
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::REDIS;
        }
diff --git a/src/Core/Cache/Type/TraitCompareDelete.php b/src/Core/Cache/Type/TraitCompareDelete.php
deleted file mode 100644 (file)
index 4873638..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Type;
-
-use Friendica\Core\Cache\Enum\Duration;
-
-/**
- * Trait TraitCompareSetDelete
- *
- * This Trait is to compensate non native "exclusive" sets/deletes in caches
- */
-trait TraitCompareDelete
-{
-       abstract public function get($key);
-
-       abstract public function set($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       abstract public function delete($key);
-
-       abstract public function add($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * NonNative - Compares if the old value is set and removes it
-        *
-        * @param string $key          The cache key
-        * @param mixed  $value        The old value we know and want to delete
-        * @return bool
-        */
-       public function compareDelete($key, $value) {
-               if ($this->add($key . "_lock", true)) {
-                       if ($this->get($key) === $value) {
-                               $this->delete($key);
-                               $this->delete($key . "_lock");
-                               return true;
-                       } else {
-                               $this->delete($key . "_lock");
-                               return false;
-                       }
-               } else {
-                       return false;
-               }
-       }
-}
diff --git a/src/Core/Cache/Type/TraitCompareSet.php b/src/Core/Cache/Type/TraitCompareSet.php
deleted file mode 100644 (file)
index 86aef92..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Type;
-
-use Friendica\Core\Cache\Enum\Duration;
-
-/**
- * Trait TraitCompareSetDelete
- *
- * This Trait is to compensate non native "exclusive" sets/deletes in caches
- */
-trait TraitCompareSet
-{
-       abstract public function get($key);
-
-       abstract public function set($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       abstract public function delete($key);
-
-       abstract public function add($key, $value, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * NonNative - Compares if the old value is set and sets the new value
-        *
-        * @param string $key         The cache key
-        * @param mixed  $oldValue    The old value we know from the cache
-        * @param mixed  $newValue    The new value we want to set
-        * @param int    $ttl      The cache lifespan, must be one of the Cache constants
-        *
-        * @return bool
-        */
-       public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES) {
-               if ($this->add($key . "_lock", true)) {
-                       if ($this->get($key) === $oldValue) {
-                               $this->set($key, $newValue, $ttl);
-                               $this->delete($key . "_lock");
-                               return true;
-                       } else {
-                               $this->delete($key . "_lock");
-                               return false;
-                       }
-               } else {
-                       return false;
-               }
-       }
-}
diff --git a/src/Core/Cache/Type/TraitMemcacheCommand.php b/src/Core/Cache/Type/TraitMemcacheCommand.php
deleted file mode 100644 (file)
index 73495e2..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Cache\Type;
-
-use Friendica\Network\HTTPException\InternalServerErrorException;
-
-/**
- * Trait for Memcache to add a custom version of the
- * method getAllKeys() since this isn't working anymore
- *
- * Adds the possibility to directly communicate with the memcache too
- */
-trait TraitMemcacheCommand
-{
-       /**
-        * @var string server address
-        */
-       protected $server;
-
-       /**
-        * @var int server port
-        */
-       protected $port;
-
-       /**
-        * Retrieves the stored keys of the memcache instance
-        * Uses custom commands, which aren't bound to the used instance of the class
-        *
-        * @todo Due the fact that we use a custom command, there are race conditions possible:
-        *       - $this->memcache(d) adds a key
-        *       - $this->getMemcacheKeys is called directly "after"
-        *       - But $this->memcache(d) isn't finished adding the key, so getMemcacheKeys doesn't find it
-        *
-        * @return array All keys of the memcache instance
-        *
-        * @throws InternalServerErrorException
-        */
-       protected function getMemcacheKeys()
-       {
-               $string = $this->sendMemcacheCommand("stats items");
-               $lines  = explode("\r\n", $string);
-               $slabs  = [];
-               $keys   = [];
-
-               foreach ($lines as $line) {
-
-                       if (preg_match("/STAT items:([\d]+):number ([\d]+)/", $line, $matches) &&
-                           isset($matches[1]) &&
-                           !in_array($matches[1], $keys)) {
-
-                               $slabs[] = $matches[1];
-                               $string  = $this->sendMemcacheCommand("stats cachedump " . $matches[1] . " " . $matches[2]);
-                               preg_match_all("/ITEM (.*?) /", $string, $matches);
-                               $keys = array_merge($keys, $matches[1]);
-                       }
-               }
-
-               return $keys;
-       }
-
-       /**
-        * Taken directly from memcache PECL source
-        * Sends a command to the memcache instance and returns the result
-        * as a string
-        *
-        * http://pecl.php.net/package/memcache
-        *
-        * @param string $command The command to send to the Memcache server
-        *
-        * @return string The returned buffer result
-        *
-        * @throws InternalServerErrorException In case the memcache server isn't available (anymore)
-        */
-       protected function sendMemcacheCommand(string $command)
-       {
-               $s = @fsockopen($this->server, $this->port);
-               if (!$s) {
-                       throw new InternalServerErrorException("Cant connect to:" . $this->server . ':' . $this->port);
-               }
-
-               fwrite($s, $command . "\r\n");
-               $buf = '';
-
-               while (!feof($s)) {
-
-                       $buf .= fgets($s, 256);
-
-                       if (strpos($buf, "END\r\n") !== false) { // stat says end
-                               break;
-                       }
-
-                       if (strpos($buf, "DELETED\r\n") !== false || strpos($buf, "NOT_FOUND\r\n") !== false) { // delete says these
-                               break;
-                       }
-
-                       if (strpos($buf, "OK\r\n") !== false) { // flush_all says ok
-                               break;
-                       }
-               }
-
-               fclose($s);
-               return ($buf);
-       }
-}
diff --git a/src/Core/Config/Cache/Cache.php b/src/Core/Config/Cache/Cache.php
deleted file mode 100644 (file)
index 77e6562..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config\Cache;
-
-use ParagonIE\HiddenString\HiddenString;
-
-/**
- * The Friendica config cache for the application
- * Initial, all *.config.php files are loaded into this cache with the
- * ConfigFileLoader ( @see ConfigFileLoader )
- */
-class Cache
-{
-       /** @var int Indicates that the cache entry is set by file - Low Priority */
-       const SOURCE_FILE = 0;
-       /** @var int Indicates that the cache entry is set by the DB config table - Middle Priority */
-       const SOURCE_DB = 1;
-       /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */
-       const SOURCE_ENV = 3;
-       /** @var int Indicates that the cache entry is fixed and must not be changed */
-       const SOURCE_FIX = 4;
-
-       /** @var int Default value for a config source */
-       const SOURCE_DEFAULT = self::SOURCE_FILE;
-
-       /**
-        * @var array
-        */
-       private $config;
-
-       /**
-        * @var int[][]
-        */
-       private $source = [];
-
-       /**
-        * @var bool
-        */
-       private $hidePasswordOutput;
-
-       /**
-        * @param array $config             A initial config array
-        * @param bool  $hidePasswordOutput True, if cache variables should take extra care of password values
-        * @param int   $source             Sets a source of the initial config values
-        */
-       public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
-       {
-               $this->hidePasswordOutput = $hidePasswordOutput;
-               $this->load($config, $source);
-       }
-
-       /**
-        * Tries to load the specified configuration array into the config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * @param array $config
-        * @param int   $source Indicates the source of the config entry
-        */
-       public function load(array $config, int $source = self::SOURCE_DEFAULT)
-       {
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       $value = $config[$category][$key];
-                                       if (isset($value)) {
-                                               $this->set($category, $key, $value, $source);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Gets a value from the config cache.
-        *
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return null|mixed Returns the value of the Config entry or null if not set
-        */
-       public function get(string $cat, string $key = null)
-       {
-               if (isset($this->config[$cat][$key])) {
-                       return $this->config[$cat][$key];
-               } else if (!isset($key) && isset($this->config[$cat])) {
-                       return $this->config[$cat];
-               } else {
-                       return 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
-        * @param int    $source The source of the current config key
-        *
-        * @return bool True, if the value is set
-        */
-       public function set(string $cat, string $key, $value, $source = self::SOURCE_DEFAULT)
-       {
-               if (!isset($this->config[$cat])) {
-                       $this->config[$cat] = [];
-                       $this->source[$cat] = [];
-               }
-
-               if (isset($this->source[$cat][$key]) &&
-                       $source < $this->source[$cat][$key]) {
-                       return false;
-               }
-
-               if ($this->hidePasswordOutput &&
-                       $key == 'password' &&
-                       is_string($value)) {
-                       $this->config[$cat][$key] = new HiddenString((string)$value);
-               } else {
-                       $this->config[$cat][$key] = $value;
-               }
-
-               $this->source[$cat][$key] = $source;
-
-               return true;
-       }
-
-       /**
-        * Deletes a value from the config cache.
-        *
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return bool true, if deleted
-        */
-       public function delete(string $cat, string $key)
-       {
-               if (isset($this->config[$cat][$key])) {
-                       unset($this->config[$cat][$key]);
-                       unset($this->source[$cat][$key]);
-                       if (count($this->config[$cat]) == 0) {
-                               unset($this->config[$cat]);
-                               unset($this->source[$cat]);
-                       }
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Returns the whole configuration
-        *
-        * @return array The configuration
-        */
-       public function getAll()
-       {
-               return $this->config;
-       }
-
-       /**
-        * Returns an array with missing categories/Keys
-        *
-        * @param array $config The array to check
-        *
-        * @return array
-        */
-       public function keyDiff(array $config)
-       {
-               $return = [];
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       if (!isset($this->config[$category][$key])) {
-                                               $return[$category][$key] = $config[$category][$key];
-                                       }
-                               }
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/Config/Cache/ConfigFileLoader.php b/src/Core/Config/Cache/ConfigFileLoader.php
deleted file mode 100644 (file)
index 4b1a09c..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config\Cache;
-
-use Exception;
-use Friendica\Core\Addon;
-use Friendica\Core\Config\Cache\Cache;
-
-/**
- * The ConfigFileLoader loads config-files and stores them in a ConfigCache ( @see Cache )
- *
- * It is capable of loading the following config files:
- * - *.config.php   (current)
- * - *.ini.php      (deprecated)
- * - *.htconfig.php (deprecated)
- */
-class ConfigFileLoader
-{
-       /**
-        * The default name of the user defined ini file
-        *
-        * @var string
-        */
-       const CONFIG_INI = 'local';
-
-       /**
-        * The default name of the user defined legacy config file
-        *
-        * @var string
-        */
-       const CONFIG_HTCONFIG = 'htconfig';
-
-       /**
-        * The sample string inside the configs, which shouldn't get loaded
-        *
-        * @var string
-        */
-       const SAMPLE_END = '-sample';
-
-       /**
-        * @var string
-        */
-       private $baseDir;
-       /**
-        * @var string
-        */
-       private $configDir;
-       /**
-        * @var string
-        */
-       private $staticDir;
-
-       /**
-        * @param string $baseDir   The base
-        * @param string $configDir
-        * @param string $staticDir
-        */
-       public function __construct(string $baseDir, string $configDir, string $staticDir)
-       {
-               $this->baseDir   = $baseDir;
-               $this->configDir = $configDir;
-               $this->staticDir = $staticDir;
-       }
-
-       /**
-        * Load the configuration files into an configuration cache
-        *
-        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
-        * expected local.config.php
-        *
-        * @param Cache $config The config cache to load to
-        * @param array $server The $_SERVER array
-        * @param bool  $raw    Setup the raw config format
-        *
-        * @throws Exception
-        */
-       public function setupCache(Cache $config, array $server = [], bool $raw = false)
-       {
-               // Load static config files first, the order is important
-               $config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_FILE);
-               $config->load($this->loadStaticConfig('settings'), Cache::SOURCE_FILE);
-
-               // try to load the legacy config first
-               $config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
-               $config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
-
-               // Now load every other config you find inside the 'config/' directory
-               $this->loadCoreConfig($config);
-
-               $config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
-
-               // In case of install mode, add the found basepath (because there isn't a basepath set yet
-               if (!$raw && empty($config->get('system', 'basepath'))) {
-                       // Setting at least the basepath we know
-                       $config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
-               }
-       }
-
-       /**
-        * Tries to load the static 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
-        */
-       private function loadStaticConfig($name)
-       {
-               $configName = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.config.php';
-               $iniName    = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
-
-               if (file_exists($configName)) {
-                       return $this->loadConfigFile($configName);
-               } elseif (file_exists($iniName)) {
-                       return $this->loadINIConfigFile($iniName);
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load the specified core-configuration into the config cache.
-        *
-        * @param Cache $config The Config cache
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       private function loadCoreConfig(Cache $config)
-       {
-               // try to load legacy ini-files first
-               foreach ($this->getConfigFiles(true) as $configFile) {
-                       $config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
-               }
-
-               // try to load supported config at last to overwrite it
-               foreach ($this->getConfigFiles() as $configFile) {
-                       $config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
-               }
-
-               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/
-                           'config'. DIRECTORY_SEPARATOR .              // config/
-                           $name . ".config.php";                   // openstreetmap.config.php
-
-               if (file_exists($filepath)) {
-                       return $this->loadConfigFile($filepath);
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load environment specific variables, based on the `env.config.php` mapping table
-        *
-        * @param array $server The $_SERVER variable
-        *
-        * @return array The config array (empty if no config was found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       public function loadEnvConfig(array $server)
-       {
-               $filepath = $this->staticDir . DIRECTORY_SEPARATOR .   // /var/www/html/static/
-                                       "env.config.php";                          // env.config.php
-
-               if (!file_exists($filepath)) {
-                       return [];
-               }
-
-               $envConfig = $this->loadConfigFile($filepath);
-
-               $return = [];
-
-               foreach ($envConfig as $envKey => $configStructure) {
-                       if (isset($server[$envKey])) {
-                               $return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
-                       }
-               }
-
-               return $return;
-       }
-
-       /**
-        * Get the config files of the config-directory
-        *
-        * @param bool $ini True, if scan for ini-files instead of config files
-        *
-        * @return array
-        */
-       private function getConfigFiles(bool $ini = false)
-       {
-               $files = scandir($this->configDir);
-               $found = array();
-
-               $filePattern = ($ini ? '*.ini.php' : '*.config.php');
-
-               // Don't load sample files
-               $sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
-
-               foreach ($files as $filename) {
-                       if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
-                               $found[] = $this->configDir . '/' . $filename;
-                       }
-               }
-
-               return $found;
-       }
-
-       /**
-        * 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 (default is empty, which means .htconfig.php)
-        *
-        * @return array The configuration array (empty if no config found)
-        *
-        * @deprecated since version 2018.09
-        */
-       private function loadLegacyConfig($name = '')
-       {
-               $name     = !empty($name) ? $name : self::CONFIG_HTCONFIG;
-               $fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
-
-               $config = [];
-               if (file_exists($fullName)) {
-                       $a         = new \stdClass();
-                       $a->config = [];
-                       include $fullName;
-
-                       $htConfigCategories = array_keys($a->config);
-
-                       // map the legacy configuration structure to the current structure
-                       foreach ($htConfigCategories as $htConfigCategory) {
-                               if (is_array($a->config[$htConfigCategory])) {
-                                       $keys = array_keys($a->config[$htConfigCategory]);
-
-                                       foreach ($keys as $key) {
-                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
-                                       }
-                               } else {
-                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
-                               }
-                       }
-
-                       unset($a);
-
-                       if (isset($db_host)) {
-                               $config['database']['hostname'] = $db_host;
-                               unset($db_host);
-                       }
-                       if (isset($db_user)) {
-                               $config['database']['username'] = $db_user;
-                               unset($db_user);
-                       }
-                       if (isset($db_pass)) {
-                               $config['database']['password'] = $db_pass;
-                               unset($db_pass);
-                       }
-                       if (isset($db_data)) {
-                               $config['database']['database'] = $db_data;
-                               unset($db_data);
-                       }
-                       if (isset($config['system']['db_charset'])) {
-                               $config['database']['charset'] = $config['system']['db_charset'];
-                       }
-                       if (isset($pidfile)) {
-                               $config['system']['pidfile'] = $pidfile;
-                               unset($pidfile);
-                       }
-                       if (isset($default_timezone)) {
-                               $config['system']['default_timezone'] = $default_timezone;
-                               unset($default_timezone);
-                       }
-                       if (isset($lang)) {
-                               $config['system']['language'] = $lang;
-                               unset($lang);
-                       }
-               }
-
-               return $config;
-       }
-
-       /**
-        * Tries to load the specified legacy configuration file and returns the config array.
-        *
-        * @param string $filepath
-        *
-        * @return array The configuration array
-        * @throws Exception
-        * @deprecated since version 2018.12
-        */
-       private function loadINIConfigFile($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)
-       {
-               $config = include($filepath);
-
-               if (!is_array($config)) {
-                       throw new Exception('Error loading config file ' . $filepath);
-               }
-
-               return $config;
-       }
-}
diff --git a/src/Core/Config/Capability/IManageConfigValues.php b/src/Core/Config/Capability/IManageConfigValues.php
new file mode 100644 (file)
index 0000000..09e70ba
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Capability;
+
+use Friendica\Core\Config\Exception\ConfigPersistenceException;
+use Friendica\Core\Config\ValueObject\Cache;
+
+/**
+ * Interface for accessing system-wide configurations
+ */
+interface IManageConfigValues
+{
+       /**
+        * Loads all configuration values of family into a cached storage.
+        *
+        * All configuration values of the system are stored in the cache.
+        *
+        * @param string $cat The category of the configuration value
+        *
+        * @return void
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function load(string $cat = 'config');
+
+       /**
+        * Get a particular user's config variable given the category name
+        * ($cat) and a $key.
+        *
+        * Get a particular config value from the given category ($cat)
+        * and the $key from a cached storage either from the database or from the cache.
+        *
+        * @param string  $cat        The category of the configuration value
+        * @param string  $key           The configuration key to query
+        * @param mixed   $default_value optional, The value to return if key is not set (default: null)
+        * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
+        *
+        * @return mixed Stored value or null if it does not exist
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        *
+        */
+       public function get(string $cat, string $key, $default_value = null, bool $refresh = false);
+
+       /**
+        * Sets a configuration value for system config
+        *
+        * Stores a config value ($value) in the category ($cat) under the key ($key)
+        *
+        * Note: Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key    The configuration key to set
+        * @param mixed  $value  The value to store
+        *
+        * @return bool Operation success
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function set(string $cat, string $key, $value): bool;
+
+       /**
+        * Deletes the given key from the system configuration.
+        *
+        * Removes the configured value from the stored cache in the cache and removes it from the database.
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key    The configuration key to delete
+        *
+        * @return bool
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        *
+        */
+       public function delete(string $cat, string $key): bool;
+
+       /**
+        * Returns the Config Cache
+        *
+        * @return Cache
+        */
+       public function getCache(): Cache;
+}
diff --git a/src/Core/Config/Exception/ConfigFileException.php b/src/Core/Config/Exception/ConfigFileException.php
new file mode 100644 (file)
index 0000000..e8d6cd6
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Config\Exception;
+
+use Throwable;
+
+class ConfigFileException extends \RuntimeException
+{
+       public function __construct($message = "", $code = 0, Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Config/Exception/ConfigPersistenceException.php b/src/Core/Config/Exception/ConfigPersistenceException.php
new file mode 100644 (file)
index 0000000..9b7a385
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Config\Exception;
+
+use Throwable;
+
+class ConfigPersistenceException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Config/Factory/Config.php b/src/Core/Config/Factory/Config.php
new file mode 100644 (file)
index 0000000..a121f94
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Factory;
+
+use Friendica\Core\Config\Capability;
+use Friendica\Core\Config\Repository;
+use Friendica\Core\Config\Type;
+use Friendica\Core\Config\Util;
+use Friendica\Core\Config\ValueObject\Cache;
+
+class Config
+{
+       /**
+        * The key of the $_SERVER variable to override the config directory
+        *
+        * @var string
+        */
+       const CONFIG_DIR_ENV = 'FRIENDICA_CONFIG_DIR';
+
+       /**
+        * The Sub directory of the config-files
+        *
+        * @var string
+        */
+       const CONFIG_DIR = 'config';
+
+       /**
+        * The Sub directory of the static config-files
+        *
+        * @var string
+        */
+       const STATIC_DIR = 'static';
+
+       /**
+        * @param string $basePath The basepath of FRIENDICA
+        * @param array  $server   The $_SERVER array
+        *
+        * @return Util\ConfigFileLoader
+        */
+       public function createConfigFileLoader(string $basePath, array $server = []): Util\ConfigFileLoader
+       {
+               if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
+                       $configDir = $server[self::CONFIG_DIR_ENV];
+               } else {
+                       $configDir = $basePath . DIRECTORY_SEPARATOR . self::CONFIG_DIR;
+               }
+               $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
+
+               return new Util\ConfigFileLoader($basePath, $configDir, $staticDir);
+       }
+
+       /**
+        * @param Util\ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig)
+        * @param array                 $server
+        *
+        * @return Cache
+        */
+       public function createCache(Util\ConfigFileLoader $loader, array $server = []): Cache
+       {
+               $configCache = new Cache();
+               $loader->setupCache($configCache, $server);
+
+               return $configCache;
+       }
+
+       /**
+        * @param Cache $configCache The config cache of this adapter
+        * @param Repository\Config $configRepo  The configuration repository
+        *
+        * @return Capability\IManageConfigValues
+        */
+       public function create(Cache $configCache, Repository\Config $configRepo)
+       {
+               if ($configCache->get('system', 'config_adapter') === 'preload') {
+                       $configuration = new Type\PreloadConfig($configCache, $configRepo);
+               } else {
+                       $configuration = new Type\JitConfig($configCache, $configRepo);
+               }
+
+               return $configuration;
+       }
+}
diff --git a/src/Core/Config/Factory/ConfigFactory.php b/src/Core/Config/Factory/ConfigFactory.php
deleted file mode 100644 (file)
index 9546a02..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config\Factory;
-
-use Exception;
-use Friendica\Core\Config;
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\Model\Config as ConfigModel;
-use Friendica\Core\Config\Cache\ConfigFileLoader;
-
-class ConfigFactory
-{
-       /**
-        * The key of the $_SERVER variable to override the config directory
-        *
-        * @var string
-        */
-       const CONFIG_DIR_ENV = 'FRIENDICA_CONFIG_DIR';
-
-       /**
-        * The Sub directory of the config-files
-        *
-        * @var string
-        */
-       const CONFIG_DIR = 'config';
-
-       /**
-        * The Sub directory of the static config-files
-        *
-        * @var string
-        */
-       const STATIC_DIR = 'static';
-
-       /**
-        * @param string $basePath The basepath of FRIENDICA
-        * @param array $serer the $_SERVER array
-        *
-        * @return \Friendica\Core\Config\Cache\ConfigFileLoader
-        */
-       public function createConfigFileLoader(string $basePath, array $server = [])
-       {
-               if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
-                       $configDir = $server[self::CONFIG_DIR_ENV];
-               } else {
-                       $configDir = $basePath . DIRECTORY_SEPARATOR . self::CONFIG_DIR;
-               }
-               $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
-
-               return new ConfigFileLoader($basePath, $configDir, $staticDir);
-       }
-
-       /**
-        * @param \Friendica\Core\Config\Cache\ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig)
-        *
-        * @return Cache
-        *
-        * @throws Exception
-        */
-       public function createCache(ConfigFileLoader $loader, array $server = [])
-       {
-               $configCache = new Cache();
-               $loader->setupCache($configCache, $server);
-
-               return $configCache;
-       }
-
-       /**
-        * @param \Friendica\Core\Config\Cache\Cache $configCache The config cache of this adapter
-        * @param ConfigModel                        $configModel The configuration model
-        *
-        * @return Config\IConfig
-        */
-       public function create(Cache $configCache, ConfigModel $configModel)
-       {
-               if ($configCache->get('system', 'config_adapter') === 'preload') {
-                       $configuration = new Config\Type\PreloadConfig($configCache, $configModel);
-               } else {
-                       $configuration = new Config\Type\JitConfig($configCache, $configModel);
-               }
-
-
-               return $configuration;
-       }
-}
diff --git a/src/Core/Config/IConfig.php b/src/Core/Config/IConfig.php
deleted file mode 100644 (file)
index 21cee2e..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config;
-
-use Friendica\Core\Config\Cache\Cache;
-
-/**
- * Interface for accessing system wide configurations
- */
-interface IConfig
-{
-
-       /**
-        * Loads all configuration values of family into a cached storage.
-        *
-        * All configuration values of the system are stored in the cache ( @param string $cat The category of the configuration value
-        *
-        * @return void
-        */
-       function load(string $cat = 'config');
-
-       /**
-        * Get a particular user's config variable given the category name
-        * ($cat) and a $key.
-        *
-        * Get a particular config value from the given category ($cat)
-        * and the $key from a cached storage either from the $this->configAdapter
-        * (@see IConfigAdapter) or from the $this->configCache (@see ConfigCache).
-        *
-        * @param string  $cat        The category of the configuration value
-        * @param string  $key           The configuration key to query
-        * @param mixed   $default_value optional, The value to return if key is not set (default: null)
-        * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
-        *
-        * @return mixed Stored value or null if it does not exist
-        */
-       function get(string $cat, string $key, $default_value = null, bool $refresh = false);
-
-       /**
-        * Sets a configuration value for system config
-        *
-        * Stores a config value ($value) in the category ($cat) under the key ($key)
-        *
-        * Note: Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key    The configuration key to set
-        * @param mixed  $value  The value to store
-        *
-        * @return bool Operation success
-        */
-       function set(string $cat, string $key, $value);
-
-       /**
-        * Deletes the given key from the system configuration.
-        *
-        * Removes the configured value from the stored cache in $this->configCache
-        * (@see ConfigCache) and removes it from the database (@see IConfigAdapter).
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key    The configuration key to delete
-        *
-        * @return bool
-        */
-       function delete(string $cat, string $key);
-
-       /**
-        * Returns the Config Cache
-        *
-        * @return Cache
-        */
-       function getCache();
-}
diff --git a/src/Core/Config/Model/Config.php b/src/Core/Config/Model/Config.php
deleted file mode 100644 (file)
index bca2145..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config\Model;
-
-use Friendica\Database\Database;
-
-/**
- * The Config model backend, which is using the general DB-model backend for configs
- */
-class Config
-{
-       /** @var Database */
-       protected $dba;
-
-       /**
-        * @param Database $dba The database connection of this model
-        */
-       public function __construct(Database $dba)
-       {
-               $this->dba = $dba;
-       }
-
-       /**
-        * Checks if the model is currently connected
-        *
-        * @return bool
-        */
-       public function isConnected()
-       {
-               return $this->dba->isConnected();
-       }
-
-       /**
-        * Loads all configuration values and returns the loaded category as an array.
-        *
-        * @param string|null $cat The category of the configuration values to load
-        *
-        * @return array The config array
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function load(string $cat = null)
-       {
-               $return = [];
-
-               if (empty($cat)) {
-                       $configs = $this->dba->select('config', ['cat', 'v', 'k']);
-               } else {
-                       $configs = $this->dba->select('config', ['cat', 'v', 'k'], ['cat' => $cat]);
-               }
-
-               while ($config = $this->dba->fetch($configs)) {
-
-                       $key   = $config['k'];
-                       $value = DbaUtils::toConfigValue($config['v']);
-
-                       // just save it in case it is set
-                       if (isset($value)) {
-                               $return[$config['cat']][$key] = $value;
-                       }
-               }
-               $this->dba->close($configs);
-
-               return $return;
-       }
-
-       /**
-        * Get a particular, system-wide config variable out of the DB with the
-        * given category name ($cat) and a key ($key).
-        *
-        * Note: Boolean variables are defined as 0/1 in the database
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to query
-        *
-        * @return array|string|null Stored value or null if it does not exist
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function get(string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return null;
-               }
-
-               $config = $this->dba->selectFirst('config', ['v'], ['cat' => $cat, 'k' => $key]);
-               if ($this->dba->isResult($config)) {
-                       $value = DbaUtils::toConfigValue($config['v']);
-
-                       // just return it in case it is set
-                       if (isset($value)) {
-                               return $value;
-                       }
-               }
-
-               return null;
-       }
-
-       /**
-        * Stores a config value ($value) in the category ($cat) under the key ($key).
-        *
-        * Note: Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param string $cat   The category of the configuration value
-        * @param string $key   The configuration key to set
-        * @param mixed  $value The value to store
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function set(string $cat, string $key, $value)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               // We store our setting values in a string variable.
-               // So we have to do the conversion here so that the compare below works.
-               // The exception are array values.
-               $compare_value = (!is_array($value) ? (string)$value : $value);
-               $stored_value  = $this->get($cat, $key);
-
-               if (isset($stored_value) && ($stored_value === $compare_value)) {
-                       return true;
-               }
-
-               $dbvalue = DbaUtils::toDbValue($value);
-
-               $result = $this->dba->update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
-
-               return $result;
-       }
-
-       /**
-        * Removes the configured value from the database.
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to delete
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function delete(string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               return $this->dba->delete('config', ['cat' => $cat, 'k' => $key]);
-       }
-}
diff --git a/src/Core/Config/Model/DbaUtils.php b/src/Core/Config/Model/DbaUtils.php
deleted file mode 100644 (file)
index da2b897..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Friendica\Core\Config\Model;
-
-class DbaUtils
-{
-       /**
-        * Formats a DB value to a config value
-        * - null   = The db-value isn't set
-        * - bool   = The db-value is either '0' or '1'
-        * - array  = The db-value is a serialized array
-        * - string = The db-value is a string
-        *
-        * Keep in mind that there aren't any numeric/integer config values in the database
-        *
-        * @param null|string $value
-        *
-        * @return null|array|string
-        */
-       public static function toConfigValue($value)
-       {
-               if (!isset($value)) {
-                       return null;
-               }
-
-               switch (true) {
-                       // manage array value
-                       case preg_match("|^a:[0-9]+:{.*}$|s", $value):
-                               return unserialize($value);
-
-                       default:
-                               return $value;
-               }
-       }
-
-       /**
-        * Formats a config value to a DB value (string)
-        *
-        * @param mixed $value
-        *
-        * @return string
-        */
-       public static function toDbValue($value): string
-       {
-               // if not set, save an empty string
-               if (!isset($value)) {
-                       return '';
-               }
-
-               switch (true) {
-                       // manage arrays
-                       case is_array($value):
-                               return serialize($value);
-
-                       default:
-                               return (string)$value;
-               }
-       }
-}
diff --git a/src/Core/Config/Repository/Config.php b/src/Core/Config/Repository/Config.php
new file mode 100644 (file)
index 0000000..db03a86
--- /dev/null
@@ -0,0 +1,187 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Repository;
+
+use Friendica\Core\Config\Exception\ConfigPersistenceException;
+use Friendica\Core\Config\Util\ValueConversion;
+use Friendica\Database\Database;
+
+/**
+ * The Config Repository, which is using the general DB-model backend for configs
+ */
+class Config
+{
+       /** @var Database */
+       protected $db;
+
+       public function __construct(Database $db)
+       {
+               $this->db = $db;
+       }
+
+       protected static $table_name = 'config';
+
+       /**
+        * Checks if the model is currently connected
+        *
+        * @return bool
+        */
+       public function isConnected(): bool
+       {
+               return $this->db->isConnected();
+       }
+
+       /**
+        * Loads all configuration values and returns the loaded category as an array.
+        *
+        * @param string|null $cat The category of the configuration values to load
+        *
+        * @return array The config array
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function load(?string $cat = null): array
+       {
+               $return = [];
+
+               try {
+                       if (empty($cat)) {
+                               $configs = $this->db->select(static::$table_name, ['cat', 'v', 'k']);
+                       } else {
+                               $configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat]);
+                       }
+
+                       while ($config = $this->db->fetch($configs)) {
+                               $key   = $config['k'];
+                               $value = ValueConversion::toConfigValue($config['v']);
+
+                               // just save it in case it is set
+                               if (isset($value)) {
+                                       $return[$config['cat']][$key] = $value;
+                               }
+                       }
+               } catch (\Exception $exception) {
+                       throw new ConfigPersistenceException(sprintf('Cannot load config category %s', $cat), $exception);
+               } finally {
+                       $this->db->close($configs);
+               }
+
+               return $return;
+       }
+
+       /**
+        * Get a particular, system-wide config variable out of the DB with the
+        * given category name ($cat) and a key ($key).
+        *
+        * Note: Boolean variables are defined as 0/1 in the database
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to query
+        *
+        * @return array|string|null Stored value or null if it does not exist
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function get(string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return null;
+               }
+
+               try {
+                       $config = $this->db->selectFirst(static::$table_name, ['v'], ['cat' => $cat, 'k' => $key]);
+                       if ($this->db->isResult($config)) {
+                               $value = ValueConversion::toConfigValue($config['v']);
+
+                               // just return it in case it is set
+                               if (isset($value)) {
+                                       return $value;
+                               }
+                       }
+               } catch (\Exception $exception) {
+                       throw new ConfigPersistenceException(sprintf('Cannot get config with category %s and key %s', $cat, $key), $exception);
+               }
+
+               return null;
+       }
+
+       /**
+        * Stores a config value ($value) in the category ($cat) under the key ($key).
+        *
+        * Note: Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param string $cat   The category of the configuration value
+        * @param string $key   The configuration key to set
+        * @param mixed  $value The value to store
+        *
+        * @return bool Operation success
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function set(string $cat, string $key, $value): bool
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               // We store our setting values in a string variable.
+               // So we have to do the conversion here so that the compare below works.
+               // The exception are array values.
+               $compare_value = (!is_array($value) ? (string)$value : $value);
+               $stored_value  = $this->get($cat, $key);
+
+               if (isset($stored_value) && ($stored_value === $compare_value)) {
+                       return true;
+               }
+
+               $dbValue = ValueConversion::toDbValue($value);
+
+               try {
+                       return $this->db->update(static::$table_name, ['v' => $dbValue], ['cat' => $cat, 'k' => $key], true);
+               } catch (\Exception $exception) {
+                       throw new ConfigPersistenceException(sprintf('Cannot set config with category %s and key %s', $cat, $key), $exception);
+               }
+       }
+
+       /**
+        * Removes the configured value from the database.
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to delete
+        *
+        * @return bool Operation success
+        *
+        * @throws ConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function delete(string $cat, string $key): bool
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               try {
+                       return $this->db->delete(static::$table_name, ['cat' => $cat, 'k' => $key]);
+               } catch (\Exception $exception) {
+                       throw new ConfigPersistenceException(sprintf('Cannot delete config with category %s and key %s', $cat, $key), $exception);
+               }
+       }
+}
diff --git a/src/Core/Config/Type/AbstractConfig.php b/src/Core/Config/Type/AbstractConfig.php
new file mode 100644 (file)
index 0000000..782f0e7
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Type;
+
+use Friendica\Core\Config\Repository\Config;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+
+/**
+ * This class is responsible for all system-wide configuration values in Friendica
+ * There are two types of storage
+ * - The Config-Files    (loaded into the FileCache @see Cache)
+ * - The Config-Repository (per Config-Repository @see Config )
+ */
+abstract class AbstractConfig implements IManageConfigValues
+{
+       /**
+        * @var Cache
+        */
+       protected $configCache;
+
+       /**
+        * @var Config
+        */
+       protected $configRepo;
+
+       /**
+        * @param Cache  $configCache The configuration cache (based on the config-files)
+        * @param Config $configRepo  The configuration repository
+        */
+       public function __construct(Cache $configCache, Config $configRepo)
+       {
+               $this->configCache = $configCache;
+               $this->configRepo  = $configRepo;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getCache(): Cache
+       {
+               return $this->configCache;
+       }
+}
diff --git a/src/Core/Config/Type/BaseConfig.php b/src/Core/Config/Type/BaseConfig.php
deleted file mode 100644 (file)
index 86a847a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config\Type;
-
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Model;
-
-/**
- * This class is responsible for all system-wide configuration values in Friendica
- * There are two types of storage
- * - The Config-Files    (loaded into the FileCache @see ConfigCache)
- * - The Config-DB-Table (per Config-DB-model @see Model\Config\Config)
- */
-abstract class BaseConfig implements IConfig
-{
-       /**
-        * @var Cache
-        */
-       protected $configCache;
-
-       /**
-        * @var \Friendica\Core\Config\Model\Config
-        */
-       protected $configModel;
-
-       /**
-        * @param Cache                               $configCache The configuration cache (based on the config-files)
-        * @param \Friendica\Core\Config\Model\Config $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, \Friendica\Core\Config\Model\Config $configModel)
-       {
-               $this->configCache = $configCache;
-               $this->configModel = $configModel;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getCache()
-       {
-               return $this->configCache;
-       }
-}
index 5e1fe24c4b5df12e25ecf8cd2515df8fbb54a2a4..b9b897f956b05468251019c99b13d97f846fed0e 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Core\Config\Type;
 
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\Model\Config;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Repository\Config;
 
 /**
  * This class implements the Just-In-Time configuration, which will cache
@@ -31,7 +31,7 @@ use Friendica\Core\Config\Model\Config;
  * Default Configuration type.
  * Provides the best performance for pages loading few configuration variables.
  */
-class JitConfig extends BaseConfig
+class JitConfig extends AbstractConfig
 {
        /**
         * @var array Array of already loaded db values (even if there was no value)
@@ -39,12 +39,12 @@ class JitConfig extends BaseConfig
        private $db_loaded;
 
        /**
-        * @param Cache                               $configCache The configuration cache (based on the config-files)
-        * @param Config $configModel The configuration model
+        * @param Cache  $configCache The configuration cache (based on the config-files)
+        * @param Config $configRepo  The configuration model
         */
-       public function __construct(Cache $configCache, Config $configModel)
+       public function __construct(Cache $configCache, Config $configRepo)
        {
-               parent::__construct($configCache, $configModel);
+               parent::__construct($configCache, $configRepo);
                $this->db_loaded = [];
 
                $this->load();
@@ -52,16 +52,15 @@ class JitConfig extends BaseConfig
 
        /**
         * {@inheritDoc}
-        *
         */
        public function load(string $cat = 'config')
        {
                // If not connected, do nothing
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return;
                }
 
-               $config = $this->configModel->load($cat);
+               $config = $this->configRepo->load($cat);
 
                if (!empty($config[$cat])) {
                        foreach ($config[$cat] as $key => $value) {
@@ -79,15 +78,14 @@ class JitConfig extends BaseConfig
        public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
        {
                // if the value isn't loaded or refresh is needed, load it to the cache
-               if ($this->configModel->isConnected() &&
-                   (empty($this->db_loaded[$cat][$key]) ||
-                    $refresh)) {
-
-                       $dbvalue = $this->configModel->get($cat, $key);
-
-                       if (isset($dbvalue)) {
-                               $this->configCache->set($cat, $key, $dbvalue, Cache::SOURCE_DB);
-                               unset($dbvalue);
+               if ($this->configRepo->isConnected() &&
+                       (empty($this->db_loaded[$cat][$key]) ||
+                        $refresh)) {
+                       $dbValue = $this->configRepo->get($cat, $key);
+
+                       if (isset($dbValue)) {
+                               $this->configCache->set($cat, $key, $dbValue, Cache::SOURCE_DB);
+                               unset($dbValue);
                        }
 
                        $this->db_loaded[$cat][$key] = true;
@@ -102,17 +100,17 @@ class JitConfig extends BaseConfig
        /**
         * {@inheritDoc}
         */
-       public function set(string $cat, string $key, $value)
+       public function set(string $cat, string $key, $value): bool
        {
                // set the cache first
                $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
 
                // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return $cached;
                }
 
-               $stored = $this->configModel->set($cat, $key, $value);
+               $stored = $this->configRepo->set($cat, $key, $value);
 
                $this->db_loaded[$cat][$key] = $stored;
 
@@ -122,7 +120,7 @@ class JitConfig extends BaseConfig
        /**
         * {@inheritDoc}
         */
-       public function delete(string $cat, string $key)
+       public function delete(string $cat, string $key): bool
        {
                $cacheRemoved = $this->configCache->delete($cat, $key);
 
@@ -130,11 +128,11 @@ class JitConfig extends BaseConfig
                        unset($this->db_loaded[$cat][$key]);
                }
 
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return $cacheRemoved;
                }
 
-               $storeRemoved = $this->configModel->delete($cat, $key);
+               $storeRemoved = $this->configRepo->delete($cat, $key);
 
                return $cacheRemoved || $storeRemoved;
        }
index c6abfcd9fc4889cc62ce7ea2e06b2ee430ae8b55..ed1b9a302bff9ba68ece86f55294acfb9b8a8898 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Core\Config\Type;
 
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\Model\Config;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Repository\Config;
 
 /**
  * This class implements the preload configuration, which will cache
@@ -30,18 +30,18 @@ use Friendica\Core\Config\Model\Config;
  *
  * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
  */
-class PreloadConfig extends BaseConfig
+class PreloadConfig extends AbstractConfig
 {
        /** @var bool */
        private $config_loaded;
 
        /**
-        * @param Cache                               $configCache The configuration cache (based on the config-files)
-        * @param Config $configModel The configuration model
+        * @param Cache  $configCache The configuration cache (based on the config-files)
+        * @param Config $configRepo  The configuration model
         */
-       public function __construct(Cache $configCache, Config $configModel)
+       public function __construct(Cache $configCache, Config $configRepo)
        {
-               parent::__construct($configCache, $configModel);
+               parent::__construct($configCache, $configRepo);
                $this->config_loaded = false;
 
                $this->load();
@@ -51,7 +51,6 @@ class PreloadConfig extends BaseConfig
         * {@inheritDoc}
         *
         * This loads all config values everytime load is called
-        *
         */
        public function load(string $cat = 'config')
        {
@@ -61,11 +60,11 @@ class PreloadConfig extends BaseConfig
                }
 
                // If not connected, do nothing
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return;
                }
 
-               $config              = $this->configModel->load();
+               $config              = $this->configRepo->load();
                $this->config_loaded = true;
 
                // load the whole category out of the DB into the cache
@@ -78,8 +77,8 @@ class PreloadConfig extends BaseConfig
        public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
        {
                if ($refresh) {
-                       if ($this->configModel->isConnected()) {
-                               $config = $this->configModel->get($cat, $key);
+                       if ($this->configRepo->isConnected()) {
+                               $config = $this->configRepo->get($cat, $key);
                                if (isset($config)) {
                                        $this->configCache->set($cat, $key, $config, Cache::SOURCE_DB);
                                }
@@ -95,7 +94,7 @@ class PreloadConfig extends BaseConfig
        /**
         * {@inheritDoc}
         */
-       public function set(string $cat, string $key, $value)
+       public function set(string $cat, string $key, $value): bool
        {
                if (!$this->config_loaded) {
                        $this->load();
@@ -105,11 +104,11 @@ class PreloadConfig extends BaseConfig
                $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
 
                // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return $cached;
                }
 
-               $stored = $this->configModel->set($cat, $key, $value);
+               $stored = $this->configRepo->set($cat, $key, $value);
 
                return $cached && $stored;
        }
@@ -117,7 +116,7 @@ class PreloadConfig extends BaseConfig
        /**
         * {@inheritDoc}
         */
-       public function delete(string $cat, string $key)
+       public function delete(string $cat, string $key): bool
        {
                if ($this->config_loaded) {
                        $this->load();
@@ -125,26 +124,12 @@ class PreloadConfig extends BaseConfig
 
                $cacheRemoved = $this->configCache->delete($cat, $key);
 
-               if (!$this->configModel->isConnected()) {
+               if (!$this->configRepo->isConnected()) {
                        return $cacheRemoved;
                }
 
-               $storeRemoved = $this->configModel->delete($cat, $key);
+               $storeRemoved = $this->configRepo->delete($cat, $key);
 
                return $cacheRemoved || $storeRemoved;
        }
-
-       public function testSetDouble()
-       {
-               $this->configModel->shouldReceive('isConnected')
-                                                 ->andReturn(true);
-
-               // constructor loading
-               $this->configModel->shouldReceive('load')
-                                                 ->with('config')
-                                                 ->andReturn(['config' => ['test' => 'it']])
-                                                 ->once();
-
-               parent::testSetDouble();
-       }
 }
diff --git a/src/Core/Config/Util/ConfigFileLoader.php b/src/Core/Config/Util/ConfigFileLoader.php
new file mode 100644 (file)
index 0000000..7740ec3
--- /dev/null
@@ -0,0 +1,364 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Util;
+
+use Friendica\Core\Addon;
+use Friendica\Core\Config\Exception\ConfigFileException;
+use Friendica\Core\Config\ValueObject\Cache;
+
+/**
+ * The ConfigFileLoader loads config-files and stores them in a ConfigCache ( @see Cache )
+ *
+ * It is capable of loading the following config files:
+ * - *.config.php   (current)
+ * - *.ini.php      (deprecated)
+ * - *.htconfig.php (deprecated)
+ */
+class ConfigFileLoader
+{
+       /**
+        * The default name of the user defined ini file
+        *
+        * @var string
+        */
+       const CONFIG_INI = 'local';
+
+       /**
+        * The default name of the user defined legacy config file
+        *
+        * @var string
+        */
+       const CONFIG_HTCONFIG = 'htconfig';
+
+       /**
+        * The sample string inside the configs, which shouldn't get loaded
+        *
+        * @var string
+        */
+       const SAMPLE_END = '-sample';
+
+       /**
+        * @var string
+        */
+       private $baseDir;
+       /**
+        * @var string
+        */
+       private $configDir;
+       /**
+        * @var string
+        */
+       private $staticDir;
+
+       /**
+        * @param string $baseDir   The base
+        * @param string $configDir
+        * @param string $staticDir
+        */
+       public function __construct(string $baseDir, string $configDir, string $staticDir)
+       {
+               $this->baseDir   = $baseDir;
+               $this->configDir = $configDir;
+               $this->staticDir = $staticDir;
+       }
+
+       /**
+        * Load the configuration files into an configuration cache
+        *
+        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
+        * expected local.config.php
+        *
+        * @param Cache $config The config cache to load to
+        * @param array $server The $_SERVER array
+        * @param bool  $raw    Setup the raw config format
+        *
+        * @throws ConfigFileException
+        */
+       public function setupCache(Cache $config, array $server = [], bool $raw = false)
+       {
+               // Load static config files first, the order is important
+               $config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_FILE);
+               $config->load($this->loadStaticConfig('settings'), Cache::SOURCE_FILE);
+
+               // try to load the legacy config first
+               $config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
+               $config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
+
+               // Now load every other config you find inside the 'config/' directory
+               $this->loadCoreConfig($config);
+
+               $config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
+
+               // In case of install mode, add the found basepath (because there isn't a basepath set yet
+               if (!$raw && empty($config->get('system', 'basepath'))) {
+                       // Setting at least the basepath we know
+                       $config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
+               }
+       }
+
+       /**
+        * Tries to load the static 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 ConfigFileException if the configuration file isn't readable
+        */
+       private function loadStaticConfig(string $name): array
+       {
+               $configName = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.config.php';
+               $iniName    = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
+
+               if (file_exists($configName)) {
+                       return $this->loadConfigFile($configName);
+               } elseif (file_exists($iniName)) {
+                       return $this->loadINIConfigFile($iniName);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the specified core-configuration into the config cache.
+        *
+        * @param Cache $config The Config cache
+        *
+        * @throws ConfigFileException if the configuration file isn't readable
+        */
+       private function loadCoreConfig(Cache $config)
+       {
+               // try to load legacy ini-files first
+               foreach ($this->getConfigFiles(true) as $configFile) {
+                       $config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
+               }
+
+               // try to load supported config at last to overwrite it
+               foreach ($this->getConfigFiles() as $configFile) {
+                       $config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
+               }
+       }
+
+       /**
+        * 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 ConfigFileException if the configuration file isn't readable
+        */
+       public function loadAddonConfig(string $name): array
+       {
+               $filepath = $this->baseDir . DIRECTORY_SEPARATOR .   // /var/www/html/
+                                       Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
+                                       $name . DIRECTORY_SEPARATOR .            // openstreetmap/
+                                       'config'. DIRECTORY_SEPARATOR .                  // config/
+                                       $name . ".config.php";                   // openstreetmap.config.php
+
+               if (file_exists($filepath)) {
+                       return $this->loadConfigFile($filepath);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load environment specific variables, based on the `env.config.php` mapping table
+        *
+        * @param array $server The $_SERVER variable
+        *
+        * @return array The config array (empty if no config was found)
+        *
+        * @throws ConfigFileException if the configuration file isn't readable
+        */
+       public function loadEnvConfig(array $server): array
+       {
+               $filepath = $this->staticDir . DIRECTORY_SEPARATOR .   // /var/www/html/static/
+                                       "env.config.php";                          // env.config.php
+
+               if (!file_exists($filepath)) {
+                       return [];
+               }
+
+               $envConfig = $this->loadConfigFile($filepath);
+
+               $return = [];
+
+               foreach ($envConfig as $envKey => $configStructure) {
+                       if (isset($server[$envKey])) {
+                               $return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
+                       }
+               }
+
+               return $return;
+       }
+
+       /**
+        * Get the config files of the config-directory
+        *
+        * @param bool $ini True, if scan for ini-files instead of config files
+        *
+        * @return array
+        */
+       private function getConfigFiles(bool $ini = false): array
+       {
+               $files = scandir($this->configDir);
+               $found = [];
+
+               $filePattern = ($ini ? '*.ini.php' : '*.config.php');
+
+               // Don't load sample files
+               $sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
+
+               foreach ($files as $filename) {
+                       if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
+                               $found[] = $this->configDir . '/' . $filename;
+                       }
+               }
+
+               return $found;
+       }
+
+       /**
+        * 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 (default is empty, which means .htconfig.php)
+        *
+        * @return array The configuration array (empty if no config found)
+        *
+        * @deprecated since version 2018.09
+        */
+       private function loadLegacyConfig(string $name = ''): array
+       {
+               $name     = !empty($name) ? $name : self::CONFIG_HTCONFIG;
+               $fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
+
+               $config = [];
+               if (file_exists($fullName)) {
+                       $a         = new \stdClass();
+                       $a->config = [];
+                       include $fullName;
+
+                       $htConfigCategories = array_keys($a->config);
+
+                       // map the legacy configuration structure to the current structure
+                       foreach ($htConfigCategories as $htConfigCategory) {
+                               if (is_array($a->config[$htConfigCategory])) {
+                                       $keys = array_keys($a->config[$htConfigCategory]);
+
+                                       foreach ($keys as $key) {
+                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
+                                       }
+                               } else {
+                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
+                               }
+                       }
+
+                       unset($a);
+
+                       if (isset($db_host)) {
+                               $config['database']['hostname'] = $db_host;
+                               unset($db_host);
+                       }
+                       if (isset($db_user)) {
+                               $config['database']['username'] = $db_user;
+                               unset($db_user);
+                       }
+                       if (isset($db_pass)) {
+                               $config['database']['password'] = $db_pass;
+                               unset($db_pass);
+                       }
+                       if (isset($db_data)) {
+                               $config['database']['database'] = $db_data;
+                               unset($db_data);
+                       }
+                       if (isset($config['system']['db_charset'])) {
+                               $config['database']['charset'] = $config['system']['db_charset'];
+                       }
+                       if (isset($pidfile)) {
+                               $config['system']['pidfile'] = $pidfile;
+                               unset($pidfile);
+                       }
+                       if (isset($default_timezone)) {
+                               $config['system']['default_timezone'] = $default_timezone;
+                               unset($default_timezone);
+                       }
+                       if (isset($lang)) {
+                               $config['system']['language'] = $lang;
+                               unset($lang);
+                       }
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified legacy configuration file and returns the config array.
+        *
+        * @param string $filepath
+        *
+        * @return array The configuration array
+        * @throws ConfigFileException
+        * @deprecated since version 2018.12
+        */
+       private function loadINIConfigFile(string $filepath): array
+       {
+               $contents = include($filepath);
+
+               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
+
+               if ($config === false) {
+                       throw new ConfigFileException('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 ConfigFileException if the config cannot get loaded.
+        */
+       private function loadConfigFile(string $filepath): array
+       {
+               $config = include($filepath);
+
+               if (!is_array($config)) {
+                       throw new ConfigFileException('Error loading config file ' . $filepath);
+               }
+
+               return $config;
+       }
+}
diff --git a/src/Core/Config/Util/ValueConversion.php b/src/Core/Config/Util/ValueConversion.php
new file mode 100644 (file)
index 0000000..a3cdf7c
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+namespace Friendica\Core\Config\Util;
+
+/**
+ * Util class to help to convert from/to (p)config values
+ */
+class ValueConversion
+{
+       /**
+        * Formats a DB value to a config value
+        * - null   = The db-value isn't set
+        * - bool   = The db-value is either '0' or '1'
+        * - array  = The db-value is a serialized array
+        * - string = The db-value is a string
+        *
+        * Keep in mind that there aren't any numeric/integer config values in the database
+        *
+        * @param string|null $value
+        *
+        * @return null|array|string
+        */
+       public static function toConfigValue(?string $value)
+       {
+               if (!isset($value)) {
+                       return null;
+               }
+
+               switch (true) {
+                       // manage array value
+                       case preg_match("|^a:[0-9]+:{.*}$|s", $value):
+                               return unserialize($value);
+
+                       default:
+                               return $value;
+               }
+       }
+
+       /**
+        * Formats a config value to a DB value (string)
+        *
+        * @param mixed $value
+        *
+        * @return string
+        */
+       public static function toDbValue($value): string
+       {
+               // if not set, save an empty string
+               if (!isset($value)) {
+                       return '';
+               }
+
+               switch (true) {
+                       // manage arrays
+                       case is_array($value):
+                               return serialize($value);
+
+                       default:
+                               return (string)$value;
+               }
+       }
+}
diff --git a/src/Core/Config/ValueObject/Cache.php b/src/Core/Config/ValueObject/Cache.php
new file mode 100644 (file)
index 0000000..e92bcce
--- /dev/null
@@ -0,0 +1,211 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\ValueObject;
+
+use Friendica\Core\Config\Util\ConfigFileLoader;
+use ParagonIE\HiddenString\HiddenString;
+
+/**
+ * The Friendica config cache for the application
+ * Initial, all *.config.php files are loaded into this cache with the
+ * ConfigFileLoader ( @see ConfigFileLoader )
+ */
+class Cache
+{
+       /** @var int Indicates that the cache entry is set by file - Low Priority */
+       const SOURCE_FILE = 0;
+       /** @var int Indicates that the cache entry is set by the DB config table - Middle Priority */
+       const SOURCE_DB = 1;
+       /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */
+       const SOURCE_ENV = 3;
+       /** @var int Indicates that the cache entry is fixed and must not be changed */
+       const SOURCE_FIX = 4;
+
+       /** @var int Default value for a config source */
+       const SOURCE_DEFAULT = self::SOURCE_FILE;
+
+       /**
+        * @var array
+        */
+       private $config = [];
+
+       /**
+        * @var int[][]
+        */
+       private $source = [];
+
+       /**
+        * @var bool
+        */
+       private $hidePasswordOutput;
+
+       /**
+        * @param array $config             A initial config array
+        * @param bool  $hidePasswordOutput True, if cache variables should take extra care of password values
+        * @param int   $source             Sets a source of the initial config values
+        */
+       public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
+       {
+               $this->hidePasswordOutput = $hidePasswordOutput;
+               $this->load($config, $source);
+       }
+
+       /**
+        * Tries to load the specified configuration array into the config array.
+        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+        *
+        * @param array $config
+        * @param int   $source Indicates the source of the config entry
+        */
+       public function load(array $config, int $source = self::SOURCE_DEFAULT)
+       {
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       $value = $config[$category][$key];
+                                       if (isset($value)) {
+                                               $this->set($category, $key, $value, $source);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Gets a value from the config cache.
+        *
+        * @param string      $cat Config category
+        * @param string|null $key Config key
+        *
+        * @return null|mixed Returns the value of the Config entry or null if not set
+        */
+       public function get(string $cat, ?string $key = null)
+       {
+               if (isset($this->config[$cat][$key])) {
+                       return $this->config[$cat][$key];
+               } elseif (!isset($key) && isset($this->config[$cat])) {
+                       return $this->config[$cat];
+               } else {
+                       return 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
+        * @param int    $source The source of the current config key
+        *
+        * @return bool True, if the value is set
+        */
+       public function set(string $cat, string $key, $value, int $source = self::SOURCE_DEFAULT): bool
+       {
+               if (!isset($this->config[$cat])) {
+                       $this->config[$cat] = [];
+                       $this->source[$cat] = [];
+               }
+
+               if (isset($this->source[$cat][$key]) &&
+                       $source < $this->source[$cat][$key]) {
+                       return false;
+               }
+
+               if ($this->hidePasswordOutput &&
+                       $key == 'password' &&
+                       is_string($value)) {
+                       $this->config[$cat][$key] = new HiddenString((string)$value);
+               } else {
+                       $this->config[$cat][$key] = $value;
+               }
+
+               $this->source[$cat][$key] = $source;
+
+               return true;
+       }
+
+       /**
+        * Deletes a value from the config cache.
+        *
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return bool true, if deleted
+        */
+       public function delete(string $cat, string $key): bool
+       {
+               if (isset($this->config[$cat][$key])) {
+                       unset($this->config[$cat][$key]);
+                       unset($this->source[$cat][$key]);
+                       if (count($this->config[$cat]) == 0) {
+                               unset($this->config[$cat]);
+                               unset($this->source[$cat]);
+                       }
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the whole configuration
+        *
+        * @return string[][] The configuration
+        */
+       public function getAll(): array
+       {
+               return $this->config;
+       }
+
+       /**
+        * Returns an array with missing categories/Keys
+        *
+        * @param string[][] $config The array to check
+        *
+        * @return string[][]
+        */
+       public function keyDiff(array $config): array
+       {
+               $return = [];
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       if (!isset($this->config[$category][$key])) {
+                                               $return[$category][$key] = $config[$category][$key];
+                                       }
+                               }
+                       }
+               }
+
+               return $return;
+       }
+}
index fc0da6cbeda750c622dd4fc3876c6ec11b513cd0..96e73b993a28e881012320f5f22df023cfb9c0c8 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Core;
 
 use DOMDocument;
 use Exception;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Database\Database;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
@@ -678,8 +678,8 @@ class Installer
        /**
         * Setup the default cache for a new installation
         *
-        * @param \Friendica\Core\Config\Cache\Cache $configCache The configuration cache
-        * @param string                             $basePath    The determined basepath
+        * @param \Friendica\Core\Config\ValueObject\Cache $configCache The configuration cache
+        * @param string                                   $basePath    The determined basepath
         *
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
index 2a2988341f662e8af6ebc6663ff8cea3251b3995..aca57793ca9711d1208c5e60f5c37231784f4a64 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Core;
 
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Session\Capability\IHandleSessions;
 use Friendica\Database\Database;
 use Friendica\Util\Strings;
 use Psr\Log\LoggerInterface;
@@ -62,7 +62,7 @@ class L10n
         */
        private $logger;
 
-       public function __construct(IConfig $config, Database $dba, LoggerInterface $logger, ISession $session, array $server, array $get)
+       public function __construct(IManageConfigValues $config, Database $dba, LoggerInterface $logger, IHandleSessions $session, array $server, array $get)
        {
                $this->dba    = $dba;
                $this->logger = $logger;
@@ -85,7 +85,7 @@ class L10n
        /**
         * Sets the language session variable
         */
-       private function setSessionVariable(ISession $session)
+       private function setSessionVariable(IHandleSessions $session)
        {
                if ($session->get('authenticated') && !$session->get('language')) {
                        $session->set('language', $this->lang);
@@ -103,7 +103,7 @@ class L10n
                }
        }
 
-       private function setLangFromSession(ISession $session)
+       private function setLangFromSession(IHandleSessions $session)
        {
                if ($session->get('language') !== $this->lang) {
                        $this->loadTranslationTable($session->get('language'));
diff --git a/src/Core/Lock/Capability/ICanLock.php b/src/Core/Lock/Capability/ICanLock.php
new file mode 100644 (file)
index 0000000..1029e2b
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Capability;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Lock\Exception\LockPersistenceException;
+
+/**
+ * Lock Interface
+ */
+interface ICanLock
+{
+       /**
+        * Checks, if a key is currently locked to a or my process
+        *
+        * @param string $key The name of the lock
+        */
+       public function isLocked(string $key): bool;
+
+       /**
+        *
+        * Acquires a lock for a given name
+        *
+        * @param string  $key     The Name of the lock
+        * @param integer $timeout Seconds until we give up
+        * @param integer $ttl     Seconds The lock lifespan, must be one of the Cache constants
+        *
+        * @throws LockPersistenceException In case the underlying persistence throws errors
+        */
+       public function acquire(string $key, int $timeout = 120, int $ttl = Duration::FIVE_MINUTES): bool;
+
+       /**
+        * Releases a lock if it was set by us
+        *
+        * @param string $key      The Name of the lock
+        * @param bool   $override Overrides the lock to get released
+        *
+        * @return bool Was the unlock successful?
+        *
+        * @throws LockPersistenceException In case the underlying persistence throws errors
+        */
+       public function release(string $key, bool $override = false): bool;
+
+       /**
+        * Releases all lock that were set by us
+        *
+        * @param bool $override Override to release all locks
+        *
+        * @return bool Was the unlock of all locks successful?
+        *
+        * @throws LockPersistenceException In case the underlying persistence throws errors
+        */
+       public function releaseAll(bool $override = false): bool;
+
+       /**
+        * Returns the name of the current lock
+        */
+       public function getName(): string;
+
+       /**
+        * Lists all locks
+        *
+        * @param string prefix optional a prefix to search
+        *
+        * @return string[] Empty if it isn't supported by the cache driver
+        *
+        * @throws LockPersistenceException In case the underlying persistence throws errors
+        */
+       public function getLocks(string $prefix = ''): array;
+}
diff --git a/src/Core/Lock/Exception/InvalidLockDriverException.php b/src/Core/Lock/Exception/InvalidLockDriverException.php
new file mode 100644 (file)
index 0000000..38f2399
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Lock\Exception;
+
+use Throwable;
+
+class InvalidLockDriverException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Lock/Exception/LockPersistenceException.php b/src/Core/Lock/Exception/LockPersistenceException.php
new file mode 100644 (file)
index 0000000..37553a8
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\Lock\Exception;
+
+use Throwable;
+
+class LockPersistenceException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/Lock/Factory/Lock.php b/src/Core/Lock/Factory/Lock.php
new file mode 100644 (file)
index 0000000..bb44c44
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Factory;
+
+use Friendica\Core\Cache\Factory\Cache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
+use Friendica\Core\Cache\Enum;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Lock\Capability\ICanLock;
+use Friendica\Core\Lock\Type;
+use Friendica\Database\Database;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class LockFactory
+ *
+ * @package Friendica\Core\Cache
+ *
+ * A basic class to generate a LockDriver
+ */
+class Lock
+{
+       /**
+        * @var string The default driver for caching
+        */
+       const DEFAULT_DRIVER = 'default';
+
+       /**
+        * @var IManageConfigValues The configuration to read parameters out of the config
+        */
+       private $config;
+
+       /**
+        * @var Database The database connection in case that the cache is used the dba connection
+        */
+       private $dba;
+
+       /**
+        * @var Cache The memory cache driver in case we use it
+        */
+       private $cacheFactory;
+
+       /**
+        * @var LoggerInterface The Friendica Logger
+        */
+       private $logger;
+
+       public function __construct(Cache $cacheFactory, IManageConfigValues $config, Database $dba, LoggerInterface $logger)
+       {
+               $this->cacheFactory = $cacheFactory;
+               $this->config       = $config;
+               $this->dba          = $dba;
+               $this->logger       = $logger;
+       }
+
+       public function create()
+       {
+               $lock_type = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER);
+
+               try {
+                       switch ($lock_type) {
+                               case Enum\Type::MEMCACHE:
+                               case Enum\Type::MEMCACHED:
+                               case Enum\Type::REDIS:
+                               case Enum\Type::APCU:
+                                       $cache = $this->cacheFactory->create($lock_type);
+                                       if ($cache instanceof ICanCacheInMemory) {
+                                               return new Type\CacheLock($cache);
+                                       } else {
+                                               throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type));
+                                       }
+                                       break;
+
+                               case 'database':
+                                       return new Type\DatabaseLock($this->dba);
+                                       break;
+
+                               case 'semaphore':
+                                       return new Type\SemaphoreLock();
+                                       break;
+
+                               default:
+                                       return self::useAutoDriver();
+                       }
+               } catch (\Exception $exception) {
+                       $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]);
+                       return self::useAutoDriver();
+               }
+       }
+
+       /**
+        * This method tries to find the best - local - locking method for Friendica
+        *
+        * The following sequence will be tried:
+        * 1. Semaphore Locking
+        * 2. Cache Locking
+        * 3. Database Locking
+        *
+        * @return ICanLock
+        */
+       private function useAutoDriver()
+       {
+               // 1. Try to use Semaphores for - local - locking
+               if (function_exists('sem_get')) {
+                       try {
+                               return new Type\SemaphoreLock();
+                       } catch (\Exception $exception) {
+                               $this->logger->warning('Using Semaphore driver for locking failed.', ['exception' => $exception]);
+                       }
+               }
+
+               // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!)
+               $cache_type = $this->config->get('system', 'cache_driver', 'database');
+               if ($cache_type != Enum\Type::DATABASE) {
+                       try {
+                               $cache = $this->cacheFactory->create($cache_type);
+                               if ($cache instanceof ICanCacheInMemory) {
+                                       return new Type\CacheLock($cache);
+                               }
+                       } catch (\Exception $exception) {
+                               $this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]);
+                       }
+               }
+
+               // 3. Use Database Locking as a Fallback
+               return new Type\DatabaseLock($this->dba);
+       }
+}
diff --git a/src/Core/Lock/Factory/LockFactory.php b/src/Core/Lock/Factory/LockFactory.php
deleted file mode 100644 (file)
index 124ed2f..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock\Factory;
-
-use Friendica\Core\Cache\Factory\CacheFactory;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock;
-use Friendica\Database\Database;
-use Psr\Log\LoggerInterface;
-
-/**
- * Class LockFactory
- *
- * @package Friendica\Core\Cache
- *
- * A basic class to generate a LockDriver
- */
-class LockFactory
-{
-       /**
-        * @var string The default driver for caching
-        */
-       const DEFAULT_DRIVER = 'default';
-
-       /**
-        * @var IConfig The configuration to read parameters out of the config
-        */
-       private $config;
-
-       /**
-        * @var Database The database connection in case that the cache is used the dba connection
-        */
-       private $dba;
-
-       /**
-        * @var CacheFactory The memory cache driver in case we use it
-        */
-       private $cacheFactory;
-
-       /**
-        * @var LoggerInterface The Friendica Logger
-        */
-       private $logger;
-
-       public function __construct(CacheFactory $cacheFactory, IConfig $config, Database $dba, LoggerInterface $logger)
-       {
-               $this->cacheFactory = $cacheFactory;
-               $this->config       = $config;
-               $this->dba          = $dba;
-               $this->logger       = $logger;
-       }
-
-       public function create()
-       {
-               $lock_type = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER);
-
-               try {
-                       switch ($lock_type) {
-                               case Type::MEMCACHE:
-                               case Type::MEMCACHED:
-                               case Type::REDIS:
-                               case Type::APCU:
-                                       $cache = $this->cacheFactory->create($lock_type);
-                                       if ($cache instanceof IMemoryCache) {
-                                               return new Lock\Type\CacheLock($cache);
-                                       } else {
-                                               throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type));
-                                       }
-                                       break;
-
-                               case 'database':
-                                       return new Lock\Type\DatabaseLock($this->dba);
-                                       break;
-
-                               case 'semaphore':
-                                       return new Lock\Type\SemaphoreLock();
-                                       break;
-
-                               default:
-                                       return self::useAutoDriver();
-                       }
-               } catch (\Exception $exception) {
-                       $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]);
-                       return self::useAutoDriver();
-               }
-       }
-
-       /**
-        * This method tries to find the best - local - locking method for Friendica
-        *
-        * The following sequence will be tried:
-        * 1. Semaphore Locking
-        * 2. Cache Locking
-        * 3. Database Locking
-        *
-        * @return Lock\ILock
-        */
-       private function useAutoDriver()
-       {
-               // 1. Try to use Semaphores for - local - locking
-               if (function_exists('sem_get')) {
-                       try {
-                               return new Lock\Type\SemaphoreLock();
-                       } catch (\Exception $exception) {
-                               $this->logger->warning('Using Semaphore driver for locking failed.', ['exception' => $exception]);
-                       }
-               }
-
-               // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!)
-               $cache_type = $this->config->get('system', 'cache_driver', 'database');
-               if ($cache_type != Type::DATABASE) {
-                       try {
-                               $cache = $this->cacheFactory->create($cache_type);
-                               if ($cache instanceof IMemoryCache) {
-                                       return new Lock\Type\CacheLock($cache);
-                               }
-                       } catch (\Exception $exception) {
-                               $this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]);
-                       }
-               }
-
-               // 3. Use Database Locking as a Fallback
-               return new Lock\Type\DatabaseLock($this->dba);
-       }
-}
diff --git a/src/Core/Lock/ILock.php b/src/Core/Lock/ILock.php
deleted file mode 100644 (file)
index 35e2130..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\Cache\Enum\Duration;
-
-/**
- * Lock Interface
- */
-interface ILock
-{
-       /**
-        * Checks, if a key is currently locked to a or my process
-        *
-        * @param string $key The name of the lock
-        *
-        * @return bool
-        */
-       public function isLocked($key);
-
-       /**
-        *
-        * Acquires a lock for a given name
-        *
-        * @param string  $key     The Name of the lock
-        * @param integer $timeout Seconds until we give up
-        * @param integer $ttl     Seconds The lock lifespan, must be one of the Cache constants
-        *
-        * @return boolean Was the lock successful?
-        */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES);
-
-       /**
-        * Releases a lock if it was set by us
-        *
-        * @param string $key      The Name of the lock
-        * @param bool   $override Overrides the lock to get released
-        *
-        * @return boolean Was the unlock successful?
-        */
-       public function release($key, $override = false);
-
-       /**
-        * Releases all lock that were set by us
-        *
-        * @param bool $override Override to release all locks
-        *
-        * @return boolean Was the unlock of all locks successful?
-        */
-       public function releaseAll($override = false);
-
-       /**
-        * Returns the name of the current lock
-        *
-        * @return string
-        */
-       public function getName();
-
-       /**
-        * Lists all locks
-        *
-        * @param string prefix optional a prefix to search
-        *
-        * @return array Empty if it isn't supported by the cache driver
-        */
-       public function getLocks(string $prefix = '');
-}
diff --git a/src/Core/Lock/Type/AbstractLock.php b/src/Core/Lock/Type/AbstractLock.php
new file mode 100644 (file)
index 0000000..fc9c57a
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Type;
+
+use Friendica\Core\Lock\Capability\ICanLock;
+
+/**
+ * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
+ */
+abstract class AbstractLock implements ICanLock
+{
+       /**
+        * @var array The local acquired locks
+        */
+       protected $acquiredLocks = [];
+
+       /**
+        * Check if we've locally acquired a lock
+        *
+        * @param string key The Name of the lock
+        *
+        * @return bool      Returns true if the lock is set
+        */
+       protected function hasAcquiredLock(string $key): bool
+       {
+               return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
+       }
+
+       /**
+        * Mark a locally acquired lock
+        *
+        * @param string $key The Name of the lock
+        */
+       protected function markAcquire(string $key)
+       {
+               $this->acquiredLocks[$key] = true;
+       }
+
+       /**
+        * Mark a release of a locally acquired lock
+        *
+        * @param string $key The Name of the lock
+        */
+       protected function markRelease(string $key)
+       {
+               unset($this->acquiredLocks[$key]);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function releaseAll(bool $override = false): bool
+       {
+               $return = true;
+
+               foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
+                       if (!$this->release($acquiredLock, $override)) {
+                               $return = false;
+                       }
+               }
+
+               return $return;
+       }
+}
diff --git a/src/Core/Lock/Type/BaseLock.php b/src/Core/Lock/Type/BaseLock.php
deleted file mode 100644 (file)
index 518475b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock\Type;
-
-use Friendica\Core\Lock\ILock;
-
-/**
- * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
- */
-abstract class BaseLock implements ILock
-{
-       /**
-        * @var array The local acquired locks
-        */
-       protected $acquiredLocks = [];
-
-       /**
-        * Check if we've locally acquired a lock
-        *
-        * @param string key The Name of the lock
-        *
-        * @return bool      Returns true if the lock is set
-        */
-       protected function hasAcquiredLock($key)
-       {
-               return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
-       }
-
-       /**
-        * Mark a locally acquired lock
-        *
-        * @param string $key The Name of the lock
-        */
-       protected function markAcquire($key)
-       {
-               $this->acquiredLocks[$key] = true;
-       }
-
-       /**
-        * Mark a release of a locally acquired lock
-        *
-        * @param string $key The Name of the lock
-        */
-       protected function markRelease($key)
-       {
-               unset($this->acquiredLocks[$key]);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function releaseAll($override = false)
-       {
-               $return = true;
-
-               foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
-                       if (!$this->release($acquiredLock, $override)) {
-                               $return = false;
-                       }
-               }
-
-               return $return;
-       }
-}
index 8a85f0765377490f06622f06b4d274837ddd035d..d3032c402c60d8514e6d1774269991379420e713 100644 (file)
 
 namespace Friendica\Core\Lock\Type;
 
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
+use Friendica\Core\Lock\Exception\LockPersistenceException;
 
-class CacheLock extends BaseLock
+class CacheLock extends AbstractLock
 {
        /**
         * @var string The static prefix of all locks inside the cache
@@ -32,16 +35,16 @@ class CacheLock extends BaseLock
        const CACHE_PREFIX = 'lock:';
 
        /**
-        * @var \Friendica\Core\Cache\ICache;
+        * @var ICanCache;
         */
        private $cache;
 
        /**
         * CacheLock constructor.
         *
-        * @param IMemoryCache $cache The CacheDriver for this type of lock
+        * @param ICanCacheInMemory $cache The CacheDriver for this type of lock
         */
-       public function __construct(IMemoryCache $cache)
+       public function __construct(ICanCacheInMemory $cache)
        {
                $this->cache = $cache;
        }
@@ -49,35 +52,39 @@ class CacheLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       public function acquire(string $key, int $timeout = 120, int $ttl = Duration::FIVE_MINUTES): bool
        {
                $got_lock = false;
                $start    = time();
 
-               $cachekey = self::getLockKey($key);
+               $lockKey = self::getLockKey($key);
 
-               do {
-                       $lock = $this->cache->get($cachekey);
-                       // When we do want to lock something that was already locked by us.
-                       if ((int)$lock == getmypid()) {
-                               $got_lock = true;
-                       }
-
-                       // When we do want to lock something new
-                       if (is_null($lock)) {
-                               // At first initialize it with "0"
-                               $this->cache->add($cachekey, 0);
-                               // Now the value has to be "0" because otherwise the key was used by another process meanwhile
-                               if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) {
+               try {
+                       do {
+                               $lock = $this->cache->get($lockKey);
+                               // When we do want to lock something that was already locked by us.
+                               if ((int)$lock == getmypid()) {
                                        $got_lock = true;
-                                       $this->markAcquire($key);
                                }
-                       }
 
-                       if (!$got_lock && ($timeout > 0)) {
-                               usleep(rand(10000, 200000));
-                       }
-               } while (!$got_lock && ((time() - $start) < $timeout));
+                               // When we do want to lock something new
+                               if (is_null($lock)) {
+                                       // At first initialize it with "0"
+                                       $this->cache->add($lockKey, 0);
+                                       // Now the value has to be "0" because otherwise the key was used by another process meanwhile
+                                       if ($this->cache->compareSet($lockKey, 0, getmypid(), $ttl)) {
+                                               $got_lock = true;
+                                               $this->markAcquire($key);
+                                       }
+                               }
+
+                               if (!$got_lock && ($timeout > 0)) {
+                                       usleep(rand(10000, 200000));
+                               }
+                       } while (!$got_lock && ((time() - $start) < $timeout));
+               } catch (CachePersistenceException $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot acquire lock for key %s', $key), $exception);
+               }
 
                return $got_lock;
        }
@@ -85,14 +92,18 @@ class CacheLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function release($key, $override = false)
+       public function release(string $key, bool $override = false): bool
        {
-               $cachekey = self::getLockKey($key);
+               $lockKey = self::getLockKey($key);
 
-               if ($override) {
-                       $return = $this->cache->delete($cachekey);
-               } else {
-                       $return = $this->cache->compareDelete($cachekey, getmypid());
+               try {
+                       if ($override) {
+                               $return = $this->cache->delete($lockKey);
+                       } else {
+                               $return = $this->cache->compareDelete($lockKey, getmypid());
+                       }
+               } catch (CachePersistenceException $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot release lock for key %s (override %b)', $key, $override), $exception);
                }
                $this->markRelease($key);
 
@@ -102,17 +113,21 @@ class CacheLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function isLocked($key)
+       public function isLocked(string $key): bool
        {
-               $cachekey = self::getLockKey($key);
-               $lock     = $this->cache->get($cachekey);
+               $lockKey = self::getLockKey($key);
+               try {
+                       $lock = $this->cache->get($lockKey);
+               } catch (CachePersistenceException $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot check lock state for key %s', $key), $exception);
+               }
                return isset($lock) && ($lock !== false);
        }
 
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return $this->cache->getName();
        }
@@ -120,11 +135,15 @@ class CacheLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function getLocks(string $prefix = '')
+       public function getLocks(string $prefix = ''): array
        {
-               $locks = $this->cache->getAllKeys(self::CACHE_PREFIX . $prefix);
+               try {
+                       $locks = $this->cache->getAllKeys(self::CACHE_PREFIX . $prefix);
+               } catch (CachePersistenceException $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot get locks with prefix %s', $prefix), $exception);
+               }
 
-               array_walk($locks, function (&$lock, $key) {
+               array_walk($locks, function (&$lock) {
                        $lock = substr($lock, strlen(self::CACHE_PREFIX));
                });
 
@@ -134,7 +153,7 @@ class CacheLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function releaseAll($override = false)
+       public function releaseAll(bool $override = false): bool
        {
                $success = parent::releaseAll($override);
 
@@ -154,7 +173,7 @@ class CacheLock extends BaseLock
         *
         * @return string        The cache key used for the cache
         */
-       private static function getLockKey($key)
+       private static function getLockKey(string $key): string
        {
                return self::CACHE_PREFIX . $key;
        }
index de44e2e2b9286d2368d2e6cbeeaa41a3ae1ee632..9c2dd2d4d35efca28137df2cc924d4ba8f1f50c9 100644 (file)
@@ -23,13 +23,14 @@ namespace Friendica\Core\Lock\Type;
 
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Lock\Enum\Type;
+use Friendica\Core\Lock\Exception\LockPersistenceException;
 use Friendica\Database\Database;
 use Friendica\Util\DateTimeFormat;
 
 /**
  * Locking driver that stores the locks in the database
  */
-class DatabaseLock extends BaseLock
+class DatabaseLock extends AbstractLock
 {
        /**
         * The current ID of the process
@@ -44,49 +45,63 @@ class DatabaseLock extends BaseLock
        private $dba;
 
        /**
-        * @param null|int $pid The Id of the current process (null means determine automatically)
+        * @param int|null $pid The id of the current process (null means determine automatically)
         */
-       public function __construct(Database $dba, $pid = null)
+       public function __construct(Database $dba, ?int $pid = null)
        {
                $this->dba = $dba;
-               $this->pid = isset($pid) ? $pid : getmypid();
+               $this->pid = $pid ?? getmypid();
        }
 
        /**
         * (@inheritdoc)
         */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       public function acquire(string $key, int $timeout = 120, int $ttl = Duration::FIVE_MINUTES): bool
        {
                $got_lock = false;
                $start    = time();
 
-               do {
-                       $this->dba->lock('locks');
-                       $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
-
-                       if ($this->dba->isResult($lock)) {
-                               if ($lock['locked']) {
-                                       // We want to lock something that was already locked by us? So we got the lock.
-                                       if ($lock['pid'] == $this->pid) {
+               try {
+                       do {
+                               $this->dba->lock('locks');
+                               $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], [
+                                       '`name` = ? AND `expires` >= ?', $key,DateTimeFormat::utcNow()
+                               ]);
+
+                               if ($this->dba->isResult($lock)) {
+                                       if ($lock['locked']) {
+                                               // We want to lock something that was already locked by us? So we got the lock.
+                                               if ($lock['pid'] == $this->pid) {
+                                                       $got_lock = true;
+                                               }
+                                       }
+                                       if (!$lock['locked']) {
+                                               $this->dba->update('locks', [
+                                                       'locked'  => true,
+                                                       'pid'     => $this->pid,
+                                                       'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')
+                                               ], ['name' => $key]);
                                                $got_lock = true;
                                        }
-                               }
-                               if (!$lock['locked']) {
-                                       $this->dba->update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
+                               } else {
+                                       $this->dba->insert('locks', [
+                                               'name'    => $key,
+                                               'locked'  => true,
+                                               'pid'     => $this->pid,
+                                               'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
                                        $got_lock = true;
+                                       $this->markAcquire($key);
                                }
-                       } else {
-                               $this->dba->insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
-                               $got_lock = true;
-                               $this->markAcquire($key);
-                       }
 
-                       $this->dba->unlock();
+                               $this->dba->unlock();
 
-                       if (!$got_lock && ($timeout > 0)) {
-                               usleep(rand(100000, 2000000));
-                       }
-               } while (!$got_lock && ((time() - $start) < $timeout));
+                               if (!$got_lock && ($timeout > 0)) {
+                                       usleep(rand(100000, 2000000));
+                               }
+                       } while (!$got_lock && ((time() - $start) < $timeout));
+               } catch (\Exception $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot acquire lock for key %s', $key), $exception);
+               }
 
                return $got_lock;
        }
@@ -94,7 +109,7 @@ class DatabaseLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function release($key, $override = false)
+       public function release(string $key, bool $override = false): bool
        {
                if ($override) {
                        $where = ['name' => $key];
@@ -102,10 +117,14 @@ class DatabaseLock extends BaseLock
                        $where = ['name' => $key, 'pid' => $this->pid];
                }
 
-               if ($this->dba->exists('locks', $where)) {
-                       $return = $this->dba->delete('locks', $where);
-               } else {
-                       $return = false;
+               try {
+                       if ($this->dba->exists('locks', $where)) {
+                               $return = $this->dba->delete('locks', $where);
+                       } else {
+                               $return = false;
+                       }
+               } catch (\Exception $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot release lock for key %s (override %b)', $key, $override), $exception);
                }
 
                $this->markRelease($key);
@@ -116,7 +135,7 @@ class DatabaseLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function releaseAll($override = false)
+       public function releaseAll(bool $override = false): bool
        {
                $success = parent::releaseAll($override);
 
@@ -125,7 +144,12 @@ class DatabaseLock extends BaseLock
                } else {
                        $where = ['pid' => $this->pid];
                }
-               $return = $this->dba->delete('locks', $where);
+
+               try {
+                       $return = $this->dba->delete('locks', $where);
+               } catch (\Exception $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot release all lock (override %b)', $override), $exception);
+               }
 
                $this->acquiredLocks = [];
 
@@ -135,9 +159,14 @@ class DatabaseLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function isLocked($key)
+       public function isLocked(string $key): bool
        {
-               $lock = $this->dba->selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+               try {
+                       $lock = $this->dba->selectFirst('locks', ['locked'], [
+                               '`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+               } catch (\Exception $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot check lock state for key %s', $key), $exception);
+               }
 
                if ($this->dba->isResult($lock)) {
                        return $lock['locked'] !== false;
@@ -149,7 +178,7 @@ class DatabaseLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::DATABASE;
        }
@@ -157,21 +186,26 @@ class DatabaseLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function getLocks(string $prefix = '')
+       public function getLocks(string $prefix = ''): array
        {
-               if (empty($prefix)) {
-                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
-               } else {
-                       $where = ['`expires` >= ? AND `name` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
-               }
+               try {
+                       if (empty($prefix)) {
+                               $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+                       } else {
+                               $where = ['`expires` >= ? AND `name` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+                       }
 
-               $stmt = $this->dba->select('locks', ['name'], $where);
+                       $stmt = $this->dba->select('locks', ['name'], $where);
 
-               $keys = [];
-               while ($key = $this->dba->fetch($stmt)) {
-                       array_push($keys, $key['name']);
+                       $keys = [];
+                       while ($key = $this->dba->fetch($stmt)) {
+                               array_push($keys, $key['name']);
+                       }
+               } catch (\Exception $exception) {
+                       throw new LockPersistenceException(sprintf('Cannot get lock with prefix %s', $prefix), $exception);
+               } finally {
+                       $this->dba->close($stmt);
                }
-               $this->dba->close($stmt);
 
                return $keys;
        }
index 4393e451535a99dca49cff6003cfb064c43d31a2..f68b5546cd2e94c4935081b4e79935000e86a7da 100644 (file)
@@ -23,16 +23,17 @@ namespace Friendica\Core\Lock\Type;
 
 use Friendica\Core\Cache\Enum\Duration;
 use Friendica\Core\Lock\Enum\Type;
+use Friendica\Core\Lock\Exception\InvalidLockDriverException;
 use function get_temppath;
 
-class SemaphoreLock extends BaseLock
+class SemaphoreLock extends AbstractLock
 {
        private static $semaphore = [];
 
        public function __construct()
        {
                if (!function_exists('sem_get')) {
-                       throw new \Exception('Semaphore lock not supported');
+                       throw new InvalidLockDriverException('Semaphore lock not supported');
                }
        }
 
@@ -57,11 +58,11 @@ class SemaphoreLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       public function acquire(string $key, int $timeout = 120, int $ttl = Duration::FIVE_MINUTES): bool
        {
                self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
                if (!empty(self::$semaphore[$key])) {
-                       if ((bool)sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
+                       if (sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
                                $this->markAcquire($key);
                                return true;
                        }
@@ -76,7 +77,7 @@ class SemaphoreLock extends BaseLock
         * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
         *                       of the using function
         */
-       public function release($key, $override = false)
+       public function release(string $key, bool $override = false): bool
        {
                $success = false;
 
@@ -96,7 +97,7 @@ class SemaphoreLock extends BaseLock
        /**
         * (@inheritdoc)
         */
-       public function isLocked($key)
+       public function isLocked(string $key): bool
        {
                return isset(self::$semaphore[$key]);
        }
@@ -104,7 +105,7 @@ class SemaphoreLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function getName()
+       public function getName(): string
        {
                return Type::SEMAPHORE;
        }
@@ -112,7 +113,7 @@ class SemaphoreLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function getLocks(string $prefix = '')
+       public function getLocks(string $prefix = ''): array
        {
                // We can just return our own semaphore keys, since we don't know
                // the state of other semaphores, even if the .sem files exists
@@ -136,7 +137,7 @@ class SemaphoreLock extends BaseLock
        /**
         * {@inheritDoc}
         */
-       public function releaseAll($override = false)
+       public function releaseAll(bool $override = false): bool
        {
                // Semaphores are just alive during a run, so there is no need to release
                // You can just release your own locks
diff --git a/src/Core/PConfig/Cache/Cache.php b/src/Core/PConfig/Cache/Cache.php
deleted file mode 100644 (file)
index 97554b2..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig\Cache;
-
-use ParagonIE\HiddenString\HiddenString;
-
-/**
- * The Friendica config cache for users
- */
-class Cache
-{
-       /**
-        * @var array
-        */
-       private $config;
-
-       /**
-        * @var bool
-        */
-       private $hidePasswordOutput;
-
-       /**
-        * @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
-        */
-       public function __construct(bool $hidePasswordOutput = true)
-       {
-               $this->hidePasswordOutput = $hidePasswordOutput;
-       }
-
-       /**
-        * Tries to load the specified configuration array into the user specific config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * @param int   $uid
-        * @param array $config
-        */
-       public function load($uid, array $config)
-       {
-               if (!is_int($uid)) {
-                       return;
-               }
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (isset($config[$category]) && is_array($config[$category])) {
-
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       $value = $config[$category][$key];
-                                       if (isset($value)) {
-                                               $this->set($uid, $category, $key, $value);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Retrieves a value from the user config cache
-        *
-        * @param int    $uid User Id
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return null|string The value of the config entry or null if not set
-        */
-       public function get($uid, string $cat, string $key = null)
-       {
-               if (!is_int($uid)) {
-                       return null;
-               }
-
-               if (isset($this->config[$uid][$cat][$key])) {
-                       return $this->config[$uid][$cat][$key];
-               } elseif (!isset($key) && isset($this->config[$uid][$cat])) {
-                       return $this->config[$uid][$cat];
-               } else {
-                       return 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
-        *
-        * @return bool Set successful
-        */
-       public function set($uid, string $cat, string $key, $value)
-       {
-               if (!is_int($uid)) {
-                       return false;
-               }
-
-               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
-                       $this->config[$uid] = [];
-               }
-
-               if (!isset($this->config[$uid][$cat])) {
-                       $this->config[$uid][$cat] = [];
-               }
-
-               if ($this->hidePasswordOutput &&
-                   $key == 'password' &&
-                   !empty($value) && is_string($value)) {
-                       $this->config[$uid][$cat][$key] = new HiddenString((string)$value);
-               } else {
-                       $this->config[$uid][$cat][$key] = $value;
-               }
-
-
-               return true;
-       }
-
-       /**
-        * Deletes a value from the user config cache
-        *
-        * @param int    $uid User Id
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return bool true, if deleted
-        */
-       public function delete($uid, string $cat, string $key)
-       {
-               if (!is_int($uid)) {
-                       return false;
-               }
-
-               if (isset($this->config[$uid][$cat][$key])) {
-                       unset($this->config[$uid][$cat][$key]);
-                       if (count($this->config[$uid][$cat]) == 0) {
-                               unset($this->config[$uid][$cat]);
-                               if (count($this->config[$uid]) == 0) {
-                                       unset($this->config[$uid]);
-                               }
-                       }
-
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Returns the whole configuration
-        *
-        * @return array The configuration
-        */
-       public function getAll()
-       {
-               return $this->config;
-       }
-
-       /**
-        * Returns an array with missing categories/Keys
-        *
-        * @param array $config The array to check
-        *
-        * @return array
-        */
-       public function keyDiff(array $config)
-       {
-               $return = [];
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       if (!isset($this->config[$category][$key])) {
-                                               $return[$category][$key] = $config[$category][$key];
-                                       }
-                               }
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/PConfig/Capability/IManagePersonalConfigValues.php b/src/Core/PConfig/Capability/IManagePersonalConfigValues.php
new file mode 100644 (file)
index 0000000..3af3576
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Capability;
+
+use Friendica\Core\PConfig\ValueObject;
+
+/**
+ * Interface for accessing user specific configurations
+ */
+interface IManagePersonalConfigValues
+{
+       /**
+        * Loads all configuration values of a user's config family into a cached storage.
+        *
+        * All configuration values of the given user are stored with the $uid in the cache
+        *
+        * @param int    $uid The user_id
+        * @param string $cat The category of the configuration value
+        *
+        * @return array The loaded config array
+        */
+       public function load(int $uid, string $cat = 'config'): array;
+
+       /**
+        * Get a particular user's config variable given the category name
+        * ($cat) and a key.
+        *
+        * Get a particular user's config value from the given category ($cat)
+        * and the $key with the $uid from a cached storage either from the database
+        * or from the configCache
+        *
+        * @param int     $uid           The user_id
+        * @param string  $cat           The category of the configuration value
+        * @param string  $key           The configuration key to query
+        * @param mixed   $default_value optional, The value to return if key is not set (default: null)
+        * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
+        *
+        * @return mixed Stored value or null if it does not exist
+        *
+        */
+       public function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false);
+
+       /**
+        * Sets a configuration value for a user
+        *
+        * Stores a config value ($value) in the category ($family) under the key ($key)
+        * for the user_id $uid.
+        *
+        * @note  Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param int    $uid   The user_id
+        * @param string $cat   The category of the configuration value
+        * @param string $key   The configuration key to set
+        * @param mixed  $value The value to store
+        *
+        * @return bool Operation success
+        */
+       public function set(int $uid, string $cat, string $key, $value): bool;
+
+       /**
+        * Deletes the given key from the users configuration.
+        *
+        * Removes the configured value from the stored cache and removes it from the database with the given $uid.
+        *
+        * @param int    $uid The user_id
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to delete
+        *
+        * @return bool
+        */
+       public function delete(int $uid, string $cat, string $key): bool;
+
+
+       /**
+        * Returns the Config Cache
+        *
+        * @return ValueObject\Cache
+        */
+       public function getCache(): ValueObject\Cache;
+}
diff --git a/src/Core/PConfig/Exception/PConfigPersistenceException.php b/src/Core/PConfig/Exception/PConfigPersistenceException.php
new file mode 100644 (file)
index 0000000..4da14c8
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Core\PConfig\Exception;
+
+use Throwable;
+
+class PConfigPersistenceException extends \RuntimeException
+{
+       public function __construct($message = "", Throwable $previous = null)
+       {
+               parent::__construct($message, 500, $previous);
+       }
+}
diff --git a/src/Core/PConfig/Factory/PConfig.php b/src/Core/PConfig/Factory/PConfig.php
new file mode 100644 (file)
index 0000000..c1793e0
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Factory;
+
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
+use Friendica\Core\PConfig\Repository;
+use Friendica\Core\PConfig\Type;
+use Friendica\Core\PConfig\ValueObject;
+
+class PConfig
+{
+       /**
+        * @param Cache              $configCache  The config cache
+        * @param ValueObject\Cache  $pConfigCache The personal config cache
+        * @param Repository\PConfig $configRepo   The configuration model
+        *
+        * @return IManagePersonalConfigValues
+        */
+       public function create(Cache $configCache, ValueObject\Cache $pConfigCache, Repository\PConfig $configRepo): IManagePersonalConfigValues
+       {
+               if ($configCache->get('system', 'config_adapter') === 'preload') {
+                       $configuration = new Type\PreloadPConfig($pConfigCache, $configRepo);
+               } else {
+                       $configuration = new Type\JitPConfig($pConfigCache, $configRepo);
+               }
+
+               return $configuration;
+       }
+}
diff --git a/src/Core/PConfig/Factory/PConfigFactory.php b/src/Core/PConfig/Factory/PConfigFactory.php
deleted file mode 100644 (file)
index eb248f1..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig\Factory;
-
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\PConfig\IPConfig;
-use Friendica\Core\PConfig\Model\PConfig as PConfigModel;
-use Friendica\Core\PConfig\Type;
-
-class PConfigFactory
-{
-       /**
-        * @param Cache                               $configCache  The config cache
-        * @param \Friendica\Core\PConfig\Cache\Cache $pConfigCache The personal config cache
-        * @param PConfigModel                        $configModel  The configuration model
-        *
-        * @return IPConfig
-        */
-       public function create(Cache $configCache, \Friendica\Core\PConfig\Cache\Cache $pConfigCache, PConfigModel $configModel)
-       {
-               if ($configCache->get('system', 'config_adapter') === 'preload') {
-                       $configuration = new Type\PreloadPConfig($pConfigCache, $configModel);
-               } else {
-                       $configuration = new Type\JitPConfig($pConfigCache, $configModel);
-               }
-
-               return $configuration;
-       }
-}
diff --git a/src/Core/PConfig/IPConfig.php b/src/Core/PConfig/IPConfig.php
deleted file mode 100644 (file)
index 1795a60..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig;
-
-use Friendica\Core\Config\Cache\Cache;
-
-/**
- * Interface for accessing user specific configurations
- */
-interface IPConfig
-{
-
-       /**
-        * Loads all configuration values of a user's config family into a cached storage.
-        *
-        * All configuration values of the given user are stored with the $uid in the cache
-        *
-        * @param int $uid The user_id
-        * @param string $cat The category of the configuration value
-        *
-        * @return array The loaded config array
-        * @see Cache
-        *
-        */
-       function load(int $uid, string $cat = 'config');
-
-       /**
-        * Get a particular user's config variable given the category name
-        * ($cat) and a key.
-        *
-        * Get a particular user's config value from the given category ($cat)
-        * and the $key with the $uid from a cached storage either from the $this->configAdapter
-        * (@see IConfigAdapter) or from the $this->configCache (@see PConfigCache).
-        *
-        * @param int     $uid           The user_id
-        * @param string  $cat           The category of the configuration value
-        * @param string  $key           The configuration key to query
-        * @param mixed   $default_value optional, The value to return if key is not set (default: null)
-        * @param boolean $refresh       optional, If true the config is loaded from the db and not from the cache (default: false)
-        *
-        * @return mixed Stored value or null if it does not exist
-        */
-       function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false);
-
-       /**
-        * Sets a configuration value for a user
-        *
-        * Stores a config value ($value) in the category ($family) under the key ($key)
-        * for the user_id $uid.
-        *
-        * @note  Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param int    $uid   The user_id
-        * @param string $cat   The category of the configuration value
-        * @param string $key   The configuration key to set
-        * @param mixed  $value The value to store
-        *
-        * @return bool Operation success
-        */
-       function set(int $uid, string $cat, string $key, $value);
-
-       /**
-        * Deletes the given key from the users's configuration.
-        *
-        * Removes the configured value from the stored cache in $this->configCache
-        * (@see ConfigCache) and removes it from the database (@see IConfigAdapter)
-        *  with the given $uid.
-        *
-        * @param int $uid The user_id
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to delete
-        *
-        * @return bool
-        */
-       function delete(int $uid, string $cat, string $key);
-
-
-       /**
-        * Returns the Config Cache
-        *
-        * @return \Friendica\Core\PConfig\Cache\Cache
-        */
-       function getCache();
-}
diff --git a/src/Core/PConfig/Model/PConfig.php b/src/Core/PConfig/Model/PConfig.php
deleted file mode 100644 (file)
index 35ff34a..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig\Model;
-
-use Friendica\Core\Config\Model\DbaUtils;
-use Friendica\Database\Database;
-
-/**
- * The Config model backend for users, which is using the general DB-model backend for user-configs
- */
-class PConfig
-{
-       /** @var Database */
-       protected $dba;
-
-       /**
-        * @param Database $dba The database connection of this model
-        */
-       public function __construct(Database $dba)
-       {
-               $this->dba = $dba;
-       }
-
-       /**
-        * Checks if the model is currently connected
-        *
-        * @return bool
-        */
-       public function isConnected()
-       {
-               return $this->dba->isConnected();
-       }
-
-       /**
-        * Loads all configuration values and returns the loaded category as an array.
-        *
-        * @param int         $uid The id of the user to load
-        * @param string|null $cat The category of the configuration values to load
-        *
-        * @return array The config array
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function load(int $uid, string $cat = null)
-       {
-               $return = [];
-
-               if (empty($cat)) {
-                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
-               } else {
-                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
-               }
-
-               while ($config = $this->dba->fetch($configs)) {
-                       $key   = $config['k'];
-                       $value = DbaUtils::toConfigValue($config['v']);
-
-                       // just save it in case it is set
-                       if (isset($value)) {
-                               $return[$config['cat']][$key] = $value;
-                       }
-               }
-               $this->dba->close($configs);
-
-               return $return;
-       }
-
-       /**
-        * Get a particular user config variable out of the DB with the
-        * given category name ($cat) and a key ($key).
-        *
-        * Note: Boolean variables are defined as 0/1 in the database
-        *
-        * @param int         $uid The id of the user to load
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to query
-        *
-        * @return array|string|null Stored value or null if it does not exist
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function get(int $uid, string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return null;
-               }
-
-               $config = $this->dba->selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-               if ($this->dba->isResult($config)) {
-                       $value = DbaUtils::toConfigValue($config['v']);
-
-                       // just return it in case it is set
-                       if (isset($value)) {
-                               return $value;
-                       }
-               }
-
-               return null;
-       }
-
-       /**
-        * Stores a config value ($value) in the category ($cat) under the key ($key) for a
-        * given user ($uid).
-        *
-        * Note: Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param int    $uid   The id of the user to load
-        * @param string $cat   The category of the configuration value
-        * @param string $key   The configuration key to set
-        * @param mixed  $value The value to store
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function set(int $uid, string $cat, string $key, $value)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               // We store our setting values in a string variable.
-               // So we have to do the conversion here so that the compare below works.
-               // The exception are array values.
-               $compare_value = (!is_array($value) ? (string)$value : $value);
-               $stored_value  = $this->get($uid, $cat, $key);
-
-               if (isset($stored_value) && ($stored_value === $compare_value)) {
-                       return true;
-               }
-
-               $dbvalue = DbaUtils::toDbValue($value);
-
-               $result = $this->dba->update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
-
-               return $result;
-       }
-
-       /**
-        * Removes the configured value of the given user.
-        *
-        * @param int    $uid The id of the user to load
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to delete
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function delete(int $uid, string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               return $this->dba->delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-       }
-}
diff --git a/src/Core/PConfig/Repository/PConfig.php b/src/Core/PConfig/Repository/PConfig.php
new file mode 100644 (file)
index 0000000..d7f1ca3
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Repository;
+
+use Friendica\Core\Config\Util\ValueConversion;
+use Friendica\Core\PConfig\Exception\PConfigPersistenceException;
+use Friendica\Database\Database;
+
+/**
+ * The Config model backend for users, which is using the general DB-model backend for user-configs
+ */
+class PConfig
+{
+       protected static $table_name = 'pconfig';
+
+       /** @var Database */
+       protected $db;
+
+       public function __construct(Database $db)
+       {
+               $this->db = $db;
+       }
+
+       /**
+        * Checks if the model is currently connected
+        *
+        * @return bool
+        */
+       public function isConnected(): bool
+       {
+               return $this->db->isConnected();
+       }
+
+       /**
+        * Loads all configuration values and returns the loaded category as an array.
+        *
+        * @param int         $uid The id of the user to load
+        * @param string|null $cat The category of the configuration values to load
+        *
+        * @return string[][] The config array
+        *
+        * @throws PConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function load(int $uid, ?string $cat = null): array
+       {
+               $return = [];
+
+               try {
+                       if (empty($cat)) {
+                               $configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['uid' => $uid]);
+                       } else {
+                               $configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
+                       }
+
+                       while ($config = $this->db->fetch($configs)) {
+                               $key   = $config['k'];
+                               $value = ValueConversion::toConfigValue($config['v']);
+
+                               // just save it in case it is set
+                               if (isset($value)) {
+                                       $return[$config['cat']][$key] = $value;
+                               }
+                       }
+               } catch (\Exception $exception) {
+                       throw new PConfigPersistenceException(sprintf('Cannot load config category %s for user %d', $cat, $uid), $exception);
+               } finally {
+                       $this->db->close($configs);
+               }
+
+               return $return;
+       }
+
+       /**
+        * Get a particular user config variable out of the DB with the
+        * given category name ($cat) and a key ($key).
+        *
+        * Note: Boolean variables are defined as 0/1 in the database
+        *
+        * @param int         $uid The id of the user to load
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to query
+        *
+        * @return array|string|null Stored value or null if it does not exist
+        *
+        * @throws PConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function get(int $uid, string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return null;
+               }
+
+               try {
+                       $config = $this->db->selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
+                       if ($this->db->isResult($config)) {
+                               $value = ValueConversion::toConfigValue($config['v']);
+
+                               // just return it in case it is set
+                               if (isset($value)) {
+                                       return $value;
+                               }
+                       }
+               } catch (\Exception $exception) {
+                       throw new PConfigPersistenceException(sprintf('Cannot get config value for category %s, key %s and user %d', $cat, $key, $uid), $exception);
+               }
+
+               return null;
+       }
+
+       /**
+        * Stores a config value ($value) in the category ($cat) under the key ($key) for a
+        * given user ($uid).
+        *
+        * Note: Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param int    $uid   The id of the user to load
+        * @param string $cat   The category of the configuration value
+        * @param string $key   The configuration key to set
+        * @param mixed  $value The value to store
+        *
+        * @return bool Operation success
+        *
+        * @throws PConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function set(int $uid, string $cat, string $key, $value): bool
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               // We store our setting values in a string variable.
+               // So we have to do the conversion here so that the compare below works.
+               // The exception are array values.
+               $compare_value = (!is_array($value) ? (string)$value : $value);
+               $stored_value  = $this->get($uid, $cat, $key);
+
+               if (isset($stored_value) && ($stored_value === $compare_value)) {
+                       return true;
+               }
+
+               try {
+                       $dbValue = ValueConversion::toDbValue($value);
+                       return $this->db->update(static::$table_name, ['v' => $dbValue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
+               } catch (\Exception $exception) {
+                       throw new PConfigPersistenceException(sprintf('Cannot set config value for category %s, key %s and user %d', $cat, $key, $uid), $exception);
+               }
+       }
+
+       /**
+        * Removes the configured value of the given user.
+        *
+        * @param int    $uid The id of the user to load
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to delete
+        *
+        * @return bool Operation success
+        *
+        * @throws PConfigPersistenceException In case the persistence layer throws errors
+        */
+       public function delete(int $uid, string $cat, string $key): bool
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               try {
+                       return $this->db->delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
+               } catch (\Exception $exception) {
+                       throw new PConfigPersistenceException(sprintf('Cannot delete config value for category %s, key %s and user %d', $cat, $key, $uid), $exception);
+               }
+       }
+}
diff --git a/src/Core/PConfig/Type/AbstractPConfigValues.php b/src/Core/PConfig/Type/AbstractPConfigValues.php
new file mode 100644 (file)
index 0000000..ddf8f6f
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Type;
+
+use Friendica\Core\PConfig\Repository;
+use Friendica\Core\PConfig\ValueObject\Cache;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
+
+/**
+ * This class is responsible for the user-specific configuration values in Friendica
+ * The values are set through the Config-DB-Table (per Config-DB-model @see Repository\PConfig)
+ *
+ * The configuration cache (@see Cache) is used for temporary caching of database calls. This will
+ * increase the performance.
+ */
+abstract class AbstractPConfigValues implements IManagePersonalConfigValues
+{
+       /**
+        * @var Cache
+        */
+       protected $configCache;
+
+       /**
+        * @var Repository\PConfig
+        */
+       protected $configModel;
+
+       /**
+        * @param Cache              $configCache The configuration cache
+        * @param Repository\PConfig $configRepo  The configuration model
+        */
+       public function __construct(Cache $configCache, Repository\PConfig $configRepo)
+       {
+               $this->configCache = $configCache;
+               $this->configModel = $configRepo;
+       }
+
+       /**
+        * Returns the Config Cache
+        *
+        * @return Cache
+        */
+       public function getCache(): Cache
+       {
+               return $this->configCache;
+       }
+}
diff --git a/src/Core/PConfig/Type/BasePConfig.php b/src/Core/PConfig/Type/BasePConfig.php
deleted file mode 100644 (file)
index 9ae374f..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig\Type;
-
-use Friendica\Core\PConfig\Cache\Cache;
-use Friendica\Core\PConfig\IPConfig;
-use Friendica\Model;
-
-/**
- * This class is responsible for the user-specific configuration values in Friendica
- * The values are set through the Config-DB-Table (per Config-DB-model @see Model\Config\PConfig)
- *
- * The configuration cache (@see Cache\PConfigCache) is used for temporary caching of database calls. This will
- * increase the performance.
- */
-abstract class BasePConfig implements IPConfig
-{
-       /**
-        * @var \Friendica\Core\PConfig\Cache\Cache
-        */
-       protected $configCache;
-
-       /**
-        * @var \Friendica\Core\PConfig\Model\PConfig
-        */
-       protected $configModel;
-
-       /**
-        * @param \Friendica\Core\PConfig\Cache\Cache   $configCache The configuration cache
-        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
-       {
-               $this->configCache = $configCache;
-               $this->configModel = $configModel;
-       }
-
-       /**
-        * Returns the Config Cache
-        *
-        * @return \Friendica\Core\PConfig\Cache\Cache
-        */
-       public function getCache()
-       {
-               return $this->configCache;
-       }
-}
index 99c3b581bf6edffa75c125089a7780b3c314b5d0..14a8b274484316504c886dd8fe778bbb60e5ae93 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Core\PConfig\Type;
 
-use Friendica\Core\PConfig\Cache\Cache;
-use Friendica\Model;
+use Friendica\Core\PConfig\Repository;
+use Friendica\Core\PConfig\ValueObject;
 
 /**
  * This class implements the Just-In-Time configuration, which will cache
@@ -31,7 +31,7 @@ use Friendica\Model;
  * Default Configuration type.
  * Provides the best performance for pages loading few configuration variables.
  */
-class JitPConfig extends BasePConfig
+class JitPConfig extends AbstractPConfigValues
 {
        /**
         * @var array Array of already loaded db values (even if there was no value)
@@ -39,12 +39,12 @@ class JitPConfig extends BasePConfig
        private $db_loaded;
 
        /**
-        * @param Cache                                 $configCache The configuration cache
-        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
+        * @param ValueObject\Cache  $configCache The configuration cache
+        * @param Repository\PConfig $configRepo  The configuration model
         */
-       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
+       public function __construct(ValueObject\Cache $configCache, Repository\PConfig $configRepo)
        {
-               parent::__construct($configCache, $configModel);
+               parent::__construct($configCache, $configRepo);
                $this->db_loaded = [];
        }
 
@@ -52,11 +52,11 @@ class JitPConfig extends BasePConfig
         * {@inheritDoc}
         *
         */
-       public function load(int $uid, string $cat = 'config')
+       public function load(int $uid, string $cat = 'config'): array
        {
                // If not connected or no uid, do nothing
                if (!$uid || !$this->configModel->isConnected()) {
-                       return;
+                       return [];
                }
 
                $config = $this->configModel->load($uid, $cat);
@@ -84,14 +84,12 @@ class JitPConfig extends BasePConfig
 
                // if the value isn't loaded or refresh is needed, load it to the cache
                if ($this->configModel->isConnected() &&
-                   (empty($this->db_loaded[$uid][$cat][$key]) ||
-                    $refresh)) {
+                       (empty($this->db_loaded[$uid][$cat][$key]) || $refresh)) {
+                       $dbValue = $this->configModel->get($uid, $cat, $key);
 
-                       $dbvalue = $this->configModel->get($uid, $cat, $key);
-
-                       if (isset($dbvalue)) {
-                               $this->configCache->set($uid, $cat, $key, $dbvalue);
-                               unset($dbvalue);
+                       if (isset($dbValue)) {
+                               $this->configCache->set($uid, $cat, $key, $dbValue);
+                               unset($dbValue);
                        }
 
                        $this->db_loaded[$uid][$cat][$key] = true;
@@ -106,7 +104,7 @@ class JitPConfig extends BasePConfig
        /**
         * {@inheritDoc}
         */
-       public function set(int $uid, string $cat, string $key, $value)
+       public function set(int $uid, string $cat, string $key, $value): bool
        {
                if (!$uid) {
                        return false;
@@ -130,7 +128,7 @@ class JitPConfig extends BasePConfig
        /**
         * {@inheritDoc}
         */
-       public function delete(int $uid, string $cat, string $key)
+       public function delete(int $uid, string $cat, string $key): bool
        {
                if (!$uid) {
                        return false;
index 4498bb409d8b20e4b8a911ebb6282d92c63cfa08..51f31691bf0a8fb7359e6e9e58075581a5c6508a 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Core\PConfig\Type;
 
-use Friendica\Core\PConfig\Cache\Cache;
-use Friendica\Model;
+use Friendica\Core\PConfig\Repository;
+use Friendica\Core\PConfig\ValueObject;
 
 /**
  * This class implements the preload configuration, which will cache
@@ -30,18 +30,18 @@ use Friendica\Model;
  *
  * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
  */
-class PreloadPConfig extends BasePConfig
+class PreloadPConfig extends AbstractPConfigValues
 {
        /** @var array */
        private $config_loaded;
 
        /**
-        * @param \Friendica\Core\PConfig\Cache\Cache   $configCache The configuration cache
-        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
+        * @param ValueObject\Cache  $configCache The configuration cache
+        * @param Repository\PConfig $configRepo  The configuration model
         */
-       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
+       public function __construct(ValueObject\Cache $configCache, Repository\PConfig $configRepo)
        {
-               parent::__construct($configCache, $configModel);
+               parent::__construct($configCache, $configRepo);
                $this->config_loaded = [];
        }
 
@@ -51,16 +51,16 @@ class PreloadPConfig extends BasePConfig
         * This loads all config values everytime load is called
         *
         */
-       public function load(int $uid, string $cat = 'config')
+       public function load(int $uid, string $cat = 'config'): array
        {
                // Don't load the whole configuration twice or with invalid uid
                if (!$uid || !empty($this->config_loaded[$uid])) {
-                       return;
+                       return [];
                }
 
                // If not connected, do nothing
                if (!$this->configModel->isConnected()) {
-                       return;
+                       return [];
                }
 
                $config                    = $this->configModel->load($uid);
@@ -101,7 +101,7 @@ class PreloadPConfig extends BasePConfig
        /**
         * {@inheritDoc}
         */
-       public function set(int $uid, string $cat, string $key, $value)
+       public function set(int $uid, string $cat, string $key, $value): bool
        {
                if (!$uid) {
                        return false;
@@ -127,7 +127,7 @@ class PreloadPConfig extends BasePConfig
        /**
         * {@inheritDoc}
         */
-       public function delete(int $uid, string $cat, string $key)
+       public function delete(int $uid, string $cat, string $key): bool
        {
                if (!$uid) {
                        return false;
diff --git a/src/Core/PConfig/ValueObject/Cache.php b/src/Core/PConfig/ValueObject/Cache.php
new file mode 100644 (file)
index 0000000..d685519
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\ValueObject;
+
+use ParagonIE\HiddenString\HiddenString;
+
+/**
+ * The Friendica config cache for users
+ */
+class Cache
+{
+       /**
+        * @var array
+        */
+       private $config = [];
+
+       /**
+        * @var bool
+        */
+       private $hidePasswordOutput;
+
+       /**
+        * @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
+        */
+       public function __construct(bool $hidePasswordOutput = true)
+       {
+               $this->hidePasswordOutput = $hidePasswordOutput;
+       }
+
+       /**
+        * Tries to load the specified configuration array into the user specific config array.
+        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+        *
+        * @param int   $uid
+        * @param array $config
+        */
+       public function load(int $uid, array $config)
+       {
+               if (!is_int($uid)) {
+                       return;
+               }
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (isset($config[$category]) && is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       $value = $config[$category][$key];
+                                       if (isset($value)) {
+                                               $this->set($uid, $category, $key, $value);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Retrieves a value from the user config cache
+        *
+        * @param int    $uid User Id
+        * @param string $cat Config category
+        * @param string|null $key Config key
+        *
+        * @return null|mixed The value of the config entry or null if not set
+        */
+       public function get(int $uid, string $cat, ?string $key = null)
+       {
+               if (!is_int($uid)) {
+                       return null;
+               }
+
+               if (isset($this->config[$uid][$cat][$key])) {
+                       return $this->config[$uid][$cat][$key];
+               } elseif (!isset($key) && isset($this->config[$uid][$cat])) {
+                       return $this->config[$uid][$cat];
+               } else {
+                       return 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
+        *
+        * @return bool Set successful
+        */
+       public function set(int $uid, string $cat, string $key, $value): bool
+       {
+               if (!is_int($uid)) {
+                       return false;
+               }
+
+               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
+                       $this->config[$uid] = [];
+               }
+
+               if (!isset($this->config[$uid][$cat])) {
+                       $this->config[$uid][$cat] = [];
+               }
+
+               if ($this->hidePasswordOutput &&
+                       $key == 'password' &&
+                       !empty($value) && is_string($value)) {
+                       $this->config[$uid][$cat][$key] = new HiddenString((string)$value);
+               } else {
+                       $this->config[$uid][$cat][$key] = $value;
+               }
+
+
+               return true;
+       }
+
+       /**
+        * Deletes a value from the user config cache
+        *
+        * @param int    $uid User Id
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return bool true, if deleted
+        */
+       public function delete(int $uid, string $cat, string $key): bool
+       {
+               if (!is_int($uid)) {
+                       return false;
+               }
+
+               if (isset($this->config[$uid][$cat][$key])) {
+                       unset($this->config[$uid][$cat][$key]);
+                       if (count($this->config[$uid][$cat]) == 0) {
+                               unset($this->config[$uid][$cat]);
+                               if (count($this->config[$uid]) == 0) {
+                                       unset($this->config[$uid]);
+                               }
+                       }
+
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the whole configuration
+        *
+        * @return string[][] The configuration
+        */
+       public function getAll(): array
+       {
+               return $this->config;
+       }
+
+       /**
+        * Returns an array with missing categories/Keys
+        *
+        * @param string[][] $config The array to check
+        *
+        * @return string[][]
+        */
+       public function keyDiff(array $config): array
+       {
+               $return = [];
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       if (!isset($this->config[$category][$key])) {
+                                               $return[$category][$key] = $config[$category][$key];
+                                       }
+                               }
+                       }
+               }
+
+               return $return;
+       }
+}
index 3c1a139298f95703e30b0ea735c6d3a0c70e34d8..8bde3cc3df976ef3759f207928fc7f826aa6b826 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Core;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Model;
 use Psr\Log\LoggerInterface;
 
@@ -48,7 +48,7 @@ class Process
        private $mode;
 
        /**
-        * @var IConfig
+        * @var IManageConfigValues
         */
        private $config;
 
@@ -67,7 +67,7 @@ class Process
         */
        private $pid;
 
-       public function __construct(LoggerInterface $logger, App\Mode $mode, IConfig $config, Model\Process $processModel, string $basepath, int $pid)
+       public function __construct(LoggerInterface $logger, App\Mode $mode, IManageConfigValues $config, Model\Process $processModel, string $basepath, int $pid)
        {
                $this->logger = $logger;
                $this->mode = $mode;
@@ -176,7 +176,7 @@ class Process
                        if (count($data) != 2) {
                                continue;
                        }
-                       list($key, $val) = $data;
+                       [$key, $val] = $data;
                        $meminfo[$key] = (int)trim(str_replace('kB', '', $val));
                        $meminfo[$key] = (int)($meminfo[$key] / 1024);
                }
diff --git a/src/Core/Session/Capability/IHandleSessions.php b/src/Core/Session/Capability/IHandleSessions.php
new file mode 100644 (file)
index 0000000..7b863b7
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Session\Capability;
+
+/**
+ * Contains all global supported Session methods
+ */
+interface IHandleSessions
+{
+       /**
+        * Start the current session
+        *
+        * @return self The own Session instance
+        */
+       public function start(): IHandleSessions;
+
+       /**
+        * Checks if the key exists in this session
+        *
+        * @param string $name
+        *
+        * @return boolean True, if it exists
+        */
+       public function exists(string $name): bool;
+
+       /**
+        * Retrieves a key from the session super global or the defaults if the key is missing or the value is falsy.
+        *
+        * Handle the case where session_start() hasn't been called and the super global isn't available.
+        *
+        * @param string $name
+        * @param mixed  $defaults
+        *
+        * @return mixed
+        */
+       public function get(string $name, $defaults = null);
+
+       /**
+        * Sets a single session variable.
+        * Overrides value of existing key.
+        *
+        * @param string $name
+        * @param mixed  $value
+        */
+       public function set(string $name, $value);
+
+       /**
+        * Sets multiple session variables.
+        * Overrides values for existing keys.
+        *
+        * @param array $values
+        */
+       public function setMultiple(array $values);
+
+       /**
+        * Removes a session variable.
+        * Ignores missing keys.
+        *
+        * @param string $name
+        */
+       public function remove(string $name);
+
+       /**
+        * Clears the current session array
+        */
+       public function clear();
+}
diff --git a/src/Core/Session/Factory/Session.php b/src/Core/Session/Factory/Session.php
new file mode 100644 (file)
index 0000000..5062c33
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Session\Factory;
+
+use Friendica\App;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Enum;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Session\Capability\IHandleSessions;
+use Friendica\Core\Session\Type;
+use Friendica\Core\Session\Handler;
+use Friendica\Database\Database;
+use Friendica\Util\Profiler;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Factory for creating a valid Session for this run
+ */
+class Session
+{
+       /** @var string The plain, PHP internal session management */
+       const HANDLER_NATIVE = 'native';
+       /** @var string Using the database for session management */
+       const HANDLER_DATABASE = 'database';
+       /** @var string Using the cache for session management */
+       const HANDLER_CACHE = 'cache';
+
+       const HANDLER_DEFAULT = self::HANDLER_DATABASE;
+
+       /**
+        * @param App\Mode            $mode
+        * @param App\BaseURL         $baseURL
+        * @param IManageConfigValues $config
+        * @param Database            $dba
+        * @param ICanCache           $cache
+        * @param LoggerInterface     $logger
+        * @param Profiler            $profiler
+        * @param array               $server
+        *
+        * @return IHandleSessions
+        */
+       public function createSession(App\Mode $mode, App\BaseURL $baseURL, IManageConfigValues $config, Database $dba, ICanCache $cache, LoggerInterface $logger, Profiler $profiler, array $server = [])
+       {
+               $profiler->startRecording('session');
+               $session = null;
+
+               try {
+                       if ($mode->isInstall() || $mode->isBackend()) {
+                               $session = new Type\Memory();
+                       } else {
+                               $session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
+                               $handler         = null;
+
+                               switch ($session_handler) {
+                                       case self::HANDLER_DATABASE:
+                                               $handler = new Handler\Database($dba, $logger, $server);
+                                               break;
+                                       case self::HANDLER_CACHE:
+                                               // In case we're using the db as cache driver, use the native db session, not the cache
+                                               if ($config->get('system', 'cache_driver') === Enum\Type::DATABASE) {
+                                                       $handler = new Handler\Database($dba, $logger, $server);
+                                               } else {
+                                                       $handler = new Handler\Cache($cache, $logger);
+                                               }
+                                               break;
+                               }
+
+                               $session = new Type\Native($baseURL, $handler);
+                       }
+               } finally {
+                       $profiler->stopRecording();
+                       return $session;
+               }
+       }
+}
diff --git a/src/Core/Session/Factory/SessionFactory.php b/src/Core/Session/Factory/SessionFactory.php
deleted file mode 100644 (file)
index 510ff08..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Session\Factory;
-
-use Friendica\App;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Session;
-use Friendica\Database\Database;
-use Friendica\Util\Profiler;
-use Psr\Log\LoggerInterface;
-
-/**
- * Factory for creating a valid Session for this run
- */
-class SessionFactory
-{
-       /** @var string The plain, PHP internal session management */
-       const HANDLER_NATIVE = 'native';
-       /** @var string Using the database for session management */
-       const HANDLER_DATABASE = 'database';
-       /** @var string Using the cache for session management */
-       const HANDLER_CACHE = 'cache';
-
-       const HANDLER_DEFAULT = self::HANDLER_DATABASE;
-
-       /**
-        * @param App\Mode        $mode
-        * @param App\BaseURL     $baseURL
-        * @param IConfig         $config
-        * @param Database        $dba
-        * @param ICache          $cache
-        * @param LoggerInterface $logger
-        * @param array           $server
-        *
-        * @return Session\ISession
-        */
-       public function createSession(App\Mode $mode, App\BaseURL $baseURL, IConfig $config, Database $dba, ICache $cache, LoggerInterface $logger, Profiler $profiler, array $server = [])
-       {
-               $profiler->startRecording('session');
-               $session = null;
-
-               try {
-                       if ($mode->isInstall() || $mode->isBackend()) {
-                               $session = new Session\Type\Memory();
-                       } else {
-                               $session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
-                               $handler = null;
-
-                               switch ($session_handler) {
-                                       case self::HANDLER_DATABASE:
-                                               $handler = new Session\Handler\Database($dba, $logger, $server);
-                                               break;
-                                       case self::HANDLER_CACHE:
-                                               // In case we're using the db as cache driver, use the native db session, not the cache
-                                               if ($config->get('system', 'cache_driver') === Type::DATABASE) {
-                                                       $handler = new Session\Handler\Database($dba, $logger, $server);
-                                               } else {
-                                                       $handler = new Session\Handler\Cache($cache);
-                                               }
-                                               break;
-                               }
-
-                               $session = new Session\Type\Native($baseURL, $handler);
-                       }
-               } finally {
-                       $profiler->stopRecording();
-                       return $session;
-               }
-       }
-}
index dc1bfa6b74a021f66c6be584943627453a5430f6..ab888e81d14d5d928c7476dfa364ec3deff200a7 100644 (file)
 
 namespace Friendica\Core\Session\Handler;
 
-use Friendica\Core\Cache\ICache;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Exception\CachePersistenceException;
 use Friendica\Core\Session;
+use Psr\Log\LoggerInterface;
 use SessionHandlerInterface;
 
 /**
@@ -30,29 +32,37 @@ use SessionHandlerInterface;
  */
 class Cache implements SessionHandlerInterface
 {
-       /** @var ICache */
+       /** @var ICanCache */
        private $cache;
+       /** @var LoggerInterface */
+       private $logger;
 
-       public function __construct(ICache $cache)
+       public function __construct(ICanCache $cache, LoggerInterface $logger)
        {
-               $this->cache = $cache;
+               $this->cache  = $cache;
+               $this->logger = $logger;
        }
 
-       public function open($save_path, $session_name)
+       public function open($path, $name): bool
        {
                return true;
        }
 
-       public function read($session_id)
+       public function read($id)
        {
-               if (empty($session_id)) {
+               if (empty($id)) {
                        return '';
                }
 
-               $data = $this->cache->get('session:' . $session_id);
-               if (!empty($data)) {
-                       Session::$exists = true;
-                       return $data;
+               try {
+                       $data = $this->cache->get('session:' . $id);
+                       if (!empty($data)) {
+                               Session::$exists = true;
+                               return $data;
+                       }
+               } catch (CachePersistenceException $exception) {
+                       $this->logger->warning('Cannot read session.'. ['id' => $id, 'exception' => $exception]);
+                       return '';
                }
 
                return '';
@@ -65,36 +75,45 @@ class Cache implements SessionHandlerInterface
         * on the case. Uses the Session::expire for existing session, 5 minutes
         * for newly created session.
         *
-        * @param string $session_id   Session ID with format: [a-z0-9]{26}
-        * @param string $session_data Serialized session data
+        * @param string $id   Session ID with format: [a-z0-9]{26}
+        * @param string $data Serialized session data
         *
-        * @return boolean Returns false if parameters are missing, true otherwise
-        * @throws \Exception
+        * @return bool Returns false if parameters are missing, true otherwise
         */
-       public function write($session_id, $session_data)
+       public function write($id, $data): bool
        {
-               if (!$session_id) {
+               if (!$id) {
                        return false;
                }
 
-               if (!$session_data) {
-                       return $this->destroy($session_id);
+               if (!$data) {
+                       return $this->destroy($id);
                }
 
-               return $this->cache->set('session:' . $session_id, $session_data, Session::$expire);
+               try {
+                       return $this->cache->set('session:' . $id, $data, Session::$expire);
+               } catch (CachePersistenceException $exception) {
+                       $this->logger->warning('Cannot write session', ['id' => $id, 'exception' => $exception]);
+                       return false;
+               }
        }
 
-       public function close()
+       public function close(): bool
        {
                return true;
        }
 
-       public function destroy($id)
+       public function destroy($id): bool
        {
-               return $this->cache->delete('session:' . $id);
+               try {
+                       return $this->cache->delete('session:' . $id);
+               } catch (CachePersistenceException $exception) {
+                       $this->logger->warning('Cannot destroy session', ['id' => $id, 'exception' => $exception]);
+                       return false;
+               }
        }
 
-       public function gc($maxlifetime)
+       public function gc($max_lifetime): bool
        {
                return true;
        }
index c0467818c0ca753f1dc0fbfae601b2a344461a75..b18d55db7ceb2b49d23ce97a77c89960a20de26f 100644 (file)
@@ -52,24 +52,29 @@ class Database implements SessionHandlerInterface
                $this->server = $server;
        }
 
-       public function open($save_path, $session_name)
+       public function open($path, $name): bool
        {
                return true;
        }
 
-       public function read($session_id)
+       public function read($id)
        {
-               if (empty($session_id)) {
+               if (empty($id)) {
                        return '';
                }
 
-               $session = $this->dba->selectFirst('session', ['data'], ['sid' => $session_id]);
-               if ($this->dba->isResult($session)) {
-                       Session::$exists = true;
-                       return $session['data'];
+               try {
+                       $session = $this->dba->selectFirst('session', ['data'], ['sid' => $id]);
+                       if ($this->dba->isResult($session)) {
+                               Session::$exists = true;
+                               return $session['data'];
+                       }
+               } catch (\Exception $exception) {
+                       $this->logger->warning('Cannot read session.'. ['id' => $id, 'exception' => $exception]);
+                       return '';
                }
 
-               $this->logger->notice('no data for session', ['session_id' => $session_id, 'uri' => $this->server['REQUEST_URI'] ?? '']);
+               $this->logger->notice('no data for session', ['session_id' => $id, 'uri' => $this->server['REQUEST_URI'] ?? '']);
 
                return '';
        }
@@ -81,49 +86,63 @@ class Database implements SessionHandlerInterface
         * on the case. Uses the Session::expire global for existing session, 5 minutes
         * for newly created session.
         *
-        * @param string $session_id   Session ID with format: [a-z0-9]{26}
-        * @param string $session_data Serialized session data
+        * @param string $id   Session ID with format: [a-z0-9]{26}
+        * @param string $data Serialized session data
         *
-        * @return boolean Returns false if parameters are missing, true otherwise
-        * @throws \Exception
+        * @return bool Returns false if parameters are missing, true otherwise
         */
-       public function write($session_id, $session_data)
+       public function write($id, $data): bool
        {
-               if (!$session_id) {
+               if (!$id) {
                        return false;
                }
 
-               if (!$session_data) {
-                       return $this->destroy($session_id);
+               if (!$data) {
+                       return $this->destroy($id);
                }
 
                $expire         = time() + Session::$expire;
                $default_expire = time() + 300;
 
-               if (Session::$exists) {
-                       $fields    = ['data' => $session_data, 'expire' => $expire];
-                       $condition = ["`sid` = ? AND (`data` != ? OR `expire` != ?)", $session_id, $session_data, $expire];
-                       $this->dba->update('session', $fields, $condition);
-               } else {
-                       $fields = ['sid' => $session_id, 'expire' => $default_expire, 'data' => $session_data];
-                       $this->dba->insert('session', $fields);
+               try {
+                       if (Session::$exists) {
+                               $fields    = ['data' => $data, 'expire' => $expire];
+                               $condition = ["`sid` = ? AND (`data` != ? OR `expire` != ?)", $id, $data, $expire];
+                               $this->dba->update('session', $fields, $condition);
+                       } else {
+                               $fields = ['sid' => $id, 'expire' => $default_expire, 'data' => $data];
+                               $this->dba->insert('session', $fields);
+                       }
+               } catch (\Exception $exception) {
+                       $this->logger->warning('Cannot write session.'. ['id' => $id, 'exception' => $exception]);
+                       return false;
                }
 
                return true;
        }
 
-       public function close()
+       public function close(): bool
        {
                return true;
        }
 
-       public function destroy($id)
+       public function destroy($id): bool
        {
-               return $this->dba->delete('session', ['sid' => $id]);
+               try {
+                       return $this->dba->delete('session', ['sid' => $id]);
+               } catch (\Exception $exception) {
+                       $this->logger->warning('Cannot destroy session.'. ['id' => $id, 'exception' => $exception]);
+                       return false;
+               }
        }
 
-       public function gc($maxlifetime)
+       public function gc($max_lifetime): bool
        {
-               return $this->dba->delete('session', ["`expire` < ?", time()]);
+               try {
+                       return $this->dba->delete('session', ["`expire` < ?", time()]);
+               } catch (\Exception $exception) {
+                       $this->logger->warning('Cannot use garbage collector.'. ['exception' => $exception]);
+                       return false;
+               }
        }
 }
diff --git a/src/Core/Session/ISession.php b/src/Core/Session/ISession.php
deleted file mode 100644 (file)
index 2b2bf32..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Session;
-
-/**
- * Contains all global supported Session methods
- */
-interface ISession
-{
-       /**
-        * Start the current session
-        *
-        * @return self The own Session instance
-        */
-       public function start();
-
-       /**
-        * Checks if the key exists in this session
-        *
-        * @param string $name
-        *
-        * @return boolean True, if it exists
-        */
-       public function exists(string $name);
-
-       /**
-        * Retrieves a key from the session super global or the defaults if the key is missing or the value is falsy.
-        *
-        * Handle the case where session_start() hasn't been called and the super global isn't available.
-        *
-        * @param string $name
-        * @param mixed  $defaults
-        *
-        * @return mixed
-        */
-       public function get(string $name, $defaults = null);
-
-       /**
-        * Sets a single session variable.
-        * Overrides value of existing key.
-        *
-        * @param string $name
-        * @param mixed  $value
-        */
-       public function set(string $name, $value);
-
-       /**
-        * Sets multiple session variables.
-        * Overrides values for existing keys.
-        *
-        * @param array $values
-        */
-       public function setMultiple(array $values);
-
-       /**
-        * Removes a session variable.
-        * Ignores missing keys.
-        *
-        * @param string $name
-        */
-       public function remove(string $name);
-
-       /**
-        * Clears the current session array
-        */
-       public function clear();
-}
index 8126804dba4e66f08be54648a8ed42be28f3bd9f..832155741c2df39982fd5f78c17a8e86547c21d3 100644 (file)
 
 namespace Friendica\Core\Session\Type;
 
+use Friendica\Core\Session\Capability\IHandleSessions;
+
 /**
  * Contains the base methods for $_SESSION interaction
  */
-class AbstractSession
+class AbstractSession implements IHandleSessions
 {
        /**
         * {@inheritDoc}
         */
-       public function start()
+       public function start(): IHandleSessions
        {
                return $this;
        }
@@ -37,7 +39,7 @@ class AbstractSession
        /**
         * {@inheritDoc}}
         */
-       public function exists(string $name)
+       public function exists(string $name): bool
        {
                return isset($_SESSION[$name]);
        }
index 635d880e7add7f5898a581018d1027a2aa6532a0..4d4020144b30516ff834cf37e6653fa73f10357f 100644 (file)
 
 namespace Friendica\Core\Session\Type;
 
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
 
 /**
  * Usable for backend processes (daemon/worker) and testing
  *
  * @todo after replacing the last direct $_SESSION call, use a internal array instead of the global variable
  */
-class Memory extends AbstractSession implements ISession
+class Memory extends AbstractSession implements IHandleSessions
 {
        public function __construct()
        {
index 4edd9a962e56102c8026e934952e6b306ce349e2..8dfbc57c84f035216d723499b178f63bab5a02de 100644 (file)
 namespace Friendica\Core\Session\Type;
 
 use Friendica\App;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
 use Friendica\Model\User\Cookie;
 use SessionHandlerInterface;
 
 /**
  * The native Session class which uses the PHP internal Session functions
  */
-class Native extends AbstractSession implements ISession
+class Native extends AbstractSession implements IHandleSessions
 {
        public function __construct(App\BaseURL $baseURL, SessionHandlerInterface $handler = null)
        {
@@ -49,7 +49,7 @@ class Native extends AbstractSession implements ISession
        /**
         * {@inheritDoc}
         */
-       public function start()
+       public function start(): IHandleSessions
        {
                session_start();
                return $this;
index 61dd8d375d6659e46102feeec142f4e084da4f19..ee6b959ff0e5802b882f7155083f3a30c69b35b8 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Core;
 
 use Exception;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Database\Database;
 use Friendica\Model\Storage;
 use Friendica\Network\HTTPException\InternalServerErrorException;
@@ -56,7 +56,7 @@ class StorageManager
 
        /** @var Database */
        private $dba;
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        private $config;
        /** @var LoggerInterface */
        private $logger;
@@ -67,15 +67,15 @@ class StorageManager
        private $currentBackend;
 
        /**
-        * @param Database        $dba
-        * @param IConfig         $config
-        * @param LoggerInterface $logger
-        * @param L10n            $l10n
+        * @param Database            $dba
+        * @param IManageConfigValues $config
+        * @param LoggerInterface     $logger
+        * @param L10n                $l10n
         *
         * @throws Storage\InvalidClassStorageException in case the active backend class is invalid
         * @throws Storage\StorageException in case of unexpected errors during the active backend class loading
         */
-       public function __construct(Database $dba, IConfig $config, LoggerInterface $logger, L10n $l10n)
+       public function __construct(Database $dba, IManageConfigValues $config, LoggerInterface $logger, L10n $l10n)
        {
                $this->dba           = $dba;
                $this->config        = $config;
index 7e5f309b33b2f368c0c6f81f6972be55bb5ee5e9..570d680dfead1498c7c3c80a46f46f42b0b1631c 100644 (file)
@@ -155,35 +155,35 @@ abstract class DI
        //
 
        /**
-        * @return Core\Cache\ICache
+        * @return \Friendica\Core\Cache\Capability\ICanCache
         */
        public static function cache()
        {
-               return self::$dice->create(Core\Cache\ICache::class);
+               return self::$dice->create(Core\Cache\Capability\ICanCache::class);
        }
 
        /**
-        * @return Core\Config\IConfig
+        * @return \Friendica\Core\Config\Capability\IManageConfigValues
         */
        public static function config()
        {
-               return self::$dice->create(Core\Config\IConfig::class);
+               return self::$dice->create(Core\Config\Capability\IManageConfigValues::class);
        }
 
        /**
-        * @return Core\PConfig\IPConfig
+        * @return \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues
         */
        public static function pConfig()
        {
-               return self::$dice->create(Core\PConfig\IPConfig::class);
+               return self::$dice->create(Core\PConfig\Capability\IManagePersonalConfigValues::class);
        }
 
        /**
-        * @return Core\Lock\ILock
+        * @return \Friendica\Core\Lock\Capability\ICanLock
         */
        public static function lock()
        {
-               return self::$dice->create(Core\Lock\ILock::class);
+               return self::$dice->create(Core\Lock\Capability\ICanLock::class);
        }
 
        /**
@@ -203,11 +203,11 @@ abstract class DI
        }
 
        /**
-        * @return Core\Session\ISession
+        * @return \Friendica\Core\Session\Capability\IHandleSessions
         */
        public static function session()
        {
-               return self::$dice->create(Core\Session\ISession::class);
+               return self::$dice->create(Core\Session\Capability\IHandleSessions::class);
        }
 
        /**
index 4a8d5d36e7746f92e6e894cf96662dfd2688e0e4..a6cc3f875d4cbcade03934afe637e9bad585f676 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Database;
 
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\System;
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Util\DateTimeFormat;
@@ -49,7 +49,7 @@ class Database
        protected $connected = false;
 
        /**
-        * @var Cache
+        * @var \Friendica\Core\Config\ValueObject\Cache
         */
        protected $configCache;
        /**
index 12d9fd45fabb9b9eb3ef02ff3b45fa6cea683524..18e2b0f553e7ac854d2e86081c3aff90140590a5 100644 (file)
@@ -4,7 +4,7 @@ namespace Friendica\Factory;
 
 use Friendica\App;
 use Friendica\BaseFactory;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Network\HTTPClient;
 use Friendica\Network\IHTTPClient;
 use Friendica\Util\Profiler;
@@ -22,14 +22,14 @@ require_once __DIR__ . '/../../static/dbstructure.config.php';
 
 class HTTPClientFactory extends BaseFactory
 {
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var Profiler */
        private $profiler;
        /** @var App\BaseURL */
        private $baseUrl;
 
-       public function __construct(LoggerInterface $logger, IConfig $config, Profiler $profiler, App\BaseURL $baseUrl)
+       public function __construct(LoggerInterface $logger, IManageConfigValues $config, Profiler $profiler, App\BaseURL $baseUrl)
        {
                parent::__construct($logger);
                $this->config   = $config;
index ad6658b563b6e8040f80d0ad36bc0922cd8e48f3..6467bf38d1406ddfc28283f8e83f09de794f1965 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Factory;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Logger;
 use Friendica\Database\Database;
 use Friendica\Network\HTTPException\InternalServerErrorException;
@@ -68,14 +68,14 @@ class LoggerFactory
        /**
         * Creates a new PSR-3 compliant logger instances
         *
-        * @param Database   $database   The Friendica Database instance
-        * @param IConfig    $config     The config
-        * @param Profiler   $profiler   The profiler of the app
-        * @param FileSystem $fileSystem FileSystem utils
+        * @param Database                                              $database   The Friendica Database instance
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config     The config
+        * @param Profiler                                              $profiler   The profiler of the app
+        * @param FileSystem                                            $fileSystem FileSystem utils
         *
         * @return LoggerInterface The PSR-3 compliant logger instance
         */
-       public function create(Database $database, IConfig $config, Profiler $profiler, FileSystem $fileSystem)
+       public function create(Database $database, IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem)
        {
                if (empty($config->get('system', 'debugging', false))) {
                        $logger = new VoidLogger();
@@ -156,16 +156,16 @@ class LoggerFactory
         *
         * It should never get filled during normal usage of Friendica
         *
-        * @param IConfig    $config     The config
-        * @param Profiler   $profiler   The profiler of the app
-        * @param FileSystem $fileSystem FileSystem utils
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config     The config
+        * @param Profiler                                              $profiler   The profiler of the app
+        * @param FileSystem                                            $fileSystem FileSystem utils
         *
         * @return LoggerInterface The PSR-3 compliant logger instance
         *
         * @throws InternalServerErrorException
         * @throws \Exception
         */
-       public static function createDev(IConfig $config, Profiler $profiler, FileSystem $fileSystem)
+       public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem)
        {
                $debugging   = $config->get('system', 'debugging');
                $stream      = $config->get('system', 'dlogfile');
index 735808e822a6eac5914c1da41905c8b44cf0b8af..4c71d6cfdd4137dadbb0e0e1a7b92f4ac18cc7b7 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Model\Storage;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 
 /**
@@ -32,7 +32,7 @@ class FilesystemConfig implements IStorageConfiguration
        // Default base folder
        const DEFAULT_BASE_FOLDER = 'storage';
 
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
 
        /** @var string */
@@ -54,10 +54,10 @@ class FilesystemConfig implements IStorageConfiguration
        /**
         * Filesystem constructor.
         *
-        * @param IConfig         $config
-        * @param L10n            $l10n
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config
+        * @param L10n                                                  $l10n
         */
-       public function __construct(IConfig $config, L10n $l10n)
+       public function __construct(IManageConfigValues $config, L10n $l10n)
        {
                $this->config = $config;
                $this->l10n   = $l10n;
index ca17ae09de4fe875dc86e57e279cf99d1eec13c1..d0db091cb9c8c24f7335bb6823cdd5b6bc5f654c 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Model\User;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 
 /**
  * Interacting with the Friendica Cookie of a user
@@ -52,12 +52,12 @@ class Cookie
        private $data;
 
        /**
-        * @param IConfig     $config
-        * @param App\BaseURL $baseURL
-        * @param array       $SERVER The $_SERVER array
-        * @param array       $COOKIE The $_COOKIE array
+        * @param \Friendica\Core\Config\Capability\IManageConfigValues $config
+        * @param App\BaseURL                                           $baseURL
+        * @param array                                                 $SERVER The $_SERVER array
+        * @param array                                                 $COOKIE The $_COOKIE array
         */
-       public function __construct(IConfig $config, App\BaseURL $baseURL, array $SERVER = [], array $COOKIE = [])
+       public function __construct(IManageConfigValues $config, App\BaseURL $baseURL, array $SERVER = [], array $COOKIE = [])
        {
                $this->sslEnabled     = $baseURL->getSSLPolicy() === App\BaseURL::SSL_POLICY_FULL;
                $this->sitePrivateKey = $config->get('system', 'site_prvkey');
index 5077d3b5db3ecdf23df08b488177a124a5f32046..078f08721db172cba056f2b54056d64ae0dbed96 100644 (file)
 namespace Friendica\Module\Admin;
 
 use Friendica\Core\Addon;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Core\Update;
 use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Model\Register;
 use Friendica\Module\BaseAdmin;
 use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Core\Config\Cache\ConfigFileLoader;
+use Friendica\Core\Config\Util\ConfigFileLoader;
 use Friendica\Util\DateTimeFormat;
 
 class Summary extends BaseAdmin
@@ -152,7 +152,7 @@ class Summary extends BaseAdmin
                }
 
                // check legacy basepath settings
-               $configLoader = (new ConfigFactory())->createConfigFileLoader($a->getBasePath(), $_SERVER);
+               $configLoader = (new Config())->createConfigFileLoader($a->getBasePath(), $_SERVER);
                $configCache = new Cache();
                $configLoader->setupCache($configCache);
                $confBasepath = $configCache->get('system', 'basepath');
index b9ae763b72174a937c8650f52bcb1ac954cc9516..bcd029246eea666fbf4c40b8171fede3273e6210 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Module;
 use Friendica\App;
 use Friendica\BaseModule;
 use Friendica\Core;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\Renderer;
 use Friendica\Core\Theme;
 use Friendica\DI;
@@ -371,11 +371,11 @@ class Install extends BaseModule
        /**
         * Checks the $_POST settings and updates the config Cache for it
         *
-        * @param Cache       $configCache The current config cache
-        * @param array       $post        The $_POST data
-        * @param string      $cat         The category of the setting
-        * @param string      $key         The key of the setting
-        * @param null|string $default     The default value
+        * @param \Friendica\Core\Config\ValueObject\Cache $configCache The current config cache
+        * @param array                                    $post        The $_POST data
+        * @param string                                   $cat         The category of the setting
+        * @param string                                   $key         The key of the setting
+        * @param null|string                              $default     The default value
         */
        private static function checkSetting(Cache $configCache, array $post, $cat, $key, $default = null)
        {
index 916ddff67a6f04dcc8259d6fb1ec29521e507e96..c3a3cd46dc402a7a4f3dc13a966e0383b74acade 100644 (file)
@@ -27,9 +27,9 @@ use Friendica\App\BaseURL;
 use Friendica\BaseFactory;
 use Friendica\Content\Text\BBCode;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Protocol;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
 use Friendica\Database\Database;
 use Friendica\Model\Contact;
 use Friendica\Module\BaseNotifications;
@@ -51,14 +51,14 @@ class Introduction extends BaseFactory
        private $baseUrl;
        /** @var L10n */
        private $l10n;
-       /** @var IPConfig */
+       /** @var \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues */
        private $pConfig;
-       /** @var ISession */
+       /** @var \Friendica\Core\Session\Capability\IHandleSessions */
        private $session;
        /** @var string */
        private $nick;
 
-       public function __construct(LoggerInterface $logger, Database $dba, BaseURL $baseUrl, L10n $l10n, App $app, IPConfig $pConfig, ISession $session)
+       public function __construct(LoggerInterface $logger, Database $dba, BaseURL $baseUrl, L10n $l10n, App $app, IManagePersonalConfigValues $pConfig, IHandleSessions $session)
        {
                parent::__construct($logger);
 
index 3a6a4133c043cccef5923f589770a63c54fbc04e..a259150cf8f432c200cf125e683e2884a8ae37a1 100644 (file)
@@ -5,7 +5,7 @@ namespace Friendica\Navigation\Notifications\Repository;
 use Friendica\App\BaseURL;
 use Friendica\BaseRepository;
 use Friendica\Content\Text\Plaintext;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\System;
@@ -33,7 +33,7 @@ class Notify extends BaseRepository
        /** @var BaseURL  */
        protected $baseUrl;
 
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        protected $config;
 
        /** @var Emailer */
@@ -44,7 +44,7 @@ class Notify extends BaseRepository
 
        protected static $table_name = 'notify';
 
-       public function __construct(Database $database, LoggerInterface $logger, L10n $l10n, BaseURL $baseUrl, IConfig $config, Emailer $emailer, Factory\Notification $notification, Factory\Notify $factory = null)
+       public function __construct(Database $database, LoggerInterface $logger, L10n $l10n, BaseURL $baseUrl, IManageConfigValues $config, Emailer $emailer, Factory\Notification $notification, Factory\Notify $factory = null)
        {
                $this->l10n         = $l10n;
                $this->baseUrl      = $baseUrl;
index c0dc1e9aa7402144a632b2a65a8c22cc062fd531..ce8bc3e3217e51b28658180d5da8d7457227cdd0 100644 (file)
@@ -23,8 +23,8 @@ namespace Friendica\Security;
 
 use Exception;
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\Session;
 use Friendica\Core\System;
@@ -46,7 +46,7 @@ use Psr\Log\LoggerInterface;
  */
 class Authentication
 {
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var App\Mode */
        private $mode;
@@ -60,25 +60,25 @@ class Authentication
        private $logger;
        /** @var User\Cookie */
        private $cookie;
-       /** @var Session\ISession */
+       /** @var \Friendica\Core\Session\Capability\IHandleSessions */
        private $session;
-       /** @var IPConfig */
+       /** @var IManagePersonalConfigValues */
        private $pConfig;
 
        /**
         * Authentication constructor.
         *
-        * @param IConfig          $config
-        * @param App\Mode         $mode
-        * @param App\BaseURL      $baseUrl
-        * @param L10n             $l10n
-        * @param Database         $dba
-        * @param LoggerInterface  $logger
-        * @param User\Cookie      $cookie
-        * @param Session\ISession $session
-        * @param IPConfig         $pConfig
+        * @param IManageConfigValues                                $config
+        * @param App\Mode                                           $mode
+        * @param App\BaseURL                                        $baseUrl
+        * @param L10n                                               $l10n
+        * @param Database                                           $dba
+        * @param LoggerInterface                                    $logger
+        * @param User\Cookie                                        $cookie
+        * @param \Friendica\Core\Session\Capability\IHandleSessions $session
+        * @param IManagePersonalConfigValues                        $pConfig
         */
-       public function __construct(IConfig $config, App\Mode $mode, App\BaseURL $baseUrl, L10n $l10n, Database $dba, LoggerInterface $logger, User\Cookie $cookie, Session\ISession $session, IPConfig $pConfig)
+       public function __construct(IManageConfigValues $config, App\Mode $mode, App\BaseURL $baseUrl, L10n $l10n, Database $dba, LoggerInterface $logger, User\Cookie $cookie, Session\Capability\IHandleSessions $session, IManagePersonalConfigValues $pConfig)
        {
                $this->config  = $config;
                $this->mode    = $mode;
index fd71dea71a85e91609fc4459bb10504c48fb840b..0e1f4238477ca9f342695d518ea4629347282916 100644 (file)
@@ -36,8 +36,8 @@ namespace Friendica\Security;
 
 use Exception;
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Database\Database;
 use Friendica\DI;
 use Friendica\Model\User;
@@ -54,11 +54,11 @@ class ExAuth
         */
        private $appMode;
        /**
-        * @var IConfig
+        * @var \Friendica\Core\Config\Capability\IManageConfigValues
         */
        private $config;
        /**
-        * @var IPConfig
+        * @var IManagePersonalConfigValues
         */
        private $pConfig;
        /**
@@ -71,14 +71,15 @@ class ExAuth
        private $baseURL;
 
        /**
-        * @param App\Mode    $appMode
-        * @param IConfig      $config
-        * @param IPConfig     $pConfig
-        * @param Database    $dba
-        * @param App\BaseURL $baseURL
+        * @param App\Mode                                                       $appMode
+        * @param IManageConfigValues                                            $config
+        * @param \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues $pConfig
+        * @param Database                                                       $dba
+        * @param App\BaseURL                                                    $baseURL
+        *
         * @throws Exception
         */
-       public function __construct(App\Mode $appMode, IConfig $config, IPConfig $pConfig, Database $dba, App\BaseURL $baseURL)
+       public function __construct(App\Mode $appMode, IManageConfigValues $config, IManagePersonalConfigValues $pConfig, Database $dba, App\BaseURL $baseURL)
        {
                $this->appMode = $appMode;
                $this->config  = $config;
index 56034a6966bf192dc81db40e03970e8c81338e3b..1e623535dde5a7ae246a5f720b15ca6c6adf91fa 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Util\EMailer;
 
 use Exception;
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
 use Friendica\Model\User;
@@ -42,7 +42,7 @@ abstract class MailBuilder
 
        /** @var L10n */
        protected $l10n;
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        protected $config;
        /** @var BaseURL */
        protected $baseUrl;
@@ -64,7 +64,7 @@ abstract class MailBuilder
        /** @var int */
        protected $recipientUid = null;
 
-       public function __construct(L10n $l10n, BaseURL $baseUrl, IConfig $config, LoggerInterface $logger)
+       public function __construct(L10n $l10n, BaseURL $baseUrl, IManageConfigValues $config, LoggerInterface $logger)
        {
                $this->l10n    = $l10n;
                $this->baseUrl = $baseUrl;
index c6323436db8d3db24ac389d740e1c13abd103853..0f25704c55d4cdafaf57227e9fe1b43a4bf798ee 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Util\EMailer;
 use Exception;
 use Friendica\App\BaseURL;
 use Friendica\Content\Text\BBCode;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
 use Friendica\Network\HTTPException\InternalServerErrorException;
@@ -70,7 +70,7 @@ class NotifyMailBuilder extends MailBuilder
        /** @var string The item link */
        private $itemLink = '';
 
-       public function __construct(L10n $l10n, BaseURL $baseUrl, IConfig $config, LoggerInterface $logger, string $siteEmailAddress, string $siteName)
+       public function __construct(L10n $l10n, BaseURL $baseUrl, IManageConfigValues $config, LoggerInterface $logger, string $siteEmailAddress, string $siteName)
        {
                parent::__construct($l10n, $baseUrl, $config, $logger);
 
index b03fa42514294000d99b6051b36cf2fe11003bd4..fef051a39dffcc93535a460c6366068f3b042273 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Util\EMailer;
 use Exception;
 use Friendica\App\BaseURL;
 use Friendica\Content\Text\BBCode;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
 use Friendica\Network\HTTPException\InternalServerErrorException;
@@ -45,7 +45,7 @@ class SystemMailBuilder extends MailBuilder
        /** @var string */
        protected $siteAdmin;
 
-       public function __construct(L10n $l10n, BaseURL $baseUrl, IConfig $config, LoggerInterface $logger,
+       public function __construct(L10n $l10n, BaseURL $baseUrl, IManageConfigValues $config, LoggerInterface $logger,
                                    string $siteEmailAddress, string $siteName)
        {
                parent::__construct($l10n, $baseUrl, $config, $logger);
index 8116fbf85017d646e03969a87e409aaee96d292c..8e63b638fa51cdb96aa5b1a646440bad7342d019 100644 (file)
 namespace Friendica\Util;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Object\EMail\IEmail;
 use Friendica\Protocol\Email;
@@ -38,9 +38,9 @@ use Psr\Log\LoggerInterface;
  */
 class Emailer
 {
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        private $config;
-       /** @var IPConfig */
+       /** @var \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues */
        private $pConfig;
        /** @var LoggerInterface */
        private $logger;
@@ -54,7 +54,7 @@ class Emailer
        /** @var string */
        private $siteEmailName;
 
-       public function __construct(IConfig $config, IPConfig $pConfig, App\BaseURL $baseURL, LoggerInterface $logger,
+       public function __construct(IManageConfigValues $config, IManagePersonalConfigValues $pConfig, App\BaseURL $baseURL, LoggerInterface $logger,
                                    L10n $defaultLang)
        {
                $this->config      = $config;
index 0ff338353eb51533d3d546eb52428e9e1e97c8c8..7e04ee563f6afe3744b6ae9116baad09f186b8e1 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Util;
 
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\System;
 use Psr\Container\ContainerExceptionInterface;
 use Psr\Container\ContainerInterface;
@@ -69,16 +69,16 @@ class Profiler implements ContainerInterface
        /**
         * Updates the enabling of the current profiler
         *
-        * @param IConfig $config
+        * @param IManageConfigValues $config
         */
-       public function update(IConfig $config)
+       public function update(IManageConfigValues $config)
        {
                $this->enabled = $config->get('system', 'profiler');
                $this->rendertime = $config->get('rendertime', 'callstack');
        }
 
        /**
-        * @param \Friendica\Core\Config\Cache\Cache $configCache The configuration cache
+        * @param \Friendica\Core\Config\ValueObject\Cache $configCache The configuration cache
         */
        public function __construct(Cache $configCache)
        {
index 4591f4761cabc42f638909436a2bcad12546244b..f4aacb340ce3e46c53c54328cda17c03171397fe 100644 (file)
@@ -41,7 +41,7 @@ use Friendica\Core\PConfig;
 use Friendica\Core\L10n;
 use Friendica\Core\Lock;
 use Friendica\Core\Process;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
 use Friendica\Core\StorageManager;
 use Friendica\Database\Database;
 use Friendica\Factory;
@@ -74,8 +74,8 @@ return [
                        $_SERVER
                ]
        ],
-       Config\Cache\ConfigFileLoader::class => [
-               'instanceOf' => Config\Factory\ConfigFactory::class,
+       Config\Util\ConfigFileLoader::class => [
+               'instanceOf' => Config\Factory\Config::class,
                'call'       => [
                        ['createConfigFileLoader', [
                                [Dice::INSTANCE => '$basepath'],
@@ -83,8 +83,8 @@ return [
                        ], Dice::CHAIN_CALL],
                ],
        ],
-       Config\Cache\Cache::class => [
-               'instanceOf' => Config\Factory\ConfigFactory::class,
+       Config\ValueObject\Cache::class => [
+               'instanceOf' => Config\Factory\Config::class,
                'call'       => [
                        ['createCache', [$_SERVER], Dice::CHAIN_CALL],
                ],
@@ -95,14 +95,14 @@ return [
                        ['determine', [], Dice::CHAIN_CALL],
                ],
        ],
-       Config\IConfig::class                   => [
-               'instanceOf' => Config\Factory\ConfigFactory::class,
+       Config\Capability\IManageConfigValues::class => [
+               'instanceOf' => Config\Factory\Config::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ],
        ],
-       PConfig\IPConfig::class => [
-               'instanceOf' => PConfig\Factory\PConfigFactory::class,
+       PConfig\Capability\IManagePersonalConfigValues::class => [
+               'instanceOf' => PConfig\Factory\PConfig::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ]
@@ -158,20 +158,20 @@ return [
                        ['createDev', [], Dice::CHAIN_CALL],
                ]
        ],
-       Cache\ICache::class             => [
-               'instanceOf' => Cache\Factory\CacheFactory::class,
+       Cache\Capability\ICanCache::class => [
+               'instanceOf' => Cache\Factory\Cache::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ],
        ],
-       Cache\IMemoryCache::class       => [
-               'instanceOf' => Cache\Factory\CacheFactory::class,
+       Cache\Capability\ICanCacheInMemory::class => [
+               'instanceOf' => Cache\Factory\Cache::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ],
        ],
-       Lock\ILock::class                    => [
-               'instanceOf' => Lock\Factory\LockFactory::class,
+       Lock\Capability\ICanLock::class => [
+               'instanceOf' => Lock\Factory\Lock::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ],
@@ -206,8 +206,8 @@ return [
                        $_SERVER, $_GET
                ],
        ],
-       ISession::class => [
-               'instanceOf' => \Friendica\Core\Session\Factory\SessionFactory::class,
+       IHandleSessions::class => [
+               'instanceOf' => \Friendica\Core\Session\Factory\Session::class,
                'call' => [
                        ['createSession', [$_SERVER], Dice::CHAIN_CALL],
                        ['start', [], Dice::CHAIN_CALL],
index c09f874fa06ff33a713cd554b192ec2b06ecff61..17e606a9e62c11877ec23a912a9e18d8bf59d817 100644 (file)
@@ -6,10 +6,10 @@
 namespace Friendica\Test;
 
 use Dice\Dice;
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Session;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
 use Friendica\Database\Database;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
@@ -33,10 +33,10 @@ abstract class FixtureTest extends DatabaseTest
                $this->dice = (new Dice())
                        ->addRules(include __DIR__ . '/../static/dependencies.config.php')
                        ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
-                       ->addRule(ISession::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]);
+                       ->addRule(IHandleSessions::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]);
                DI::init($this->dice);
 
-               /** @var IConfig $config */
+               /** @var IManageConfigValues $config */
                $configCache = $this->dice->create(Cache::class);
                $configCache->set('database', 'disable_pdo', true);
 
index cca9bd37e80c379925ed35cafbc9721aa15925c2..4e6e8640d63e9a21d4f95a360e76048172754be4 100644 (file)
@@ -42,7 +42,7 @@ trait AppMockTrait
        protected $app;
 
        /**
-        * @var MockInterface|Config\IConfig The mocked Config Cache
+        * @var MockInterface|\Friendica\Core\Config\Capability\IManageConfigValues The mocked Config Cache
         */
        protected $configMock;
 
@@ -74,21 +74,21 @@ trait AppMockTrait
                $this->dice = \Mockery::mock(Dice::class)->makePartial();
                $this->dice = $this->dice->addRules(include __DIR__ . '/../../static/dependencies.config.php');
 
-               $this->configMock = \Mockery::mock(Config\Cache\Cache::class);
+               $this->configMock = \Mockery::mock(Config\ValueObject\Cache::class);
                $this->dice->shouldReceive('create')
-                          ->with(Config\Cache\Cache::class)
+                          ->with(Config\ValueObject\Cache::class)
                           ->andReturn($this->configMock);
                $this->mode = \Mockery::mock(App\Mode::class);
                $this->dice->shouldReceive('create')
                           ->with(App\Mode::class)
                           ->andReturn($this->mode);
-               $configModel= \Mockery::mock(Config\Model\Config::class);
+               $configModel= \Mockery::mock(Config\Repository\Config::class);
                // Disable the adapter
                $configModel->shouldReceive('isConnected')->andReturn(false);
 
                $config = new Config\Type\JitConfig($this->configMock, $configModel);
                $this->dice->shouldReceive('create')
-                          ->with(Config\IConfig::class)
+                          ->with(Config\Capability\IManageConfigValues::class)
                           ->andReturn($config);
 
                // Mocking App and most used functions
index 3d207d07d157beaefd5fd294fe3535103e56d1cb..9065ca1685e4968f8ea60cb025392cefdac95322 100644 (file)
@@ -23,15 +23,15 @@ namespace Friendica\Test\functional;
 
 use Dice\Dice;
 use Friendica\App;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Friendica\Database\Database;
 use Friendica\Test\Util\VFSTrait;
 use Friendica\Util\BasePath;
-use Friendica\Core\Config\Cache\ConfigFileLoader;
+use Friendica\Core\Config\Util\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use PHPUnit\Framework\TestCase;
 use Psr\Log\LoggerInterface;
@@ -158,10 +158,10 @@ class DependencyCheckTest extends TestCase
 
        public function testConfiguration()
        {
-               /** @var IConfig $config */
-               $config = $this->dice->create(IConfig::class);
+               /** @var IManageConfigValues $config */
+               $config = $this->dice->create(IManageConfigValues::class);
 
-               self::assertInstanceOf(IConfig::class, $config);
+               self::assertInstanceOf(IManageConfigValues::class, $config);
 
                self::assertNotEmpty($config->get('database', 'username'));
        }
@@ -176,8 +176,8 @@ class DependencyCheckTest extends TestCase
 
        public function testDevLogger()
        {
-               /** @var IConfig $config */
-               $config = $this->dice->create(IConfig::class);
+               /** @var IManageConfigValues $config */
+               $config = $this->dice->create(IManageConfigValues::class);
                $config->set('system', 'dlogfile', $this->root->url() . '/friendica.log');
 
                /** @var LoggerInterface $logger */
@@ -188,26 +188,26 @@ class DependencyCheckTest extends TestCase
 
        public function testCache()
        {
-               /** @var ICache $cache */
-               $cache = $this->dice->create(ICache::class);
+               /** @var ICanCache $cache */
+               $cache = $this->dice->create(ICanCache::class);
 
-               self::assertInstanceOf(ICache::class, $cache);
+               self::assertInstanceOf(ICanCache::class, $cache);
        }
 
        public function testMemoryCache()
        {
-               /** @var IMemoryCache $cache */
-               $cache = $this->dice->create(IMemoryCache::class);
+               /** @var ICanCacheInMemory $cache */
+               $cache = $this->dice->create(ICanCacheInMemory::class);
 
                // We need to check "just" ICache, because the default Cache is DB-Cache, which isn't a memorycache
-               self::assertInstanceOf(ICache::class, $cache);
+               self::assertInstanceOf(ICanCache::class, $cache);
        }
 
        public function testLock()
        {
-               /** @var ILock $cache */
-               $lock = $this->dice->create(ILock::class);
+               /** @var ICanLock $cache */
+               $lock = $this->dice->create(ICanLock::class);
 
-               self::assertInstanceOf(ILock::class, $lock);
+               self::assertInstanceOf(ICanLock::class, $lock);
        }
 }
index 553eef2a0aa8b74e246760684db4c93e6e15a454..90de2d64759d7a1d7bd419b74f3d1f851add28e4 100644 (file)
@@ -6,8 +6,8 @@
 namespace Friendica\Test\legacy;
 
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Core\Protocol;
 use Friendica\DI;
 use Friendica\Network\HTTPException;
@@ -45,7 +45,7 @@ class ApiTest extends FixtureTest
        /** @var App */
        protected $app;
 
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        protected $config;
 
        /**
@@ -59,8 +59,8 @@ class ApiTest extends FixtureTest
 
                parent::setUp();
 
-               /** @var IConfig $config */
-               $this->config = $this->dice->create(IConfig::class);
+               /** @var \Friendica\Core\Config\Capability\IManageConfigValues $config */
+               $this->config = $this->dice->create(IManageConfigValues::class);
 
                $this->config->set('system', 'url', 'http://localhost');
                $this->config->set('system', 'hostname', 'localhost');
@@ -813,7 +813,7 @@ class ApiTest extends FixtureTest
         */
        public function testApiGetUserWithFrioSchema()
        {
-               $pConfig = $this->dice->create(IPConfig::class);
+               $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
                $pConfig->set($this->selfUser['id'], 'frio', 'schema', 'red');
                $user = api_get_user($this->app);
                self::assertSelfUser($user);
@@ -829,7 +829,7 @@ class ApiTest extends FixtureTest
         */
        public function testApiGetUserWithEmptyFrioSchema()
        {
-               $pConfig = $this->dice->create(IPConfig::class);
+               $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
                $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
                $user = api_get_user($this->app);
                self::assertSelfUser($user);
@@ -845,7 +845,7 @@ class ApiTest extends FixtureTest
         */
        public function testApiGetUserWithCustomFrioSchema()
        {
-               $pConfig = $this->dice->create(IPConfig::class);
+               $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
                $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
                $pConfig->set($this->selfUser['id'], 'frio', 'nav_bg', '#123456');
                $pConfig->set($this->selfUser['id'], 'frio', 'link_color', '#123456');
index c3a5c5e72b4f99f0c10edf3f573a9b1bcfcf890e..9f38a25468265cf741ef9da1853e36fca4a60dc5 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\App;
 use Detection\MobileDetect;
 use Friendica\App\Mode;
 use Friendica\App\Module;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Database\Database;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\VFSTrait;
index 730d1d886311365058dfbf314c02dd2e3ba338a5..a928a96bfbd8a4a44baea639a0938712e4d6d2e7 100644 (file)
 namespace Friendica\Test\src\App;
 
 use Friendica\App;
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Friendica\LegacyModule;
 use Friendica\Module\HTTPException\PageNotFound;
 use Friendica\Module\WellKnown\HostMeta;
@@ -172,18 +172,18 @@ class ModuleTest extends DatabaseTest
         */
        public function testModuleClass($assert, string $name, string $command, bool $privAdd)
        {
-               $config = Mockery::mock(IConfig::class);
+               $config = Mockery::mock(IManageConfigValues::class);
                $config->shouldReceive('get')->with('config', 'private_addons', false)->andReturn($privAdd)->atMost()->once();
 
                $l10n = Mockery::mock(L10n::class);
                $l10n->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
 
-               $cache = Mockery::mock(ICache::class);
+               $cache = Mockery::mock(ICanCache::class);
                $cache->shouldReceive('get')->with('routerDispatchData')->andReturn('')->atMost()->once();
                $cache->shouldReceive('get')->with('lastRoutesFileModifiedTime')->andReturn('')->atMost()->once();
                $cache->shouldReceive('set')->withAnyArgs()->andReturn(false)->atMost()->twice();
 
-               $lock = Mockery::mock(ILock::class);
+               $lock = Mockery::mock(ICanLock::class);
                $lock->shouldReceive('acquire')->andReturn(true);
                $lock->shouldReceive('isLocked')->andReturn(false);
 
index 3a3c0469b4f810a59cb03ec754aefa864ba48d02..1e9e5d5eef83fb0d43684680c65e8cb688e9c518 100644 (file)
@@ -22,9 +22,9 @@
 namespace Friendica\Test\src\App;
 
 use Friendica\App\Router;
-use Friendica\Core\Cache\ICache;
+use Friendica\Core\Cache\Capability\ICanCache;
 use Friendica\Core\L10n;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Friendica\Module;
 use Friendica\Network\HTTPException\MethodNotAllowedException;
 use Friendica\Network\HTTPException\NotFoundException;
@@ -37,11 +37,11 @@ class RouterTest extends TestCase
        /** @var L10n|MockInterface */
        private $l10n;
        /**
-        * @var ICache
+        * @var ICanCache
         */
        private $cache;
        /**
-        * @var ILock
+        * @var \Friendica\Core\Lock\Capability\ICanLock
         */
        private $lock;
 
@@ -52,11 +52,11 @@ class RouterTest extends TestCase
                $this->l10n = Mockery::mock(L10n::class);
                $this->l10n->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
 
-               $this->cache = Mockery::mock(ICache::class);
+               $this->cache = Mockery::mock(ICanCache::class);
                $this->cache->shouldReceive('get')->andReturn(null);
                $this->cache->shouldReceive('set')->andReturn(false);
 
-               $this->lock = Mockery::mock(ILock::class);
+               $this->lock = Mockery::mock(ICanLock::class);
                $this->lock->shouldReceive('acquire')->andReturn(true);
                $this->lock->shouldReceive('isLocked')->andReturn(false);
        }
index f11d38365887dd195c6ddc70aa6d4c17e4cc8979..760a732d670fe96fc60553fdb1593332d2a45722 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Console;
 use Dice\Dice;
 use Friendica\App;
 use Friendica\Console\AutomaticInstallation;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\Core\Installer;
 use Friendica\Core\L10n;
 use Friendica\Core\Logger;
@@ -53,7 +53,7 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
        private $assertFileDb;
 
        /**
-        * @var \Friendica\Core\Config\Cache\Cache The configuration cache to check after each test
+        * @var \Friendica\Core\Config\ValueObject\Cache The configuration cache to check after each test
         */
        private $configCache;
 
index bea4399b3ac333c47ba93d49209ec2d7ac07989c..36d8e8846c8c9da8de9acbf61209329611c8ed2a 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Console;
 use Friendica\App;
 use Friendica\App\Mode;
 use Friendica\Console\Config;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Mockery;
 use Mockery\LegacyMockInterface;
 use Mockery\MockInterface;
@@ -35,7 +35,7 @@ class ConfigConsoleTest extends ConsoleTest
         * @var App\Mode|MockInterface $appMode
         */
        private $appMode;
-       /** @var IConfig|LegacyMockInterface|MockInterface */
+       /** @var IManageConfigValues|LegacyMockInterface|MockInterface */
        private $configMock;
 
        protected function setUp() : void
@@ -52,7 +52,7 @@ class ConfigConsoleTest extends ConsoleTest
                $this->appMode->shouldReceive('has')
                                          ->andReturn(true);
 
-               $this->configMock = Mockery::mock(IConfig::class);
+               $this->configMock = Mockery::mock(IManageConfigValues::class);
        }
 
        public function testSetGetKeyValue()
index 1f33be100e031e7876b111a3bef65a84fd5f81c9..b8bbfc0b075eb7f6f0edb507e62a3c8395718d2e 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Console;
 use Friendica\App;
 use Friendica\App\Mode;
 use Friendica\Console\Lock;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Mockery;
 use Mockery\MockInterface;
 
@@ -36,7 +36,7 @@ class LockConsoleTest extends ConsoleTest
        private $appMode;
 
        /**
-        * @var ILock|MockInterface
+        * @var ICanLock|MockInterface
         */
        private $lockMock;
 
@@ -54,7 +54,7 @@ class LockConsoleTest extends ConsoleTest
                $this->appMode->shouldReceive('has')
                        ->andReturn(true);
 
-               $this->lockMock = Mockery::mock(ILock::class);
+               $this->lockMock = Mockery::mock(ICanLock::class);
        }
 
        public function testList()
index e19ebf9cbca218ec8fb0ca33423f8a1012c2b9d0..c060a889ec0d18eeb52d10ab820c6cfec844f7bf 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Console;
 
 use Friendica\Console\ServerBlock;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Mockery;
 
 class ServerBlockConsoleTest extends ConsoleTest
@@ -38,7 +38,7 @@ class ServerBlockConsoleTest extends ConsoleTest
                ]
        ];
        /**
-        * @var IConfig|Mockery\LegacyMockInterface|Mockery\MockInterface
+        * @var IManageConfigValues|Mockery\LegacyMockInterface|Mockery\MockInterface
         */
        private $configMock;
 
@@ -46,7 +46,7 @@ class ServerBlockConsoleTest extends ConsoleTest
        {
                parent::setUp();
 
-               $this->configMock = Mockery::mock(IConfig::class);
+               $this->configMock = Mockery::mock(IManageConfigValues::class);
        }
 
        /**
index 5e5d1c17d5bb3e04818a459f535c073134b40df6..b57aab391406a46586669b8d3132fef2f4283aaf 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Test\src\Core\Cache;
 
-use Friendica\Core\Cache\ICache;
-use Friendica\Core\Cache\IMemoryCache;
+use Friendica\Core\Cache\Capability\ICanCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 use Friendica\Test\MockedTest;
 use Friendica\Util\PidFile;
 
@@ -34,12 +34,12 @@ abstract class CacheTest extends MockedTest
        protected $startTime = 1417011228;
 
        /**
-        * @var ICache
+        * @var ICanCache
         */
        protected $instance;
 
        /**
-        * @var IMemoryCache
+        * @var \Friendica\Core\Cache\Capability\ICanCacheInMemory
         */
        protected $cache;
 
index 55011f87cfea2e686cbf4dca1b700b9b6e28616a..a1cc42840c2b5a4cfff156577b2025ecbaf418fb 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Core\Cache;
 
 use Friendica\Core\Cache;
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
@@ -53,8 +53,8 @@ class DatabaseCacheTest extends CacheTest
                $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
 
                // load real config to avoid mocking every config-entry which is related to the Database class
-               $configFactory = new ConfigFactory();
-               $loader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
+               $configFactory = new Config();
+               $loader = (new Config())->createConfigFileLoader($this->root->url(), []);
                $configCache = $configFactory->createCache($loader);
 
                $dba = new StaticDatabase($configCache, $profiler, $logger);
index 6916f51695e29194404d3fd322f2cc508d14ef4c..8b50a999dd590f5cccc25540a1882e308ed185d0 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Cache;
 
 use Exception;
 use Friendica\Core\Cache\Type\MemcacheCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Mockery;
 
 /**
@@ -34,7 +34,7 @@ class MemcacheCacheTest extends MemoryCacheTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['MEMCACHE_HOST'] ?? 'localhost';
                $port = $_SERVER['MEMCACHE_PORT'] ?? '11211';
index cc912e364d09e8d73cc1fc143d64b7699f2c4579..831458c3365062db382c5cd2c8a8d44a965c7bd1 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Cache;
 
 use Exception;
 use Friendica\Core\Cache\Type\MemcachedCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Mockery;
 use Psr\Log\NullLogger;
 
@@ -35,7 +35,7 @@ class MemcachedCacheTest extends MemoryCacheTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['MEMCACHED_HOST'] ?? 'localhost';
                $port = $_SERVER['MEMCACHED_PORT'] ?? '11211';
index eca25fa69404c86027f0db884670b1f297a21741..5159cb458436d1db27bdd5e76e1d0a7b043ee2d4 100644 (file)
 namespace Friendica\Test\src\Core\Cache;
 
 use Exception;
-use Friendica\Core\Cache\IMemoryCache;
+use Friendica\Core\Cache\Capability\ICanCacheInMemory;
 
 abstract class MemoryCacheTest extends CacheTest
 {
        /**
-        * @var IMemoryCache
+        * @var \Friendica\Core\Cache\Capability\ICanCacheInMemory
         */
        protected $instance;
 
@@ -35,7 +35,7 @@ abstract class MemoryCacheTest extends CacheTest
        {
                parent::setUp();
 
-               if (!($this->instance instanceof IMemoryCache)) {
+               if (!($this->instance instanceof ICanCacheInMemory)) {
                        throw new Exception('MemoryCacheTest unsupported');
                }
        }
index f5c540d32d79941f6a9803a43e8381967a3170ba..9a859cd10b5652ec6982c7e82e9e108704542f21 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Cache;
 
 use Exception;
 use Friendica\Core\Cache\Type\RedisCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Mockery;
 
 /**
@@ -34,7 +34,7 @@ class RedisCacheTest extends MemoryCacheTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['REDIS_HOST'] ?? 'localhost';
                $port = $_SERVER['REDIS_PORT'] ?? 6379;
index 530b5b4826df35091e2e14f4dc4a0afd6cc593ec..b369127c095561bdc934ef37667353849471924f 100644 (file)
@@ -49,7 +49,7 @@ class CacheTest extends MockedTest
                ];
        }
 
-       private function assertConfigValues($data, Cache\Cache $configCache)
+       private function assertConfigValues($data, \Friendica\Core\Config\ValueObject\Cache $configCache)
        {
                foreach ($data as $cat => $values) {
                        foreach ($values as $key => $value) {
@@ -64,7 +64,7 @@ class CacheTest extends MockedTest
         */
        public function testLoadConfigArray($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
                $configCache->load($data);
 
                self::assertConfigValues($data, $configCache);
@@ -83,27 +83,27 @@ class CacheTest extends MockedTest
                        ]
                ];
 
-               $configCache = new Cache\Cache();
-               $configCache->load($data, Cache\Cache::SOURCE_DB);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
+               $configCache->load($data, \Friendica\Core\Config\ValueObject\Cache::SOURCE_DB);
                // doesn't override - Low Priority due Config file
-               $configCache->load($override, Cache\Cache::SOURCE_FILE);
+               $configCache->load($override, \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE);
 
                self::assertConfigValues($data, $configCache);
 
                // override the value - High Prio due Server Env
-               $configCache->load($override, Cache\Cache::SOURCE_ENV);
+               $configCache->load($override, \Friendica\Core\Config\ValueObject\Cache::SOURCE_ENV);
 
                self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
                self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
 
                // Don't overwrite server ENV variables - even in load mode
-               $configCache->load($data, Cache\Cache::SOURCE_DB);
+               $configCache->load($data, \Friendica\Core\Config\ValueObject\Cache::SOURCE_DB);
 
                self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
                self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
 
                // Overwrite ENV variables with ENV variables
-               $configCache->load($data, Cache\Cache::SOURCE_ENV);
+               $configCache->load($data, \Friendica\Core\Config\ValueObject\Cache::SOURCE_ENV);
 
                self::assertConfigValues($data, $configCache);
                self::assertNotEquals($override['system']['test'], $configCache->get('system', 'test'));
@@ -115,7 +115,7 @@ class CacheTest extends MockedTest
         */
        public function testLoadConfigArrayWrong()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                // empty dataset
                $configCache->load([]);
@@ -136,7 +136,7 @@ class CacheTest extends MockedTest
         */
        public function testGetAll($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
                $configCache->load($data);
 
                $all = $configCache->getAll();
@@ -151,7 +151,7 @@ class CacheTest extends MockedTest
         */
        public function testSetGet($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                foreach ($data as $cat => $values) {
                        foreach ($values as $key => $value) {
@@ -167,7 +167,7 @@ class CacheTest extends MockedTest
         */
        public function testGetEmpty()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                self::assertNull($configCache->get('something', 'value'));
        }
@@ -177,7 +177,7 @@ class CacheTest extends MockedTest
         */
        public function testGetCat()
        {
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'system' => [
                                'key1' => 'value1',
                                'key2' => 'value2',
@@ -205,7 +205,7 @@ class CacheTest extends MockedTest
         */
        public function testDelete($data)
        {
-               $configCache = new Cache\Cache($data);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache($data);
 
                foreach ($data as $cat => $values) {
                        foreach ($values as $key => $value) {
@@ -222,7 +222,7 @@ class CacheTest extends MockedTest
         */
        public function testKeyDiffWithResult($data)
        {
-               $configCache = new Cache\Cache($data);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache($data);
 
                $diffConfig = [
                        'fakeCat' => [
@@ -239,7 +239,7 @@ class CacheTest extends MockedTest
         */
        public function testKeyDiffWithoutResult($data)
        {
-               $configCache = new Cache\Cache($data);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache($data);
 
                $diffConfig = $configCache->getAll();
 
@@ -251,7 +251,7 @@ class CacheTest extends MockedTest
         */
        public function testPasswordHide()
        {
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'database' => [
                                'password' => 'supersecure',
                                'username' => 'notsecured',
@@ -268,7 +268,7 @@ class CacheTest extends MockedTest
         */
        public function testPasswordShow()
        {
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'database' => [
                                'password' => 'supersecure',
                                'username' => 'notsecured',
@@ -285,7 +285,7 @@ class CacheTest extends MockedTest
         */
        public function testEmptyPassword()
        {
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'database' => [
                                'password' => '',
                                'username' => '',
@@ -299,7 +299,7 @@ class CacheTest extends MockedTest
 
        public function testWrongTypePassword()
        {
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'database' => [
                                'password' => new stdClass(),
                                'username' => '',
@@ -309,7 +309,7 @@ class CacheTest extends MockedTest
                self::assertNotEmpty($configCache->get('database', 'password'));
                self::assertEmpty($configCache->get('database', 'username'));
 
-               $configCache = new Cache\Cache([
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache([
                        'database' => [
                                'password' => 23,
                                'username' => '',
@@ -327,19 +327,19 @@ class CacheTest extends MockedTest
        public function testSetOverrides($data)
        {
 
-               $configCache = new Cache\Cache();
-               $configCache->load($data, Cache\Cache::SOURCE_DB);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
+               $configCache->load($data, \Friendica\Core\Config\ValueObject\Cache::SOURCE_DB);
 
                // test with wrong override
-               self::assertFalse($configCache->set('system', 'test', '1234567', Cache\Cache::SOURCE_FILE));
+               self::assertFalse($configCache->set('system', 'test', '1234567', \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE));
                self::assertEquals($data['system']['test'], $configCache->get('system', 'test'));
 
                // test with override (equal)
-               self::assertTrue($configCache->set('system', 'test', '8910', Cache\Cache::SOURCE_DB));
+               self::assertTrue($configCache->set('system', 'test', '8910', \Friendica\Core\Config\ValueObject\Cache::SOURCE_DB));
                self::assertEquals('8910', $configCache->get('system', 'test'));
 
                // test with override (over)
-               self::assertTrue($configCache->set('system', 'test', '111213', Cache\Cache::SOURCE_ENV));
+               self::assertTrue($configCache->set('system', 'test', '111213', \Friendica\Core\Config\ValueObject\Cache::SOURCE_ENV));
                self::assertEquals('111213', $configCache->get('system', 'test'));
        }
 }
index ed5cfa1ef687302b12a83131c46b68dbb63d42f9..dcb5b88de543f8203694ae3f46824d16039dea4b 100644 (file)
 namespace Friendica\Test\src\Core\Config\Cache;
 
 use Friendica\Core\Config\Cache;
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Core\Config\Cache\ConfigFileLoader;
+use Friendica\Core\Config\Util\ConfigFileLoader;
 use org\bovigo\vfs\vfsStream;
 
 class ConfigFileLoaderTest extends MockedTest
@@ -48,10 +48,10 @@ class ConfigFileLoaderTest extends MockedTest
 
                $configFileLoader = new ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -74,10 +74,10 @@ class ConfigFileLoaderTest extends MockedTest
 
                $configFileLoader = new ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
        }
@@ -103,10 +103,10 @@ class ConfigFileLoaderTest extends MockedTest
 
                $configFileLoader = new ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -140,10 +140,10 @@ class ConfigFileLoaderTest extends MockedTest
 
                $configFileLoader = new ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -174,12 +174,12 @@ class ConfigFileLoaderTest extends MockedTest
                        ->at($this->root)
                        ->setContent(file_get_contents($file));
 
-               $configFileLoader = new ConfigFileLoader(
+               $configFileLoader = new \Friendica\Core\Config\Util\ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -228,10 +228,10 @@ class ConfigFileLoaderTest extends MockedTest
                        ->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
                        ->setContent(file_get_contents($file));
 
-               $configFileLoader = new ConfigFileLoader(
+               $configFileLoader = new \Friendica\Core\Config\Util\ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
 
                $conf = $configFileLoader->loadAddonConfig('test');
@@ -265,12 +265,12 @@ class ConfigFileLoaderTest extends MockedTest
                                ->at($this->root->getChild('config'))
                         ->setContent(file_get_contents($fileDir . 'B.config.php'));
 
-               $configFileLoader = new ConfigFileLoader(
+               $configFileLoader = new \Friendica\Core\Config\Util\ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -299,12 +299,12 @@ class ConfigFileLoaderTest extends MockedTest
                         ->at($this->root->getChild('config'))
                         ->setContent(file_get_contents($fileDir . 'B.ini.php'));
 
-               $configFileLoader = new ConfigFileLoader(
+               $configFileLoader = new \Friendica\Core\Config\Util\ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -333,12 +333,12 @@ class ConfigFileLoaderTest extends MockedTest
                         ->at($this->root->getChild('config'))
                         ->setContent(file_get_contents($fileDir . 'B.ini.php'));
 
-               $configFileLoader = new ConfigFileLoader(
+               $configFileLoader = new \Friendica\Core\Config\Util\ConfigFileLoader(
                        $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
                );
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -353,8 +353,8 @@ class ConfigFileLoaderTest extends MockedTest
        {
                $this->delConfigFile('local.config.php');
 
-               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
-               $configCache = new Cache\Cache();
+               $configFileLoader = (new Config())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
@@ -379,8 +379,8 @@ class ConfigFileLoaderTest extends MockedTest
                                 ->at($this->root->getChild('config2'))
                                 ->setContent(file_get_contents($fileDir . 'B.config.php'));
 
-               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
-               $configCache = new Cache\Cache();
+               $configFileLoader = (new Config())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
+               $configCache = new \Friendica\Core\Config\ValueObject\Cache();
 
                $configFileLoader->setupCache($configCache);
 
index e7708598758ec0d55d113e3beaae1b96df420054..0c9788c9c3ab6c1953d6c84b6a7631883e3810ae 100644 (file)
@@ -22,8 +22,8 @@
 namespace Friendica\Test\src\Core\Config;
 
 use Friendica\Core\Config\Cache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Config\Model\Config as ConfigModel;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Config\Repository\Config as ConfigModel;
 use Friendica\Test\MockedTest;
 use Mockery\MockInterface;
 use Mockery;
@@ -33,10 +33,10 @@ abstract class ConfigTest extends MockedTest
        /** @var ConfigModel|MockInterface */
        protected $configModel;
 
-       /** @var Cache\Cache */
+       /** @var \Friendica\Core\Config\ValueObject\Cache */
        protected $configCache;
 
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        protected $testedConfig;
 
        /**
@@ -61,11 +61,11 @@ abstract class ConfigTest extends MockedTest
 
                // Create the config model
                $this->configModel = Mockery::mock(ConfigModel::class);
-               $this->configCache = new Cache\Cache();
+               $this->configCache = new \Friendica\Core\Config\ValueObject\Cache();
        }
 
        /**
-        * @return IConfig
+        * @return \Friendica\Core\Config\Capability\IManageConfigValues
         */
        abstract public function getInstance();
 
@@ -161,7 +161,7 @@ abstract class ConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // assert config is loaded everytime
                self::assertConfig('config', $data['config']);
@@ -176,7 +176,7 @@ abstract class ConfigTest extends MockedTest
        public function testLoad(array $data, array $load)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                foreach ($load as $loadedCats) {
                        $this->testedConfig->load($loadedCats);
@@ -257,7 +257,7 @@ abstract class ConfigTest extends MockedTest
        public function testCacheLoadDouble(array $data1, array $data2, array $expect = [])
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                foreach ($data1 as $cat => $data) {
                        $this->testedConfig->load($cat);
@@ -282,7 +282,7 @@ abstract class ConfigTest extends MockedTest
                $this->configModel->shouldReceive('load')->withAnyArgs()->andReturn([])->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertEmpty($this->testedConfig->getCache()->getAll());
        }
@@ -299,7 +299,7 @@ abstract class ConfigTest extends MockedTest
                                  ->times(3);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set('test', 'it', $data));
 
@@ -317,7 +317,7 @@ abstract class ConfigTest extends MockedTest
                $this->configModel->shouldReceive('set')->with('test', 'it', $data)->andReturn(true)->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set('test', 'it', $data));
 
@@ -331,7 +331,7 @@ abstract class ConfigTest extends MockedTest
        public function testGetWrongWithoutDB()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertNull($this->testedConfig->get('test', 'it'));
@@ -353,10 +353,10 @@ abstract class ConfigTest extends MockedTest
         */
        public function testGetWithRefresh($data)
        {
-               $this->configCache->load(['test' => ['it' => 'now']], Cache\Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => 'now']], \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertEquals('now', $this->testedConfig->get('test', 'it'));
@@ -378,10 +378,10 @@ abstract class ConfigTest extends MockedTest
         */
        public function testDeleteWithoutDB($data)
        {
-               $this->configCache->load(['test' => ['it' => $data]], Cache\Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => $data]], \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertEquals($data, $this->testedConfig->get('test', 'it'));
                self::assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
@@ -398,7 +398,7 @@ abstract class ConfigTest extends MockedTest
         */
        public function testDeleteWithDB()
        {
-               $this->configCache->load(['test' => ['it' => 'now', 'quarter' => 'true']], Cache\Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => 'now', 'quarter' => 'true']], \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE);
 
                $this->configModel->shouldReceive('delete')
                                  ->with('test', 'it')
@@ -418,7 +418,7 @@ abstract class ConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // directly set the value to the cache
                $this->testedConfig->getCache()->set('test', 'it', 'now');
@@ -444,9 +444,9 @@ abstract class ConfigTest extends MockedTest
        public function testSetGetHighPrio()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
 
-               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache\Cache::SOURCE_FILE);
+               $this->testedConfig->getCache()->set('config', 'test', 'prio', \Friendica\Core\Config\ValueObject\Cache::SOURCE_FILE);
                self::assertEquals('prio', $this->testedConfig->get('config', 'test'));
 
                // now you have to get the new variable entry because of the new set the get refresh succeed as well
@@ -460,10 +460,10 @@ abstract class ConfigTest extends MockedTest
        public function testSetGetLowPrio()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\Config\ValueObject\Cache::class, $this->testedConfig->getCache());
                self::assertEquals('it', $this->testedConfig->get('config', 'test'));
 
-               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache\Cache::SOURCE_ENV);
+               $this->testedConfig->getCache()->set('config', 'test', 'prio', \Friendica\Core\Config\ValueObject\Cache::SOURCE_ENV);
                // now you have to get the env variable entry as output, even with a new set (which failed) and a get refresh
                self::assertFalse($this->testedConfig->set('config', 'test', '123'));
                self::assertEquals('prio', $this->testedConfig->get('config', 'test', '', true));
index bdb1d53c0b112d500b98feb17a9faf803a4ba698..4742d41d882853a54c95179c021855dfead3ddb5 100644 (file)
@@ -23,7 +23,7 @@
 namespace Friendica\Core;
 
 use Dice\Dice;
-use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\ValueObject\Cache;
 use Friendica\DI;
 use Friendica\Network\IHTTPResult;
 use Friendica\Network\IHTTPClient;
index e08a0d7ca82be623b56b44428f1e8bb296ca27c3..3bf0a96ef3333af83c69058758292733b3c298d4 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Core\Lock;
 
 use Friendica\Core\Lock\Type\DatabaseLock;
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
@@ -55,8 +55,8 @@ class DatabaseLockDriverTest extends LockTest
                $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
 
                // load real config to avoid mocking every config-entry which is related to the Database class
-               $configFactory = new ConfigFactory();
-               $loader        = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
+               $configFactory = new Config();
+               $loader        = (new Config())->createConfigFileLoader($this->root->url(), []);
                $configCache   = $configFactory->createCache($loader);
 
                $dba = new StaticDatabase($configCache, $profiler, $logger);
index 8fc4926b06b08293bd26377c416fb7a149812cb9..d1cca4c36ba070424b217031a6cd21d0b9aae7b6 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Core\Lock;
 
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock\Capability\ICanLock;
 use Friendica\Test\MockedTest;
 
 abstract class LockTest extends MockedTest
@@ -32,7 +32,7 @@ abstract class LockTest extends MockedTest
        protected $startTime = 1417011228;
 
        /**
-        * @var ILock
+        * @var ICanLock
         */
        protected $instance;
 
index a3068b6a53b8c31ffbb4440526f0388c93ab1645..14d18cfe266ebb3d0a1b1496efef02f619b6118c 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Lock;
 
 use Exception;
 use Friendica\Core\Cache\Type\MemcacheCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 
@@ -35,7 +35,7 @@ class MemcacheCacheLockTest extends LockTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['MEMCACHE_HOST'] ?? 'localhost';
                $port = $_SERVER['MEMCACHE_PORT'] ?? '11211';
index 26cc16f22b8601433f79285de7910ddf0afc2ca0..e623a12faf14087a658dcb8c7e76b84e40285800 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Lock;
 
 use Exception;
 use Friendica\Core\Cache\Type\MemcachedCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 use Psr\Log\NullLogger;
@@ -36,7 +36,7 @@ class MemcachedCacheLockTest extends LockTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['MEMCACHED_HOST'] ?? 'localhost';
                $port = $_SERVER['MEMCACHED_PORT'] ?? '11211';
index fba68b197c1cab4409f2ab80b0005e10e693f5fd..179de63a8605f212374d74ca71df331ce52746b4 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Lock;
 
 use Exception;
 use Friendica\Core\Cache\Type\RedisCache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 
@@ -35,7 +35,7 @@ class RedisCacheLockTest extends LockTest
 {
        protected function getInstance()
        {
-               $configMock = Mockery::mock(IConfig::class);
+               $configMock = Mockery::mock(IManageConfigValues::class);
 
                $host = $_SERVER['REDIS_HOST'] ?? 'localhost';
                $port = $_SERVER['REDIS_PORT'] ?? 6379;
index 59b110a333aafe3a8c78f1915ed5c2e2d86d358b..17e83a37d3cf752bd403f8cfa8df4f8eff35c48c 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Lock;
 
 use Dice\Dice;
 use Friendica\App;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Config\Type\JitConfig;
 use Friendica\Core\Lock\Type\SemaphoreLock;
 use Friendica\DI;
@@ -46,7 +46,7 @@ class SemaphoreLockTest extends LockTest
                        ->shouldReceive('get')
                        ->with('system', 'temppath')
                        ->andReturn('/tmp/');
-               $dice->shouldReceive('create')->with(IConfig::class)->andReturn($configMock);
+               $dice->shouldReceive('create')->with(IManageConfigValues::class)->andReturn($configMock);
 
                // @todo Because "get_temppath()" is using static methods, we have to initialize the BaseObject
                DI::init($dice);
index 99e0e914da9b2ce17b68a9909bb048961d23ee97..53a46895da5ff495c2895cc30c21c89b33fb8bfc 100644 (file)
@@ -47,7 +47,7 @@ class CacheTest extends MockedTest
                ];
        }
 
-       private function assertConfigValues($data, Cache\Cache $configCache, $uid)
+       private function assertConfigValues($data, \Friendica\Core\PConfig\ValueObject\Cache $configCache, $uid)
        {
                foreach ($data as $cat => $values) {
                        foreach ($values as $key => $value) {
@@ -63,7 +63,7 @@ class CacheTest extends MockedTest
         */
        public function testSetGet($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
                $uid         = 345;
 
                foreach ($data as $cat => $values) {
@@ -81,7 +81,7 @@ class CacheTest extends MockedTest
         */
        public function testGetCat()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
                $uid         = 345;
 
                $configCache->load($uid, [
@@ -113,7 +113,7 @@ class CacheTest extends MockedTest
         */
        public function testDelete($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
                $uid         = 345;
 
                foreach ($data as $cat => $values) {
@@ -136,7 +136,7 @@ class CacheTest extends MockedTest
         */
        public function testKeyDiffWithResult()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $diffConfig = [
                        'fakeCat' => [
@@ -154,7 +154,7 @@ class CacheTest extends MockedTest
         */
        public function testKeyDiffWithoutResult($data)
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, $data);
 
@@ -168,7 +168,7 @@ class CacheTest extends MockedTest
         */
        public function testPasswordHide()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, [
                        'database' => [
@@ -187,7 +187,7 @@ class CacheTest extends MockedTest
         */
        public function testPasswordShow()
        {
-               $configCache = new Cache\Cache(false);
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache(false);
 
                $configCache->load(1, [
                        'database' => [
@@ -206,7 +206,7 @@ class CacheTest extends MockedTest
         */
        public function testEmptyPassword()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, [
                        'database' => [
@@ -221,7 +221,7 @@ class CacheTest extends MockedTest
 
        public function testWrongTypePassword()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, [
                        'database' => [
@@ -233,7 +233,7 @@ class CacheTest extends MockedTest
                self::assertNotEmpty($configCache->get(1, 'database', 'password'));
                self::assertEmpty($configCache->get(1, 'database', 'username'));
 
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, [
                        'database' => [
@@ -251,7 +251,7 @@ class CacheTest extends MockedTest
         */
        public function testTwoUid()
        {
-               $configCache = new Cache\Cache();
+               $configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
 
                $configCache->load(1, [
                        'cat1' => [
@@ -272,21 +272,4 @@ class CacheTest extends MockedTest
                self::assertNull($configCache->get(1, 'cat2', 'key2'));
                self::assertNull($configCache->get(2, 'cat1', 'key1'));
        }
-
-       /**
-        * Test when using an invalid UID
-        * @todo check it the clean way before using the config class
-        */
-       public function testInvalidUid()
-       {
-               // bad UID!
-               $uid = null;
-
-               $configCache = new Cache\Cache();
-
-               self::assertNull($configCache->get($uid, 'cat1', 'cat2'));
-
-               self::assertFalse($configCache->set($uid, 'cat1', 'key1', 'doesn\'t matter!'));
-               self::assertFalse($configCache->delete($uid, 'cat1', 'key1'));
-       }
 }
index 9288b10585a0c20ecb82c40895105dbdd5fe021d..1f0e89364ebcf83e3208d05632e216b5f3d2bd6b 100644 (file)
@@ -22,8 +22,8 @@
 namespace Friendica\Test\src\Core\PConfig;
 
 use Friendica\Core\PConfig\Cache;
-use Friendica\Core\PConfig\Type\BasePConfig;
-use Friendica\Core\PConfig\Model\PConfig as PConfigModel;
+use Friendica\Core\PConfig\Type\AbstractPConfigValues;
+use Friendica\Core\PConfig\Repository\PConfig as PConfigModel;
 use Friendica\Test\MockedTest;
 use Mockery;
 use Mockery\MockInterface;
@@ -33,10 +33,10 @@ abstract class PConfigTest extends MockedTest
        /** @var PConfigModel|MockInterface */
        protected $configModel;
 
-       /** @var Cache\Cache */
+       /** @var \Friendica\Core\PConfig\ValueObject\Cache */
        protected $configCache;
 
-       /** @var BasePConfig */
+       /** @var AbstractPConfigValues */
        protected $testedConfig;
 
        /**
@@ -63,11 +63,11 @@ abstract class PConfigTest extends MockedTest
 
                // Create the config model
                $this->configModel = Mockery::mock(PConfigModel::class);
-               $this->configCache = new Cache\Cache();
+               $this->configCache = new \Friendica\Core\PConfig\ValueObject\Cache();
        }
 
        /**
-        * @return \Friendica\Core\PConfig\Type\BasePConfig
+        * @return \Friendica\Core\PConfig\Type\AbstractPConfigValues
         */
        abstract public function getInstance();
 
@@ -163,7 +163,7 @@ abstract class PConfigTest extends MockedTest
        public function testSetUp()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertEmpty($this->testedConfig->getCache()->getAll());
        }
@@ -174,7 +174,7 @@ abstract class PConfigTest extends MockedTest
        public function testLoad(int $uid, array $data, array $possibleCats, array $load)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                foreach ($load as $loadedCats) {
                        $this->testedConfig->load($uid, $loadedCats);
@@ -257,7 +257,7 @@ abstract class PConfigTest extends MockedTest
        public function testCacheLoadDouble(int $uid, array $data1, array $data2, array $expect)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                foreach ($data1 as $cat => $data) {
                        $this->testedConfig->load($uid, $cat);
@@ -281,7 +281,7 @@ abstract class PConfigTest extends MockedTest
        public function testSetGetWithoutDB(int $uid, $data)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
 
@@ -302,7 +302,7 @@ abstract class PConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
 
@@ -316,7 +316,7 @@ abstract class PConfigTest extends MockedTest
        public function testGetWrongWithoutDB()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertNull($this->testedConfig->get(0, 'test', 'it'));
@@ -341,7 +341,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($uid, ['test' => ['it' => 'now']]);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertEquals('now', $this->testedConfig->get($uid, 'test', 'it'));
@@ -366,7 +366,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($uid, ['test' => ['it' => $data]]);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it'));
                self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
@@ -405,7 +405,7 @@ abstract class PConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                // directly set the value to the cache
                $this->testedConfig->getCache()->set($uid, 'test', 'it', 'now');
@@ -465,7 +465,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($data2['uid'], $data2['data']);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(\Friendica\Core\PConfig\ValueObject\Cache::class, $this->testedConfig->getCache());
 
                self::assertConfig($data1['uid'], 'cat1', $data1['data']['cat1']);
                self::assertConfig($data1['uid'], 'cat2', $data1['data']['cat2']);
index b7e5715edc0f0e3d9588c7916bbef8045d4d6fea..f9d05e6374869d6bce65cd4bc392e5dbfbebfda3 100644 (file)
 namespace Friendica\Test\src\Core;
 
 use Dice\Dice;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\Config\Type\PreloadConfig;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
-use Friendica\Core\Session\ISession;
+use Friendica\Core\Session\Capability\IHandleSessions;
+use Friendica\Core\Session\Type\Memory;
 use Friendica\Core\StorageManager;
 use Friendica\Database\Database;
 use Friendica\DI;
-use Friendica\Core\Config\Factory\ConfigFactory;
-use Friendica\Core\Config\Model\Config;
+use Friendica\Core\Config\Factory\Config;
+use Friendica\Core\Config\Repository;
 use Friendica\Model\Storage;
-use Friendica\Core\Session;
 use Friendica\Network\HTTPClient;
 use Friendica\Test\DatabaseTest;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Core\Config\Cache\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use org\bovigo\vfs\vfsStream;
 use Psr\Log\LoggerInterface;
@@ -50,7 +49,7 @@ class StorageManagerTest extends DatabaseTest
        use VFSTrait;
        /** @var Database */
        private $dba;
-       /** @var IConfig */
+       /** @var IManageConfigValues */
        private $config;
        /** @var LoggerInterface */
        private $logger;
@@ -75,13 +74,13 @@ class StorageManagerTest extends DatabaseTest
                $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
 
                // load real config to avoid mocking every config-entry which is related to the Database class
-               $configFactory = new ConfigFactory();
+               $configFactory = new Config();
                $loader        = $configFactory->createConfigFileLoader($this->root->url(), []);
                $configCache   = $configFactory->createCache($loader);
 
                $this->dba = new StaticDatabase($configCache, $profiler, $this->logger);
 
-               $configModel  = new Config($this->dba);
+               $configModel  = new Repository\Config($this->dba);
                $this->config = new PreloadConfig($configCache, $configModel);
                $this->config->set('storage', 'name', 'Database');
                $this->config->set('storage', 'filesystem_path', $this->root->getChild(Storage\FilesystemConfig::DEFAULT_BASE_FOLDER)->url());
@@ -253,7 +252,7 @@ class StorageManagerTest extends DatabaseTest
                $dice = (new Dice())
                        ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
                        ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
-                       ->addRule(ISession::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]);
+                       ->addRule(IHandleSessions::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]);
                DI::init($dice);
 
                $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
@@ -281,7 +280,7 @@ class StorageManagerTest extends DatabaseTest
                $dice = (new Dice())
                        ->addRules(include __DIR__ . '/../../../static/dependencies.config.php')
                        ->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
-                       ->addRule(ISession::class, ['instanceOf' => Session\Type\Memory::class, 'shared' => true, 'call' => null]);
+                       ->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null]);
                DI::init($dice);
 
                $storageManager = new StorageManager($this->dba, $this->config, $this->logger, $this->l10n);
index ecb4d52d490d4d9f052ff09deaf5d3ec3bdd3d7a..d3ef38df934105d0b46cf5fa99f21ac59614e28a 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace Friendica\Test\src\Model;
 
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Model\Process;
 use Friendica\Test\DatabaseTest;
 use Friendica\Test\Util\Database\StaticDatabase;
@@ -31,8 +31,8 @@ class ProcessTest extends DatabaseTest
                $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
 
                // load real config to avoid mocking every config-entry which is related to the Database class
-               $configFactory = new ConfigFactory();
-               $loader        = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
+               $configFactory = new Config();
+               $loader        = (new Config())->createConfigFileLoader($this->root->url(), []);
                $configCache   = $configFactory->createCache($loader);
 
                $this->dba = new StaticDatabase($configCache, $profiler, $logger);
index e92dd213521d7d6b5fd64cce716b3eb334159419..796b8937c046ff209b845257c23bdf2ed7a980f8 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Model\Storage;
 
-use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\Config;
 use Friendica\Model\Storage\Database;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
@@ -52,8 +52,8 @@ class DatabaseStorageTest extends StorageTest
                $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
 
                // load real config to avoid mocking every config-entry which is related to the Database class
-               $configFactory = new ConfigFactory();
-               $loader        = (new ConfigFactory())->createConfigFileLoader($this->root->url(), []);
+               $configFactory = new Config();
+               $loader        = (new Config())->createConfigFileLoader($this->root->url(), []);
                $configCache   = $configFactory->createCache($loader);
 
                $dba = new StaticDatabase($configCache, $profiler, $logger);
index 5821309386cc87dcf6c5e7b64b6042270f540f39..a5989b1cd626454ba995b7cc3baa5d6e8064a3c6 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Model\Storage;
 
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Model\Storage\FilesystemConfig;
 use Friendica\Model\Storage\IStorageConfiguration;
@@ -46,7 +46,7 @@ class FilesystemStorageConfigTest extends StorageConfigTest
        {
                /** @var MockInterface|L10n $l10n */
                $l10n   = \Mockery::mock(L10n::class)->makePartial();
-               $config = \Mockery::mock(IConfig::class);
+               $config = \Mockery::mock(IManageConfigValues::class);
                $config->shouldReceive('get')
                                         ->with('storage', 'filesystem_path', FilesystemConfig::DEFAULT_BASE_FOLDER)
                                         ->andReturn($this->root->getChild('storage')->url());
index c9656b84f87828fcf710a2eddfefec016ae423cf..b833ef558b4189158c8ba13ebe65bd85a1ef6cc5 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Model\User;
 
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Model\User\Cookie;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\StaticCookie;
@@ -30,7 +30,7 @@ use Mockery\MockInterface;
 
 class CookieTest extends MockedTest
 {
-       /** @var MockInterface|IConfig */
+       /** @var MockInterface|\Friendica\Core\Config\Capability\IManageConfigValues */
        private $config;
        /** @var MockInterface|BaseURL */
        private $baseUrl;
@@ -41,7 +41,7 @@ class CookieTest extends MockedTest
 
                parent::setUp();
 
-               $this->config = \Mockery::mock(IConfig::class);
+               $this->config = \Mockery::mock(IManageConfigValues::class);
                $this->baseUrl = \Mockery::mock(BaseURL::class);
        }
 
index 79f0637e3f179a11882a02ab8fa73592759581bd..4c15f440dc452b23457ad70090b950b71425c455 100644 (file)
@@ -2,7 +2,7 @@
 namespace Friendica\Test\src\Util;
 
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Test\MockedTest;
 
 class BaseURLTest extends MockedTest
@@ -173,7 +173,7 @@ class BaseURLTest extends MockedTest
         */
        public function testCheck($server, $input, $assert)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
@@ -295,7 +295,7 @@ class BaseURLTest extends MockedTest
         */
        public function testSave($input, $save, $url)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
@@ -333,7 +333,7 @@ class BaseURLTest extends MockedTest
         */
        public function testSaveByUrl($input, $save, $url)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
@@ -409,7 +409,7 @@ class BaseURLTest extends MockedTest
         */
        public function testGetURL($sslPolicy, $ssl, $url, $assert)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
@@ -467,7 +467,7 @@ class BaseURLTest extends MockedTest
         */
        public function testCheckRedirectHTTPS($server, $forceSSL, $sslPolicy, $url, $redirect)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
@@ -503,7 +503,7 @@ class BaseURLTest extends MockedTest
         */
        public function testWrongSave($fail)
        {
-               $configMock = \Mockery::mock(IConfig::class);
+               $configMock = \Mockery::mock(IManageConfigValues::class);
                $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
                $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
                $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn(BaseURL::DEFAULT_SSL_SCHEME);
index 7f96e010a5b0e65482550dceebae7fd0d56fba2d..21a0ffa2dec766afb620bfb86344191eaf14cd37 100644 (file)
@@ -3,9 +3,9 @@
 namespace Friendica\Test\src\Util;
 
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
-use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
 use Friendica\Object\EMail\IEmail;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\EmailerSpy;
@@ -26,9 +26,9 @@ class EMailerTest extends MockedTest
        use VFSTrait;
        use HookMockTrait;
 
-       /** @var IConfig|MockInterface */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues|MockInterface */
        private $config;
-       /** @var IPConfig|MockInterface */
+       /** @var \Friendica\Core\PConfig\Capability\IManagePersonalConfigValues|MockInterface */
        private $pConfig;
        /** @var L10n|MockInterface */
        private $l10n;
@@ -41,12 +41,12 @@ class EMailerTest extends MockedTest
 
                $this->setUpVfsDir();
 
-               $this->config  = \Mockery::mock(IConfig::class);
+               $this->config  = \Mockery::mock(IManageConfigValues::class);
                $this->config->shouldReceive('get')->withArgs(['config', 'sender_email'])->andReturn('test@friendica.local')->once();
                $this->config->shouldReceive('get')->withArgs(['config', 'sitename', 'Friendica Social Network'])->andReturn('Friendica Social Network')->once();
                $this->config->shouldReceive('get')->withArgs(['system', 'sendmail_params', true])->andReturn(true);
 
-               $this->pConfig = \Mockery::mock(IPConfig::class);
+               $this->pConfig = \Mockery::mock(IManagePersonalConfigValues::class);
                $this->l10n    = \Mockery::mock(L10n::class);
                $this->baseUrl = \Mockery::mock(BaseURL::class);
                $this->baseUrl->shouldReceive('getHostname')->andReturn('friendica.local');
index 88452a9dab3cb2a4108c25d575f546b03afc306d..83c22d7ec6b9b776afd5f4d3401ab54e2440f5c9 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Util\Emailer;
 
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Object\EMail\IEmail;
@@ -41,7 +41,7 @@ class MailBuilderTest extends MockedTest
 {
        use VFSTrait;
 
-       /** @var IConfig|MockInterface */
+       /** @var IManageConfigValues|MockInterface */
        private $config;
        /** @var L10n|MockInterface */
        private $l10n;
@@ -57,7 +57,7 @@ class MailBuilderTest extends MockedTest
 
                $this->setUpVfsDir();
 
-               $this->config  = \Mockery::mock(IConfig::class);
+               $this->config  = \Mockery::mock(IManageConfigValues::class);
                $this->l10n    = \Mockery::mock(L10n::class);
                $this->baseUrl = \Mockery::mock(BaseURL::class);
                $this->baseUrl->shouldReceive('getHostname')->andReturn('friendica.local');
index 87b51030f77f45fe387b9149d384c95e30b7c2a0..6cb0708edda04c4b671ca7479f084294e98a0b3e 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Util\Emailer;
 
 use Friendica\App\BaseURL;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Core\L10n;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\VFSTrait;
@@ -34,7 +34,7 @@ class SystemMailBuilderTest extends MockedTest
 {
        use VFSTrait;
 
-       /** @var IConfig */
+       /** @var \Friendica\Core\Config\Capability\IManageConfigValues */
        private $config;
        /** @var L10n */
        private $l10n;
@@ -47,7 +47,7 @@ class SystemMailBuilderTest extends MockedTest
 
                $this->setUpVfsDir();
 
-               $this->config  = \Mockery::mock(IConfig::class);
+               $this->config  = \Mockery::mock(IManageConfigValues::class);
                $this->config->shouldReceive('get')->with('config', 'admin_name')->andReturn('Admin');
                $this->l10n    = \Mockery::mock(L10n::class);
                $this->l10n->shouldReceive('t')->andReturnUsing(function ($msg) {
index 4c55c419b8909484823db69a4b6b00553ade42b3..9a9492d172d755c684074adbccced93390a427c8 100644 (file)
@@ -21,8 +21,8 @@
 
 namespace Friendica\Test\src\Util;
 
-use Friendica\Core\Config\Cache\Cache;
-use Friendica\Core\Config\IConfig;
+use Friendica\Core\Config\ValueObject\Cache;
+use Friendica\Core\Config\Capability\IManageConfigValues;
 use Friendica\Test\MockedTest;
 use Friendica\Util\Profiler;
 use Mockery\MockInterface;
@@ -256,7 +256,7 @@ class ProfilerTest extends MockedTest
 
                $profiler->saveTimestamp(time(), 'network', 'test1');
 
-               $config = \Mockery::mock(IConfig::class);
+               $config = \Mockery::mock(IManageConfigValues::class);
                $config->shouldReceive('get')
                            ->with('system', 'profiler')
                            ->andReturn(false)