--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Hooks\Capabilities;
+
+/**
+ * All interfaces, marking this interface are valid Strategies for Hook calls
+ */
+interface IAmAStrategy
+{
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Hooks\Capabilities;
+
+use Friendica\Core\Hooks\Exceptions\HookInstanceException;
+use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
+
+/**
+ * Managing special instance and decorator treatments for classes
+ */
+interface ICanManageInstances
+{
+ /**
+ * Register a class(strategy) for a given interface with a unique name.
+ *
+ * @see https://refactoring.guru/design-patterns/strategy
+ *
+ * @param string $interface The interface, which the given class implements
+ * @param string $name The name of the given class, which will be used for factories, dependency injections etc.
+ * @param string $class The class of the given class
+ * @param ?array $arguments Additional arguments, which can be passed to the constructor
+ *
+ * @return $this This interface for chain-calls
+ *
+ * @throws HookRegisterArgumentException in case the given class for the interface isn't valid or already set
+ */
+ public function registerStrategy(string $interface, string $name, string $class, array $arguments = null): self;
+
+ /**
+ * Register a new decorator for a given class or interface
+ * @see https://refactoring.guru/design-patterns/decorator
+ *
+ * @note Decorator attach new behaviors to classes without changing them or without letting them know about it.
+ *
+ * @param string $class The class or interface, which gets decorated by a class
+ * @param string $decoratorClass The class, which mimics the given class or interface and adds new functionality
+ * @param array $arguments Additional arguments, which can be passed to the constructor of "decoratorClass"
+ *
+ * @return $this This interface for chain-calls
+ *
+ * @throws HookRegisterArgumentException in case the given class for the class or interface isn't valid
+ */
+ public function registerDecorator(string $class, string $decoratorClass, array $arguments = []): self;
+
+ /**
+ * Returns a new instance of a given class for the corresponding name
+ *
+ * The instance will be build based on the registered strategy and the (unique) name
+ *
+ * In case, there are registered decorators for this class as well, all decorators of the list will be wrapped
+ * around the instance before returning it
+ *
+ * @param string $class A given class or interface, which will get returned
+ * @param string $name The name of the concrete class, wich
+ * @param array $arguments Additional arguments, which can be passed to the constructor of "$class" at runtime
+ *
+ * @return object The concrete instance of the type "$class"
+ *
+ * @throws HookInstanceException In case the class cannot get created
+ */
+ public function getInstance(string $class, string $name, array $arguments = []): object;
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Hooks\Exceptions;
+
+class HookInstanceException extends \RuntimeException
+{
+ public function __construct($message = "", \Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Hooks\Exceptions;
+
+class HookRegisterArgumentException extends \RuntimeException
+{
+ public function __construct($message = "", \Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Hooks\Model;
+
+use Dice\Dice;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
+use Friendica\Core\Hooks\Exceptions\HookInstanceException;
+use Friendica\Core\Hooks\Exceptions\HookRegisterArgumentException;
+
+/** {@inheritDoc} */
+class InstanceManager implements ICanManageInstances
+{
+ protected $instance = [];
+ protected $instanceArguments = [];
+ protected $decorator = [];
+
+ /** @var Dice */
+ protected $dice;
+
+ public function __construct(Dice $dice)
+ {
+ $this->dice = $dice;
+ }
+
+ /** {@inheritDoc} */
+ public function registerStrategy(string $interface, string $name, string $class, array $arguments = null): ICanManageInstances
+ {
+ if (!is_a($class, $interface, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s is not a valid class for the interface %s', $class, $interface));
+ }
+
+ if (!is_a($class, IAmAStrategy::class, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s does not inherit from the marker interface %s', $class, IAmAStrategy::class));
+ }
+
+ if (!empty($this->instance[$interface][$name])) {
+ throw new HookRegisterArgumentException(sprintf('A class with the name %s is already set for the interface %s', $name, $interface));
+ }
+
+ $this->instance[$interface][$name] = $class;
+ $this->instanceArguments[$interface][$name] = $arguments;
+
+ return $this;
+ }
+
+ /** {@inheritDoc} */
+ public function registerDecorator(string $class, string $decoratorClass, array $arguments = []): ICanManageInstances
+ {
+ if (!is_a($decoratorClass, $class, true)) {
+ throw new HookRegisterArgumentException(sprintf('%s is not a valid subsituation for the given class or interface %s', $decoratorClass, $class));
+ }
+
+ $this->decorator[$class][] = [
+ 'class' => $decoratorClass,
+ 'arguments' => $arguments,
+ ];
+
+ return $this;
+ }
+
+ /** {@inheritDoc} */
+ public function getInstance(string $class, string $name, array $arguments = []): object
+ {
+ if (empty($this->instance[$class][$name])) {
+ throw new HookInstanceException(sprintf('The class with the name %s isn\'t registered for the class or interface %s', $name, $class));
+ }
+
+ $instance = $this->dice->create($this->instance[$class][$name], array_merge($this->instanceArguments[$class][$name] ?? [], $arguments));
+
+ foreach ($this->decorator[$class] ?? [] as $decorator) {
+ $this->dice = $this->dice->addRule($class, [
+ 'instanceOf' => $decorator['class'],
+ 'constructParams' => empty($decorator['arguments']) ? null : $decorator['arguments'],
+ /// @todo maybe support call structures for hooks as well in a later stage - could make factory calls easier
+ 'call' => null,
+ 'substitutions' => [$class => $instance],
+ ]);
+
+ $instance = $this->dice->create($class);
+ }
+
+ return $instance;
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Logger\Exception;
+
+use Throwable;
+
+class LoggerInvalidException extends \RuntimeException
+{
+ public function __construct($message = "", Throwable $previous = null)
+ {
+ parent::__construct($message, 500, $previous);
+ }
+}
namespace Friendica\Core\Logger\Factory;
use Friendica\Core\Config\Capability\IManageConfigValues;
-use Friendica\Core;
-use Friendica\Core\Logger\Capabilities\IHaveCallIntrospections;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
use Friendica\Core\Logger\Exception\LogLevelException;
-use Friendica\Database\Database;
-use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\FileSystem;
use Friendica\Core\Logger\Type\ProfilerLogger;
use Friendica\Core\Logger\Type\StreamLogger;
use Friendica\Core\Logger\Type\SyslogLogger;
-use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
const DEV_CHANNEL = 'dev';
/** @var string The log-channel (app, worker, ...) */
- private $channel;
+ protected $channel;
+ /** @var ICanManageInstances */
+ protected $instanceManager;
+ /** @var IManageConfigValues */
+ protected $config;
- public function __construct(string $channel, bool $includeAddon = true)
+ public function __construct(string $channel, ICanManageInstances $instanceManager, IManageConfigValues $config, string $logfile = null)
{
- $this->channel = $channel;
+ $this->channel = $channel;
+ $this->instanceManager = $instanceManager;
+ $this->config = $config;
- /// @fixme clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
- if ($includeAddon) {
- Core\Addon::loadAddons();
- Core\Hook::loadHooks();
+ $this->instanceManager
+ ->registerStrategy(LoggerInterface::class, 'syslog', SyslogLogger::class)
+ ->registerStrategy(LoggerInterface::class, 'stream', StreamLogger::class, isset($logfile) ? [$logfile] : null);
+
+ if ($this->config->get('system', 'profiling') ?? false) {
+ $this->instanceManager->registerDecorator(LoggerInterface::class, ProfilerLogger::class);
}
}
/**
* Creates a new PSR-3 compliant logger instances
*
- * @param Database $database The Friendica Database instance
- * @param IManageConfigValues $config The config
- * @param Profiler $profiler The profiler of the app
- * @param FileSystem $fileSystem FileSystem utils
- * @param string|null $minLevel (optional) Override minimum Loglevel to log
+ * @param string|null $loglevel (optional) A given loglevel in case the loglevel in the config isn't applicable
*
* @return LoggerInterface The PSR-3 compliant logger instance
*/
- public function create(Database $database, IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection, ?string $minLevel = null): LoggerInterface
+ public function create(string $loglevel = null): LoggerInterface
{
- if (empty($config->get('system', 'debugging', false))) {
- $logger = new NullLogger();
- $database->setLogger($logger);
- return $logger;
- }
-
- $minLevel = $minLevel ?? $config->get('system', 'loglevel');
- $loglevel = self::mapLegacyConfigDebugLevel((string)$minLevel);
-
- $name = $config->get('system', 'logger_config', 'stream');
-
- switch ($name) {
- case 'syslog':
- try {
- $logger = new SyslogLogger($this->channel, $introspection, $loglevel, $config->get('system', 'syslog_flags', SyslogLogger::DEFAULT_FLAGS), $config->get('system', 'syslog_facility', SyslogLogger::DEFAULT_FACILITY));
- } catch (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $e) {
- // No logger ...
- $logger = new NullLogger();
- }
- break;
-
- case 'stream':
- default:
- $data = [
- 'name' => $name,
- 'channel' => $this->channel,
- 'introspection' => $introspection,
- 'loglevel' => $loglevel,
- 'logger' => null,
- ];
- try {
- Core\Hook::callAll('logger_instance', $data);
- } catch (InternalServerErrorException $exception) {
- $data['logger'] = null;
- }
-
- if (($data['logger'] ?? null) instanceof LoggerInterface) {
- $logger = $data['logger'];
- }
-
- if (empty($logger)) {
- $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 (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $t) {
- // No logger ...
- $logger = new NullLogger();
- }
- } else {
- try {
- $logger = new SyslogLogger($this->channel, $introspection, $loglevel);
- } catch (LogLevelException $exception) {
- // If there's a wrong config value for loglevel, try again with standard
- $logger = $this->create($database, $config, $profiler, $fileSystem, $introspection, LogLevel::NOTICE);
- $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
- } catch (\Throwable $e) {
- // No logger ...
- $logger = new NullLogger();
- }
- }
- }
- break;
+ if (empty($this->config->get('system', 'debugging') ?? false)) {
+ return new NullLogger();
}
- $profiling = $config->get('system', 'profiling', false);
+ $loglevel = $loglevel ?? static::mapLegacyConfigDebugLevel($this->config->get('system', 'loglevel'));
+ $name = $this->config->get('system', 'logger_config') ?? 'stream';
- // In case profiling is enabled, wrap the ProfilerLogger around the current logger
- if (isset($profiling) && $profiling !== false) {
- $logger = new ProfilerLogger($logger, $profiler);
+ try {
+ /** @var LoggerInterface */
+ return $this->instanceManager->getInstance(LoggerInterface::class, $name, [$this->channel, $loglevel]);
+ } catch (LogLevelException $exception) {
+ // If there's a wrong config value for loglevel, try again with standard
+ $logger = $this->create(LogLevel::NOTICE);
+ $logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
+ return $logger;
+ } catch (\Throwable $e) {
+ // No logger ...
+ return new NullLogger();
}
-
- $database->setLogger($logger);
- return $logger;
}
/**
*
* It should never get filled during normal usage of Friendica
*
- * @param 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 \Exception
*/
- public static function createDev(IManageConfigValues $config, Profiler $profiler, FileSystem $fileSystem, IHaveCallIntrospections $introspection)
+ public function createDev()
{
- $debugging = $config->get('system', 'debugging');
- $stream = $config->get('system', 'dlogfile');
- $developerIp = $config->get('system', 'dlogip');
+ $debugging = $this->config->get('system', 'debugging');
+ $stream = $this->config->get('system', 'dlogfile');
+ $developerIp = $this->config->get('system', 'dlogip');
if ((!isset($developerIp) || !$debugging) &&
(!is_file($stream) || is_writable($stream))) {
return new NullLogger();
}
- $name = $config->get('system', 'logger_config', 'stream');
-
- switch ($name) {
-
- case 'syslog':
- $logger = new SyslogLogger(self::DEV_CHANNEL, $introspection, LogLevel::DEBUG);
- break;
-
- case 'stream':
- default:
- $data = [
- 'name' => $name,
- 'channel' => self::DEV_CHANNEL,
- 'introspection' => $introspection,
- 'loglevel' => LogLevel::DEBUG,
- 'logger' => null,
- ];
- try {
- Core\Hook::callAll('logger_instance', $data);
- } catch (InternalServerErrorException $exception) {
- $data['logger'] = null;
- }
-
- if (($data['logger'] ?? null) instanceof LoggerInterface) {
- return $data['logger'];
- }
-
- $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);
- }
+ $name = $this->config->get('system', 'logger_config') ?? 'stream';
- return $logger;
+ /** @var LoggerInterface */
+ return $this->instanceManager->getInstance(LoggerInterface::class, $name, [self::DEV_CHANNEL, LogLevel::DEBUG, $stream]);
}
/**
namespace Friendica\Core\Logger\Type;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
use Friendica\Core\Logger\Exception\LoggerArgumentException;
use Friendica\Core\Logger\Exception\LoggerException;
use Friendica\Core\Logger\Exception\LogLevelException;
/**
* A Logger instance for logging into a stream (file, stdout, stderr)
*/
-class StreamLogger extends AbstractLogger
+class StreamLogger extends AbstractLogger implements IAmAStrategy
{
/**
* The minimum loglevel at which this logger will be triggered
/**
* {@inheritdoc}
- * @param string|resource $stream The stream to write with this logger (either a file or a stream, i.e. stdout)
* @param string $level The minimum loglevel at which this logger will be triggered
*
* @throws LoggerArgumentException
* @throws LogLevelException
*/
- public function __construct($channel, $stream, Introspection $introspection, FileSystem $fileSystem, string $level = LogLevel::DEBUG)
+ public function __construct(string $channel, IManageConfigValues $config, Introspection $introspection, FileSystem $fileSystem, string $level = LogLevel::DEBUG)
{
$this->fileSystem = $fileSystem;
+ $stream = $this->logfile ?? $config->get('system', 'logfile');
+ if ((file_exists($stream) && !is_writable($stream)) || is_writable(basename($stream))) {
+ throw new LoggerArgumentException(sprintf('%s is not a valid logfile', $stream));
+ }
+
parent::__construct($channel, $introspection);
if (is_resource($stream)) {
namespace Friendica\Core\Logger\Type;
+use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
use Friendica\Core\Logger\Exception\LoggerException;
use Friendica\Core\Logger\Exception\LogLevelException;
use Friendica\Core\Logger\Util\Introspection;
* A Logger instance for syslogging (fast, but simple)
* @see http://php.net/manual/en/function.syslog.php
*/
-class SyslogLogger extends AbstractLogger
+class SyslogLogger extends AbstractLogger implements IAmAStrategy
{
const IDENT = 'Friendica';
/**
* {@inheritdoc}
* @param string $level The minimum loglevel at which this logger will be triggered
- * @param int $logOpts Indicates what logging options will be used when generating a log message
- * @param int $logFacility Used to specify what type of program is logging the message
*
* @throws LogLevelException
* @throws LoggerException
*/
- public function __construct($channel, Introspection $introspection, string $level = LogLevel::NOTICE, int $logOpts = self::DEFAULT_FLAGS, int $logFacility = self::DEFAULT_FACILITY )
+ public function __construct(string $channel, IManageConfigValues $config, Introspection $introspection, string $level = LogLevel::NOTICE)
{
parent::__construct($channel, $introspection);
- $this->logOpts = $logOpts;
- $this->logFacility = $logFacility;
+
+ $this->logOpts = $config->get('system', 'syslog_flags') ?? static::DEFAULT_FLAGS;
+ $this->logFacility = $config->get('system', 'syslog_facility') ?? static::DEFAULT_FACILITY;
$this->logLevel = $this->mapLevelToPriority($level);
$this->introspection->addClasses([self::class]);
}
use PDOException;
use PDOStatement;
use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
/**
* This class is for the low level database stuff that does driver specific things.
/** @var ViewDefinition */
protected $viewDefinition;
- public function __construct(IManageConfigValues $config, Profiler $profiler, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition)
+ public function __construct(IManageConfigValues $config, Profiler $profiler, DbaDefinition $dbaDefinition, ViewDefinition $viewDefinition, LoggerInterface $logger)
{
// We are storing these values for being able to perform a reconnect
- $this->config = $config;
- $this->profiler = $profiler;
+ $this->config = $config;
+ $this->profiler = $profiler;
$this->dbaDefinition = $dbaDefinition;
$this->viewDefinition = $viewDefinition;
-
- // Temporary NullLogger until we can fetch the logger class from the config
- $this->logger = new NullLogger();
+ $this->logger = $logger;
$this->connect();
}
$this->testmode = $test;
}
- /**
- * Sets the logger for DBA
- *
- * @note this is necessary because if we want to load the logger configuration
- * from the DB, but there's an error, we would print out an exception.
- * So the logger gets updated after the logger configuration can be retrieved
- * from the database
- *
- * @param LoggerInterface $logger
- */
- public function setLogger(LoggerInterface $logger)
- {
- $this->logger = $logger;
- }
-
/**
* Sets the profiler for DBA
*
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
+use Friendica\Core\Hooks\Capabilities\ICanManageInstances;
+use Friendica\Core\Hooks\Model\InstanceManager;
use Friendica\Core\PConfig;
use Friendica\Core\L10n;
use Friendica\Core\Lock;
$_SERVER
]
],
+ ICanManageInstances::class => [
+ 'instanceOf' => InstanceManager::class,
+ 'constructParams' => [
+ [Dice::INSTANCE => Dice::SELF],
+ ],
+ ],
Config\Util\ConfigFileManager::class => [
'instanceOf' => Config\Factory\Config::class,
'call' => [
use Friendica\Test\DatabaseTestTrait;
use Friendica\Test\Util\Database\StaticDatabase;
use Friendica\Util\Profiler;
+use Psr\Log\NullLogger;
trait CreateDatabaseTrait
{
],
]));
- $database = new StaticDatabase($config, new Profiler($config), (new DbaDefinition($this->root->url()))->load(), (new ViewDefinition($this->root->url()))->load());
+ $database = new StaticDatabase($config, new Profiler($config), (new DbaDefinition($this->root->url()))->load(), (new ViewDefinition($this->root->url()))->load(), new NullLogger());
$database->setTestmode(true);
return $database;
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Test\Util\Hooks\InstanceMocks;
+
+use Friendica\Core\Hooks\Capabilities\IAmAStrategy;
+
+class FakeInstance implements IAmADecoratedInterface, IAmAStrategy
+{
+ protected $aText = null;
+ protected $cBool = null;
+ protected $bText = null;
+
+ public function __construct(string $aText = null, bool $cBool = null, string $bText = null)
+ {
+ $this->aText = $aText;
+ $this->cBool = $cBool;
+ $this->bText = $bText;
+ }
+
+ public function createSomething(string $aText, bool $cBool, string $bText): string
+ {
+ $this->aText = $aText;
+ $this->cBool = $cBool;
+ $this->bText = $bText;
+ }
+
+ public function getAText(): ?string
+ {
+ return $this->aText;
+ }
+
+ public function getBText(): ?string
+ {
+ return $this->bText;
+ }
+
+ public function getCBool(): ?bool
+ {
+ return $this->cBool;
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Test\Util\Hooks\InstanceMocks;
+
+class FakeInstanceDecorator implements IAmADecoratedInterface
+{
+ public static $countInstance = 0;
+
+ /** @var IAmADecoratedInterface */
+ protected $orig;
+ protected $prefix = '';
+
+ public function __construct(IAmADecoratedInterface $orig, string $prefix = '')
+ {
+ $this->orig = $orig;
+ $this->prefix = $prefix;
+
+ self::$countInstance++;
+ }
+
+ public function createSomething(string $aText, bool $cBool, string $bText): string
+ {
+ return $this->orig->createSomething($aText, $cBool, $bText);
+ }
+
+ public function getAText(): ?string
+ {
+ return $this->prefix . $this->orig->getAText();
+ }
+
+ public function getBText(): ?string
+ {
+ return $this->prefix . $this->orig->getBText();
+ }
+
+ public function getCBool(): ?bool
+ {
+ return $this->prefix . $this->orig->getCBool();
+ }
+}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Test\Util\Hooks\InstanceMocks;
+
+interface IAmADecoratedInterface
+{
+ public function createSomething(string $aText, bool $cBool, string $bText): string;
+
+ public function getAText(): ?string;
+
+ public function getBText(): ?string;
+
+ public function getCBool(): ?bool;
+}
use Friendica\App;
use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\Cache\Capability\ICanCacheInMemory;
-use Friendica\Core\Config\Model\Config;
use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Lock\Capability\ICanLock;
use Friendica\Test\Util\VFSTrait;
use Friendica\Util\BasePath;
use Friendica\Core\Config\Util\ConfigFileManager;
-use Friendica\Util\Profiler;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
$this->setUpVfsDir();
$this->dice = (new Dice())
- ->addRules(include __DIR__ . '/../../static/dependencies.config.php');
+ ->addRules(include __DIR__ . '/../../static/dependencies.config.php')
+ ->addRule(BasePath::class, [
+ 'constructParams' => [
+ $this->root->url(),
+ [],
+ ],
+ ])
+ ->addRule(LoggerInterface::class, ['constructParams' => ['test']]);
+
+ /** @var IManageConfigValues $config */
+ $config = $this->dice->create(IManageConfigValues::class);
+ $config->set('system', 'logfile', $this->root->url() . '/logs/friendica.log');
}
/**
public function testLogger()
{
/** @var LoggerInterface $logger */
- $logger = $this->dice->create(LoggerInterface::class, ['test']);
+ $logger = $this->dice->create(LoggerInterface::class, [['$channel' => 'test']]);
self::assertInstanceOf(LoggerInterface::class, $logger);
}
$config->set('system', 'dlogfile', $this->root->url() . '/friendica.log');
/** @var LoggerInterface $logger */
- $logger = $this->dice->create('$devLogger', ['dev']);
+ $logger = $this->dice->create('$devLogger', [['$channel' => 'dev']]);
self::assertInstanceOf(LoggerInterface::class, $logger);
}
/** @var ICanCache $cache */
$cache = $this->dice->create(ICanCache::class);
+
self::assertInstanceOf(ICanCache::class, $cache);
}
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
- $dba = new StaticDatabase($config, $profiler, $dbaDefinition, $viewDefinition);
+ $dba = new StaticDatabase($config, $profiler, $dbaDefinition, $viewDefinition, new NullLogger());
$this->cache = new Cache\Type\DatabaseCache('database', $dba);
return $this->cache;
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2010-2023, 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\Test\src\Core\Hooks\Model;
+
+use Dice\Dice;
+use Friendica\Core\Hooks\Model\InstanceManager;
+use Friendica\Test\MockedTest;
+use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstance;
+use Friendica\Test\Util\Hooks\InstanceMocks\FakeInstanceDecorator;
+use Friendica\Test\Util\Hooks\InstanceMocks\IAmADecoratedInterface;
+
+class InstanceManagerTest extends MockedTest
+{
+ public function testEqualButNotSameInstance()
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class);
+
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake');
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake');
+
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ }
+
+ protected function tearDown(): void
+ {
+ FakeInstanceDecorator::$countInstance = 0;
+
+ parent::tearDown();
+ }
+
+ public function dataTests(): array
+ {
+ return [
+ 'only_a' => [
+ 'aString' => 'test',
+ ],
+ 'a_b' => [
+ 'aString' => 'test',
+ 'cBool' => false,
+ 'bString' => 'test23',
+
+ ],
+ 'a_c' => [
+ 'aString' => 'test',
+ 'cBool' => false,
+ 'bString' => null,
+ ],
+ 'a_b_c' => [
+ 'aString' => 'test',
+ 'cBool' => false,
+ 'bString' => 'test23',
+ ],
+ 'null' => [],
+ ];
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testInstanceWithConstructorAnonymArgs(string $aString = null, bool $cBool = null, string $bString = null)
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $args = [];
+
+ if (isset($aString)) {
+ $args[] = $aString;
+ }
+ if (isset($bString)) {
+ $args[] = $bString;
+ }
+ if (isset($cBool)) {
+ $args[] = $cBool;
+ }
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
+
+ /** @var IAmADecoratedInterface $getInstanceA */
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake');
+ /** @var IAmADecoratedInterface $getInstanceB */
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake');
+
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ self::assertEquals($aString, $getInstanceA->getAText());
+ self::assertEquals($aString, $getInstanceB->getAText());
+ self::assertEquals($bString, $getInstanceA->getBText());
+ self::assertEquals($bString, $getInstanceB->getBText());
+ self::assertEquals($cBool, $getInstanceA->getCBool());
+ self::assertEquals($cBool, $getInstanceB->getCBool());
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testInstanceConstructorAndGetInstanceWithNamedArgs(string $aString = null, bool $cBool = null, string $bString = null)
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $args = [];
+
+ if (isset($aString)) {
+ $args[] = $aString;
+ }
+ if (isset($cBool)) {
+ $args[] = $cBool;
+ }
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
+
+ /** @var IAmADecoratedInterface $getInstanceA */
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake', [$bString]);
+ /** @var IAmADecoratedInterface $getInstanceB */
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake', [$bString]);
+
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ self::assertEquals($aString, $getInstanceA->getAText());
+ self::assertEquals($aString, $getInstanceB->getAText());
+ self::assertEquals($bString, $getInstanceA->getBText());
+ self::assertEquals($bString, $getInstanceB->getBText());
+ self::assertEquals($cBool, $getInstanceA->getCBool());
+ self::assertEquals($cBool, $getInstanceB->getCBool());
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testInstanceWithTwoStrategies(string $aString = null, bool $cBool = null, string $bString = null)
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $args = [];
+
+ if (isset($aString)) {
+ $args[] = $aString;
+ }
+ if (isset($cBool)) {
+ $args[] = $cBool;
+ }
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
+
+ /** @var IAmADecoratedInterface $getInstanceA */
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake', [$bString]);
+ /** @var IAmADecoratedInterface $getInstanceB */
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake23', [$bString]);
+
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ self::assertEquals($aString, $getInstanceA->getAText());
+ self::assertEquals($aString, $getInstanceB->getAText());
+ self::assertEquals($bString, $getInstanceA->getBText());
+ self::assertEquals($bString, $getInstanceB->getBText());
+ self::assertEquals($cBool, $getInstanceA->getCBool());
+ self::assertEquals($cBool, $getInstanceB->getCBool());
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testDecorator(string $aString = null, bool $cBool = null, string $bString = null)
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $args = [];
+
+ if (isset($aString)) {
+ $args[] = $aString;
+ }
+ if (isset($cBool)) {
+ $args[] = $cBool;
+ }
+
+ $prefix = 'prefix1';
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
+ $instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class, [$prefix]);
+
+ /** @var IAmADecoratedInterface $getInstanceA */
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake', [$bString]);
+ /** @var IAmADecoratedInterface $getInstanceB */
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake23', [$bString]);
+
+ self::assertEquals(2, FakeInstanceDecorator::$countInstance);
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ self::assertEquals($prefix . $aString, $getInstanceA->getAText());
+ self::assertEquals($prefix . $aString, $getInstanceB->getAText());
+ self::assertEquals($prefix . $bString, $getInstanceA->getBText());
+ self::assertEquals($prefix . $bString, $getInstanceB->getBText());
+ self::assertEquals($prefix . $cBool, $getInstanceA->getCBool());
+ self::assertEquals($prefix . $cBool, $getInstanceB->getCBool());
+ }
+
+ /**
+ * @dataProvider dataTests
+ */
+ public function testTwoDecoratorWithPrefix(string $aString = null, bool $cBool = null, string $bString = null)
+ {
+ $instance = new InstanceManager(new Dice());
+
+ $args = [];
+
+ if (isset($aString)) {
+ $args[] = $aString;
+ }
+ if (isset($cBool)) {
+ $args[] = $cBool;
+ }
+
+ $prefix = 'prefix1';
+
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake', FakeInstance::class, $args);
+ $instance->registerStrategy(IAmADecoratedInterface::class, 'fake23', FakeInstance::class, $args);
+ $instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class, [$prefix]);
+ $instance->registerDecorator(IAmADecoratedInterface::class, FakeInstanceDecorator::class);
+
+ /** @var IAmADecoratedInterface $getInstanceA */
+ $getInstanceA = $instance->getInstance(IAmADecoratedInterface::class, 'fake', [$bString]);
+ /** @var IAmADecoratedInterface $getInstanceB */
+ $getInstanceB = $instance->getInstance(IAmADecoratedInterface::class, 'fake23', [$bString]);
+
+ self::assertEquals(4, FakeInstanceDecorator::$countInstance);
+ self::assertEquals($getInstanceA, $getInstanceB);
+ self::assertNotSame($getInstanceA, $getInstanceB);
+ self::assertEquals($prefix . $aString, $getInstanceA->getAText());
+ self::assertEquals($prefix . $aString, $getInstanceB->getAText());
+ self::assertEquals($prefix . $bString, $getInstanceA->getBText());
+ self::assertEquals($prefix . $bString, $getInstanceB->getBText());
+ self::assertEquals($prefix . $cBool, $getInstanceA->getCBool());
+ self::assertEquals($prefix . $cBool, $getInstanceB->getCBool());
+ }
+}
namespace Friendica\Test\src\Core\Logger;
+use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Test\MockedTest;
use Friendica\Core\Logger\Util\Introspection;
use Mockery\MockInterface;
* @var Introspection|MockInterface
*/
protected $introspection;
+ /**
+ * @var IManageConfigValues|MockInterface
+ */
+ protected $config;
/**
* Returns the content of the current logger instance
'line' => self::LINE,
'function' => self::FUNC
]);
+
+ $this->config = \Mockery::mock(IManageConfigValues::class);
}
public function assertLogline($string)
$this->logfile = vfsStream::newFile('friendica.log')
->at($this->root);
- $logger = new StreamLogger('test', $this->logfile->url(), $this->introspection, $this->fileSystem, $level);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn($this->logfile->url())->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem, $level);
return $logger;
}
return $this->logfile->getContent();
}
- /**
- * Test if a stream is working
- */
- public function testStream()
- {
- $logfile = vfsStream::newFile('friendica.log')
- ->at($this->root);
-
- $filehandler = fopen($logfile->url(), 'ab');
-
- $logger = new \Friendica\Core\Logger\Type\StreamLogger('test', $filehandler, $this->introspection, $this->fileSystem);
- $logger->emergency('working');
-
- $text = $logfile->getContent();
-
- self::assertLogline($text);
- }
-
- /**
- * Test if the close statement is working
- */
- public function testClose()
- {
- $logfile = vfsStream::newFile('friendica.log')
- ->at($this->root);
-
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
- $logger->emergency('working');
- $logger->close();
- // close doesn't affect
- $logger->emergency('working too');
-
- $text = $logfile->getContent();
-
- self::assertLoglineNums(2, $text);
- }
-
/**
* Test when a file isn't set
*/
$this->expectException(LoggerArgumentException::class);
$this->expectExceptionMessage("Missing stream URL.");
- $logger = new StreamLogger('test', '', $this->introspection, $this->fileSystem);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn('')->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem);
$logger->emergency('not working');
}
*/
public function testWrongUrl()
{
- $this->expectException(LoggerException::class);
- $this->expectExceptionMessage("Cannot create stream.");
+ $this->expectException(LoggerArgumentException::class);
$logfile = vfsStream::newFile('friendica.log')
->at($this->root)->chmod(0);
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn($logfile->url())->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem);
$logger->emergency('not working');
}
$this->expectException(LogLevelException::class);
$this->expectExceptionMessageMatches("/The level \".*\" is not valid./");
- $logger = new StreamLogger('test', 'file.text', $this->introspection, $this->fileSystem, 'NOPE');
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn('file.text')->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem, 'NOPE');
}
/**
$logfile = vfsStream::newFile('friendica.log')
->at($this->root);
- $logger = new StreamLogger('test', $logfile->url(), $this->introspection, $this->fileSystem);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn($logfile->url())->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem);
$logger->log('NOPE', 'a test');
}
$this->expectException(LoggerArgumentException::class);
$this->expectExceptionMessage("A stream must either be a resource or a string.");
- $logger = new StreamLogger('test', null, $this->introspection, $this->fileSystem);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn(null)->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem);
}
/**
chdir($this->root->getChild('logs')->url());
- $logger = new StreamLogger('test', '../friendica.log' , $this->introspection, $this->fileSystem);
+ $this->config->shouldReceive('get')->with('system', 'logfile')->andReturn('../friendica.log')->once();
+
+ $logger = new StreamLogger('test', $this->config, $this->introspection, $this->fileSystem);
$logger->info('Test');
}
parent::setUp();
$this->introspection->shouldReceive('addClasses')->with([SyslogLogger::class]);
+ $this->config->shouldReceive('get')->with('system', 'syslog_flags')->andReturn(SyslogLogger::DEFAULT_FLAGS)
+ ->once();
+ $this->config->shouldReceive('get')->with('system', 'syslog_facility')
+ ->andReturn(SyslogLogger::DEFAULT_FACILITY)->once();
}
/**
*/
protected function getInstance($level = LogLevel::DEBUG)
{
- $this->logger = new SyslogLoggerWrapper('test', $this->introspection, $level);
+ $this->logger = new SyslogLoggerWrapper('test', $this->config, $this->introspection, $level);
return $this->logger;
}
$this->expectException(LogLevelException::class);
$this->expectExceptionMessageMatches("/The level \".*\" is not valid./");
- $logger = new SyslogLoggerWrapper('test', $this->introspection, 'NOPE');
+ $logger = new SyslogLoggerWrapper('test', $this->config, $this->introspection, 'NOPE');
}
/**
$this->expectException(LogLevelException::class);
$this->expectExceptionMessageMatches("/The level \".*\" is not valid./");
- $logger = new SyslogLoggerWrapper('test', $this->introspection);
+ $logger = new SyslogLoggerWrapper('test', $this->config, $this->introspection);
$logger->log('NOPE', 'a test');
}
*/
public function testClose()
{
- $logger = new SyslogLoggerWrapper('test', $this->introspection);
+ $logger = new SyslogLoggerWrapper('test', $this->config, $this->introspection);
$logger->emergency('test');
$logger->close();
// Reopened itself
namespace Friendica\Test\src\Core\Logger;
+use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\Logger\Type\SyslogLogger;
use Friendica\Core\Logger\Util\Introspection;
use Psr\Log\LogLevel;
{
private $content;
- public function __construct($channel, Introspection $introspection, $level = LogLevel::NOTICE, $logOpts = LOG_PID, $logFacility = LOG_USER)
+ public function __construct($channel, IManageConfigValues $config, Introspection $introspection, $level = LogLevel::NOTICE)
{
- parent::__construct($channel, $introspection, $level, $logOpts, $logFacility);
+ parent::__construct($channel, $config, $introspection, $level);
$this->content = '';
}