context.php: improve type safety, fix sonarlint complexity

This commit is contained in:
fowr 2025-03-30 13:35:33 -03:00
parent 1db76080f8
commit 84a59e35c6

View File

@ -12,12 +12,22 @@ use Vichan\Service\RemoteCaptchaQuery;
defined('TINYBOARD') or exit; defined('TINYBOARD') or exit;
class Context { class Context {
/**
* @var array<string, mixed>
*/
private array $definitions; private array $definitions;
/**
* @param array<string, mixed> $definitions
*/
public function __construct(array $definitions) { public function __construct(array $definitions) {
$this->definitions = $definitions; $this->definitions = $definitions;
} }
/**
* @param string $name
* @return mixed
*/
public function get(string $name): mixed { public function get(string $name): mixed {
if (!isset($this->definitions[$name])) { if (!isset($this->definitions[$name])) {
throw new \RuntimeException("Could not find a dependency named $name"); throw new \RuntimeException("Could not find a dependency named $name");
@ -35,57 +45,18 @@ class Context {
function build_context(array $config): Context { function build_context(array $config): Context {
return new Context([ return new Context([
'config' => $config, 'config' => $config,
LogDriver::class => function($c) { LogDriver::class => fn(Context $c): LogDriver => build_log_driver(
$config = $c->get('config'); $c->get('config')
),
$name = $config['log_system']['name']; HttpDriver::class => function(Context $c): HttpDriver {
$level = $config['debug'] ? LogDriver::DEBUG : LogDriver::NOTICE;
$backend = $config['log_system']['type'];
$legacy_syslog = isset($config['syslog']) && $config['syslog'];
// Check 'syslog' for backwards compatibility.
if ($legacy_syslog || $backend === 'syslog') {
$log_driver = new SyslogLogDriver($name, $level, $config['log_system']['syslog_stderr']);
if ($legacy_syslog) {
$log_driver->log(LogDriver::NOTICE, 'The configuration setting \'syslog\' is deprecated. Please use \'log_system\' instead');
}
return $log_driver;
} elseif ($backend === 'file') {
return new FileLogDriver($name, $level, $config['log_system']['file_path']);
} elseif ($backend === 'stderr') {
return new StderrLogDriver($name, $level);
} elseif ($backend === 'error_log') {
return new ErrorLogLogDriver($name, $level);
} else {
$log_driver = new ErrorLogLogDriver($name, $level);
$log_driver->log(LogDriver::ERROR, "Unknown 'log_system' value '$backend', using 'error_log' default");
return $log_driver;
}
},
HttpDriver::class => function($c) {
$config = $c->get('config'); $config = $c->get('config');
return new HttpDriver($config['upload_by_url_timeout'], $config['max_filesize']); return new HttpDriver($config['upload_by_url_timeout'], $config['max_filesize']);
}, },
RemoteCaptchaQuery::class => function($c) { RemoteCaptchaQuery::class => fn(Context $c): RemoteCaptchaQuery => build_remote_captcha_query(
$config = $c->get('config'); $c->get('config'),
$http = $c->get(HttpDriver::class); $c->get(HttpDriver::class)
switch ($config['captcha']['provider']) { ),
case 'recaptcha': SecureImageCaptchaQuery::class => function(Context $c): SecureImageCaptchaQuery {
return new ReCaptchaQuery($http, $config['captcha']['recaptcha']['secret']);
case 'hcaptcha':
return new HCaptchaQuery(
$http,
$config['captcha']['hcaptcha']['secret'],
$config['captcha']['hcaptcha']['sitekey']
);
case 'yandexcaptcha':
return new YandexCaptchaQuery($http, $config['captcha']['yandexcaptcha']['secret']);
default:
throw new \RuntimeException('No remote captcha service available');
}
},
SecureImageCaptchaQuery::class => function($c) {
$config = $c->get('config'); $config = $c->get('config');
if ($config['captcha']['provider'] !== 'native') { if ($config['captcha']['provider'] !== 'native') {
throw new \RuntimeException('No native captcha service available'); throw new \RuntimeException('No native captcha service available');
@ -96,22 +67,80 @@ function build_context(array $config): Context {
$config['captcha']['native']['provider_check'] $config['captcha']['native']['provider_check']
); );
}, },
CacheDriver::class => function($c) { CacheDriver::class => fn(): CacheDriver => \Cache::getCache(),
// Use the global for backwards compatibility. \PDO::class => function(): \PDO {
return \cache::getCache();
},
\PDO::class => function($c) {
global $pdo; global $pdo;
// Ensure the PDO is initialized. // Ensure the PDO is initialized.
sql_open(); \sql_open();
return $pdo; return $pdo;
}, },
ReportQueries::class => function($c) { ReportQueries::class => fn(Context $c): ReportQueries => new ReportQueries(
$auto_maintenance = (bool)$c->get('config')['auto_maintenance']; $c->get(\PDO::class),
$pdo = $c->get(\PDO::class); (bool)$c->get('config')['auto_maintenance']
return new ReportQueries($pdo, $auto_maintenance); ),
}, IpNoteQueries::class => fn(Context $c): IpNoteQueries => new IpNoteQueries(
IpNoteQueries::class => fn($c) => new IpNoteQueries($c->get(\PDO::class), $c->get(CacheDriver::class)), $c->get(\PDO::class),
UserPostQueries::class => fn($c) => new UserPostQueries($c->get(\PDO::class)) $c->get(CacheDriver::class)
),
UserPostQueries::class => fn(Context $c): UserPostQueries => new UserPostQueries(
$c->get(\PDO::class)
)
]); ]);
} }
function build_log_driver(array $config): LogDriver {
$name = $config['log_system']['name'];
$level = $config['debug'] ? LogDriver::DEBUG : LogDriver::NOTICE;
$backend = $config['log_system']['type'];
$legacy_syslog = isset($config['syslog']) && $config['syslog'];
// Check 'syslog' for backwards compatibility.
if ($legacy_syslog || $backend === 'syslog') {
$log_driver = new SyslogLogDriver(
$name,
$level,
$config['log_system']['syslog_stderr']
);
if ($legacy_syslog) {
$log_driver->log(
LogDriver::NOTICE,
"The configuration setting 'syslog' is deprecated. Please use 'log_system' instead"
);
}
return $log_driver;
} elseif ($backend === 'file') {
return new FileLogDriver(
$name,
$level,
$config['log_system']['file_path']
);
} elseif ($backend === 'stderr') {
return new StderrLogDriver($name, $level);
} else {
return new ErrorLogLogDriver($name, $level);
}
}
function build_remote_captcha_query(array $config, HttpDriver $http): RemoteCaptchaQuery {
switch ($config['captcha']['provider']) {
case 'recaptcha':
return new ReCaptchaQuery(
$http,
$config['captcha']['recaptcha']['secret']
);
case 'hcaptcha':
return new HCaptchaQuery(
$http,
$config['captcha']['hcaptcha']['secret'],
$config['captcha']['hcaptcha']['sitekey']
);
case 'yandexcaptcha':
return new YandexCaptchaQuery(
$http,
$config['captcha']['yandexcaptcha']['secret']
);
default:
throw new \RuntimeException('No remote captcha service available');
}
}