I am cloning Magento’s AdminUserCreateCommand to create my custom command to set the role given in command argument. Plan is to create the user using this module just like as default magento’s command without saving role for now and when it works, I would like to save the provided role for user instead of default administrator role. I will further make use of /setup/src/Magento/Setup/Model/AdminAccount.php
and will modify retrieveAdministratorsRoleId()
to set role_name from taken input through this command.
app/code/Mymodule/CreateUser/registration.php
<?php
use MagentoFrameworkComponentComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Mymodule_CreateUser', __DIR__);
app/code/Mymodule/CreateUser/etc/module.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Mymodule_CreateUser" setup_version="1.0.0"/>
</config>
app/code/Mymodule/CreateUser/etc/di.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="LaminasServiceManagerServiceLocatorInterface" type="LaminasServiceManagerServiceManager" />
<preference for="MagentoFrameworkSetupLoggerInterface" type="MagentoFrameworkSetupConsoleLogger" />
<type name="MagentoFrameworkConsoleCommandList">
<arguments>
<argument name="commands" xsi:type="array">
<item name="AdminUserCreateCommand" xsi:type="object">MymoduleCreateUserConsoleCommandAdminUserCreateCommand</item>
</argument>
</arguments>
</type>
</config>
app/code/Mymodule/CreateUser/Console/Command/AdminUserCreateCommand.php
<?php
declare(strict_types=1);
namespace MymoduleCreateUserConsoleCommand;
use MagentoFrameworkSetupConsoleLogger;
use MagentoSetupModelAdminAccount;
use MagentoSetupModelInstallerFactory;
use MagentoUserModelUserValidationRules;
use SymfonyComponentConsoleQuestionQuestion;
use MagentoSetupConsoleCommandAbstractSetupCommand;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleInputInputOption;
use SymfonyComponentConsoleOutputOutputInterface;
class AdminUserCreateCommand extends AbstractSetupCommand
{
/**
* @var InstallerFactory
*/
private $installerFactory;
/**
* @var UserValidationRules
*/
private $validationRules;
/**
* @param InstallerFactory $installerFactory
* @param UserValidationRules $validationRules
*/
public function __construct(InstallerFactory $installerFactory, UserValidationRules $validationRules)
{
$this->installerFactory = $installerFactory;
$this->validationRules = $validationRules;
parent::__construct();
}
/**
* Initialization of the command
*
* @return void
*/
protected function configure()
{
$this->setName('admin:myuser:create')
->setDescription('Creates an administrator with role')
->setDefinition($this->getOptionsList());
parent::configure();
}
/**
* Creation admin user in interaction mode.
*
* @param SymfonyComponentConsoleInputInputInterface $input
* @param SymfonyComponentConsoleOutputOutputInterface $output
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
/** @var SymfonyComponentConsoleHelperQuestionHelper $questionHelper */
$questionHelper = $this->getHelper('question');
if (!$input->getOption(AdminAccount::KEY_USER)) {
$question = new Question('<question>Admin user:</question> ', '');
$this->addNotEmptyValidator($question);
$input->setOption(
AdminAccount::KEY_USER,
$questionHelper->ask($input, $output, $question)
);
}
if (!$input->getOption(AdminAccount::KEY_PASSWORD)) {
$question = new Question('<question>Admin password:</question> ', '');
$question->setHidden(true);
$question->setValidator(function ($value) use ($output) {
$user = new MagentoFrameworkDataObject();
$user->setPassword($value);
$validator = new MagentoFrameworkValidatorDataObject();
$this->validationRules->addPasswordRules($validator);
$validator->isValid($user);
foreach ($validator->getMessages() as $message) {
throw new Exception($message);
}
return $value;
});
$input->setOption(
AdminAccount::KEY_PASSWORD,
$questionHelper->ask($input, $output, $question)
);
}
if (!$input->getOption('admin-role')) {
$question = new Question('<question>Admin role:</question> ', '');
$this->addNotEmptyValidator($question);
$input->setOption(
'admin-role',
$questionHelper->ask($input, $output, $question)
);
}
if (!$input->getOption(AdminAccount::KEY_EMAIL)) {
$question = new Question('<question>Admin email:</question> ', '');
$this->addNotEmptyValidator($question);
$input->setOption(
AdminAccount::KEY_EMAIL,
$questionHelper->ask($input, $output, $question)
);
}
if (!$input->getOption(AdminAccount::KEY_FIRST_NAME)) {
$question = new Question('<question>Admin first name:</question> ', '');
$this->addNotEmptyValidator($question);
$input->setOption(
AdminAccount::KEY_FIRST_NAME,
$questionHelper->ask($input, $output, $question)
);
}
if (!$input->getOption(AdminAccount::KEY_LAST_NAME)) {
$question = new Question('<question>Admin last name:</question> ', '');
$this->addNotEmptyValidator($question);
$input->setOption(
AdminAccount::KEY_LAST_NAME,
$questionHelper->ask($input, $output, $question)
);
}
}
/**
* Add not empty validator.
*
* @param SymfonyComponentConsoleQuestionQuestion $question
* @return void
*/
private function addNotEmptyValidator(Question $question)
{
$question->setValidator(function ($value) {
if (trim($value) == '') {
throw new Exception('The value cannot be empty');
}
return $value;
});
}
/**
* {@inheritdoc}
*/
protected function execute(
InputInterface $input,
OutputInterface $output
) {
$errors = $this->validate($input);
if ($errors) {
$output->writeln('<error>' . implode('</error>' . PHP_EOL . '<error>', $errors) . '</error>');
// we must have an exit code higher than zero to indicate something was wrong
return MagentoFrameworkConsoleCli::RETURN_FAILURE;
}
$installer = $this->installerFactory->create(new ConsoleLogger($output));
$installer->installAdminUser($input->getOptions());
$output->writeln(
'<info>Created Magento administrator user named ' . $input->getOption(AdminAccount::KEY_USER) . '</info>'
);
return MagentoFrameworkConsoleCli::RETURN_SUCCESS;
}
/**
* Get list of arguments for the command
*
* @param int $mode The mode of options.
* @return InputOption[]
*/
public function getOptionsList($mode = InputOption::VALUE_REQUIRED)
{
$requiredStr = ($mode === InputOption::VALUE_REQUIRED ? '(Required) ' : '');
return [
new InputOption(
AdminAccount::KEY_USER,
null,
$mode,
$requiredStr . 'Admin user'
),
new InputOption(
AdminAccount::KEY_PASSWORD,
null,
$mode,
$requiredStr . 'Admin password'
),
new InputOption(
'admin-role',
null,
$mode,
$requiredStr . 'Admin role'
),
new InputOption(
AdminAccount::KEY_EMAIL,
null,
$mode,
$requiredStr . 'Admin email'
),
new InputOption(
AdminAccount::KEY_FIRST_NAME,
null,
$mode,
$requiredStr . 'Admin first name'
),
new InputOption(
AdminAccount::KEY_LAST_NAME,
null,
$mode,
$requiredStr . 'Admin last name'
),
];
}
/**
* Check if all admin options are provided
*
* @param InputInterface $input
* @return string[]
*/
public function validate(InputInterface $input)
{
$errors = [];
$user = new MagentoFrameworkDataObject();
$user->setFirstname($input->getOption(AdminAccount::KEY_FIRST_NAME))
->setLastname($input->getOption(AdminAccount::KEY_LAST_NAME))
->setUsername($input->getOption(AdminAccount::KEY_USER))
->setRole($input->getOption('admin-role'))
->setEmail($input->getOption(AdminAccount::KEY_EMAIL))
->setPassword(
$input->getOption(AdminAccount::KEY_PASSWORD) === null
? '' : $input->getOption(AdminAccount::KEY_PASSWORD)
);
$validator = new MagentoFrameworkValidatorDataObject();
$this->validationRules->addUserInfoRules($validator);
$this->validationRules->addPasswordRules($validator);
if (!$validator->isValid($user)) {
$errors = array_merge($errors, $validator->getMessages());
}
return $errors;
}
}
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento admin:myuser:create
This is the error I am getting when I execute the command with all required input
2
Answers
should this code not be like
I think it will be easy to create user as administrator first.
table authorization_role
authorization_rule
The role should exist before on Database
I think it will be easy to use this mecanism
Update
The problem comes from class Installer in your constructor. By default, Magento 2 uses this class in the "/setup" folder because the environment is different.
What can I recommad is to delete this class from your constructor and use a Model of USERS, all what you need from this class is this
you can use it otherwise without calling the Installer class using adminAccountFactory.