Merge remote-tracking branch 'upstream/develop' into error-handling

This commit is contained in:
Michael 2021-10-31 05:25:39 +00:00
commit 516018861e
235 changed files with 10885 additions and 10716 deletions

View file

@ -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\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\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\Type::MEMCACHE:
$cache = new Cache\MemcacheCache($this->hostname, $this->config);
break;
case Cache\Type::MEMCACHED:
$cache = new Cache\MemcachedCache($this->hostname, $this->config, $this->logger);
break;
case Cache\Type::REDIS:
$cache = new Cache\RedisCache($this->hostname, $this->config);
break;
case Cache\Type::APCU:
$cache = new Cache\APCuCache($this->hostname);
break;
default:
$cache = new Cache\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\ProfilerCache($cache, $this->profiler);
} else {
return $cache;
}
}
}

View file

@ -1,122 +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\Factory;
use Exception;
use Friendica\Core\Config;
use Friendica\Core\Config\Cache;
use Friendica\Model\Config\Config as ConfigModel;
use Friendica\Model\Config\PConfig as PConfigModel;
use Friendica\Util\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 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 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 Cache $configCache The config cache of this adapter
* @param ConfigModel $configModel The configuration model
*
* @return Config\IConfig
*/
public function createConfig(Cache $configCache, ConfigModel $configModel)
{
if ($configCache->get('system', 'config_adapter') === 'preload') {
$configuration = new Config\PreloadConfig($configCache, $configModel);
} else {
$configuration = new Config\JitConfig($configCache, $configModel);
}
return $configuration;
}
/**
* @param Cache $configCache The config cache
* @param \Friendica\Core\PConfig\Cache $pConfigCache The personal config cache
* @param PConfigModel $configModel The configuration model
*
* @return \Friendica\Core\PConfig\IPConfig
*/
public function createPConfig(Cache $configCache, \Friendica\Core\PConfig\Cache $pConfigCache, PConfigModel $configModel)
{
if ($configCache->get('system', 'config_adapter') === 'preload') {
$configuration = new \Friendica\Core\PConfig\PreloadPConfig($pConfigCache, $configModel);
} else {
$configuration = new \Friendica\Core\PConfig\JitPConfig($pConfigCache, $configModel);
}
return $configuration;
}
}

View file

@ -1,113 +0,0 @@
<?php
namespace Friendica\Factory;
use Friendica\App;
use Friendica\BaseFactory;
use Friendica\Core\Config\IConfig;
use Friendica\Network\HTTPClient;
use Friendica\Network\IHTTPClient;
use Friendica\Util\Profiler;
use Friendica\Util\Strings;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\RequestOptions;
use mattwright\URLResolver;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface;
require_once __DIR__ . '/../../static/dbstructure.config.php';
class HTTPClientFactory extends BaseFactory
{
/** @var IConfig */
private $config;
/** @var Profiler */
private $profiler;
/** @var App\BaseURL */
private $baseUrl;
public function __construct(LoggerInterface $logger, IConfig $config, Profiler $profiler, App\BaseURL $baseUrl)
{
parent::__construct($logger);
$this->config = $config;
$this->profiler = $profiler;
$this->baseUrl = $baseUrl;
}
/**
* Creates a IHTTPClient for communications with HTTP endpoints
*
* @param HandlerStack|null $handlerStack (optional) A handler replacement (just usefull at test environments)
*
* @return IHTTPClient
*/
public function createClient(HandlerStack $handlerStack = null): IHTTPClient
{
$proxy = $this->config->get('system', 'proxy');
if (!empty($proxy)) {
$proxyuser = $this->config->get('system', 'proxyuser');
if (!empty($proxyuser)) {
$proxy = $proxyuser . '@' . $proxy;
}
}
$logger = $this->logger;
$onRedirect = function (
RequestInterface $request,
ResponseInterface $response,
UriInterface $uri
) use ($logger) {
$logger->notice('Curl redirect.', ['url' => $request->getUri(), 'to' => $uri, 'method' => $request->getMethod()]);
};
$userAgent = FRIENDICA_PLATFORM . " '" .
FRIENDICA_CODENAME . "' " .
FRIENDICA_VERSION . '-' .
DB_UPDATE_VERSION . '; ' .
$this->baseUrl->get();
$guzzle = new Client([
RequestOptions::ALLOW_REDIRECTS => [
'max' => 8,
'on_redirect' => $onRedirect,
'track_redirect' => true,
'strict' => true,
'referer' => true,
],
RequestOptions::HTTP_ERRORS => false,
// Without this setting it seems as if some webservers send compressed content
// This seems to confuse curl so that it shows this uncompressed.
/// @todo We could possibly set this value to "gzip" or something similar
RequestOptions::DECODE_CONTENT => '',
RequestOptions::FORCE_IP_RESOLVE => ($this->config->get('system', 'ipv4_resolve') ? 'v4' : null),
RequestOptions::CONNECT_TIMEOUT => 10,
RequestOptions::TIMEOUT => $this->config->get('system', 'curl_timeout', 60),
// by default we will allow self-signed certs
// but it can be overridden
RequestOptions::VERIFY => (bool)$this->config->get('system', 'verifyssl'),
RequestOptions::PROXY => $proxy,
RequestOptions::HEADERS => [
'User-Agent' => $userAgent,
],
'handler' => $handlerStack ?? HandlerStack::create(),
]);
$resolver = new URLResolver();
$resolver->setUserAgent($userAgent);
$resolver->setMaxRedirects(10);
$resolver->setRequestTimeout(10);
// if the file is too large then exit
$resolver->setMaxResponseDataSize(1000000);
// Designate a temporary file that will store cookies during the session.
// Some websites test the browser for cookie support, so this enhances results.
$resolver->setCookieJar(get_temppath() .'/resolver-cookie-' . Strings::getRandomName(10));
return new HTTPClient($logger, $this->profiler, $guzzle, $resolver);
}
}

