add new demo symfony files
This commit is contained in:
263
app/src/Command/AddUserCommand.php
Normal file
263
app/src/Command/AddUserCommand.php
Normal file
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\UserRepository;
|
||||
use App\Utils\Validator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
use function Symfony\Component\String\u;
|
||||
|
||||
/**
|
||||
* A console command that creates users and stores them in the database.
|
||||
*
|
||||
* To use this command, open a terminal window, enter into your project
|
||||
* directory and execute the following:
|
||||
*
|
||||
* $ php bin/console app:add-user
|
||||
*
|
||||
* To output detailed information, increase the command verbosity:
|
||||
*
|
||||
* $ php bin/console app:add-user -vv
|
||||
*
|
||||
* See https://symfony.com/doc/current/console.html
|
||||
*
|
||||
* We use the default services.yaml configuration, so command classes are registered as services.
|
||||
* See https://symfony.com/doc/current/console/commands_as_services.html
|
||||
*
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||
*/
|
||||
class AddUserCommand extends Command
|
||||
{
|
||||
// to make your command lazily loaded, configure the $defaultName static property,
|
||||
// so it will be instantiated only when the command is actually called.
|
||||
protected static $defaultName = 'app:add-user';
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
private $io;
|
||||
|
||||
private $entityManager;
|
||||
private $passwordEncoder;
|
||||
private $validator;
|
||||
private $users;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, UserPasswordEncoderInterface $encoder, Validator $validator, UserRepository $users)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->entityManager = $em;
|
||||
$this->passwordEncoder = $encoder;
|
||||
$this->validator = $validator;
|
||||
$this->users = $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->setDescription('Creates users and stores them in the database')
|
||||
->setHelp($this->getCommandHelp())
|
||||
// commands can optionally define arguments and/or options (mandatory and optional)
|
||||
// see https://symfony.com/doc/current/components/console/console_arguments.html
|
||||
->addArgument('username', InputArgument::OPTIONAL, 'The username of the new user')
|
||||
->addArgument('password', InputArgument::OPTIONAL, 'The plain password of the new user')
|
||||
->addArgument('email', InputArgument::OPTIONAL, 'The email of the new user')
|
||||
->addArgument('full-name', InputArgument::OPTIONAL, 'The full name of the new user')
|
||||
->addOption('admin', null, InputOption::VALUE_NONE, 'If set, the user is created as an administrator')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* This optional method is the first one executed for a command after configure()
|
||||
* and is useful to initialize properties based on the input arguments and options.
|
||||
*/
|
||||
protected function initialize(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
// SymfonyStyle is an optional feature that Symfony provides so you can
|
||||
// apply a consistent look to the commands of your application.
|
||||
// See https://symfony.com/doc/current/console/style.html
|
||||
$this->io = new SymfonyStyle($input, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed after initialize() and before execute(). Its purpose
|
||||
* is to check if some of the options/arguments are missing and interactively
|
||||
* ask the user for those values.
|
||||
*
|
||||
* This method is completely optional. If you are developing an internal console
|
||||
* command, you probably should not implement this method because it requires
|
||||
* quite a lot of work. However, if the command is meant to be used by external
|
||||
* users, this method is a nice way to fall back and prevent errors.
|
||||
*/
|
||||
protected function interact(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if (null !== $input->getArgument('username') && null !== $input->getArgument('password') && null !== $input->getArgument('email') && null !== $input->getArgument('full-name')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->io->title('Add User Command Interactive Wizard');
|
||||
$this->io->text([
|
||||
'If you prefer to not use this interactive wizard, provide the',
|
||||
'arguments required by this command as follows:',
|
||||
'',
|
||||
' $ php bin/console app:add-user username password email@example.com',
|
||||
'',
|
||||
'Now we\'ll ask you for the value of all the missing command arguments.',
|
||||
]);
|
||||
|
||||
// Ask for the username if it's not defined
|
||||
$username = $input->getArgument('username');
|
||||
if (null !== $username) {
|
||||
$this->io->text(' > <info>Username</info>: '.$username);
|
||||
} else {
|
||||
$username = $this->io->ask('Username', null, [$this->validator, 'validateUsername']);
|
||||
$input->setArgument('username', $username);
|
||||
}
|
||||
|
||||
// Ask for the password if it's not defined
|
||||
$password = $input->getArgument('password');
|
||||
if (null !== $password) {
|
||||
$this->io->text(' > <info>Password</info>: '.u('*')->repeat(u($password)->length()));
|
||||
} else {
|
||||
$password = $this->io->askHidden('Password (your type will be hidden)', [$this->validator, 'validatePassword']);
|
||||
$input->setArgument('password', $password);
|
||||
}
|
||||
|
||||
// Ask for the email if it's not defined
|
||||
$email = $input->getArgument('email');
|
||||
if (null !== $email) {
|
||||
$this->io->text(' > <info>Email</info>: '.$email);
|
||||
} else {
|
||||
$email = $this->io->ask('Email', null, [$this->validator, 'validateEmail']);
|
||||
$input->setArgument('email', $email);
|
||||
}
|
||||
|
||||
// Ask for the full name if it's not defined
|
||||
$fullName = $input->getArgument('full-name');
|
||||
if (null !== $fullName) {
|
||||
$this->io->text(' > <info>Full Name</info>: '.$fullName);
|
||||
} else {
|
||||
$fullName = $this->io->ask('Full Name', null, [$this->validator, 'validateFullName']);
|
||||
$input->setArgument('full-name', $fullName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is executed after interact() and initialize(). It usually
|
||||
* contains the logic to execute to complete this command task.
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$stopwatch = new Stopwatch();
|
||||
$stopwatch->start('add-user-command');
|
||||
|
||||
$username = $input->getArgument('username');
|
||||
$plainPassword = $input->getArgument('password');
|
||||
$email = $input->getArgument('email');
|
||||
$fullName = $input->getArgument('full-name');
|
||||
$isAdmin = $input->getOption('admin');
|
||||
|
||||
// make sure to validate the user data is correct
|
||||
$this->validateUserData($username, $plainPassword, $email, $fullName);
|
||||
|
||||
// create the user and encode its password
|
||||
$user = new User();
|
||||
$user->setFullName($fullName);
|
||||
$user->setUsername($username);
|
||||
$user->setEmail($email);
|
||||
$user->setRoles([$isAdmin ? 'ROLE_ADMIN' : 'ROLE_USER']);
|
||||
|
||||
// See https://symfony.com/doc/current/security.html#c-encoding-passwords
|
||||
$encodedPassword = $this->passwordEncoder->encodePassword($user, $plainPassword);
|
||||
$user->setPassword($encodedPassword);
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->io->success(sprintf('%s was successfully created: %s (%s)', $isAdmin ? 'Administrator user' : 'User', $user->getUsername(), $user->getEmail()));
|
||||
|
||||
$event = $stopwatch->stop('add-user-command');
|
||||
if ($output->isVerbose()) {
|
||||
$this->io->comment(sprintf('New user database id: %d / Elapsed time: %.2f ms / Consumed memory: %.2f MB', $user->getId(), $event->getDuration(), $event->getMemory() / (1024 ** 2)));
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function validateUserData($username, $plainPassword, $email, $fullName): void
|
||||
{
|
||||
// first check if a user with the same username already exists.
|
||||
$existingUser = $this->users->findOneBy(['username' => $username]);
|
||||
|
||||
if (null !== $existingUser) {
|
||||
throw new RuntimeException(sprintf('There is already a user registered with the "%s" username.', $username));
|
||||
}
|
||||
|
||||
// validate password and email if is not this input means interactive.
|
||||
$this->validator->validatePassword($plainPassword);
|
||||
$this->validator->validateEmail($email);
|
||||
$this->validator->validateFullName($fullName);
|
||||
|
||||
// check if a user with the same email already exists.
|
||||
$existingEmail = $this->users->findOneBy(['email' => $email]);
|
||||
|
||||
if (null !== $existingEmail) {
|
||||
throw new RuntimeException(sprintf('There is already a user registered with the "%s" email.', $email));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The command help is usually included in the configure() method, but when
|
||||
* it's too long, it's better to define a separate method to maintain the
|
||||
* code readability.
|
||||
*/
|
||||
private function getCommandHelp(): string
|
||||
{
|
||||
return <<<'HELP'
|
||||
The <info>%command.name%</info> command creates new users and saves them in the database:
|
||||
|
||||
<info>php %command.full_name%</info> <comment>username password email</comment>
|
||||
|
||||
By default the command creates regular users. To create administrator users,
|
||||
add the <comment>--admin</comment> option:
|
||||
|
||||
<info>php %command.full_name%</info> username password email <comment>--admin</comment>
|
||||
|
||||
If you omit any of the three required arguments, the command will ask you to
|
||||
provide the missing values:
|
||||
|
||||
# command will ask you for the email
|
||||
<info>php %command.full_name%</info> <comment>username password</comment>
|
||||
|
||||
# command will ask you for the email and password
|
||||
<info>php %command.full_name%</info> <comment>username</comment>
|
||||
|
||||
# command will ask you for all arguments
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
HELP;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user