mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Core/Config
* convert configuration from list of constants to object * fixes config changes not applying on cli whithout closing and reopening again * config variables are no longer embedded in localization text
This commit is contained in:
@@ -324,20 +324,7 @@ class AjaxAdmin extends AjaxHandler
|
||||
$key = trim($this->_get['key']);
|
||||
$val = trim(urldecode($this->_get['val']));
|
||||
|
||||
if ($key === null)
|
||||
return 'empty option name given';
|
||||
|
||||
if (!strlen($key))
|
||||
return 'invalid chars in option name: [a-z 0-9 _ . -] are allowed';
|
||||
|
||||
if (ini_get($key) === false || ini_set($key, $val) === false)
|
||||
return 'this configuration option cannot be set';
|
||||
|
||||
if (DB::Aowow()->selectCell('SELECT 1 FROM ?_config WHERE `flags` & ?d AND `key` = ?', CON_FLAG_PHP, $key))
|
||||
return 'this configuration option is already in use';
|
||||
|
||||
DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `cat`, `flags`) VALUES (?, ?, 0, ?d)', $key, $val, CON_FLAG_TYPE_STRING | CON_FLAG_PHP);
|
||||
return '';
|
||||
return Cfg::add($key, $val);
|
||||
}
|
||||
|
||||
protected function confRemove() : string
|
||||
@@ -345,39 +332,15 @@ class AjaxAdmin extends AjaxHandler
|
||||
if (!$this->reqGET('key'))
|
||||
return 'invalid configuration option given';
|
||||
|
||||
if (DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0', $this->_get['key'], CON_FLAG_PERSISTENT))
|
||||
return '';
|
||||
else
|
||||
return 'option name is either protected or was not found';
|
||||
return Cfg::delete($this->_get['key']);
|
||||
}
|
||||
|
||||
protected function confUpdate() : string
|
||||
{
|
||||
$key = trim($this->_get['key']);
|
||||
$val = trim(urldecode($this->_get['val']));
|
||||
$msg = '';
|
||||
|
||||
if (!strlen($key))
|
||||
return 'empty option name given';
|
||||
|
||||
$cfg = DB::Aowow()->selectRow('SELECT `flags`, `value` FROM ?_config WHERE `key` = ?', $key);
|
||||
if (!$cfg)
|
||||
return 'configuration option not found';
|
||||
|
||||
if (!($cfg['flags'] & CON_FLAG_TYPE_STRING) && !strlen($val))
|
||||
return 'empty value given';
|
||||
else if ($cfg['flags'] & CON_FLAG_TYPE_INT && !preg_match('/^-?\d+$/i', $val))
|
||||
return "value must be integer";
|
||||
else if ($cfg['flags'] & CON_FLAG_TYPE_FLOAT && !preg_match('/^-?\d*(,|.)?\d+$/i', $val))
|
||||
return "value must be float";
|
||||
else if ($cfg['flags'] & CON_FLAG_TYPE_BOOL && $val != '1')
|
||||
$val = '0';
|
||||
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $val, $key);
|
||||
if (!$this->confOnChange($key, $val, $msg))
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $cfg['value'], $key);
|
||||
|
||||
return $msg;
|
||||
return Cfg::set($key, $val);
|
||||
}
|
||||
|
||||
protected function wtSave() : string
|
||||
@@ -563,7 +526,7 @@ class AjaxAdmin extends AjaxHandler
|
||||
protected static function checkKey(string $val) : string
|
||||
{
|
||||
// expecting string
|
||||
if (preg_match('/[^a-z0-9_\.\-]/i', $val))
|
||||
if (preg_match(Cfg::PATTERN_INV_CONF_KEY, $val))
|
||||
return '';
|
||||
|
||||
return strtolower($val);
|
||||
@@ -586,73 +549,6 @@ class AjaxAdmin extends AjaxHandler
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**********/
|
||||
/* helper */
|
||||
/**********/
|
||||
|
||||
private static function confOnChange(string $key, string $val, string &$msg) : bool
|
||||
{
|
||||
$fn = $buildList = null;
|
||||
|
||||
switch ($key)
|
||||
{
|
||||
case 'battlegroup':
|
||||
$buildList = 'realms,realmMenu';
|
||||
break;
|
||||
case 'name_short':
|
||||
$buildList = 'searchboxBody,demo,searchplugin';
|
||||
break;
|
||||
case 'site_host':
|
||||
$buildList = 'searchplugin,demo,power,searchboxBody';
|
||||
break;
|
||||
case 'static_host':
|
||||
$buildList = 'searchplugin,power,searchboxBody,searchboxScript';
|
||||
break;
|
||||
case 'contact_email':
|
||||
$buildList = 'markup';
|
||||
break;
|
||||
case 'locales':
|
||||
$buildList = 'locales';
|
||||
$msg .= ' * remember to rebuild all static files for the language you just added.<br />';
|
||||
$msg .= ' * you can speed this up by supplying the regionCode to the setup: <pre class="q1">--locales=<regionCodes,> -f</pre>';
|
||||
break;
|
||||
case 'profiler_enable':
|
||||
$buildList = 'realms,realmMenu';
|
||||
$fn = function($x) use (&$msg) {
|
||||
if (!$x)
|
||||
return true;
|
||||
|
||||
return Profiler::queueStart($msg);
|
||||
};
|
||||
break;
|
||||
case 'acc_auth_mode':
|
||||
$fn = function($x) use (&$msg) {
|
||||
if ($x == 1 && !extension_loaded('gmp'))
|
||||
{
|
||||
$msg .= 'PHP extension GMP is required to use TrinityCore as auth source, but is not currently enabled.<br />';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
break;
|
||||
default: // nothing to do, everything is fine
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($buildList)
|
||||
{
|
||||
// we need to use exec as build() can only be run from CLI
|
||||
exec('php aowow --build='.$buildList, $out);
|
||||
foreach ($out as $o)
|
||||
if (strstr($o, 'ERR'))
|
||||
$msg .= explode('0m]', $o)[1]."<br />\n";
|
||||
}
|
||||
|
||||
return $fn ? $fn($val) : true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -86,7 +86,7 @@ class AjaxData extends AjaxHandler
|
||||
case 'item-scaling':
|
||||
case 'realms':
|
||||
case 'statistics':
|
||||
if (!Util::loadStaticFile($set, $result) && CFG_DEBUG)
|
||||
if (!Util::loadStaticFile($set, $result) && Cfg::get('DEBUG'))
|
||||
$result .= "alert('could not fetch static data: ".$set."');";
|
||||
|
||||
$result .= "\n\n";
|
||||
@@ -102,7 +102,7 @@ class AjaxData extends AjaxHandler
|
||||
case 'enchants':
|
||||
case 'itemsets':
|
||||
case 'pets':
|
||||
if (!Util::loadStaticFile($set, $result, true) && CFG_DEBUG)
|
||||
if (!Util::loadStaticFile($set, $result, true) && Cfg::get('DEBUG'))
|
||||
$result .= "alert('could not fetch static data: ".$set." for locale: ".User::$localeString."');";
|
||||
|
||||
$result .= "\n\n";
|
||||
|
||||
@@ -48,7 +48,7 @@ class AjaxProfile extends AjaxHandler
|
||||
if (!$this->params)
|
||||
return;
|
||||
|
||||
if (!CFG_PROFILER_ENABLE)
|
||||
if (!Cfg::get('PROFILER_ENABLE'))
|
||||
return;
|
||||
|
||||
switch ($this->params[0])
|
||||
@@ -563,7 +563,7 @@ class AjaxProfile extends AjaxHandler
|
||||
if ($pBase['realm'])
|
||||
{
|
||||
$profile['region'] = [$rData['region'], Lang::profiler('regions', $rData['region'])];
|
||||
$profile['battlegroup'] = [Profiler::urlize(CFG_BATTLEGROUP), CFG_BATTLEGROUP];
|
||||
$profile['battlegroup'] = [Profiler::urlize(Cfg::get('BATTLEGROUP')), Cfg::get('BATTLEGROUP')];
|
||||
$profile['realm'] = [Profiler::urlize($rData['name'], true), $rData['name']];
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ class AjaxProfile extends AjaxHandler
|
||||
$profile['titles'] = $data;
|
||||
break;
|
||||
case Type::QUEST:
|
||||
$qList = new QuestList(array(['id', array_keys($data)], CFG_SQL_LIMIT_NONE));
|
||||
$qList = new QuestList(array(['id', array_keys($data)], Cfg::get('SQL_LIMIT_NONE')));
|
||||
$qResult = [];
|
||||
foreach ($qList->iterate() as $id => $__)
|
||||
$qResult[$id] = [$qList->getField('cat1'), $qList->getField('cat2')];
|
||||
@@ -691,7 +691,7 @@ class AjaxProfile extends AjaxHandler
|
||||
|
||||
if ($items = DB::Aowow()->select('SELECT * FROM ?_profiler_items WHERE id = ?d', $pBase['id']))
|
||||
{
|
||||
$itemz = new ItemList(array(['id', array_column($items, 'item')], CFG_SQL_LIMIT_NONE));
|
||||
$itemz = new ItemList(array(['id', array_column($items, 'item')], Cfg::get('SQL_LIMIT_NONE')));
|
||||
if (!$itemz->error)
|
||||
{
|
||||
$data = $itemz->getListviewData(ITEMINFO_JSON | ITEMINFO_SUBITEMS);
|
||||
@@ -720,7 +720,7 @@ class AjaxProfile extends AjaxHandler
|
||||
|
||||
// if ($au = $char->getField('auras'))
|
||||
// {
|
||||
// $auraz = new SpellList(array(['id', $char->getField('auras')], CFG_SQL_LIMIT_NONE));
|
||||
// $auraz = new SpellList(array(['id', $char->getField('auras')], Cfg::get('SQL_LIMIT_NONE')));
|
||||
// $dataz = $auraz->getListviewData();
|
||||
// $modz = $auraz->getProfilerMods();
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ abstract class BaseType
|
||||
{
|
||||
$where = [];
|
||||
$linking = ' AND ';
|
||||
$limit = CFG_SQL_LIMIT_DEFAULT;
|
||||
$limit = Cfg::get('SQL_LIMIT_DEFAULT');
|
||||
|
||||
if (!$this->queryBase || $conditions === null)
|
||||
return;
|
||||
@@ -875,7 +875,7 @@ trait sourceHelper
|
||||
$buff[$_curTpl['moreType']][] = $_curTpl['moreTypeId'];
|
||||
|
||||
foreach ($buff as $type => $ids)
|
||||
$this->sourceMore[$type] = Type::newList($type, [CFG_SQL_LIMIT_NONE, ['id', $ids]]);
|
||||
$this->sourceMore[$type] = Type::newList($type, [Cfg::get('SQL_LIMIT_NONE'), ['id', $ids]]);
|
||||
}
|
||||
|
||||
$s = array_keys($this->sources[$this->id]);
|
||||
|
||||
@@ -116,7 +116,7 @@ class CommunityContent
|
||||
if (!$_)
|
||||
continue;
|
||||
|
||||
$obj = Type::newList($type, [CFG_SQL_LIMIT_NONE, ['id', $_]]);
|
||||
$obj = Type::newList($type, [Cfg::get('SQL_LIMIT_NONE'), ['id', $_]]);
|
||||
if (!$obj)
|
||||
continue;
|
||||
|
||||
@@ -154,7 +154,7 @@ class CommunityContent
|
||||
CC_FLAG_DELETED,
|
||||
User::$id,
|
||||
User::isInGroup(U_GROUP_COMMENTS_MODERATOR),
|
||||
CFG_SQL_LIMIT_DEFAULT
|
||||
Cfg::get('SQL_LIMIT_DEFAULT')
|
||||
);
|
||||
|
||||
foreach ($comments as $c)
|
||||
@@ -320,7 +320,7 @@ class CommunityContent
|
||||
if (!$ids)
|
||||
continue;
|
||||
|
||||
$obj = Type::newList($t, [CFG_SQL_LIMIT_NONE, ['id', $ids]]);
|
||||
$obj = Type::newList($t, [Cfg::get('SQL_LIMIT_NONE'), ['id', $ids]]);
|
||||
if (!$obj || $obj->error)
|
||||
continue;
|
||||
|
||||
@@ -410,13 +410,13 @@ class CommunityContent
|
||||
{
|
||||
$videos = DB::Aowow()->selectPage($nFound, self::$viQuery,
|
||||
CC_FLAG_STICKY,
|
||||
$typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP,
|
||||
$typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP,
|
||||
CC_FLAG_APPROVED,
|
||||
CC_FLAG_DELETED,
|
||||
!$typeOrUser ? 'date' : DBSIMPLE_SKIP,
|
||||
!$typeOrUser ? CFG_SQL_LIMIT_SEARCH : DBSIMPLE_SKIP
|
||||
!$typeOrUser ? 'date' : DBSIMPLE_SKIP,
|
||||
!$typeOrUser ? Cfg::get('SQL_LIMIT_SEARCH') : DBSIMPLE_SKIP
|
||||
);
|
||||
|
||||
if ($typeOrUser <= 0) // not for search by type/typeId
|
||||
@@ -455,13 +455,13 @@ class CommunityContent
|
||||
{
|
||||
$screenshots = DB::Aowow()->selectPage($nFound, self::$ssQuery,
|
||||
CC_FLAG_STICKY,
|
||||
$typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP,
|
||||
$typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP,
|
||||
$typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP,
|
||||
CC_FLAG_APPROVED,
|
||||
CC_FLAG_DELETED,
|
||||
!$typeOrUser ? 'date' : DBSIMPLE_SKIP,
|
||||
!$typeOrUser ? CFG_SQL_LIMIT_SEARCH : DBSIMPLE_SKIP
|
||||
!$typeOrUser ? 'date' : DBSIMPLE_SKIP,
|
||||
!$typeOrUser ? Cfg::get('SQL_LIMIT_SEARCH') : DBSIMPLE_SKIP
|
||||
);
|
||||
|
||||
if ($typeOrUser <= 0) // not for search by type/typeId
|
||||
|
||||
387
includes/config.class.php
Normal file
387
includes/config.class.php
Normal file
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
|
||||
if (!defined('AOWOW_REVISION'))
|
||||
die('illegal access');
|
||||
|
||||
class Cfg
|
||||
{
|
||||
public const PATTERN_CONF_KEY = '/[a-z0-9_\.\-]/i';
|
||||
public const PATTERN_INV_CONF_KEY = '/[^a-z0-9_\.\-]/i';
|
||||
public const PATTERN_INVALID_CHARS = '/\p{C}/ui';
|
||||
|
||||
// config flags
|
||||
public const FLAG_TYPE_INT = 0x001; // validate with intVal()
|
||||
public const FLAG_TYPE_FLOAT = 0x002; // validate with floatVal()
|
||||
public const FLAG_TYPE_BOOL = 0x004; // 0 || 1
|
||||
public const FLAG_TYPE_STRING = 0x008; //
|
||||
public const FLAG_OPT_LIST = 0x010; // single option
|
||||
public const FLAG_BITMASK = 0x020; // multiple options
|
||||
public const FLAG_PHP = 0x040; // applied with ini_set() [restrictions apply!]
|
||||
public const FLAG_PERSISTENT = 0x080; // can not be deleted
|
||||
public const FLAG_REQUIRED = 0x100; // required to have non-empty value
|
||||
public const FLAG_ON_LOAD_FN = 0x200; // run static function of the same name after load
|
||||
public const FLAG_ON_SET_FN = 0x400; // run static function of the same name as validator
|
||||
public const FLAG_INTERNAL = 0x800; // can not be configures, automaticly calculated, skip on lists
|
||||
|
||||
public const CAT_MISCELLANEOUS = 0;
|
||||
public const CAT_SITE = 1;
|
||||
public const CAT_CACHE = 2;
|
||||
public const CAT_ACCOUNT = 3;
|
||||
public const CAT_SESSION = 4;
|
||||
public const CAT_SITE_REPUTATION = 5;
|
||||
public const CAT_ANALYTICS = 6;
|
||||
public const CAT_PROFILER = 7;
|
||||
|
||||
public static $categories = array( // don't mind the ordering ... please?
|
||||
1 => 'Site', 'Caching', 'Account', 'Session', 'Site Reputation', 'Google Analytics', 'Profiler', 0 => 'Other'
|
||||
);
|
||||
|
||||
private const IDX_VALUE = 0;
|
||||
private const IDX_FLAGS = 1;
|
||||
private const IDX_CATEGORY = 2;
|
||||
private const IDX_DEFAULT = 3;
|
||||
private const IDX_COMMENT = 4;
|
||||
|
||||
private static $store = []; // name => [value, flags, cat, default, comment]
|
||||
|
||||
private static $rebuildScripts = array(
|
||||
// 'rep_req_border_unco' => ['global'], // currently not a template or buildScript
|
||||
// 'rep_req_border_rare' => ['global'],
|
||||
// 'rep_req_border_epic' => ['global'],
|
||||
// 'rep_req_border_lege' => ['global'],
|
||||
'profiler_enable' => ['realms', 'realmMenu'],
|
||||
'battlegroup' => ['realms', 'realmMenu'],
|
||||
'name_short' => ['searchplugin', 'searchboxBody', 'searchboxScript', 'demo'],
|
||||
'site_host' => ['searchplugin', 'searchboxBody', 'searchboxScript', 'demo', 'power'],
|
||||
'static_host' => ['searchplugin', 'searchboxBody', 'searchboxScript', 'power'],
|
||||
'contact_email' => ['markup'],
|
||||
'locales' => ['locales']
|
||||
);
|
||||
|
||||
public static function load() : void
|
||||
{
|
||||
if (!DB::isConnectable(DB_AOWOW))
|
||||
return;
|
||||
|
||||
$sets = DB::Aowow()->select('SELECT `key` AS ARRAY_KEY, `value` AS "0", `flags` AS "1", `cat` AS "2", `default` AS "3", `comment` AS "4" FROM ?_config ORDER BY `key` ASC');
|
||||
foreach ($sets as $key => [$value, $flags, $catg, $default, $comment])
|
||||
{
|
||||
$php = $flags & self::FLAG_PHP;
|
||||
|
||||
if ($err = self::validate($value, $flags, $comment))
|
||||
{
|
||||
trigger_error('Aowow config '.strtoupper($key).' failed validation and was skipped: '.$err, E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($flags & self::FLAG_INTERNAL)
|
||||
{
|
||||
trigger_error('Aowow config '.strtoupper($key).' is flagged as internaly generated and should not have been set in DB.', E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($flags & self::FLAG_ON_LOAD_FN)
|
||||
{
|
||||
if (!method_exists('Cfg', $key))
|
||||
trigger_error('Aowow config '.strtoupper($key).' flagged for onLoadFN handling, but no handler was set', E_USER_WARNING);
|
||||
else
|
||||
self::{$key}($value);
|
||||
}
|
||||
|
||||
if ($php)
|
||||
ini_set(strtolower($key), $value);
|
||||
|
||||
self::$store[strtolower($key)] = [$value, $flags, $catg, $default, $comment];
|
||||
}
|
||||
}
|
||||
|
||||
public static function add(string $key, /*int|string*/ $value) : string
|
||||
{
|
||||
if (!$key)
|
||||
return 'empty option name given';
|
||||
|
||||
$key = strtolower($key);
|
||||
|
||||
if (preg_match(self::PATTERN_INV_CONF_KEY, $key))
|
||||
return 'invalid chars in option name: [a-z 0-9 _ . -] are allowed';
|
||||
|
||||
if (isset(self::$store[$key]))
|
||||
return 'this configuration option is already in use';
|
||||
|
||||
if ($errStr = self::validate($value))
|
||||
return $errStr;
|
||||
|
||||
if (ini_get($key) === false || ini_set($key, $value) === false)
|
||||
return 'this configuration option cannot be set';
|
||||
|
||||
$flags = self::FLAG_TYPE_STRING | self::FLAG_PHP;
|
||||
if (!DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `cat`, `flags`) VALUES (?, ?, ?d, ?d)', $key, $value, self::CAT_MISCELLANEOUS, $flags))
|
||||
return 'internal error';
|
||||
|
||||
self::$store[$key] = [$value, $flags, self::CAT_MISCELLANEOUS, null, null];
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function delete(string $key) : string
|
||||
{
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset(self::$store[$key]))
|
||||
return 'configuration option not found';
|
||||
|
||||
if (self::$store[$key][self::IDX_FLAGS] & self::FLAG_PERSISTENT)
|
||||
return 'can\'t delete persistent options';
|
||||
|
||||
if (!(self::$store[$key][self::IDX_FLAGS] & self::FLAG_PHP))
|
||||
return 'can\'t delete non-php options';
|
||||
|
||||
if (self::$store[$key][self::IDX_FLAGS] & self::FLAG_INTERNAL)
|
||||
return 'can\'t delete internal options';
|
||||
|
||||
if (!DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0 AND (`flags` & ?d) > 0', $key, self::FLAG_PERSISTENT, self::FLAG_PHP))
|
||||
return 'internal error';
|
||||
|
||||
unset(self::$store[$key]);
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function get(string $key, bool $fromDB = false, bool $fullInfo = false) // : int|float|string
|
||||
{
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset(self::$store[$key]))
|
||||
{
|
||||
trigger_error('cfg not defined: '.$key, E_USER_ERROR);
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($fromDB && $fullInfo)
|
||||
return array_values(DB::Aowow()->selectRow('SELECT `value`, `flags`, `cat`, `default`, `comment` FROM ?_config WHERE `key` = ?', $key));
|
||||
if ($fromDB)
|
||||
return DB::Aowow()->selectCell('SELECT `value` FROM ?_config WHERE `key` = ?', $key);
|
||||
if ($fullInfo)
|
||||
return self::$store[$key];
|
||||
|
||||
return self::$store[$key][self::IDX_VALUE];
|
||||
}
|
||||
|
||||
public static function set(string $key, /*int|string*/ $value, ?array &$rebuildFiles = []) : string
|
||||
{
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset(self::$store[$key]))
|
||||
return 'configuration option not found';
|
||||
|
||||
[$oldValue, $flags, , , $comment] = self::$store[$key];
|
||||
|
||||
if ($flags & self::FLAG_INTERNAL)
|
||||
return 'can\'t set internal options directly';
|
||||
|
||||
if ($err = self::validate($value, $flags, $comment))
|
||||
return $err;
|
||||
|
||||
if ($flags & self::FLAG_REQUIRED && !strlen($value))
|
||||
return 'empty value given for required config';
|
||||
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $value, $key);
|
||||
|
||||
self::$store[$key][self::IDX_VALUE] = $value;
|
||||
|
||||
// validate change
|
||||
if ($flags & self::FLAG_ON_SET_FN)
|
||||
{
|
||||
$errMsg = '';
|
||||
if (!method_exists('Cfg', $key))
|
||||
$errMsg = 'required onSetFN validator not set';
|
||||
else
|
||||
self::{$key}($value, $errMsg);
|
||||
|
||||
if ($errMsg)
|
||||
{
|
||||
// rollback change
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $oldValue, $key);
|
||||
self::$store[$key][self::IDX_VALUE] = $oldValue;
|
||||
|
||||
// trigger_error($errMsg) ?
|
||||
return $errMsg;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flags & self::FLAG_ON_LOAD_FN)
|
||||
{
|
||||
if (!method_exists('Cfg', $key))
|
||||
return 'Aowow config '.strtoupper($key).' flagged for onLoadFN handling, but no handler was set';
|
||||
else
|
||||
self::{$key}($value);
|
||||
}
|
||||
|
||||
// trigger setup build
|
||||
return self::handleFileBuild($key, $rebuildFiles);
|
||||
}
|
||||
|
||||
public static function reset(string $key, ?array &$rebuildFiles = []) : string
|
||||
{
|
||||
$key = strtolower($key);
|
||||
|
||||
if (!isset(self::$store[$key]))
|
||||
return 'configuration option not found';
|
||||
|
||||
[, $flags, , $default, ] = self::$store[$key];
|
||||
if ($flags & self::FLAG_INTERNAL)
|
||||
return 'can\'t set internal options directly';
|
||||
|
||||
if (!$default)
|
||||
return 'config option has no default value';
|
||||
|
||||
// @eval .. some dafault values are supplied as bitmask or the likes
|
||||
if (!($flags & Cfg::FLAG_TYPE_STRING))
|
||||
$default = @eval('return ('.$default.');');
|
||||
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $default, $key);
|
||||
self::$store[$key][self::IDX_VALUE] = $default;
|
||||
|
||||
// trigger setup build
|
||||
return self::handleFileBuild($key, $rebuildFiles);
|
||||
}
|
||||
|
||||
public static function forCategory(int $category) : Generator
|
||||
{
|
||||
foreach (self::$store as $k => [, $flags, $catg, , ])
|
||||
if ($catg == $category && !($flags & self::FLAG_INTERNAL))
|
||||
yield $k => self::$store[$k];
|
||||
}
|
||||
|
||||
public static function applyToString(string $string) : string
|
||||
{
|
||||
return preg_replace_callback(
|
||||
['/CFG_([A-Z_]+)/', '/((HOST|STATIC)_URL)/'],
|
||||
function ($m) {
|
||||
if (!isset(self::$store[strtolower($m[1])]))
|
||||
return $m[1];
|
||||
|
||||
[$val, $flags, , , ] = self::$store[strtolower($m[1])];
|
||||
return $flags & (self::FLAG_TYPE_FLOAT | self::FLAG_TYPE_INT) ? Lang::nf($val) : $val;
|
||||
},
|
||||
$string
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/************/
|
||||
/* internal */
|
||||
/************/
|
||||
|
||||
private static function validate(&$value, int $flags = self::FLAG_TYPE_STRING | self::FLAG_PHP, string $comment = ' - ') : string
|
||||
{
|
||||
$value = preg_replace(self::PATTERN_INVALID_CHARS, '', $value);
|
||||
|
||||
if (!($flags & (self::FLAG_TYPE_BOOL | self::FLAG_TYPE_FLOAT | self::FLAG_TYPE_INT | self::FLAG_TYPE_STRING)))
|
||||
return 'no type set for value';
|
||||
|
||||
if ($flags & self::FLAG_TYPE_INT && !Util::checkNumeric($value, NUM_CAST_INT))
|
||||
return 'value must be integer';
|
||||
|
||||
if ($flags & self::FLAG_TYPE_FLOAT && !Util::checkNumeric($value, NUM_CAST_FLOAT))
|
||||
return 'value must be float';
|
||||
|
||||
if ($flags & self::FLAG_OPT_LIST)
|
||||
{
|
||||
$info = explode(' - ', $comment)[1];
|
||||
foreach (explode(', ', $info) as $option)
|
||||
if (explode(':', $option)[0] == $value)
|
||||
return '';
|
||||
|
||||
return 'value not in range';
|
||||
}
|
||||
|
||||
if ($flags & self::FLAG_BITMASK)
|
||||
{
|
||||
$mask = 0x0;
|
||||
$info = explode(' - ', $comment)[1];
|
||||
foreach (explode(', ', $info) as $option)
|
||||
$mask |= (1 << explode(':', $option)[0]);
|
||||
|
||||
if (!($value &= $mask))
|
||||
return 'value not in range';
|
||||
}
|
||||
|
||||
if ($flags & self::FLAG_TYPE_BOOL)
|
||||
$value = (bool)$value;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private static function handleFileBuild(string $key, array &$rebuildFiles) : string
|
||||
{
|
||||
if (!isset(self::$rebuildScripts[$key]))
|
||||
return '';
|
||||
|
||||
$msg = '';
|
||||
|
||||
if (CLI)
|
||||
{
|
||||
$rebuildFiles = array_merge($rebuildFiles, self::$rebuildScripts[$key]);
|
||||
return '';
|
||||
}
|
||||
|
||||
// not in CLI mode and build() can only be run from CLI. .. todo: other options..?
|
||||
exec('php aowow --build='.implode(',', self::$rebuildScripts[$key]), $out);
|
||||
foreach ($out as $o)
|
||||
if (strstr($o, 'ERR'))
|
||||
$msg .= explode('0m]', $o)[1]."<br />\n";
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
private static function acc_auth_mode(/*int|string*/ $value, ?string $msg = '') : bool
|
||||
{
|
||||
if ($value == 1 && !extension_loaded('gmp'))
|
||||
{
|
||||
$msg .= 'PHP extension GMP is required to use TrinityCore as auth source, but is not currently enabled.';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function profiler_enable(/*int|string*/ $value, ?string $msg = '') : bool
|
||||
{
|
||||
if ($value != 1)
|
||||
return true;
|
||||
|
||||
return Profiler::queueStart($msg);
|
||||
}
|
||||
|
||||
private static function static_host(/*int|string*/ $value, ?string $msg = '') : bool
|
||||
{
|
||||
self::$store['static_url'] = array( // points js to images & scripts
|
||||
(self::useSSL() ? 'https://' : 'http://').$value,
|
||||
self::FLAG_PERSISTENT | self::FLAG_TYPE_STRING | self::FLAG_INTERNAL,
|
||||
self::CAT_SITE,
|
||||
null, // no default value
|
||||
null, // no comment/info
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function site_host(/*int|string*/ $value, ?string $msg = '') : bool
|
||||
{
|
||||
self::$store['host_url'] = array( // points js to executable files
|
||||
(self::useSSL() ? 'https://' : 'http://').$value,
|
||||
self::FLAG_PERSISTENT | self::FLAG_TYPE_STRING | self::FLAG_INTERNAL,
|
||||
self::CAT_SITE,
|
||||
null, // no default value
|
||||
null, // no comment/info
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function useSSL() : bool
|
||||
{
|
||||
return (($_SERVER['HTTPS'] ?? 'off') != 'off') || (self::$store['force_ssl'][self::IDX_VALUE] ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -79,7 +79,7 @@ class DB
|
||||
// make number sensible again
|
||||
$data['code'] = abs($data['code']);
|
||||
|
||||
if (defined('CFG_DEBUG') && CFG_DEBUG)
|
||||
if (Cfg::get('DEBUG') >= CLI::LOG_INFO)
|
||||
{
|
||||
echo "\nDB ERROR\n";
|
||||
foreach ($data as $k => $v)
|
||||
|
||||
@@ -98,16 +98,6 @@ define('SITEREP_ACTION_ARTICLE', 16); // Guide approved (a
|
||||
define('SITEREP_ACTION_USER_WARNED', 17); // Moderator Warning
|
||||
define('SITEREP_ACTION_USER_SUSPENDED', 18); // Moderator Suspension
|
||||
|
||||
// config flags
|
||||
define('CON_FLAG_TYPE_INT', 0x01); // validate with intVal()
|
||||
define('CON_FLAG_TYPE_FLOAT', 0x02); // validate with floatVal()
|
||||
define('CON_FLAG_TYPE_BOOL', 0x04); // 0 || 1
|
||||
define('CON_FLAG_TYPE_STRING', 0x08); //
|
||||
define('CON_FLAG_OPT_LIST', 0x10); // single option
|
||||
define('CON_FLAG_BITMASK', 0x20); // multiple options
|
||||
define('CON_FLAG_PHP', 0x40); // applied with ini_set() [restrictions apply!]
|
||||
define('CON_FLAG_PERSISTENT', 0x80); // can not be deleted
|
||||
|
||||
// Auth Result
|
||||
define('AUTH_OK', 0);
|
||||
define('AUTH_WRONGUSER', 1);
|
||||
|
||||
@@ -22,15 +22,10 @@ if ($error)
|
||||
die(CLI ? strip_tags($error) : $error);
|
||||
|
||||
|
||||
if (file_exists('config/config.php'))
|
||||
require_once 'config/config.php';
|
||||
else
|
||||
$AoWoWconf = [];
|
||||
|
||||
|
||||
require_once 'includes/defines.php';
|
||||
require_once 'includes/libs/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (using variant: https://github.com/ivan1986/DbSimple/tree/master)
|
||||
require_once 'includes/utilities.php'; // helper functions
|
||||
require_once 'includes/config.class.php'; // Config holder
|
||||
require_once 'includes/game.php'; // game related data & functions
|
||||
require_once 'includes/profiler.class.php';
|
||||
require_once 'includes/user.class.php';
|
||||
@@ -93,36 +88,59 @@ set_error_handler(function($errNo, $errStr, $errFile, $errLine)
|
||||
if (strstr($errStr, 'mysqli_connect') && $errNo == E_WARNING)
|
||||
return true;
|
||||
|
||||
$errName = 'unknown error'; // errors not in this list can not be handled by set_error_handler (as per documentation) or are ignored
|
||||
$uGroup = U_GROUP_EMPLOYEE;
|
||||
$errName = 'unknown error'; // errors not in this list can not be handled by set_error_handler (as per documentation) or are ignored
|
||||
$uGroup = U_GROUP_EMPLOYEE;
|
||||
$logLevel = CLI::LOG_BLANK;
|
||||
|
||||
if ($errNo == E_WARNING) // 0x0002
|
||||
$errName = 'E_WARNING';
|
||||
{
|
||||
$errName = 'E_WARNING';
|
||||
$logLevel = CLI::LOG_WARN;
|
||||
}
|
||||
else if ($errNo == E_PARSE) // 0x0004
|
||||
$errName = 'E_PARSE';
|
||||
{
|
||||
$errName = 'E_PARSE';
|
||||
$logLevel = CLI::LOG_ERROR;
|
||||
}
|
||||
else if ($errNo == E_NOTICE) // 0x0008
|
||||
$errName = 'E_NOTICE';
|
||||
{
|
||||
$errName = 'E_NOTICE';
|
||||
$logLevel = CLI::LOG_INFO;
|
||||
}
|
||||
else if ($errNo == E_USER_ERROR) // 0x0100
|
||||
$errName = 'E_USER_ERROR';
|
||||
{
|
||||
$errName = 'E_USER_ERROR';
|
||||
$logLevel = CLI::LOG_ERROR;
|
||||
}
|
||||
else if ($errNo == E_USER_WARNING) // 0x0200
|
||||
$errName = 'E_USER_WARNING';
|
||||
{
|
||||
$errName = 'E_USER_WARNING';
|
||||
$logLevel = CLI::LOG_WARN;
|
||||
}
|
||||
else if ($errNo == E_USER_NOTICE) // 0x0400
|
||||
{
|
||||
$errName = 'E_USER_NOTICE';
|
||||
$uGroup = U_GROUP_STAFF;
|
||||
$errName = 'E_USER_NOTICE';
|
||||
$uGroup = U_GROUP_STAFF;
|
||||
$logLevel = CLI::LOG_INFO;
|
||||
}
|
||||
else if ($errNo == E_RECOVERABLE_ERROR) // 0x1000
|
||||
$errName = 'E_RECOVERABLE_ERROR';
|
||||
|
||||
Util::addNote($uGroup, $errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine);
|
||||
if (CLI)
|
||||
CLI::write($errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine, $errNo & (E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE) ? CLI::LOG_WARN : CLI::LOG_ERROR);
|
||||
{
|
||||
$errName = 'E_RECOVERABLE_ERROR';
|
||||
$logLevel = CLI::LOG_ERROR;
|
||||
}
|
||||
|
||||
if (DB::isConnected(DB_AOWOW))
|
||||
DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()',
|
||||
AOWOW_REVISION, $errNo, $errFile, $errLine, CLI ? 'CLI' : ($_SERVER['QUERY_STRING'] ?? ''), User::$groups, $errStr
|
||||
);
|
||||
|
||||
if (Cfg::get('DEBUG') >= $logLevel)
|
||||
{
|
||||
Util::addNote($uGroup, $errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine);
|
||||
if (CLI)
|
||||
CLI::write($errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine, $errNo & (E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE) ? CLI::LOG_WARN : CLI::LOG_ERROR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}, E_AOWOW);
|
||||
|
||||
@@ -161,6 +179,11 @@ register_shutdown_function(function()
|
||||
});
|
||||
|
||||
// Setup DB-Wrapper
|
||||
if (file_exists('config/config.php'))
|
||||
require_once 'config/config.php';
|
||||
else
|
||||
$AoWoWconf = [];
|
||||
|
||||
if (!empty($AoWoWconf['aowow']['db']))
|
||||
DB::load(DB_AOWOW, $AoWoWconf['aowow']);
|
||||
|
||||
@@ -175,80 +198,29 @@ if (!empty($AoWoWconf['characters']))
|
||||
if (!empty($charDBInfo))
|
||||
DB::load(DB_CHARACTERS . $realm, $charDBInfo);
|
||||
|
||||
|
||||
// load config to constants
|
||||
function loadConfig(bool $noPHP = false) : void
|
||||
{
|
||||
$sets = DB::isConnected(DB_AOWOW) ? DB::Aowow()->select('SELECT `key` AS ARRAY_KEY, `value`, `flags` FROM ?_config') : [];
|
||||
foreach ($sets as $k => $v)
|
||||
{
|
||||
$php = $v['flags'] & CON_FLAG_PHP;
|
||||
if ($php && $noPHP)
|
||||
continue;
|
||||
|
||||
// this should not have been possible
|
||||
if (!strlen($v['value']) && !($v['flags'] & CON_FLAG_TYPE_STRING) && !$php)
|
||||
{
|
||||
trigger_error('Aowow config value CFG_'.strtoupper($k).' is empty - config will not be used!', E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($v['flags'] & CON_FLAG_TYPE_INT)
|
||||
$val = intVal($v['value']);
|
||||
else if ($v['flags'] & CON_FLAG_TYPE_FLOAT)
|
||||
$val = floatVal($v['value']);
|
||||
else if ($v['flags'] & CON_FLAG_TYPE_BOOL)
|
||||
$val = (bool)$v['value'];
|
||||
else if ($v['flags'] & CON_FLAG_TYPE_STRING)
|
||||
$val = preg_replace("/[\p{C}]/ui", '', $v['value']);
|
||||
else if ($php)
|
||||
{
|
||||
trigger_error('PHP config value '.strtolower($k).' has no type set - config will not be used!', E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
else // if (!$php)
|
||||
{
|
||||
trigger_error('Aowow config value CFG_'.strtoupper($k).' has no type set - value forced to 0!', E_USER_ERROR);
|
||||
$val = 0;
|
||||
}
|
||||
|
||||
if ($php)
|
||||
ini_set(strtolower($k), $val);
|
||||
else if (!defined('CFG_'.strtoupper($k)))
|
||||
define('CFG_'.strtoupper($k), $val);
|
||||
}
|
||||
|
||||
$required = ['CFG_SCREENSHOT_MIN_SIZE', 'CFG_CONTACT_EMAIL', 'CFG_NAME', 'CFG_NAME_SHORT', 'CFG_FORCE_SSL', 'CFG_DEBUG'];
|
||||
foreach ($required as $r)
|
||||
if (!defined($r))
|
||||
define($r, '');
|
||||
}
|
||||
loadConfig();
|
||||
$AoWoWconf = null; // empty auths
|
||||
|
||||
|
||||
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || (!empty($AoWoWconf['aowow']) && CFG_FORCE_SSL);
|
||||
if (defined('CFG_STATIC_HOST')) // points js to images & scripts
|
||||
define('STATIC_URL', ($secure ? 'https://' : 'http://').CFG_STATIC_HOST);
|
||||
|
||||
if (defined('CFG_SITE_HOST')) // points js to executable files
|
||||
define('HOST_URL', ($secure ? 'https://' : 'http://').CFG_SITE_HOST);
|
||||
// load config from DB
|
||||
Cfg::load();
|
||||
|
||||
|
||||
// handle non-fatal errors and notices
|
||||
error_reporting(CFG_DEBUG ? E_AOWOW : 0);
|
||||
error_reporting(Cfg::get('DEBUG') ? E_AOWOW : 0);
|
||||
|
||||
|
||||
if (!CLI)
|
||||
{
|
||||
// not displaying the brb gnomes as static_host is missing, but eh...
|
||||
if (!DB::isConnected(DB_AOWOW) || !DB::isConnected(DB_WORLD) || !defined('HOST_URL') || !defined('STATIC_URL'))
|
||||
if (!DB::isConnected(DB_AOWOW) || !DB::isConnected(DB_WORLD) || !Cfg::get('HOST_URL') || !Cfg::get('STATIC_URL'))
|
||||
(new GenericPage())->maintenance();
|
||||
|
||||
// Setup Session
|
||||
if (CFG_SESSION_CACHE_DIR && Util::writeDir(CFG_SESSION_CACHE_DIR))
|
||||
session_save_path(getcwd().'/'.CFG_SESSION_CACHE_DIR);
|
||||
$cacheDir = Cfg::get('SESSION_CACHE_DIR');
|
||||
if ($cacheDir && Util::writeDir($cacheDir))
|
||||
session_save_path(getcwd().'/'.$cacheDir);
|
||||
|
||||
session_set_cookie_params(15 * YEAR, '/', '', $secure, true);
|
||||
session_set_cookie_params(15 * YEAR, '/', '', (($_SERVER['HTTPS'] ?? 'off') != 'off') || Cfg::get('FORCE_SSL'), true);
|
||||
session_cache_limiter('private');
|
||||
if (!session_start())
|
||||
{
|
||||
@@ -260,7 +232,7 @@ if (!CLI)
|
||||
User::save(); // save user-variables in session
|
||||
|
||||
// set up some logging (~10 queries will execute before we init the user and load the config)
|
||||
if (CFG_DEBUG && User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN))
|
||||
if (Cfg::get('DEBUG') >= CLI::LOG_INFO && User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN))
|
||||
{
|
||||
DB::Aowow()->setLogger(['DB', 'profiler']);
|
||||
DB::World()->setLogger(['DB', 'profiler']);
|
||||
@@ -278,7 +250,7 @@ if (!CLI)
|
||||
if (isset($_GET['locale']))
|
||||
{
|
||||
$loc = intVal($_GET['locale']);
|
||||
if ($loc <= MAX_LOCALES && $loc >= 0 && (CFG_LOCALES & (1 << $loc)))
|
||||
if ($loc <= MAX_LOCALES && $loc >= 0 && (Cfg::get('LOCALES') & (1 << $loc)))
|
||||
User::useLocale($loc);
|
||||
}
|
||||
|
||||
@@ -293,6 +265,4 @@ if (!CLI)
|
||||
else if (DB::isConnected(DB_AOWOW))
|
||||
Lang::load(LOCALE_EN);
|
||||
|
||||
$AoWoWconf = null; // empty auths
|
||||
|
||||
?>
|
||||
|
||||
@@ -283,7 +283,7 @@ class Loot
|
||||
if (!$struct)
|
||||
return false;
|
||||
|
||||
$items = new ItemList(array(['i.id', $struct[1]], CFG_SQL_LIMIT_NONE));
|
||||
$items = new ItemList(array(['i.id', $struct[1]], Cfg::get('SQL_LIMIT_NONE')));
|
||||
$this->jsGlobals = $items->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED);
|
||||
$foo = $items->getListviewData();
|
||||
|
||||
@@ -386,13 +386,16 @@ class Loot
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getByItem(int $entry, int $maxResults = CFG_SQL_LIMIT_DEFAULT, array $lootTableList = []) : bool
|
||||
public function getByItem(int $entry, int $maxResults = -1, array $lootTableList = []) : bool
|
||||
{
|
||||
$this->entry = intVal($entry);
|
||||
|
||||
if (!$this->entry)
|
||||
return false;
|
||||
|
||||
if ($maxResults < 0)
|
||||
$maxResults = Cfg::get('SQL_LIMIT_DEFAULT');
|
||||
|
||||
// [fileName, tabData, tabName, tabId, extraCols, hiddenCols, visibleCols]
|
||||
$tabsFinal = array(
|
||||
[Type::ITEM, [], '$LANG.tab_containedin', 'contained-in-item', [], [], []],
|
||||
|
||||
@@ -243,7 +243,7 @@ class Profiler
|
||||
// not on already scheduled - recalc time and set status to PR_QUEUE_STATUS_WAITING
|
||||
if ($rData['status'] != PR_QUEUE_STATUS_WAITING)
|
||||
{
|
||||
$newTime = CFG_DEBUG ? time() : max($rData['time'] + CFG_PROFILER_RESYNC_DELAY, time());
|
||||
$newTime = Cfg::get('DEBUG') ? time() : max($rData['time'] + Cfg::get('PROFILER_RESYNC_DELAY'), time());
|
||||
DB::Aowow()->query('UPDATE ?_profiler_sync SET requestTime = ?d, status = ?d, errorCode = 0 WHERE realm = ?d AND realmGUID = ?d AND `type` = ?d AND typeId = ?d', $newTime, PR_QUEUE_STATUS_WAITING, $realmId, $guid, $type, $localId);
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ class Profiler
|
||||
|
||||
public static function resyncStatus($type, array $subjectGUIDs)
|
||||
{
|
||||
$response = [CFG_PROFILER_ENABLE ? 2 : 0]; // in theory you could have multiple queues; used as divisor for: (15 / x) + 2
|
||||
$response = [Cfg::get('PROFILER_ENABLE') ? 2 : 0]; // in theory you could have multiple queues; used as divisor for: (15 / x) + 2
|
||||
if (!$subjectGUIDs)
|
||||
$response[] = [PR_QUEUE_STATUS_ENDED, 0, 0, PR_QUEUE_ERROR_CHAR];
|
||||
else
|
||||
@@ -306,7 +306,7 @@ class Profiler
|
||||
else
|
||||
$response[] = array(
|
||||
$subjectStatus[$guid]['status'],
|
||||
$subjectStatus[$guid]['status'] != PR_QUEUE_STATUS_READY ? CFG_PROFILER_RESYNC_PING : 0,
|
||||
$subjectStatus[$guid]['status'] != PR_QUEUE_STATUS_READY ? Cfg::get('PROFILER_RESYNC_PING') : 0,
|
||||
array_search($type.':'.$guid, $queue) + 1,
|
||||
0,
|
||||
1 // nResycTries - unsure about this one
|
||||
|
||||
@@ -152,7 +152,7 @@ class RemoteArenaTeamList extends ArenaTeamList
|
||||
foreach ($this->iterate() as $guid => &$curTpl)
|
||||
{
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
|
||||
// realm, rank
|
||||
$r = explode(':', $guid);
|
||||
@@ -208,7 +208,7 @@ class RemoteArenaTeamList extends ArenaTeamList
|
||||
);
|
||||
|
||||
// equalize subject distribution across realms
|
||||
$limit = CFG_SQL_LIMIT_DEFAULT;
|
||||
$limit = Cfg::get('SQL_LIMIT_DEFAULT');
|
||||
foreach ($conditions as $c)
|
||||
if (is_int($c))
|
||||
$limit = $c;
|
||||
@@ -244,7 +244,7 @@ class RemoteArenaTeamList extends ArenaTeamList
|
||||
foreach ($teams as $team)
|
||||
$gladiators = array_merge($gladiators, array_keys($team));
|
||||
|
||||
$profiles[$realmId] = new RemoteProfileList(array(['c.guid', $gladiators], CFG_SQL_LIMIT_NONE), ['sv' => $realmId]);
|
||||
$profiles[$realmId] = new RemoteProfileList(array(['c.guid', $gladiators], Cfg::get('SQL_LIMIT_NONE')), ['sv' => $realmId]);
|
||||
|
||||
if (!$profiles[$realmId]->error)
|
||||
$profiles[$realmId]->initializeLocalEntries();
|
||||
@@ -346,7 +346,7 @@ class LocalArenaTeamList extends ArenaTeamList
|
||||
}
|
||||
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
|
||||
$curTpl['members'] = $members[$id];
|
||||
}
|
||||
|
||||
@@ -146,13 +146,13 @@ class GuideList extends BaseType
|
||||
if ($c = $this->getField('classId'))
|
||||
{
|
||||
$n = Lang::game('cl', $c);
|
||||
$specStr .= ' – <span class="icontiny c'.$c.'" style="background-image: url('.STATIC_URL.'/images/wow/icons/tiny/class_'.Game::$classFileStrings[$c].'.gif)">%s</span>';
|
||||
$specStr .= ' – <span class="icontiny c'.$c.'" style="background-image: url('.Cfg::get('STATIC_URL').'/images/wow/icons/tiny/class_'.Game::$classFileStrings[$c].'.gif)">%s</span>';
|
||||
|
||||
if (($s = $this->getField('specId')) > -1)
|
||||
{
|
||||
$i = Game::$specIconStrings[$c][$s];
|
||||
$n = '';
|
||||
$specStr .= '<span class="icontiny c'.$c.'" style="background-image: url('.STATIC_URL.'/images/wow/icons/tiny/'.$i.'.gif)">'.Lang::game('classSpecs', $c, $s).'</span>';
|
||||
$specStr .= '<span class="icontiny c'.$c.'" style="background-image: url('.Cfg::get('STATIC_URL').'/images/wow/icons/tiny/'.$i.'.gif)">'.Lang::game('classSpecs', $c, $s).'</span>';
|
||||
}
|
||||
|
||||
$specStr = sprintf($specStr, $n);
|
||||
|
||||
@@ -182,7 +182,7 @@ class RemoteGuildList extends GuildList
|
||||
foreach ($this->iterate() as $guid => &$curTpl)
|
||||
{
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
|
||||
$r = explode(':', $guid)[0];
|
||||
if (!empty($realms[$r]))
|
||||
@@ -213,7 +213,7 @@ class RemoteGuildList extends GuildList
|
||||
$distrib[$curTpl['realm']]++;
|
||||
}
|
||||
|
||||
$limit = CFG_SQL_LIMIT_DEFAULT;
|
||||
$limit = Cfg::get('SQL_LIMIT_DEFAULT');
|
||||
foreach ($conditions as $c)
|
||||
if (is_int($c))
|
||||
$limit = $c;
|
||||
@@ -292,7 +292,7 @@ class LocalGuildList extends GuildList
|
||||
}
|
||||
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -834,7 +834,7 @@ class ItemList extends BaseType
|
||||
$pop = array_pop($enhance['g']);
|
||||
$col = $pop ? 1 : 0;
|
||||
$hasMatch &= $pop ? (($gems[$pop]['colorMask'] & (1 << $colorId)) ? 1 : 0) : 0;
|
||||
$icon = $pop ? sprintf(Util::$bgImagePath['tiny'], STATIC_URL, strtolower($gems[$pop]['iconString'])) : null;
|
||||
$icon = $pop ? sprintf('style="background-image: url(%s/images/wow/icons/tiny/%s.gif)"', Cfg::get('STATIC_URL'), strtolower($gems[$pop]['iconString'])) : null;
|
||||
$text = $pop ? Util::localizedString($gems[$pop], 'name') : Lang::item('socket', $colorId);
|
||||
|
||||
if ($interactive)
|
||||
@@ -848,7 +848,7 @@ class ItemList extends BaseType
|
||||
{
|
||||
$pop = array_pop($enhance['g']);
|
||||
$col = $pop ? 1 : 0;
|
||||
$icon = $pop ? sprintf(Util::$bgImagePath['tiny'], STATIC_URL, strtolower($gems[$pop]['iconString'])) : null;
|
||||
$icon = $pop ? sprintf('style="background-image: url(%s/images/wow/icons/tiny/%s.gif)"', Cfg::get('STATIC_URL'), strtolower($gems[$pop]['iconString'])) : null;
|
||||
$text = $pop ? Util::localizedString($gems[$pop], 'name') : Lang::item('socket', -1);
|
||||
|
||||
if ($interactive)
|
||||
@@ -1580,7 +1580,7 @@ class ItemList extends BaseType
|
||||
array_column($randEnchants, 'enchantId5')
|
||||
));
|
||||
|
||||
$enchants = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE));
|
||||
$enchants = new EnchantmentList(array(['id', $enchIds], Cfg::get('SQL_LIMIT_NONE')));
|
||||
foreach ($enchants->iterate() as $eId => $_)
|
||||
{
|
||||
$this->rndEnchIds[$eId] = array(
|
||||
|
||||
@@ -531,7 +531,7 @@ class RemoteProfileList extends ProfileList
|
||||
$talentSpells = [];
|
||||
$talentLookup = [];
|
||||
$distrib = null;
|
||||
$limit = CFG_SQL_LIMIT_DEFAULT;
|
||||
$limit = Cfg::get('SQL_LIMIT_DEFAULT');
|
||||
|
||||
foreach ($conditions as $c)
|
||||
if (is_int($c))
|
||||
@@ -541,7 +541,7 @@ class RemoteProfileList extends ProfileList
|
||||
foreach ($this->iterate() as $guid => &$curTpl)
|
||||
{
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
|
||||
// realm
|
||||
[$r, $g] = explode(':', $guid);
|
||||
@@ -575,7 +575,7 @@ class RemoteProfileList extends ProfileList
|
||||
$curTpl['activespec'] = $curTpl['activeTalentGroup'];
|
||||
|
||||
// equalize distribution
|
||||
if ($limit != CFG_SQL_LIMIT_NONE)
|
||||
if ($limit != Cfg::get('SQL_LIMIT_NONE'))
|
||||
{
|
||||
if (empty($distrib[$curTpl['realm']]))
|
||||
$distrib[$curTpl['realm']] = 1;
|
||||
@@ -753,7 +753,7 @@ class LocalProfileList extends ProfileList
|
||||
}
|
||||
|
||||
// battlegroup
|
||||
$curTpl['battlegroup'] = CFG_BATTLEGROUP;
|
||||
$curTpl['battlegroup'] = Cfg::get('BATTLEGROUP');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class SoundList extends BaseType
|
||||
// enum to string
|
||||
$data['type'] = self::$fileTypes[$data['type']];
|
||||
// get real url
|
||||
$data['url'] = STATIC_URL . '/wowsounds/' . $data['id'];
|
||||
$data['url'] = Cfg::get('STATIC_URL') . '/wowsounds/' . $data['id'];
|
||||
// v push v
|
||||
$this->fileBuffer[$id] = $data;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class SpellList extends BaseType
|
||||
}
|
||||
|
||||
if ($foo)
|
||||
$this->relItems = new ItemList(array(['i.id', array_unique($foo)], CFG_SQL_LIMIT_NONE));
|
||||
$this->relItems = new ItemList(array(['i.id', array_unique($foo)], Cfg::get('SQL_LIMIT_NONE')));
|
||||
}
|
||||
|
||||
// use if you JUST need the name
|
||||
|
||||
@@ -41,7 +41,7 @@ class User
|
||||
// check IP bans
|
||||
if ($ipBan = DB::Aowow()->selectRow('SELECT count, unbanDate FROM ?_account_bannedips WHERE ip = ? AND type = 0', self::$ip))
|
||||
{
|
||||
if ($ipBan['count'] > CFG_ACC_FAILED_AUTH_COUNT && $ipBan['unbanDate'] > time())
|
||||
if ($ipBan['count'] > Cfg::get('ACC_FAILED_AUTH_COUNT') && $ipBan['unbanDate'] > time())
|
||||
return false;
|
||||
else if ($ipBan['unbanDate'] <= time())
|
||||
DB::Aowow()->query('DELETE FROM ?_account_bannedips WHERE ip = ?', self::$ip);
|
||||
@@ -193,11 +193,12 @@ class User
|
||||
}
|
||||
|
||||
// check; pick first viable if failed
|
||||
if (CFG_LOCALES && !(CFG_LOCALES & (1 << $loc)))
|
||||
$allowedLoc = Cfg::get('LOCALES');
|
||||
if ($allowedLoc && !($allowedLoc & (1 << $loc)))
|
||||
{
|
||||
foreach (Util::$localeStrings as $idx => $__)
|
||||
{
|
||||
if (CFG_LOCALES & (1 << $idx))
|
||||
if ($allowedLoc & (1 << $idx))
|
||||
{
|
||||
$loc = $idx;
|
||||
break;
|
||||
@@ -236,7 +237,7 @@ class User
|
||||
$user = 0;
|
||||
$hash = '';
|
||||
|
||||
switch (CFG_ACC_AUTH_MODE)
|
||||
switch (Cfg::get('ACC_AUTH_MODE'))
|
||||
{
|
||||
case AUTH_MODE_SELF:
|
||||
{
|
||||
@@ -246,11 +247,11 @@ class User
|
||||
// handle login try limitation
|
||||
$ip = DB::Aowow()->selectRow('SELECT ip, count, unbanDate FROM ?_account_bannedips WHERE type = 0 AND ip = ?', self::$ip);
|
||||
if (!$ip || $ip['unbanDate'] < time()) // no entry exists or time expired; set count to 1
|
||||
DB::Aowow()->query('REPLACE INTO ?_account_bannedips (ip, type, count, unbanDate) VALUES (?, 0, 1, UNIX_TIMESTAMP() + ?d)', self::$ip, CFG_ACC_FAILED_AUTH_BLOCK);
|
||||
DB::Aowow()->query('REPLACE INTO ?_account_bannedips (ip, type, count, unbanDate) VALUES (?, 0, 1, UNIX_TIMESTAMP() + ?d)', self::$ip, Cfg::get('ACC_FAILED_AUTH_BLOCK'));
|
||||
else // entry already exists; increment count
|
||||
DB::Aowow()->query('UPDATE ?_account_bannedips SET count = count + 1, unbanDate = UNIX_TIMESTAMP() + ?d WHERE ip = ?', CFG_ACC_FAILED_AUTH_BLOCK, self::$ip);
|
||||
DB::Aowow()->query('UPDATE ?_account_bannedips SET count = count + 1, unbanDate = UNIX_TIMESTAMP() + ?d WHERE ip = ?', Cfg::get('ACC_FAILED_AUTH_BLOCK'), self::$ip);
|
||||
|
||||
if ($ip && $ip['count'] >= CFG_ACC_FAILED_AUTH_COUNT && $ip['unbanDate'] >= time())
|
||||
if ($ip && $ip['count'] >= Cfg::get('ACC_FAILED_AUTH_COUNT') && $ip['unbanDate'] >= time())
|
||||
return AUTH_IPBANNED;
|
||||
|
||||
$query = DB::Aowow()->SelectRow('
|
||||
@@ -406,12 +407,12 @@ class User
|
||||
// different auth modes require different usernames
|
||||
$min = 0; // external case
|
||||
$max = 0;
|
||||
if (CFG_ACC_AUTH_MODE == AUTH_MODE_SELF)
|
||||
if (Cfg::get('ACC_AUTH_MODE') == AUTH_MODE_SELF)
|
||||
{
|
||||
$min = 4;
|
||||
$max = 16;
|
||||
}
|
||||
else if (CFG_ACC_AUTH_MODE == AUTH_MODE_REALM)
|
||||
else if (Cfg::get('ACC_AUTH_MODE') == AUTH_MODE_REALM)
|
||||
{
|
||||
$min = 3;
|
||||
$max = 32;
|
||||
@@ -430,7 +431,7 @@ class User
|
||||
$errCode = 0;
|
||||
|
||||
// only enforce for own passwords
|
||||
if (mb_strlen($pass) < 6 && CFG_ACC_AUTH_MODE == AUTH_MODE_SELF)
|
||||
if (mb_strlen($pass) < 6 && Cfg::get('ACC_AUTH_MODE') == AUTH_MODE_SELF)
|
||||
$errCode = 1;
|
||||
// else if (preg_match('/[^\w\d!"#\$%]/', $pass)) // such things exist..? :o
|
||||
// $errCode = 2;
|
||||
@@ -443,7 +444,7 @@ class User
|
||||
$_SESSION['user'] = self::$id;
|
||||
$_SESSION['hash'] = self::$passHash;
|
||||
$_SESSION['locale'] = self::$localeId;
|
||||
$_SESSION['timeout'] = self::$expires ? time() + CFG_SESSION_TIMEOUT_DELAY : 0;
|
||||
$_SESSION['timeout'] = self::$expires ? time() + Cfg::get('SESSION_TIMEOUT_DELAY') : 0;
|
||||
// $_SESSION['dataKey'] does not depend on user login status and is set in User::init()
|
||||
}
|
||||
|
||||
@@ -475,7 +476,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_COMMENT | ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return false;
|
||||
|
||||
return self::$perms || self::$reputation >= CFG_REP_REQ_COMMENT;
|
||||
return self::$perms || self::$reputation >= Cfg::get('REP_REQ_COMMENT');
|
||||
}
|
||||
|
||||
public static function canReply()
|
||||
@@ -483,7 +484,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_COMMENT | ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return false;
|
||||
|
||||
return self::$perms || self::$reputation >= CFG_REP_REQ_REPLY;
|
||||
return self::$perms || self::$reputation >= Cfg::get('REP_REQ_REPLY');
|
||||
}
|
||||
|
||||
public static function canUpvote()
|
||||
@@ -491,7 +492,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_COMMENT | ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return false;
|
||||
|
||||
return self::$perms || (self::$reputation >= CFG_REP_REQ_UPVOTE && self::$dailyVotes > 0);
|
||||
return self::$perms || (self::$reputation >= Cfg::get('REP_REQ_UPVOTE') && self::$dailyVotes > 0);
|
||||
}
|
||||
|
||||
public static function canDownvote()
|
||||
@@ -499,7 +500,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_RATE | ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return false;
|
||||
|
||||
return self::$perms || (self::$reputation >= CFG_REP_REQ_DOWNVOTE && self::$dailyVotes > 0);
|
||||
return self::$perms || (self::$reputation >= Cfg::get('REP_REQ_DOWNVOTE') && self::$dailyVotes > 0);
|
||||
}
|
||||
|
||||
public static function canSupervote()
|
||||
@@ -507,7 +508,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_RATE | ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return false;
|
||||
|
||||
return self::$reputation >= CFG_REP_REQ_SUPERVOTE;
|
||||
return self::$reputation >= Cfg::get('REP_REQ_SUPERVOTE');
|
||||
}
|
||||
|
||||
public static function canUploadScreenshot()
|
||||
@@ -536,7 +537,7 @@ class User
|
||||
|
||||
public static function isPremium()
|
||||
{
|
||||
return self::isInGroup(U_GROUP_PREMIUM) || self::$reputation >= CFG_REP_REQ_PREMIUM;
|
||||
return self::isInGroup(U_GROUP_PREMIUM) || self::$reputation >= Cfg::get('REP_REQ_PREMIUM');
|
||||
}
|
||||
|
||||
/**************/
|
||||
@@ -559,7 +560,7 @@ class User
|
||||
if (!self::$id || self::$banStatus & (ACC_BAN_PERM | ACC_BAN_TEMP))
|
||||
return 0;
|
||||
|
||||
return CFG_USER_MAX_VOTES + (self::$reputation >= CFG_REP_REQ_VOTEMORE_BASE ? 1 + intVal((self::$reputation - CFG_REP_REQ_VOTEMORE_BASE) / CFG_REP_REQ_VOTEMORE_ADD) : 0);
|
||||
return Cfg::get('USER_MAX_VOTES') + (self::$reputation >= Cfg::get('REP_REQ_VOTEMORE_BASE') ? 1 + intVal((self::$reputation - Cfg::get('REP_REQ_VOTEMORE_BASE')) / Cfg::get('REP_REQ_VOTEMORE_ADD')) : 0);
|
||||
}
|
||||
|
||||
public static function getReputation()
|
||||
@@ -585,8 +586,8 @@ class User
|
||||
$gUser['canDownvote'] = self::canDownvote();
|
||||
$gUser['canPostReplies'] = self::canReply();
|
||||
$gUser['superCommentVotes'] = self::canSupervote();
|
||||
$gUser['downvoteRep'] = CFG_REP_REQ_DOWNVOTE;
|
||||
$gUser['upvoteRep'] = CFG_REP_REQ_UPVOTE;
|
||||
$gUser['downvoteRep'] = Cfg::get('REP_REQ_DOWNVOTE');
|
||||
$gUser['upvoteRep'] = Cfg::get('REP_REQ_UPVOTE');
|
||||
$gUser['characters'] = self::getCharacters();
|
||||
$gUser['excludegroups'] = self::$excludeGroups;
|
||||
$gUser['settings'] = (new StdClass); // profiler requires this to be set; has property premiumborder (NYI)
|
||||
|
||||
@@ -132,19 +132,19 @@ trait TrRequestData
|
||||
|
||||
abstract class CLI
|
||||
{
|
||||
const CHR_BELL = 7;
|
||||
const CHR_BACK = 8;
|
||||
const CHR_TAB = 9;
|
||||
const CHR_LF = 10;
|
||||
const CHR_CR = 13;
|
||||
const CHR_ESC = 27;
|
||||
const CHR_BACKSPACE = 127;
|
||||
private const CHR_BELL = 7;
|
||||
private const CHR_BACK = 8;
|
||||
private const CHR_TAB = 9;
|
||||
private const CHR_LF = 10;
|
||||
private const CHR_CR = 13;
|
||||
private const CHR_ESC = 27;
|
||||
private const CHR_BACKSPACE = 127;
|
||||
|
||||
const LOG_BLANK = 0;
|
||||
const LOG_OK = 1;
|
||||
const LOG_WARN = 2;
|
||||
const LOG_ERROR = 3;
|
||||
const LOG_INFO = 4;
|
||||
public const LOG_BLANK = 0;
|
||||
public const LOG_ERROR = 1;
|
||||
public const LOG_WARN = 2;
|
||||
public const LOG_INFO = 3;
|
||||
public const LOG_OK = 4;
|
||||
|
||||
private static $logHandle = null;
|
||||
private static $hasReadline = null;
|
||||
@@ -216,6 +216,11 @@ abstract class CLI
|
||||
}
|
||||
}
|
||||
|
||||
public static function grey(string $str) : string
|
||||
{
|
||||
return CLI_HAS_E ? "\e[90m".$str."\e[0m" : $str;
|
||||
}
|
||||
|
||||
public static function red(string $str) : string
|
||||
{
|
||||
return CLI_HAS_E ? "\e[31m".$str."\e[0m" : $str;
|
||||
@@ -536,17 +541,6 @@ abstract class Util
|
||||
null, 'bc', 'wotlk', 'cata', 'mop'
|
||||
);
|
||||
|
||||
public static $bgImagePath = array (
|
||||
'tiny' => 'style="background-image: url(%s/images/wow/icons/tiny/%s.gif)"',
|
||||
'small' => 'style="background-image: url(%s/images/wow/icons/small/%s.jpg)"',
|
||||
'medium' => 'style="background-image: url(%s/images/wow/icons/medium/%s.jpg)"',
|
||||
'large' => 'style="background-image: url(%s/images/wow/icons/large/%s.jpg)"',
|
||||
);
|
||||
|
||||
public static $configCats = array( // don't mind the ordering ... please?
|
||||
1 => 'Site', 'Caching', 'Account', 'Session', 'Site Reputation', 'Google Analytics', 'Profiler', 0 => 'Other'
|
||||
);
|
||||
|
||||
public static $tcEncoding = '0zMcmVokRsaqbdrfwihuGINALpTjnyxtgevElBCDFHJKOPQSUWXYZ123456789';
|
||||
private static $notes = [];
|
||||
|
||||
@@ -737,7 +731,7 @@ abstract class Util
|
||||
// html may contain 'Pictures' and FlavorImages and "stuff"
|
||||
$text = preg_replace_callback(
|
||||
'/src="([^"]+)"/i',
|
||||
function ($m) { return 'src="'.STATIC_URL.'/images/wow/'.strtr($m[1], ['\\' => '/']).'.png"'; },
|
||||
function ($m) { return sprintf('src="%s/images/wow/%s.png"', Cfg::get('STATIC_URL'), strtr($m[1], ['\\' => '/'])); },
|
||||
strtr($text, $pairs)
|
||||
);
|
||||
}
|
||||
@@ -848,8 +842,8 @@ abstract class Util
|
||||
return strtr($data, array(
|
||||
'<script' => '<scr"+"ipt',
|
||||
'script>' => 'scr"+"ipt>',
|
||||
'HOST_URL' => HOST_URL,
|
||||
'STATIC_URL' => STATIC_URL
|
||||
'HOST_URL' => Cfg::get('HOST_URL'),
|
||||
'STATIC_URL' => Cfg::get('STATIC_URL')
|
||||
));
|
||||
}
|
||||
|
||||
@@ -955,43 +949,59 @@ abstract class Util
|
||||
return mb_strtolower($str);
|
||||
}
|
||||
|
||||
// note: valid integer > 32bit are returned as float
|
||||
// doesn't handle scientific notation .. why would you input 3e3 for 3000..?
|
||||
public static function checkNumeric(&$data, $typeCast = NUM_ANY)
|
||||
{
|
||||
if ($data === null)
|
||||
return false;
|
||||
else if (!is_array($data))
|
||||
|
||||
if (is_array($data))
|
||||
{
|
||||
$rawData = $data; // do not transform strings
|
||||
|
||||
$data = trim($data);
|
||||
if (preg_match('/^-?\d*,\d+$/', $data))
|
||||
$data = strtr($data, ',', '.');
|
||||
|
||||
if (is_numeric($data))
|
||||
{
|
||||
$data += 0; // becomes float or int
|
||||
|
||||
if ((is_float($data) && $typeCast == NUM_REQ_INT) ||
|
||||
(is_int($data) && $typeCast == NUM_REQ_FLOAT))
|
||||
return false;
|
||||
|
||||
if (is_float($data) && $typeCast == NUM_CAST_INT)
|
||||
$data = intval($data);
|
||||
|
||||
if (is_int($data) && $typeCast == NUM_CAST_FLOAT)
|
||||
$data = floatval($data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$data = $rawData;
|
||||
return false;
|
||||
array_walk($data, function(&$x) use($typeCast) { self::checkNumeric($x, $typeCast); });
|
||||
return false; // always false for passed arrays
|
||||
}
|
||||
|
||||
array_walk($data, function(&$x) use($typeCast) { self::checkNumeric($x, $typeCast); });
|
||||
// already in required state
|
||||
if ((is_float($data) && $typeCast == NUM_REQ_FLOAT) ||
|
||||
(is_int($data) && $typeCast == NUM_REQ_INT))
|
||||
return true;
|
||||
|
||||
return false; // always false for passed arrays
|
||||
// irreconcilable state
|
||||
if ((!is_int($data) && $typeCast == NUM_REQ_INT) ||
|
||||
(!is_float($data) && $typeCast == NUM_REQ_FLOAT))
|
||||
return false;
|
||||
|
||||
$number = $data; // do not transform strings, store state
|
||||
$nMatches = 0;
|
||||
|
||||
$number = trim($number);
|
||||
$number = preg_replace('/^(-?\d*)[.,](\d+)$/', '$1.$2', $number, -1, $nMatches);
|
||||
|
||||
// is float string
|
||||
if ($nMatches)
|
||||
{
|
||||
if ($typeCast == NUM_CAST_INT)
|
||||
$data = intVal($number);
|
||||
else if ($typeCast == NUM_CAST_FLOAT)
|
||||
$data = floatVal($number);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// is int string (is_numeric can only handle strings in base 10)
|
||||
if (is_numeric($number) || preg_match('/0[xb]?\d+/', $number))
|
||||
{
|
||||
$number = intVal($number, 0); // 'base 0' auto-detects base
|
||||
if ($typeCast == NUM_CAST_INT)
|
||||
$data = $number;
|
||||
else if ($typeCast == NUM_CAST_FLOAT)
|
||||
$data = floatVal($number);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// is string string
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function arraySumByKey(array &$ref, array ...$adds) : void
|
||||
@@ -1090,18 +1100,18 @@ abstract class Util
|
||||
switch ($action)
|
||||
{
|
||||
case SITEREP_ACTION_REGISTER:
|
||||
$x['amount'] = CFG_REP_REWARD_REGISTER;
|
||||
$x['amount'] = Cfg::get('REP_REWARD_REGISTER');
|
||||
break;
|
||||
case SITEREP_ACTION_DAILYVISIT:
|
||||
$x['sourceA'] = time();
|
||||
$x['amount'] = CFG_REP_REWARD_DAILYVISIT;
|
||||
$x['amount'] = Cfg::get('REP_REWARD_DAILYVISIT');
|
||||
break;
|
||||
case SITEREP_ACTION_COMMENT:
|
||||
if (empty($miscData['id']))
|
||||
return false;
|
||||
|
||||
$x['sourceA'] = $miscData['id']; // commentId
|
||||
$x['amount'] = CFG_REP_REWARD_COMMENT;
|
||||
$x['amount'] = Cfg::get('REP_REWARD_COMMENT');
|
||||
break;
|
||||
case SITEREP_ACTION_UPVOTED:
|
||||
case SITEREP_ACTION_DOWNVOTED:
|
||||
@@ -1118,7 +1128,7 @@ abstract class Util
|
||||
|
||||
$x['sourceA'] = $miscData['id']; // commentId
|
||||
$x['sourceB'] = $miscData['voterId'];
|
||||
$x['amount'] = $action == SITEREP_ACTION_UPVOTED ? CFG_REP_REWARD_UPVOTED : CFG_REP_REWARD_DOWNVOTED;
|
||||
$x['amount'] = $action == SITEREP_ACTION_UPVOTED ? Cfg::get('REP_REWARD_UPVOTED') : Cfg::get('REP_REWARD_DOWNVOTED');
|
||||
break;
|
||||
case SITEREP_ACTION_UPLOAD:
|
||||
if (empty($miscData['id']) || empty($miscData['what']))
|
||||
@@ -1126,7 +1136,7 @@ abstract class Util
|
||||
|
||||
$x['sourceA'] = $miscData['id']; // screenshotId or videoId
|
||||
$x['sourceB'] = $miscData['what']; // screenshot:1 or video:NYD
|
||||
$x['amount'] = CFG_REP_REWARD_UPLOAD;
|
||||
$x['amount'] = Cfg::get('REP_REWARD_UPLOAD');
|
||||
break;
|
||||
case SITEREP_ACTION_GOOD_REPORT: // NYI
|
||||
case SITEREP_ACTION_BAD_REPORT:
|
||||
@@ -1134,14 +1144,14 @@ abstract class Util
|
||||
return false;
|
||||
|
||||
$x['sourceA'] = $miscData['id'];
|
||||
$x['amount'] = $action == SITEREP_ACTION_GOOD_REPORT ? CFG_REP_REWARD_GOOD_REPORT : CFG_REP_REWARD_BAD_REPORT;
|
||||
$x['amount'] = $action == SITEREP_ACTION_GOOD_REPORT ? Cfg::get('REP_REWARD_GOOD_REPORT') : Cfg::get('REP_REWARD_BAD_REPORT');
|
||||
break;
|
||||
case SITEREP_ACTION_ARTICLE:
|
||||
if (empty($miscData['id'])) // guideId
|
||||
return false;
|
||||
|
||||
$x['sourceA'] = $miscData['id'];
|
||||
$x['amount'] = CFG_REP_REWARD_ARTICLE;
|
||||
$x['amount'] = Cfg::get('REP_REWARD_ARTICLE');
|
||||
break;
|
||||
case SITEREP_ACTION_USER_WARNED: // NYI
|
||||
case SITEREP_ACTION_USER_SUSPENDED:
|
||||
@@ -1149,7 +1159,7 @@ abstract class Util
|
||||
return false;
|
||||
|
||||
$x['sourceA'] = $miscData['id'];
|
||||
$x['amount'] = $action == SITEREP_ACTION_USER_WARNED ? CFG_REP_REWARD_USER_WARNED : CFG_REP_REWARD_USER_SUSPENDED;
|
||||
$x['amount'] = $action == SITEREP_ACTION_USER_WARNED ? Cfg::get('REP_REWARD_USER_WARNED') : Cfg::get('REP_REWARD_USER_SUSPENDED');
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1318,7 +1328,7 @@ abstract class Util
|
||||
{
|
||||
$flags = $forceFlags ?: (JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
if (CFG_DEBUG && !$forceFlags)
|
||||
if (Cfg::get('DEBUG') && !$forceFlags)
|
||||
$flags |= JSON_PRETTY_PRINT;
|
||||
|
||||
$json = json_encode($data, $flags);
|
||||
@@ -1658,7 +1668,7 @@ abstract class Util
|
||||
return [(int)$deg, $desc];
|
||||
}
|
||||
|
||||
static function mask2bits($bitmask, $offset = 0)
|
||||
static function mask2bits(int $bitmask, int $offset = 0) : array
|
||||
{
|
||||
$bits = [];
|
||||
$i = 0;
|
||||
|
||||
Reference in New Issue
Block a user