mirror of
https://github.com/torrentpier/torrentpier
synced 2025-08-21 22:03:49 -07:00
refactor(config): encapsulate global $bb_cfg array in Config class (#1950)
- Create new TorrentPier\Config singleton class with dot notation support - Add config() helper function for global access - Replace direct $bb_cfg access in core files (common.php, Emailer.php, Ajax.php) - Implement methods: get(), set(), has(), all(), getSection(), merge() - Add magic methods for property-like access - Maintain backward compatibility with existing $bb_cfg usage BREAKING CHANGE: None - maintains full backward compatibility
This commit is contained in:
parent
8907dbf991
commit
5842994782
4 changed files with 231 additions and 39 deletions
37
common.php
37
common.php
|
@ -86,6 +86,19 @@ if (is_file(BB_PATH . '/library/config.local.php')) {
|
|||
require_once BB_PATH . '/library/config.local.php';
|
||||
}
|
||||
|
||||
// Initialize Config singleton
|
||||
$config = \TorrentPier\Config::init($bb_cfg);
|
||||
|
||||
/**
|
||||
* Get the Config instance
|
||||
*
|
||||
* @return \TorrentPier\Config
|
||||
*/
|
||||
function config(): \TorrentPier\Config
|
||||
{
|
||||
return \TorrentPier\Config::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize debug
|
||||
*/
|
||||
|
@ -100,16 +113,16 @@ if (APP_ENV === 'local') {
|
|||
/**
|
||||
* Server variables initialize
|
||||
*/
|
||||
$server_protocol = $bb_cfg['cookie_secure'] ? 'https://' : 'http://';
|
||||
$server_port = in_array((int)$bb_cfg['server_port'], [80, 443], true) ? '' : ':' . $bb_cfg['server_port'];
|
||||
define('FORUM_PATH', $bb_cfg['script_path']);
|
||||
define('FULL_URL', $server_protocol . $bb_cfg['server_name'] . $server_port . $bb_cfg['script_path']);
|
||||
$server_protocol = config()->get('cookie_secure') ? 'https://' : 'http://';
|
||||
$server_port = in_array((int)config()->get('server_port'), [80, 443], true) ? '' : ':' . config()->get('server_port');
|
||||
define('FORUM_PATH', config()->get('script_path'));
|
||||
define('FULL_URL', $server_protocol . config()->get('server_name') . $server_port . config()->get('script_path'));
|
||||
unset($server_protocol, $server_port);
|
||||
|
||||
/**
|
||||
* Database
|
||||
*/
|
||||
$DBS = new TorrentPier\Legacy\Dbs($bb_cfg);
|
||||
$DBS = new TorrentPier\Legacy\Dbs(config()->all());
|
||||
|
||||
function DB(string $db_alias = 'db')
|
||||
{
|
||||
|
@ -120,7 +133,7 @@ function DB(string $db_alias = 'db')
|
|||
/**
|
||||
* Cache
|
||||
*/
|
||||
$CACHES = new TorrentPier\Legacy\Caches($bb_cfg);
|
||||
$CACHES = new TorrentPier\Legacy\Caches(config()->all());
|
||||
|
||||
function CACHE(string $cache_name)
|
||||
{
|
||||
|
@ -131,22 +144,22 @@ function CACHE(string $cache_name)
|
|||
/**
|
||||
* Datastore
|
||||
*/
|
||||
switch ($bb_cfg['datastore_type']) {
|
||||
switch (config()->get('datastore_type')) {
|
||||
case 'apcu':
|
||||
$datastore = new TorrentPier\Legacy\Datastore\APCu($bb_cfg['cache']['prefix']);
|
||||
$datastore = new TorrentPier\Legacy\Datastore\APCu(config()->get('cache.prefix'));
|
||||
break;
|
||||
case 'memcached':
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Memcached($bb_cfg['cache']['memcached'], $bb_cfg['cache']['prefix']);
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Memcached(config()->get('cache.memcached'), config()->get('cache.prefix'));
|
||||
break;
|
||||
case 'sqlite':
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Sqlite($bb_cfg['cache']['db_dir'] . 'datastore', $bb_cfg['cache']['prefix']);
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Sqlite(config()->get('cache.db_dir') . 'datastore', config()->get('cache.prefix'));
|
||||
break;
|
||||
case 'redis':
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Redis($bb_cfg['cache']['redis'], $bb_cfg['cache']['prefix']);
|
||||
$datastore = new TorrentPier\Legacy\Datastore\Redis(config()->get('cache.redis'), config()->get('cache.prefix'));
|
||||
break;
|
||||
case 'filecache':
|
||||
default:
|
||||
$datastore = new TorrentPier\Legacy\Datastore\File($bb_cfg['cache']['db_dir'] . 'datastore/', $bb_cfg['cache']['prefix']);
|
||||
$datastore = new TorrentPier\Legacy\Datastore\File(config()->get('cache.db_dir') . 'datastore/', config()->get('cache.prefix'));
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
|
|
@ -68,7 +68,7 @@ class Ajax
|
|||
*/
|
||||
public function exec()
|
||||
{
|
||||
global $lang, $bb_cfg;
|
||||
global $lang;
|
||||
|
||||
// Exit if we already have errors
|
||||
if (!empty($this->response['error_code'])) {
|
||||
|
@ -89,8 +89,8 @@ class Ajax
|
|||
}
|
||||
|
||||
// Exit if board is disabled via ON/OFF trigger or by admin
|
||||
if ($bb_cfg['board_disable'] || is_file(BB_DISABLED)) {
|
||||
if ($bb_cfg['board_disable']) {
|
||||
if (config()->get('board_disable') || is_file(BB_DISABLED)) {
|
||||
if (config()->get('board_disable')) {
|
||||
$this->ajax_die($lang['BOARD_DISABLE']);
|
||||
} elseif (is_file(BB_DISABLED) && $this->action !== 'manage_admin') {
|
||||
$this->ajax_die($lang['BOARD_DISABLE_CRON']);
|
||||
|
|
182
src/Config.php
Normal file
182
src/Config.php
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
/**
|
||||
* TorrentPier – Bull-powered BitTorrent tracker engine
|
||||
*
|
||||
* @copyright Copyright (c) 2005-2025 TorrentPier (https://torrentpier.com)
|
||||
* @link https://github.com/torrentpier/torrentpier for the canonical source repository
|
||||
* @license https://github.com/torrentpier/torrentpier/blob/master/LICENSE MIT License
|
||||
*/
|
||||
|
||||
namespace TorrentPier;
|
||||
|
||||
/**
|
||||
* Configuration management class
|
||||
*
|
||||
* Encapsulates the global $bb_cfg array and provides methods to access configuration values
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
private static ?Config $instance = null;
|
||||
private array $config = [];
|
||||
|
||||
private function __construct(array $config = [])
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance of Config
|
||||
*/
|
||||
public static function getInstance(array $config = []): Config
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self($config);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the config with the global $bb_cfg array
|
||||
*/
|
||||
public static function init(array $bb_cfg): Config
|
||||
{
|
||||
self::$instance = new self($bb_cfg);
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a configuration value by key
|
||||
* Supports dot notation for nested arrays (e.g., 'db.host')
|
||||
*/
|
||||
public function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
if (str_contains($key, '.')) {
|
||||
return $this->getNestedValue($key, $default);
|
||||
}
|
||||
|
||||
return $this->config[$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a configuration value by key
|
||||
* Supports dot notation for nested arrays
|
||||
*/
|
||||
public function set(string $key, mixed $value): void
|
||||
{
|
||||
if (str_contains($key, '.')) {
|
||||
$this->setNestedValue($key, $value);
|
||||
} else {
|
||||
$this->config[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a configuration key exists
|
||||
* Supports dot notation for nested arrays
|
||||
*/
|
||||
public function has(string $key): bool
|
||||
{
|
||||
if (str_contains($key, '.')) {
|
||||
return $this->getNestedValue($key) !== null;
|
||||
}
|
||||
|
||||
return array_key_exists($key, $this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all configuration values
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a nested value using dot notation
|
||||
*/
|
||||
private function getNestedValue(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$keys = explode('.', $key);
|
||||
$value = $this->config;
|
||||
|
||||
foreach ($keys as $k) {
|
||||
if (!is_array($value) || !array_key_exists($k, $value)) {
|
||||
return $default;
|
||||
}
|
||||
$value = $value[$k];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a nested value using dot notation
|
||||
*/
|
||||
private function setNestedValue(string $key, mixed $value): void
|
||||
{
|
||||
$keys = explode('.', $key);
|
||||
$target = &$this->config;
|
||||
|
||||
foreach ($keys as $k) {
|
||||
if (!isset($target[$k]) || !is_array($target[$k])) {
|
||||
$target[$k] = [];
|
||||
}
|
||||
$target = &$target[$k];
|
||||
}
|
||||
|
||||
$target = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional configuration values
|
||||
*/
|
||||
public function merge(array $config): void
|
||||
{
|
||||
$this->config = array_merge_recursive($this->config, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a section of the configuration
|
||||
*/
|
||||
public function getSection(string $section): array
|
||||
{
|
||||
return $this->config[$section] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to allow property access
|
||||
*/
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to allow property setting
|
||||
*/
|
||||
public function __set(string $key, mixed $value): void
|
||||
{
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to check if property exists
|
||||
*/
|
||||
public function __isset(string $key): bool
|
||||
{
|
||||
return $this->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent cloning of the singleton instance
|
||||
*/
|
||||
private function __clone() {}
|
||||
|
||||
/**
|
||||
* Prevent unserialization of the singleton instance
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \Exception("Cannot unserialize a singleton.");
|
||||
}
|
||||
}
|
|
@ -87,17 +87,15 @@ class Emailer
|
|||
*/
|
||||
public function set_template(string $template_file, string $template_lang = ''): void
|
||||
{
|
||||
global $bb_cfg;
|
||||
|
||||
if (!$template_lang) {
|
||||
$template_lang = $bb_cfg['default_lang'];
|
||||
$template_lang = config()->get('default_lang');
|
||||
}
|
||||
|
||||
if (empty($this->tpl_msg[$template_lang . $template_file])) {
|
||||
$tpl_file = LANG_ROOT_DIR . '/' . $template_lang . '/email/' . $template_file . '.html';
|
||||
|
||||
if (!is_file($tpl_file)) {
|
||||
$tpl_file = LANG_ROOT_DIR . '/' . $bb_cfg['default_lang'] . '/email/' . $template_file . '.html';
|
||||
$tpl_file = LANG_ROOT_DIR . '/' . config()->get('default_lang') . '/email/' . $template_file . '.html';
|
||||
|
||||
if (!is_file($tpl_file)) {
|
||||
throw new Exception('Could not find email template file: ' . $template_file);
|
||||
|
@ -125,9 +123,9 @@ class Emailer
|
|||
*/
|
||||
public function send(string $email_format = 'text/plain'): bool
|
||||
{
|
||||
global $bb_cfg, $lang;
|
||||
global $lang;
|
||||
|
||||
if (!$bb_cfg['emailer']['enabled']) {
|
||||
if (!config()->get('emailer.enabled')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -142,24 +140,25 @@ class Emailer
|
|||
$this->subject = !empty($this->subject) ? $this->subject : $lang['EMAILER_SUBJECT']['EMPTY'];
|
||||
|
||||
/** Prepare message */
|
||||
if ($bb_cfg['emailer']['smtp']['enabled']) {
|
||||
if (!empty($bb_cfg['emailer']['smtp']['host'])) {
|
||||
if (empty($bb_cfg['emailer']['smtp']['ssl_type'])) {
|
||||
$bb_cfg['emailer']['smtp']['ssl_type'] = null;
|
||||
if (config()->get('emailer.smtp.enabled')) {
|
||||
if (!empty(config()->get('emailer.smtp.host'))) {
|
||||
$sslType = config()->get('emailer.smtp.ssl_type');
|
||||
if (empty($sslType)) {
|
||||
$sslType = null;
|
||||
}
|
||||
/** @var EsmtpTransport $transport external SMTP with SSL */
|
||||
$transport = (new EsmtpTransport(
|
||||
$bb_cfg['emailer']['smtp']['host'],
|
||||
$bb_cfg['emailer']['smtp']['port'],
|
||||
$bb_cfg['emailer']['smtp']['ssl_type']
|
||||
config()->get('emailer.smtp.host'),
|
||||
config()->get('emailer.smtp.port'),
|
||||
$sslType
|
||||
))
|
||||
->setUsername($bb_cfg['emailer']['smtp']['username'])
|
||||
->setPassword($bb_cfg['emailer']['smtp']['password']);
|
||||
->setUsername(config()->get('emailer.smtp.username'))
|
||||
->setPassword(config()->get('emailer.smtp.password'));
|
||||
} else {
|
||||
$transport = new EsmtpTransport('localhost', 25);
|
||||
}
|
||||
} else {
|
||||
$transport = new SendmailTransport($bb_cfg['emailer']['sendmail_command']);
|
||||
$transport = new SendmailTransport(config()->get('emailer.sendmail_command'));
|
||||
}
|
||||
|
||||
$mailer = new Mailer($transport);
|
||||
|
@ -168,9 +167,9 @@ class Emailer
|
|||
$message = (new Email())
|
||||
->subject($this->subject)
|
||||
->to($this->to)
|
||||
->from(new Address($bb_cfg['board_email'], $bb_cfg['board_email_sitename']))
|
||||
->returnPath(new Address($bb_cfg['bounce_email']))
|
||||
->replyTo($this->reply ?? new Address($bb_cfg['board_email']));
|
||||
->from(new Address(config()->get('board_email'), config()->get('board_email_sitename')))
|
||||
->returnPath(new Address(config()->get('bounce_email')))
|
||||
->replyTo($this->reply ?? new Address(config()->get('board_email')));
|
||||
|
||||
/**
|
||||
* This non-standard header tells compliant autoresponders ("email holiday mode") to not
|
||||
|
@ -209,12 +208,10 @@ class Emailer
|
|||
*/
|
||||
public function assign_vars($vars): void
|
||||
{
|
||||
global $bb_cfg;
|
||||
|
||||
$this->vars = array_merge([
|
||||
'BOARD_EMAIL' => $bb_cfg['board_email'],
|
||||
'SITENAME' => $bb_cfg['board_email_sitename'],
|
||||
'EMAIL_SIG' => !empty($bb_cfg['board_email_sig']) ? "-- \n{$bb_cfg['board_email_sig']}" : '',
|
||||
'BOARD_EMAIL' => config()->get('board_email'),
|
||||
'SITENAME' => config()->get('board_email_sitename'),
|
||||
'EMAIL_SIG' => !empty(config()->get('board_email_sig')) ? "-- \n" . config()->get('board_email_sig') : '',
|
||||
], $vars);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue