CLI/readline

* do not reuse prompt variable for use input
This commit is contained in:
Sarjuuk
2024-06-17 16:13:55 +02:00
parent d03448b053
commit 06ffba0239
5 changed files with 56 additions and 65 deletions

View File

@@ -366,7 +366,7 @@ abstract class CLI
this also means, you can't hide input at all, least process it
*/
public static function read(array &$fields, bool $singleChar = false) : bool
public static function read(array $fields, ?array &$userInput = []) : bool
{
// first time set
if (self::$hasReadline === null)
@@ -378,12 +378,11 @@ abstract class CLI
stream_set_blocking(STDIN, false);
foreach ($fields as $name => $data)
{
$vars = ['desc', 'isHidden', 'validPattern'];
foreach ($vars as $idx => $v)
$$v = isset($data[$idx]) ? $data[$idx] : false;
// pad default values onto $fields
array_walk($fields, function(&$val, $_, $pad) { $val += $pad; }, ['', false, false, '']);
foreach ($fields as $name => [$desc, $isHidden, $singleChar, $validPattern])
{
$charBuff = '';
if ($desc)
@@ -431,7 +430,7 @@ abstract class CLI
// standalone \n or \r
else if ($keyId == self::CHR_LF || $keyId == self::CHR_CR)
{
$fields[$name] = $charBuff;
$userInput[$name] = $charBuff;
break 2;
}
else if (!$validPattern || preg_match($validPattern, $char))
@@ -442,7 +441,7 @@ abstract class CLI
if ($singleChar && self::$hasReadline)
{
$fields[$name] = $charBuff;
$userInput[$name] = $charBuff;
break 2;
}
}
@@ -452,11 +451,11 @@ abstract class CLI
echo chr(self::CHR_BELL);
foreach ($fields as $f)
if (strlen($f))
foreach ($userInput as $ui)
if (strlen($ui))
return true;
$fields = null;
$userInput = null;
return true;
}
}

View File

@@ -30,34 +30,34 @@ function account() : void
User::useLocale(LOCALE_EN);
Lang::load(LOCALE_EN);
if (CLI::read($fields))
if (CLI::read($fields, $uiAccount))
{
CLI::write();
if (!User::isValidName($fields['name'], $e))
if (!User::isValidName($uiAccount['name'], $e))
CLI::write(Lang::account($e == 1 ? 'errNameLength' : 'errNameChars'), CLI::LOG_ERROR);
else if (!User::isValidPass($fields['pass1'], $e))
else if (!User::isValidPass($uiAccount['pass1'], $e))
CLI::write(Lang::account($e == 1 ? 'errPassLength' : 'errPassChars'), CLI::LOG_ERROR);
else if ($fields['pass1'] != $fields['pass2'])
else if ($uiAccount['pass1'] != $uiAccount['pass2'])
CLI::write(Lang::account('passMismatch'), CLI::LOG_ERROR);
else if ($_ = DB::Aowow()->SelectCell('SELECT 1 FROM ?_account WHERE user = ? AND (status <> ?d OR (status = ?d AND statusTimer > UNIX_TIMESTAMP()))', $fields['name'], ACC_STATUS_NEW, ACC_STATUS_NEW))
else if ($_ = DB::Aowow()->SelectCell('SELECT 1 FROM ?_account WHERE user = ? AND (status <> ?d OR (status = ?d AND statusTimer > UNIX_TIMESTAMP()))', $uiAccount['name'], ACC_STATUS_NEW, ACC_STATUS_NEW))
CLI::write(Lang::account('nameInUse'), CLI::LOG_ERROR);
else
{
// write to db
$ok = DB::Aowow()->query('REPLACE INTO ?_account (user, passHash, displayName, joindate, email, allowExpire, userGroups, userPerms) VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?, 0, ?d, 1)',
$fields['name'],
User::hashCrypt($fields['pass1']),
Util::ucFirst($fields['name']),
$uiAccount['name'],
User::hashCrypt($uiAccount['pass1']),
Util::ucFirst($uiAccount['name']),
Cfg::get('CONTACT_EMAIL'),
U_GROUP_ADMIN
);
if ($ok)
{
$newId = DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE user = ?', $fields['name']);
$newId = DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE user = ?', $uiAccount['name']);
Util::gainSiteReputation($newId, SITEREP_ACTION_REGISTER);
CLI::write("account ".$fields['name']." created successfully", CLI::LOG_OK);
CLI::write("account ".$uiAccount['name']." created successfully", CLI::LOG_OK);
}
else // something went wrong
CLI::write(Lang::main('intError'), CLI::LOG_ERROR);

View File

@@ -128,44 +128,43 @@ function dbconfig() : void
while (true)
{
$inp = ['idx' => ['', true, '/\d|R|N/i']];
if (CLI::read($inp, true) && $inp)
if (CLI::read(['idx' => ['', true, true, '/\d|R|N/i']], $uiIndex) && $uiIndex)
{
if (strtoupper($inp['idx']) == 'R')
if (strtoupper($uiIndex['idx']) == 'R')
continue 2;
else if (($inp['idx'] >= DB_AOWOW && $inp['idx'] < (DB_CHARACTERS + $nCharDBs)) || strtoupper($inp['idx']) == 'N')
else if (($uiIndex['idx'] >= DB_AOWOW && $uiIndex['idx'] < (DB_CHARACTERS + $nCharDBs)) || strtoupper($uiIndex['idx']) == 'N')
{
$curFields = $inp['idx'] ? $dbFields : array_slice($dbFields, 0, 4);
$curFields = $uiIndex['idx'] ? $dbFields : array_slice($dbFields, 0, 4);
if (strtoupper($inp['idx']) == 'N') // add new characters DB
$curFields['realmId'] = ['Realm Id', false, '/\d{1,3}/'];
if (strtoupper($uiIndex['idx']) == 'N') // add new characters DB
$curFields['realmId'] = ['Realm Id', false, false, '/\d{1,3}/'];
if (CLI::read($curFields))
if (CLI::read($curFields, $uiRealm))
{
if ($inp['idx'] == DB_AOWOW && $curFields)
$curFields['prefix'] = 'aowow_';
if ($uiIndex['idx'] == DB_AOWOW && $uiRealm)
$uiRealm['prefix'] = 'aowow_';
if (strtoupper($inp['idx']) == 'N') // new char DB
if (strtoupper($uiIndex['idx']) == 'N') // new char DB
{
if ($curFields)
if ($uiRealm)
{
$_ = $curFields['realmId'];
unset($curFields['realmId']);
$AoWoWconf[$databases[DB_CHARACTERS]][$_] = $curFields;
$_ = $uiRealm['realmId'];
unset($uiRealm['realmId']);
$AoWoWconf[$databases[DB_CHARACTERS]][$_] = $uiRealm;
}
}
else if ($inp['idx'] < DB_CHARACTERS) // auth, world or aowow
$AoWoWconf[$databases[$inp['idx']]] = $curFields ?: array_combine(array_keys($dbFields), ['', '', '', '', '']);
else if ($uiIndex['idx'] < DB_CHARACTERS) // auth, world or aowow
$AoWoWconf[$databases[$uiIndex['idx']]] = $uiRealm ?: array_combine(array_keys($dbFields), ['', '', '', '', '']);
else // existing char DB
{
$i = 0;
foreach ($AoWoWconf[$databases[DB_CHARACTERS]] as $realmId => &$dbInfo)
{
if ($inp['idx'] - DB_CHARACTERS != $i++)
if ($uiIndex['idx'] - DB_CHARACTERS != $i++)
continue;
if ($curFields)
$dbInfo = $curFields;
if ($uiRealm)
$dbInfo = $uiRealm;
else
unset($AoWoWconf[$databases[DB_CHARACTERS]][$realmId]);
}

View File

@@ -212,8 +212,7 @@ function setup() : void
if ($resp == 301 || $resp == 302)
{
CLI::write('self test received status '.CLI::bold($resp).' (page moved) for '.$conf.', pointing to: '.$protocol.$host.$testFile, CLI::LOG_WARN);
$inp = ['x' => ['should '.CLI::bold($conf).' be set to '.CLI::bold($host).' and force_ssl be updated? (y/n)', true, '/y|n/i']];
if (!CLI::read($inp, true) || !$inp || strtolower($inp['x']) == 'n')
if (!CLI::read(['x' => ['should '.CLI::bold($conf).' be set to '.CLI::bold($host).' and force_ssl be updated? (y/n)', true, true, '/y|n/i']], $uiYN) || !$uiYN || strtolower($uiYN['x']) == 'n')
$error[] = ' * '.$protocol.$host.$testFile.' ['.$resp.']';
else
{
@@ -277,9 +276,8 @@ function setup() : void
{
CLI::write('Found firstrun progression info. (Halted on subscript '.($steps[$startStep][1][0] ? $steps[$startStep][1] : $steps[$startStep][0]).')', CLI::LOG_INFO);
$inp = ['x' => ['continue setup? (y/n)', true, '/y|n/i']];
$msg = '';
if (!CLI::read($inp, true) || !$inp || strtolower($inp['x']) == 'n')
if (!CLI::read(['x' => ['continue setup? (y/n)', true, true, '/y|n/i']], $uiYN) || !$uiYN || strtolower($uiYN['x']) == 'n')
{
$msg = 'Starting setup from scratch...';
$startStep = 0;
@@ -311,8 +309,7 @@ function setup() : void
{
CLI::write($step[3]);
$inp = ['x' => ['Press any key to continue', true]];
if (!CLI::read($inp, true)) // we don't actually care about the input
if (!CLI::read([['Press any key to continue', true]])) // we don't actually care about the input
return;
}
@@ -348,11 +345,10 @@ function setup() : void
break;
}
$inp = ['x' => ['['.CLI::bold('c').']ontinue anyway? ['.CLI::bold('r').']etry? ['.CLI::bold('a').']bort?', true, '/c|r|a/i']];
if (CLI::read($inp, true) && $inp)
if (CLI::read(['x' => ['['.CLI::bold('c').']ontinue anyway? ['.CLI::bold('r').']etry? ['.CLI::bold('a').']bort?', true, true, '/c|r|a/i']], $uiCRA) && $uiCRA)
{
CLI::write();
switch(strtolower($inp['x']))
switch(strtolower($uiCRA['x']))
{
case 'c':
$saveProgress($idx);

View File

@@ -107,12 +107,11 @@ function siteconfig() : void
CLI::write();
}
$inp = ['idx' => ['', false, Cfg::PATTERN_CONF_KEY]];
if (CLI::read($inp) && $inp && $inp['idx'] !== '')
if (CLI::read(['idx' => ['', false, false, Cfg::PATTERN_CONF_KEY]], $uiIndex) && $uiIndex && $uiIndex['idx'] !== '')
{
$idx = array_search(strtolower($inp['idx']), $cfgList);
$idx = array_search(strtolower($uiIndex['idx']), $cfgList);
if ($idx === false)
$idx = intVal($inp['idx']);
$idx = intVal($uiIndex['idx']);
// add new php setting
if ($idx == $sumNum)
@@ -123,13 +122,13 @@ function siteconfig() : void
while (true)
{
$setting = array(
'key' => ['option name', false, Cfg::PATTERN_CONF_KEY],
'key' => ['option name', false, false, Cfg::PATTERN_CONF_KEY],
'val' => ['value', ]
);
if (CLI::read($setting) && $setting)
if (CLI::read($setting, $uiSetting) && $uiSetting)
{
$key = strtolower($setting['key']);
if ($err = Cfg::add($key, $setting['val']))
$key = strtolower($uiSetting['key']);
if ($err = Cfg::add($key, $uiSetting['val']))
CLI::write($err, CLI::LOG_ERROR);
else
CLI::write('new php configuration added', CLI::LOG_OK);
@@ -177,15 +176,14 @@ function siteconfig() : void
while (true)
{
$action = ['idx' => ['', true, '/[edr]/i']];
if (CLI::read($action, true) && $action)
if (CLI::read(['idx' => ['', true, true, '/[edr]/i']], $uiEDR) && $uiEDR)
{
switch (strtoupper($action['idx']))
switch (strtoupper($uiEDR['idx']))
{
case 'E': // edit value
$pattern = false;
$single = false;
$value = ['idx' => ['Select new value', false, &$pattern]];
$prompt = ['idx' => ['Select new value', false, &$single, &$pattern]];
if ($flags & Cfg::FLAG_OPT_LIST)
{
@@ -218,12 +216,11 @@ function siteconfig() : void
while (true)
{
$use = $value;
if (CLI::read($use, $single))
if (CLI::read($prompt, $uiValue))
{
CLI::write();
$inp = $use['idx'] ?? '';
$inp = $uiValue['idx'] ?? '';
if ($err = Cfg::set($key, $inp, $updScripts))
{