Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Tweaked the use of SymfonyStyle in commands #595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 39 additions & 52 deletions src/AppBundle/Command/AddUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -45,6 +45,7 @@ class AddUserCommand extends Command
{
const MAX_ATTEMPTS = 5;

private $io;
private $entityManager;
private $passwordEncoder;

Expand Down Expand Up @@ -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
Expand All @@ -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 protected]',
'',
Expand All @@ -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(' > <info>Username</info>: '.$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(' > <info>Username</info>: '.$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(' > <info>Password</info>: '.str_repeat('*', mb_strlen($password)));
} else {
$io->text(' > <info>Password</info>: '.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(' > <info>Email</info>: '.$email);
} else {
$io->text(' > <info>Email</info>: '.$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(' > <info>Full Name</info>: '.$fullName);
} else {
$io->text(' > <info>Full Name</info>: '.$fullName);
$fullName = $this->io->ask('Full Name', null, [$this, 'fullNameValidator']);
$input->setArgument('full-name', $fullName);
}
}

Expand All @@ -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');
Expand All @@ -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)));
}
}

Expand Down
23 changes: 13 additions & 10 deletions src/AppBundle/Command/DeleteUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class DeleteUserCommand extends Command
{
const MAX_ATTEMPTS = 5;

private $io;
private $entityManager;

public function __construct(EntityManagerInterface $em)
Expand Down Expand Up @@ -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:',
'',
Expand All @@ -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);
}

Expand All @@ -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()));
}

/**
Expand Down
40 changes: 20 additions & 20 deletions src/AppBundle/Command/ListUsersCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}

/**
Expand Down