View file

@ -1,145 +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\Factory;
use Friendica\Core\Cache\IMemoryCache;
use Friendica\Core\Cache\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\CacheLock($cache);
} else {
throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type));
}
break;
case 'database':
return new Lock\DatabaseLock($this->dba);
break;
case 'semaphore':
return new Lock\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\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\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\DatabaseLock($this->dba);
}
}

View file

@ -1,293 +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\Factory;
use Friendica\Core\Config\IConfig;
use Friendica\Core\Logger;
use Friendica\Database\Database;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Util\FileSystem;
use Friendica\Util\Introspection;
use Friendica\Util\Logger\Monolog\DevelopHandler;
use Friendica\Util\Logger\Monolog\IntrospectionProcessor;
use Friendica\Util\Logger\ProfilerLogger;
use Friendica\Util\Logger\StreamLogger;
use Friendica\Util\Logger\SyslogLogger;
use Friendica\Util\Logger\VoidLogger;
use Friendica\Util\Profiler;
use Monolog;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
/**
* A logger factory
*
* Currently only Monolog is supported
*/
class LoggerFactory
{
const DEV_CHANNEL = 'dev';
/**
* A list of classes, which shouldn't get logged
*
* @var array
*/
private static $ignoreClassList = [
Logger::class,
Profiler::class,
'Friendica\\Util\\Logger',
];
private $channel;
public function __construct(string $channel)
{
$this->channel = $channel;
}
/**
* 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
*
* @return LoggerInterface The PSR-3 compliant logger instance
*/
public function create(Database $database, IConfig $config, Profiler $profiler, FileSystem $fileSystem)
{
if (empty($config->get('system', 'debugging', false))) {
$logger = new VoidLogger();
$database->setLogger($logger);
return $logger;
}
$introspection = new Introspection(self::$ignoreClassList);
$level = $config->get('system', 'loglevel');
$loglevel = self::mapLegacyConfigDebugLevel((string)$level);
switch ($config->get('system', 'logger_config', 'stream')) {
case 'monolog':
$loggerTimeZone = new \DateTimeZone('UTC');
Monolog\Logger::setTimezone($loggerTimeZone);
$logger = new Monolog\Logger($this->channel);
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
$logger->pushProcessor(new IntrospectionProcessor($introspection, LogLevel::DEBUG));
$stream = $config->get('system', 'logfile');
// just add a stream in case it's either writable or not file
if (!is_file($stream) || is_writable($stream)) {
try {
static::addStreamHandler($logger, $stream, $loglevel);
} catch (\Throwable $e) {
// No Logger ..
$logger = new VoidLogger();
}
}
break;
case 'syslog':
try {
$logger = new SyslogLogger($this->channel, $introspection, $loglevel);
} catch (\Throwable $e) {
// No logger ...
$logger = new VoidLogger();
}
break;
case 'stream':
default:
$stream = $config->get('system', 'logfile');
// just add a stream in case it's either writable or not file
if (!is_file($stream) || is_writable($stream)) {
try {
$logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel);
} catch (\Throwable $t) {
// No logger ...
$logger = new VoidLogger();
}
} else {
$logger = new VoidLogger();
}
break;
}
$profiling = $config->get('system', 'profiling', false);
// In case profiling is enabled, wrap the ProfilerLogger around the current logger
if (isset($profiling) && $profiling !== false) {
$logger = new ProfilerLogger($logger, $profiler);
}
$database->setLogger($logger);
return $logger;
}
/**
* Creates a new PSR-3 compliant develop logger
*
* If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
* you'll use this logger instance for the duration of your work.
*
* It should never get filled during normal usage of Friendica
*
* @param IConfig $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)
{
$debugging = $config->get('system', 'debugging');
$stream = $config->get('system', 'dlogfile');
$developerIp = $config->get('system', 'dlogip');
if ((!isset($developerIp) || !$debugging) &&
(!is_file($stream) || is_writable($stream))) {
$logger = new VoidLogger();
return $logger;
}
$loggerTimeZone = new \DateTimeZone('UTC');
Monolog\Logger::setTimezone($loggerTimeZone);
$introspection = new Introspection(self::$ignoreClassList);
switch ($config->get('system', 'logger_config', 'stream')) {
case 'monolog':
$loggerTimeZone = new \DateTimeZone('UTC');
Monolog\Logger::setTimezone($loggerTimeZone);
$logger = new Monolog\Logger(self::DEV_CHANNEL);
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
$logger->pushProcessor(new IntrospectionProcessor($introspection, LogLevel::DEBUG));
$logger->pushHandler(new DevelopHandler($developerIp));
static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
break;
case 'syslog':
$logger = new SyslogLogger(self::DEV_CHANNEL, $introspection, LogLevel::DEBUG);
break;
case 'stream':
default:
$logger = new StreamLogger(self::DEV_CHANNEL, $stream, $introspection, $fileSystem, LogLevel::DEBUG);
break;
}
$profiling = $config->get('system', 'profiling', false);
// In case profiling is enabled, wrap the ProfilerLogger around the current logger
if (isset($profiling) && $profiling !== false) {
$logger = new ProfilerLogger($logger, $profiler);
}
return $logger;
}
/**
* Mapping a legacy level to the PSR-3 compliant levels
*
* @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
*
* @param string $level the level to be mapped
*
* @return string the PSR-3 compliant level
*/
private static function mapLegacyConfigDebugLevel($level)
{
switch ($level) {
// legacy WARNING
case "0":
return LogLevel::ERROR;
// legacy INFO
case "1":
return LogLevel::WARNING;
// legacy TRACE
case "2":
return LogLevel::NOTICE;
// legacy DEBUG
case "3":
return LogLevel::INFO;
// legacy DATA
case "4":
// legacy ALL
case "5":
return LogLevel::DEBUG;
// default if nothing set
default:
return $level;
}
}
/**
* Adding a handler to a given logger instance
*
* @param LoggerInterface $logger The logger instance
* @param mixed $stream The stream which handles the logger output
* @param string $level The level, for which this handler at least should handle logging
*
* @return void
*
* @throws \Exception in case of general failures
*/
public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
{
if ($logger instanceof Monolog\Logger) {
$loglevel = Monolog\Logger::toMonologLevel($level);
// fallback to notice if an invalid loglevel is set
if (!is_int($loglevel)) {
$loglevel = LogLevel::NOTICE;
}
$fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
$formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
$fileHandler->setFormatter($formatter);
$logger->pushHandler($fileHandler);
}
}
public static function addVoidHandler($logger)
{
if ($logger instanceof Monolog\Logger) {
$logger->pushHandler(new Monolog\Handler\NullHandler());
}
}
}

View file

@ -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\Factory;
use Friendica\App;
use Friendica\Core\Cache\ICache;
use Friendica\Core\Cache\Type;
use Friendica\Core\Config\IConfig;
use Friendica\Core\Session;
use Friendica\Core\System;
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\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\Native($baseURL, $handler);
}
} finally {
$profiler->stopRecording();
return $session;
}
}
}