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\Core\Hooks\Capabilities\ICanCreateInstances;
use Friendica\Util\Profiler;
-use Psr\Log\LoggerInterface;
/**
* Class CacheFactory
* @var string The default cache if nothing set
*/
const DEFAULT_TYPE = Enum\Type::DATABASE;
+ /** @var ICanCreateInstances */
+ protected $instanceCreator;
+ /** @var IManageConfigValues */
+ protected $config;
+ /** @var Profiler */
+ protected $profiler;
- /**
- * @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)
+ public function __construct(ICanCreateInstances $instanceCreator, IManageConfigValues $config, Profiler $profiler)
{
- $this->hostname = $baseURL->getHost();
- $this->config = $config;
- $this->dba = $dba;
- $this->profiler = $profiler;
- $this->logger = $logger;
+ $this->config = $config;
+ $this->instanceCreator = $instanceCreator;
+ $this->profiler = $profiler;
}
/**
*/
public function createDistributed(string $type = null): ICanCache
{
- if ($type === Enum\Type::APCU) {
+ if ($type === Type\APCuCache::$NAME) {
throw new InvalidCacheDriverException('apcu doesn\'t support distributed caching.');
}
/**
* Creates a new Cache instance
*
- * @param string $type The type of cache
+ * @param string $strategy The strategy, which cache instance should be used
*
* @return ICanCache
*
* @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
*/
- protected function create(string $type): ICanCache
+ protected function create(string $strategy): ICanCache
{
- 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);
- }
+ /** @var ICanCache $cache */
+ $cache = $this->instanceCreator->create(ICanCache::class, $strategy);
$profiling = $this->config->get('system', 'profiling', false);
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
/**
*/
class APCuCache extends AbstractCache implements ICanCacheInMemory
{
+ public static $NAME = 'apcu';
+
use CompareSetTrait;
use CompareDeleteTrait;
/**
- * @param string $hostname
- *
* @throws InvalidCacheDriverException
*/
public function __construct(string $hostname)
return true;
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Type::APCU;
- }
}
*/
abstract class AbstractCache implements ICanCache
{
+ public static $NAME = '';
+
/**
* @var string The hostname
*/
return $result;
}
}
+
+ /** {@inheritDoc} */
+ public function getName(): string
+ {
+ return static::$NAME;
+ }
}
*/
class ArrayCache extends AbstractCache implements ICanCacheInMemory
{
+ public static $NAME = 'array';
+
use CompareDeleteTrait;
/** @var array Array with the cached data */
return false;
}
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Enum\Type::ARRAY;
- }
}
*/
class DatabaseCache extends AbstractCache implements ICanCache
{
+ public static $NAME = 'database';
+
/**
* @var Database
*/
throw new CachePersistenceException('Cannot clear cache', $exception);
}
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Enum\Type::DATABASE;
- }
}
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
use Friendica\Core\Cache\Exception\CachePersistenceException;
use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
use Friendica\Core\Config\Capability\IManageConfigValues;
*/
class MemcacheCache extends AbstractCache implements ICanCacheInMemory
{
+ static $NAME = 'memcached';
+
use CompareSetTrait;
use CompareDeleteTrait;
use MemcacheCommandTrait;
$cacheKey = $this->getCacheKey($key);
return $this->memcache->add($cacheKey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Type::MEMCACHE;
- }
}
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
use Friendica\Core\Cache\Exception\CachePersistenceException;
use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
use Friendica\Core\Config\Capability\IManageConfigValues;
*/
class MemcachedCache extends AbstractCache implements ICanCacheInMemory
{
+ static $NAME = 'memcached';
+
use CompareSetTrait;
use CompareDeleteTrait;
use MemcacheCommandTrait;
$cacheKey = $this->getCacheKey($key);
return $this->memcached->add($cacheKey, $value, $ttl);
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Type::MEMCACHED;
- }
}
namespace Friendica\Core\Cache\Type;
-use Exception;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Cache\Enum\Type;
use Friendica\Core\Cache\Exception\CachePersistenceException;
use Friendica\Core\Cache\Exception\InvalidCacheDriverException;
use Friendica\Core\Config\Capability\IManageConfigValues;
*/
class RedisCache extends AbstractCache implements ICanCacheInMemory
{
+ public static $NAME = 'redis';
+
/**
* @var Redis
*/
$redis_pw = $config->get('system', 'redis_password');
$redis_db = $config->get('system', 'redis_db', 0);
- if (!empty($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) {
- throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
- } elseif (!@$this->redis->connect($redis_host)) {
- throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available');
- }
+ try {
- if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) {
- throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
- }
+ if (!empty($redis_port) && !@$this->redis->connect($redis_host, $redis_port)) {
+ throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
+ } else if (!@$this->redis->connect($redis_host)) {
+ throw new CachePersistenceException('Expected Redis server at ' . $redis_host . ' isn\'t available');
+ }
+
+ if (!empty($redis_pw) && !$this->redis->auth($redis_pw)) {
+ throw new CachePersistenceException('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
+ }
- if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
- throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+ if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
+ throw new CachePersistenceException('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+ }
+ } catch (\RedisException $exception) {
+ throw new CachePersistenceException('Redis connection fails unexpectedly', $exception);
}
}
$this->redis->unwatch();
return false;
}
-
- /**
- * {@inheritDoc}
- */
- public function getName(): string
- {
- return Type::REDIS;
- }
}
$_SERVER,
],
],
+ '$hostname' => [
+ 'instanceOf' => App\BaseURL::class,
+ 'constructParams' => [
+ $_SERVER,
+ ],
+ 'call' => [
+ ['getHost', [], Dice::CHAIN_CALL],
+ ],
+ ],
+ Cache\Type\AbstractCache::class => [
+ 'constructParams' => [
+ [Dice::INSTANCE => '$hostname'],
+ ],
+ ],
App\Page::class => [
'constructParams' => [
[Dice::INSTANCE => '$basepath'],
*
*/
-use Friendica\Core\Hooks\Capabilities\BehavioralHookType as H;
+use Friendica\Core\Cache;
use Friendica\Core\Logger\Type;
use Psr\Log;
Type\SyslogLogger::class => ['syslog'],
Type\StreamLogger::class => ['stream'],
],
+ Cache\Capability\ICanCache::class => [
+ Cache\Type\APCuCache::class => ['apcu'],
+ Cache\Type\DatabaseCache::class => ['database', ''],
+ Cache\Type\MemcacheCache::class => ['memcache'],
+ Cache\Type\MemcachedCache::class => ['memcached'],
+ Cache\Type\RedisCache::class => ['redis'],
+ ]
];
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<phpunit
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ bootstrap="bootstrap.php"
+ verbose="true"
+ timeoutForSmallTests="900"
+ timeoutForMediumTests="900"
+ timeoutForLargeTests="900"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
+ <testsuite name="friendica-addons">
+ <directory suffix=".php">../addon/*/tests/</directory>
+ </testsuite>
+ <!-- Filters for Code Coverage -->
+ <coverage>
+ <include>
+ <directory suffix=".php">../addon/</directory>
+ </include>
+ <exclude>
+ <directory suffix=".php">../addon/*/tests/</directory>
+ <directory suffix=".php">../addon/*/view/</directory>
+ <directory suffix=".php">../addon/*/vendor/</directory>
+ </exclude>
+ </coverage>
+</phpunit>
namespace Friendica\Test\src\Core\Cache;
+use Friendica\App\BaseURL;
use Friendica\Core\Cache;
use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\CreateDatabaseTrait;