mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Setup/Maintenance
* toggle maintenance mode in a more reasonable manner (i.e. not when displaying help test) * move connectivity tests to class DB * restore generate everything functionality when running --sql and --build with an empty parameter set
This commit is contained in:
@@ -49,6 +49,23 @@ class DB
|
||||
self::$connectionCache[$idx] = true;
|
||||
}
|
||||
|
||||
public static function test(array $options, ?string &$err = '') : bool
|
||||
{
|
||||
$defPort = ini_get('mysqli.default_port');
|
||||
$port = 0;
|
||||
if (strstr($options['host'], ':'))
|
||||
[$options['host'], $port] = explode(':', $options['host']);
|
||||
|
||||
if ($link = @mysqli_connect($options['host'], $options['user'], $options['pass'], $options['db'], $port ?: $defPort))
|
||||
{
|
||||
mysqli_close($link);
|
||||
return true;
|
||||
}
|
||||
|
||||
$err = '['.mysqli_connect_errno().'] '.mysqli_connect_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function errorHandler($message, $data)
|
||||
{
|
||||
if (!error_reporting())
|
||||
|
||||
@@ -12,65 +12,44 @@ require_once 'setup/tools/setupScript.class.php';
|
||||
require_once 'setup/tools/dbc.class.php';
|
||||
require_once 'setup/tools/imagecreatefromblp.func.php';
|
||||
|
||||
|
||||
function finish(bool $unlock = true) : void
|
||||
function finish() : void
|
||||
{
|
||||
if (CLISetup::getOpt('delete')) // generated with TEMPORARY keyword. Manual deletion is not needed
|
||||
CLI::write('generated dbc_* - tables have been deleted.', CLI::LOG_INFO);
|
||||
|
||||
if ($unlock)
|
||||
lockSite(false);
|
||||
|
||||
die("\n");
|
||||
}
|
||||
|
||||
function lockSite(bool $enable = true) : void
|
||||
{
|
||||
if (DB::isConnectable(DB_AOWOW))
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ?d WHERE `key` = "maintenance"', $enable ? 1 : 0);
|
||||
}
|
||||
|
||||
CLISetup::init();
|
||||
|
||||
if (!CLISetup::getOpt(0x3))
|
||||
die(CLISetup::optHelp(0x7));
|
||||
|
||||
$cmd = CLISetup::getOpt(0x3)[0]; // get arguments present in argGroup 1 or 2, if set. Pick first.
|
||||
$unlock = false;
|
||||
$s = [];
|
||||
$b = [];
|
||||
$cmd = CLISetup::getOpt(0x3)[0]; // get arguments present in argGroup 1 or 2, if set. Pick first.
|
||||
$s = [];
|
||||
$b = [];
|
||||
switch ($cmd) // we accept only one main parameter
|
||||
{
|
||||
case 'setup':
|
||||
lockSite(true);
|
||||
require_once 'setup/tools/clisetup/firstrun.func.php';
|
||||
$success = firstrun();
|
||||
|
||||
finish($success);
|
||||
case 'sql':
|
||||
case 'build':
|
||||
lockSite(true);
|
||||
$unlock = true;
|
||||
case 'account':
|
||||
case 'dbconfig':
|
||||
case 'siteconfig':
|
||||
require_once 'setup/tools/clisetup/'.$cmd.'.func.php';
|
||||
$cmd();
|
||||
|
||||
finish($unlock);
|
||||
finish();
|
||||
case 'update':
|
||||
lockSite(true);
|
||||
require_once 'setup/tools/clisetup/update.func.php';
|
||||
|
||||
[$s, $b] = update(); // return true if we do not rebuild stuff
|
||||
update($s, $b); // return true if we do not rebuild stuff
|
||||
if (!$s && !$b)
|
||||
finish(true);
|
||||
finish();
|
||||
case 'sync':
|
||||
lockSite(true);
|
||||
require_once 'setup/tools/clisetup/sync.func.php';
|
||||
|
||||
sync($s, $b);
|
||||
finish(true);
|
||||
finish();
|
||||
case 'dbc':
|
||||
foreach (CLISetup::getOpt('dbc') as $n)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,12 @@ class CLISetup
|
||||
'ruRU' => LOCALE_RU
|
||||
);
|
||||
|
||||
public const LOCK_OFF = 0;
|
||||
public const LOCK_ON = 1;
|
||||
public const LOCK_RESTORE = 2;
|
||||
|
||||
private static $lock = 1;
|
||||
|
||||
private const ARGV_REQUIRED = 0x01;
|
||||
private const ARGV_OPTIONAL = 0x02;
|
||||
private const ARGV_ARRAY = 0x10;
|
||||
@@ -123,6 +129,12 @@ class CLISetup
|
||||
foreach (self::$locales as $idx => $str)
|
||||
if (!defined('CFG_LOCALES') || CFG_LOCALES & (1 << $idx))
|
||||
self::$localeIds[] = $idx;
|
||||
|
||||
// get site status
|
||||
if (DB::isConnectable(DB_AOWOW))
|
||||
self::$lock = (int)DB::Aowow()->selectCell('SELECT `value` FROM ?_config WHERE `key` = "maintenance"');
|
||||
else
|
||||
self::$lock = self::LOCK_ON;
|
||||
}
|
||||
|
||||
public static function getOpt(...$args)
|
||||
@@ -182,6 +194,17 @@ class CLISetup
|
||||
}
|
||||
|
||||
|
||||
/*******************/
|
||||
/* web page access */
|
||||
/*******************/
|
||||
|
||||
public static function siteLock(int $mode = self::LOCK_RESTORE) : void
|
||||
{
|
||||
if (DB::isConnectable(DB_AOWOW))
|
||||
DB::Aowow()->query('UPDATE ?_config SET `value` = ?d WHERE `key` = "maintenance"', (int)!!($mode == self::LOCK_RESTORE ? self::$lock : $mode));
|
||||
}
|
||||
|
||||
|
||||
/*******************/
|
||||
/* MPQ-file access */
|
||||
/*******************/
|
||||
|
||||
@@ -11,7 +11,7 @@ if (!CLI)
|
||||
/* Account creation */
|
||||
/********************/
|
||||
|
||||
function account()
|
||||
function account() : void
|
||||
{
|
||||
$fields = array(
|
||||
'name' => ['Username', false],
|
||||
|
||||
@@ -11,15 +11,17 @@ if (!CLI)
|
||||
/* Create required files */
|
||||
/*************************/
|
||||
|
||||
function build($syncMe = null)
|
||||
function build($syncMe = null) : array
|
||||
{
|
||||
require_once 'setup/tools/fileGen.class.php';
|
||||
|
||||
FileGen::init($syncMe !== null ? FileGen::MODE_UPDATE : FileGen::MODE_NORMAL, $syncMe ?: []);
|
||||
if(!FileGen::init($syncMe !== null ? FileGen::MODE_UPDATE : FileGen::MODE_NORMAL, $syncMe ?: []))
|
||||
return [];
|
||||
|
||||
$done = [];
|
||||
if (FileGen::$subScripts)
|
||||
{
|
||||
CLISetup::siteLock(CLISetup::LOCK_ON);
|
||||
$allOk = true;
|
||||
|
||||
// start file generation
|
||||
@@ -80,6 +82,8 @@ function build($syncMe = null)
|
||||
CLI::write('successfully finished file generation', CLI::LOG_OK);
|
||||
else
|
||||
CLI::write('finished file generation with errors', CLI::LOG_ERROR);
|
||||
|
||||
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
|
||||
}
|
||||
else if (FileGen::getMode() == FileGen::MODE_NORMAL)
|
||||
CLI::write('no valid script names supplied', CLI::LOG_ERROR);
|
||||
|
||||
@@ -11,7 +11,7 @@ if (!CLI)
|
||||
/* Configure DB connection*/
|
||||
/**************************/
|
||||
|
||||
function dbconfig()
|
||||
function dbconfig() : void
|
||||
{
|
||||
$databases = ['aowow', 'world', 'auth', 'characters'];
|
||||
$AoWoWconf = [];
|
||||
@@ -24,21 +24,11 @@ function dbconfig()
|
||||
);
|
||||
$testDB = function($idx, $name, $dbInfo)
|
||||
{
|
||||
$buff = '['.CLI::bold($idx).'] '.str_pad($name, 17);
|
||||
$errStr = '';
|
||||
$defPort = ini_get('mysqli.default_port');
|
||||
$port = 0;
|
||||
|
||||
if (strstr($dbInfo['host'], ':'))
|
||||
[$dbInfo['host'], $port] = explode(':', $dbInfo['host']);
|
||||
$buff = '['.CLI::bold($idx).'] '.str_pad($name, 17);
|
||||
|
||||
if ($dbInfo['host'])
|
||||
{
|
||||
// test DB
|
||||
if ($link = @mysqli_connect($dbInfo['host'], $dbInfo['user'], $dbInfo['pass'], $dbInfo['db'], $port ?: $defPort))
|
||||
mysqli_close($link);
|
||||
else
|
||||
$errStr = '['.mysqli_connect_errno().'] '.mysqli_connect_error();
|
||||
DB::test($dbInfo, $errStr);
|
||||
|
||||
$buff .= $errStr ? CLI::red('ERR ') : CLI::green('OK ');
|
||||
$buff .= 'mysqli://'.$dbInfo['user'].':'.str_pad('', mb_strlen($dbInfo['pass']), '*').'@'.$dbInfo['host'].($port ? ':'.$port : null).'/'.$dbInfo['db'];
|
||||
@@ -54,10 +44,8 @@ function dbconfig()
|
||||
require 'config/config.php';
|
||||
|
||||
foreach ($databases as $idx => $name)
|
||||
{
|
||||
if (empty($AoWoWconf[$name]) && $name != 'characters' )
|
||||
$AoWoWconf[$name] = array_combine(array_keys($dbFields), ['', '', '', '', '']);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ if (!CLI)
|
||||
/* string setup steps together for first use */
|
||||
/*********************************************/
|
||||
|
||||
function firstrun() : bool
|
||||
function setup() : void
|
||||
{
|
||||
require_once 'setup/tools/sqlGen.class.php';
|
||||
require_once 'setup/tools/fileGen.class.php';
|
||||
@@ -118,26 +118,16 @@ function firstrun() : bool
|
||||
require 'config/config.php';
|
||||
|
||||
$error = [];
|
||||
$defPort = ini_get('mysqli.default_port');
|
||||
|
||||
foreach (['aowow', 'world', 'auth'] as $idx => $what)
|
||||
foreach (['world', 'aowow', 'auth'] as $idx => $what)
|
||||
{
|
||||
if ($what == 'auth' && (empty($AoWoWconf['auth']) || empty($AoWoWconf['auth']['host'])))
|
||||
continue;
|
||||
|
||||
$port = 0;
|
||||
if (strstr($AoWoWconf[$what]['host'], ':'))
|
||||
[$AoWoWconf[$what]['host'], $port] = explode(':', $AoWoWconf[$what]['host']);
|
||||
|
||||
if ($link = @mysqli_connect($AoWoWconf[$what]['host'], $AoWoWconf[$what]['user'], $AoWoWconf[$what]['pass'], $AoWoWconf[$what]['db'], $port ?: $defPort))
|
||||
{
|
||||
mysqli_close($link);
|
||||
|
||||
// init proper access for further setup
|
||||
// init proper access for further setup
|
||||
if (DB::test($AoWoWconf[$what], $err))
|
||||
DB::load($idx, $AoWoWconf[$what]);
|
||||
}
|
||||
else
|
||||
$error[] = ' * '.$what.': '.'['.mysqli_connect_errno().'] '.mysqli_connect_error();
|
||||
$error[] = ' * '.$what.': '.$err;
|
||||
}
|
||||
|
||||
return empty($error);
|
||||
@@ -247,7 +237,7 @@ function firstrun() : bool
|
||||
}
|
||||
|
||||
CLI::write();
|
||||
exit;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($startStep)
|
||||
@@ -274,6 +264,8 @@ function firstrun() : bool
|
||||
/* run */
|
||||
/*******/
|
||||
|
||||
CLISetup::siteLock(CLISetup::LOCK_ON);
|
||||
|
||||
foreach ($steps as $idx => $step)
|
||||
{
|
||||
if ($startStep > $idx)
|
||||
@@ -288,7 +280,7 @@ function firstrun() : bool
|
||||
|
||||
$inp = ['x' => ['Press any key to continue', true]];
|
||||
if (!CLI::read($inp, true)) // we don't actually care about the input
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
@@ -329,20 +321,21 @@ function firstrun() : bool
|
||||
case 'r':
|
||||
break;
|
||||
case 'a':
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLI::write();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink('cache/firstrun');
|
||||
CLISetup::siteLock(CLISetup::LOCK_OFF);
|
||||
CLI::write('setup finished', CLI::LOG_OK);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -11,7 +11,7 @@ if (!CLI)
|
||||
/* Configure Site variables */
|
||||
/****************************/
|
||||
|
||||
function siteconfig()
|
||||
function siteconfig() : void
|
||||
{
|
||||
$reqKeys = ['site_host', 'static_host'];
|
||||
$updScripts = [];
|
||||
|
||||
@@ -11,15 +11,17 @@ if (!CLI)
|
||||
/* Create content from world tables / dbc files */
|
||||
/************************************************/
|
||||
|
||||
function sql($syncMe = null)
|
||||
function sql($syncMe = null) : array
|
||||
{
|
||||
require_once 'setup/tools/sqlGen.class.php';
|
||||
|
||||
SqlGen::init($syncMe !== null ? SqlGen::MODE_UPDATE : SqlGen::MODE_NORMAL, $syncMe ?: []);
|
||||
if (!SqlGen::init($syncMe !== null ? SqlGen::MODE_UPDATE : SqlGen::MODE_NORMAL, $syncMe ?: []))
|
||||
return [];
|
||||
|
||||
$done = [];
|
||||
if (SqlGen::$subScripts)
|
||||
{
|
||||
CLISetup::siteLock(CLISetup::LOCK_ON);
|
||||
$allOk = true;
|
||||
|
||||
// start file generation
|
||||
@@ -46,6 +48,8 @@ function sql($syncMe = null)
|
||||
CLI::write('successfully finished sql generation', CLI::LOG_OK);
|
||||
else
|
||||
CLI::write('finished sql generation with errors', CLI::LOG_ERROR);
|
||||
|
||||
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
|
||||
}
|
||||
else if (SqlGen::getMode() == SqlGen::MODE_NORMAL)
|
||||
CLI::write('no valid script names supplied', CLI::LOG_ERROR);
|
||||
|
||||
@@ -27,7 +27,7 @@ function sync(array $s = [], array $b = []) : void
|
||||
CLI::write(' e.g.: "php aowow --sync=creature_queststarter" causes the table aowow_quests_startend to be recreated.', -1, false);
|
||||
CLI::write(' Also quest-related profiler files will be recreated as they depend on aowow_quests_startend and thus indirectly on creature_queststarter.', -1, false);
|
||||
CLI::write();
|
||||
exit;
|
||||
return;
|
||||
}
|
||||
|
||||
$_s = sql($s);
|
||||
@@ -43,6 +43,9 @@ function sync(array $s = [], array $b = []) : void
|
||||
$_ = array_diff($b, $_b);
|
||||
DB::Aowow()->query('UPDATE ?_dbversion SET `build` = ?', $_ ? implode(' ', $_) : '');
|
||||
}
|
||||
|
||||
if (!$s && !$_s && !$b && !$_b)
|
||||
CLI::write('no valid table names supplied', CLI::LOG_ERROR);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -11,7 +11,7 @@ if (!CLI)
|
||||
/* automaticly apply sql-updates */
|
||||
/*********************************/
|
||||
|
||||
function update() : array
|
||||
function update(?array &$sql = [], ?array &$build = []) : void
|
||||
{
|
||||
[$date, $part] = array_values(DB::Aowow()->selectRow('SELECT `date`, `part` FROM ?_dbversion'));
|
||||
|
||||
@@ -25,10 +25,11 @@ function update() : array
|
||||
CLI::write();
|
||||
CLI::write(' Last Update: '.date(Util::$dateFormatInternal, $date).' (Part #'.$part.')', -1, false);
|
||||
CLI::write();
|
||||
exit;
|
||||
return;
|
||||
}
|
||||
|
||||
CLI::write('checking sql updates');
|
||||
CLISetup::siteLock(CLISetup::LOCK_ON);
|
||||
|
||||
$nFiles = 0;
|
||||
foreach (glob('setup/updates/*.sql') as $file)
|
||||
@@ -69,6 +70,7 @@ function update() : array
|
||||
CLI::write(' -> '.date('d.m.Y', $fDate).' #'.$fPart.': '.$nQuerys.' queries applied', CLI::LOG_OK);
|
||||
}
|
||||
|
||||
CLISetup::siteLock(CLISetup::LOCK_RESTORE);
|
||||
CLI::write($nFiles ? 'applied '.$nFiles.' update(s)' : 'db is already up to date', CLI::LOG_OK);
|
||||
|
||||
// fetch sql/build after applying updates, as they may contain sync-prompts
|
||||
@@ -84,8 +86,6 @@ function update() : array
|
||||
|
||||
if ($build)
|
||||
CLI::write('The following file(s) require syncing: '.implode(', ', $build));
|
||||
|
||||
return [$sql, $build];
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -65,33 +65,25 @@ class FileGen
|
||||
'STATIC_URL' => STATIC_URL
|
||||
);
|
||||
|
||||
public static function init($mode = self::MODE_NORMAL, array $updScripts = [])
|
||||
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : bool
|
||||
{
|
||||
self::$defaultExecTime = ini_get('max_execution_time');
|
||||
$doScripts = null;
|
||||
|
||||
self::$mode = $mode;
|
||||
|
||||
// handle command prompts
|
||||
self::handleCLIOpts($doScripts);
|
||||
if ($mode == self::MODE_NORMAL && !$doScripts)
|
||||
if (!CLISetup::$localeIds)
|
||||
{
|
||||
self::printCLIHelp();
|
||||
exit;
|
||||
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// handle command prompts
|
||||
if (!self::handleCLIOpts($doScripts))
|
||||
return false;
|
||||
|
||||
// check passed subscript names; limit to real scriptNames
|
||||
self::$subScripts = array_merge(array_keys(self::$tplFiles), array_keys(self::$datasets));
|
||||
if ($doScripts || $updScripts)
|
||||
self::$subScripts = array_intersect($doScripts ?: $updScripts, self::$subScripts);
|
||||
else if ($doScripts === null)
|
||||
self::$subScripts = [];
|
||||
|
||||
if (!CLISetup::$localeIds /* todo: && this script has localized text */)
|
||||
{
|
||||
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
|
||||
exit;
|
||||
}
|
||||
|
||||
// create directory structure
|
||||
CLI::write('FileGen::init() - creating required directories');
|
||||
@@ -102,9 +94,11 @@ class FileGen
|
||||
|
||||
CLI::write('created '.$pathOk.' extra paths'.($pathOk == count(self::$reqDirs) ? '' : ' with errors'));
|
||||
CLI::write();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function handleCLIOpts(&$doScripts)
|
||||
private static function handleCLIOpts(?array &$doScripts) : bool
|
||||
{
|
||||
$doScripts = [];
|
||||
|
||||
@@ -117,7 +111,7 @@ class FileGen
|
||||
else
|
||||
self::printCLIHelp();
|
||||
|
||||
exit;
|
||||
return false;
|
||||
}
|
||||
|
||||
// required subScripts
|
||||
@@ -136,10 +130,19 @@ class FileGen
|
||||
$doScripts[] = $name;
|
||||
}
|
||||
|
||||
$doScripts = $doScripts ? array_unique($doScripts) : null;
|
||||
if (!$doScripts)
|
||||
return false;
|
||||
|
||||
$doScripts = array_unique($doScripts);
|
||||
return true;
|
||||
}
|
||||
else if ($_ = CLISetup::getOpt('build'))
|
||||
{
|
||||
$doScripts = $_;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function printCLIHelp()
|
||||
|
||||
@@ -23,13 +23,17 @@ class SqlGen
|
||||
public static $defaultExecTime = 30;
|
||||
public static $sqlBatchSize = 1000;
|
||||
|
||||
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : void
|
||||
public static function init(int $mode = self::MODE_NORMAL, array $updScripts = []) : bool
|
||||
{
|
||||
self::$defaultExecTime = ini_get('max_execution_time');
|
||||
$doScripts = null;
|
||||
|
||||
self::$mode = $mode;
|
||||
|
||||
if (!CLISetup::$localeIds)
|
||||
{
|
||||
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// register subscripts
|
||||
foreach (glob('setup/tools/sqlgen/*.func.php') as $file)
|
||||
include_once $file;
|
||||
@@ -76,25 +80,15 @@ class SqlGen
|
||||
}
|
||||
|
||||
// handle command prompts
|
||||
self::handleCLIOpts($doScripts);
|
||||
if ($mode == self::MODE_NORMAL && !$doScripts)
|
||||
{
|
||||
self::printCLIHelp();
|
||||
exit;
|
||||
}
|
||||
if (!self::handleCLIOpts($doScripts))
|
||||
return false;
|
||||
|
||||
// check passed subscript names; limit to real scriptNames
|
||||
self::$subScripts = array_keys(self::$tables);
|
||||
if ($doScripts || $updScripts)
|
||||
self::$subScripts = array_intersect($doScripts ?: $updScripts, self::$subScripts);
|
||||
else if ($doScripts === null)
|
||||
self::$subScripts = [];
|
||||
|
||||
if (!CLISetup::$localeIds /* && this script has localized text */)
|
||||
{
|
||||
CLI::write('No valid locale specified. Check your config or --locales parameter, if used', CLI::LOG_ERROR);
|
||||
exit;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function register(SetupScript $ssRef) : void
|
||||
@@ -138,14 +132,14 @@ class SqlGen
|
||||
}
|
||||
}
|
||||
|
||||
private static function handleCLIOpts(&$doTbls) : void
|
||||
private static function handleCLIOpts(?array &$doTbls) : bool
|
||||
{
|
||||
$doTbls = [];
|
||||
|
||||
if (CLISetup::getOpt('help') && self::$mode == self::MODE_NORMAL)
|
||||
{
|
||||
self::printCLIHelp();
|
||||
exit;
|
||||
return false;
|
||||
}
|
||||
|
||||
// required subScripts
|
||||
@@ -160,10 +154,19 @@ class SqlGen
|
||||
if (array_intersect($sync, $ssRef->getDependencies(true)))
|
||||
$doTbls[] = $name;
|
||||
|
||||
$doTbls = $doTbls ? array_unique($doTbls) : null;
|
||||
if (!$doTbls)
|
||||
return false;
|
||||
|
||||
$doTbls = array_unique($doTbls);
|
||||
return true;
|
||||
}
|
||||
else if ($_ = CLISetup::getOpt('sql'))
|
||||
{
|
||||
$doTbls = $_;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function printCLIHelp() : void
|
||||
|
||||
Reference in New Issue
Block a user