diff --git a/src/AppBundle/Command/AddUserCommand.php b/src/AppBundle/Command/AddUserCommand.php
index d263434fe..17e0744a4 100644
--- a/src/AppBundle/Command/AddUserCommand.php
+++ b/src/AppBundle/Command/AddUserCommand.php
@@ -18,9 +18,9 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
+use Symfony\Component\Stopwatch\Stopwatch;
/**
* A command console that creates users and stores them in the database.
@@ -45,6 +45,7 @@ class AddUserCommand extends Command
{
const MAX_ATTEMPTS = 5;
+ private $io;
private $entityManager;
private $passwordEncoder;
@@ -76,6 +77,18 @@ protected function configure()
;
}
+ /**
+ * 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)
+ {
+ // 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
@@ -92,18 +105,10 @@ protected function interact(InputInterface $input, OutputInterface $output)
return;
}
- // See: http://symfony.com/doc/current/console/style.html
- $io = new SymfonyStyle($input, $output);
-
- // Use the title() method to display the title
- $io->title('Add User Command Interactive Wizard');
-
- // multi-line messages can be displayed this way...
- $io->text('If you prefer to not use this interactive wizard, provide the');
- $io->text('arguments required by this command as follows:');
-
- // ...but you can also pass an array of strings to the text() method
- $io->text([
+ $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',
'',
@@ -112,61 +117,45 @@ protected function interact(InputInterface $input, OutputInterface $output)
// Ask for the username if it's not defined
$username = $input->getArgument('username');
- if (null === $username) {
- $question = new Question('Username');
- $question->setValidator(function ($answer) {
+ if (null !== $username) {
+ $this->io->text(' > Username: '.$username);
+ } else {
+ $username = $this->io->ask('Username', null, function ($answer) {
if (empty($answer)) {
throw new \RuntimeException('The username cannot be empty');
}
return $answer;
});
- $question->setMaxAttempts(self::MAX_ATTEMPTS);
- $username = $io->askQuestion($question);
$input->setArgument('username', $username);
- } else {
- $io->text(' > Username: '.$username);
}
// Ask for the password if it's not defined
$password = $input->getArgument('password');
- if (null === $password) {
- $question = new Question('Password (your type will be hidden)');
- $question->setValidator([$this, 'passwordValidator']);
- $question->setHidden(true);
- $question->setMaxAttempts(self::MAX_ATTEMPTS);
-
- $password = $io->askQuestion($question);
- $input->setArgument('password', $password);
+ if (null !== $password) {
+ $this->io->text(' > Password: '.str_repeat('*', mb_strlen($password)));
} else {
- $io->text(' > Password: '.str_repeat('*', mb_strlen($password)));
+ $password = $this->io->askHidden('Password (your type will be hidden)', null, [$this, 'passwordValidator']);
+ $input->setArgument('password', $password);
}
// Ask for the email if it's not defined
$email = $input->getArgument('email');
- if (null === $email) {
- $question = new Question('Email');
- $question->setValidator([$this, 'emailValidator']);
- $question->setMaxAttempts(self::MAX_ATTEMPTS);
-
- $email = $io->askQuestion($question);
- $input->setArgument('email', $email);
+ if (null !== $email) {
+ $this->io->text(' > Email: '.$email);
} else {
- $io->text(' > Email: '.$email);
+ $email = $this->io->ask('Email', null, [$this, 'emailValidator']);
+ $input->setArgument('email', $email);
}
// Ask for the full name if it's not defined
$fullName = $input->getArgument('full-name');
- if (null === $fullName) {
- $question = new Question('Full Name');
- $question->setValidator([$this, 'fullNameValidator']);
- $question->setMaxAttempts(self::MAX_ATTEMPTS);
-
- $fullName = $io->askQuestion($question);
- $input->setArgument('full-name', $fullName);
+ if (null !== $fullName) {
+ $this->io->text(' > Full Name: '.$fullName);
} else {
- $io->text(' > Full Name: '.$fullName);
+ $fullName = $this->io->ask('Full Name', null, [$this, 'fullNameValidator']);
+ $input->setArgument('full-name', $fullName);
}
}
@@ -176,8 +165,8 @@ protected function interact(InputInterface $input, OutputInterface $output)
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $startTime = microtime(true);
- $io = new SymfonyStyle($input, $output);
+ $stopwatch = new Stopwatch();
+ $stopwatch->start('add-user-command');
$username = $input->getArgument('username');
$plainPassword = $input->getArgument('password');
@@ -202,13 +191,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->entityManager->persist($user);
$this->entityManager->flush();
- $io->success(sprintf('%s was successfully created: %s (%s)', $isAdmin ? 'Administrator user' : 'User', $user->getUsername(), $user->getEmail()));
+ $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()) {
- $finishTime = microtime(true);
- $elapsedTime = $finishTime - $startTime;
-
- $io->note(sprintf('New user database id: %d / Elapsed time: %.2f ms', $user->getId(), $elapsedTime * 1000));
+ $this->io->comment(sprintf('New user database id: %d / Elapsed time: %.2f ms / Consumed memory: %.2f MB', $user->getId(), $event->getDuration(), $event->getMemory() / pow(1024, 2)));
}
}
diff --git a/src/AppBundle/Command/DeleteUserCommand.php b/src/AppBundle/Command/DeleteUserCommand.php
index 060357908..a89db0ecb 100644
--- a/src/AppBundle/Command/DeleteUserCommand.php
+++ b/src/AppBundle/Command/DeleteUserCommand.php
@@ -40,6 +40,7 @@ class DeleteUserCommand extends Command
{
const MAX_ATTEMPTS = 5;
+ private $io;
private $entityManager;
public function __construct(EntityManagerInterface $em)
@@ -71,18 +72,22 @@ protected function configure()
);
}
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ // 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);
+ }
+
protected function interact(InputInterface $input, OutputInterface $output)
{
if (null !== $input->getArgument('username')) {
return;
}
- // See: http://symfony.com/doc/current/console/style.html
- $io = new SymfonyStyle($input, $output);
-
- $io->title('Delete User Command Interactive Wizard');
-
- $io->text([
+ $this->io->title('Delete 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:',
'',
@@ -92,8 +97,7 @@ protected function interact(InputInterface $input, OutputInterface $output)
'',
]);
- $username = $io->ask('Username', null, [$this, 'usernameValidator']);
-
+ $username = $this->io->ask('Username', null, [$this, 'usernameValidator']);
$input->setArgument('username', $username);
}
@@ -118,8 +122,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->entityManager->remove($user);
$this->entityManager->flush();
- (new SymfonyStyle($input, $output))
- ->success(sprintf('User "%s" (ID: %d, email: %s) was successfully deleted.', $user->getUsername(), $userId, $user->getEmail()));
+ $this->io->success(sprintf('User "%s" (ID: %d, email: %s) was successfully deleted.', $user->getUsername(), $userId, $user->getEmail()));
}
/**
diff --git a/src/AppBundle/Command/ListUsersCommand.php b/src/AppBundle/Command/ListUsersCommand.php
index 11e699088..59950debe 100644
--- a/src/AppBundle/Command/ListUsersCommand.php
+++ b/src/AppBundle/Command/ListUsersCommand.php
@@ -14,11 +14,11 @@
use AppBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
/**
* A command console that lists all the existing users.
@@ -94,34 +94,34 @@ protected function execute(InputInterface $input, OutputInterface $output)
// Doctrine query returns an array of objects and we need an array of plain arrays
$usersAsPlainArrays = array_map(function (User $user) {
- return [$user->getId(), $user->getFullName(), $user->getUsername(), $user->getEmail(), implode(', ', $user->getRoles())];
+ return [
+ $user->getId(),
+ $user->getFullName(),
+ $user->getUsername(),
+ $user->getEmail(),
+ implode(', ', $user->getRoles()),
+ ];
}, $users);
// In your console commands you should always use the regular output type,
// which outputs contents directly in the console window. However, this
- // particular command uses the BufferedOutput type instead.
- // The reason is that the table displaying the list of users can be sent
- // via email if the '--send-to' option is provided. Instead of complicating
- // things, the BufferedOutput allows to get the command output and store
- // it in a variable before displaying it.
+ // command uses the BufferedOutput type instead, to be able to get the output
+ // contents before displaying them. This is needed because the command allows
+ // to send the list of users via email with the '--send-to' option
$bufferedOutput = new BufferedOutput();
+ $io = new SymfonyStyle($input, $bufferedOutput);
+ $io->table(
+ ['ID', 'Full Name', 'Username', 'Email', 'Roles'],
+ $usersAsPlainArrays
+ );
- $table = new Table($bufferedOutput);
- $table
- ->setHeaders(['ID', 'Full Name', 'Username', 'Email', 'Roles'])
- ->setRows($usersAsPlainArrays)
- ->setStyle(clone Table::getStyleDefinition('symfony-style-guide'))
- ;
- $table->render();
-
- // instead of displaying the table of users, store it in a variable
- $tableContents = $bufferedOutput->fetch();
+ // instead of just displaying the table of users, store its contents in a variable
+ $usersAsATable = $bufferedOutput->fetch();
+ $output->write($usersAsATable);
if (null !== $email = $input->getOption('send-to')) {
- $this->sendReport($tableContents, $email);
+ $this->sendReport($usersAsATable, $email);
}
-
- $output->writeln($tableContents);
}
/**