Merge pull request #784 from Zankaria/micro-di
(What should be a) much better Dependency Injection implementation
This commit is contained in:
@@ -1,66 +1,58 @@
|
||||
<?php
|
||||
namespace Vichan;
|
||||
|
||||
use RuntimeException;
|
||||
use Vichan\Driver\{HttpDriver, HttpDrivers, Log, LogDrivers};
|
||||
|
||||
defined('TINYBOARD') or exit;
|
||||
|
||||
|
||||
interface DependencyFactory {
|
||||
public function buildLogDriver(): Log;
|
||||
public function buildHttpDriver(): HttpDriver;
|
||||
}
|
||||
|
||||
class WebDependencyFactory implements DependencyFactory {
|
||||
private array $config;
|
||||
|
||||
|
||||
public function __construct(array $config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function buildLogDriver(): Log {
|
||||
$name = $this->config['log_system']['name'];
|
||||
$level = $this->config['debug'] ? Log::DEBUG : Log::NOTICE;
|
||||
$backend = $this->config['log_system']['type'];
|
||||
|
||||
// Check 'syslog' for backwards compatibility.
|
||||
if ((isset($this->config['syslog']) && $this->config['syslog']) || $backend === 'syslog') {
|
||||
return LogDrivers::syslog($name, $level, $this->config['log_system']['syslog_stderr']);
|
||||
} elseif ($backend === 'file') {
|
||||
return LogDrivers::file($name, $level, $this->config['log_system']['file_path']);
|
||||
} elseif ($backend === 'stderr') {
|
||||
return LogDrivers::stderr($name, $level);
|
||||
} elseif ($backend === 'none') {
|
||||
return LogDrivers::none();
|
||||
} else {
|
||||
return LogDrivers::error_log($name, $level);
|
||||
}
|
||||
}
|
||||
|
||||
public function buildHttpDriver(): HttpDriver {
|
||||
return HttpDrivers::getHttpDriver(
|
||||
$this->config['upload_by_url_timeout'],
|
||||
$this->config['max_filesize']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Context {
|
||||
private DependencyFactory $factory;
|
||||
private ?Log $log;
|
||||
private ?HttpDriver $http;
|
||||
private array $definitions;
|
||||
|
||||
|
||||
public function __construct(DependencyFactory $factory) {
|
||||
$this->factory = $factory;
|
||||
public function __construct(array $definitions) {
|
||||
$this->definitions = $definitions;
|
||||
}
|
||||
|
||||
public function getLog(): Log {
|
||||
return $this->log ??= $this->factory->buildLogDriver();
|
||||
}
|
||||
public function get(string $name): mixed {
|
||||
if (!isset($this->definitions[$name])) {
|
||||
throw new RuntimeException("Could not find a dependency named $name");
|
||||
}
|
||||
|
||||
public function getHttpDriver(): HttpDriver {
|
||||
return $this->http ??= $this->factory->buildHttpDriver();
|
||||
$ret = $this->definitions[$name];
|
||||
if (is_callable($ret) && !is_string($ret) && !is_array($ret)) {
|
||||
$ret = $ret($this);
|
||||
$this->definitions[$name] = $ret;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
function build_context(array $config): Context {
|
||||
return new Context([
|
||||
'config' => $config,
|
||||
Log::class => function($c) {
|
||||
$config = $c->get('config');
|
||||
|
||||
$name = $config['log_system']['name'];
|
||||
$level = $config['debug'] ? Log::DEBUG : Log::NOTICE;
|
||||
$backend = $config['log_system']['type'];
|
||||
|
||||
// Check 'syslog' for backwards compatibility.
|
||||
if ((isset($config['syslog']) && $config['syslog']) || $backend === 'syslog') {
|
||||
return LogDrivers::syslog($name, $level, $this->config['log_system']['syslog_stderr']);
|
||||
} elseif ($backend === 'file') {
|
||||
return LogDrivers::file($name, $level, $this->config['log_system']['file_path']);
|
||||
} elseif ($backend === 'stderr') {
|
||||
return LogDrivers::stderr($name, $level);
|
||||
} elseif ($backend === 'none') {
|
||||
return LogDrivers::none();
|
||||
} else {
|
||||
return LogDrivers::error_log($name, $level);
|
||||
}
|
||||
},
|
||||
HttpDriver::class => function($c) {
|
||||
$config = $c->get('config');
|
||||
return HttpDrivers::getHttpDriver($config['upload_by_url_timeout'], $config['max_filesize']);
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user