setName('toggle-user')
->setAliases(['disableuser', 'enableuser', 'toggleuser', 'change-user-state'])
->addOption(
'user',
'u',
InputOption::VALUE_REQUIRED,
'The username'
)
->addOption(
'state',
's',
InputOption::VALUE_REQUIRED,
'The state of the account. Can be either `enabled` or `disabled`. [default: "enabled"]'
)
->setDescription('Changes whether user can login or not')
->setHelp('The toggle-user sets a user\'s login status to enabled or disabled.')
;
}
/**
* @return int|null|void
*/
protected function serve()
{
$this->options = [
'user' => $this->input->getOption('user'),
'state' => $this->input->getOption('state')
];
$this->validateOptions();
$helper = $this->getHelper('question');
$data = [];
$this->output->writeln('Setting User State');
$this->output->writeln('');
if (!$this->options['user']) {
// Get username and validate
$question = new Question('Enter a username: ');
$question->setValidator(function ($value) {
return $this->validate('user', $value);
});
$username = $helper->ask($this->input, $this->output, $question);
} else {
$username = $this->options['user'];
}
if (!$this->options['state'] && !count(array_filter($this->options))) {
// Choose State
$question = new ChoiceQuestion(
'Please choose the state for the account:',
array('enabled' => 'Enabled', 'disabled' => 'Disabled'),
'enabled'
);
$question->setErrorMessage('State %s is invalid.');
$data['state'] = $helper->ask($this->input, $this->output, $question);
} else {
$data['state'] = $this->options['state'] ?: 'enabled';
}
// Lowercase the username for the filename
$username = strtolower($username);
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
// Grab the account file and read in the information before setting the file (prevent setting erase)
$oldUserFile = CompiledYamlFile::instance($locator->findResource('account://' . $username . YAML_EXT, true, true));
$oldData = (array)$oldUserFile->content();
//Set the state feild to new state
$oldData['state'] = $data['state'];
// Create user object and save it using oldData (with updated state)
$user = new User($oldData);
$file = CompiledYamlFile::instance($locator->findResource('account://' . $username . YAML_EXT, true, true));
$user->file($file);
$user->save();
$this->output->writeln('');
$this->output->writeln('Success! User ' . $username . ' state set to .' . $data['state']);
}
/**
*
*/
protected function validateOptions()
{
foreach (array_filter($this->options) as $type => $value) {
$this->validate($type, $value);
}
}
/**
* @param $type
* @param $value
* @param string $extra
*
* @return mixed
*/
protected function validate($type, $value, $extra = '')
{
/** @var Config $config */
$config = Grav::instance()['config'];
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
$username_regex = '/' . $config->get('system.username_regex') . '/';
switch ($type) {
case 'user':
if (!preg_match($username_regex, $value)) {
throw new \RuntimeException('Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed');
}
if (!file_exists($locator->findResource('account://' . $value . YAML_EXT))) {
throw new \RuntimeException('Username "' . $value . '" does not exist, please pick another username');
}
break;
case 'state':
if ($value !== 'enabled' && $value !== 'disabled') {
throw new \RuntimeException('State is not valid');
}
break;
}
return $value;
}
}