Passed
Push — fix_coverage_in_scrutinizer ( cd0379...a04ba4 )
by Herberto
13:22
created

ListUsersCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 3
crap 2
1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace App\Command;
13
14
use App\Entity\User;
15
use App\Repository\UserRepository;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\BufferedOutput;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Console\Style\SymfonyStyle;
22
23
/**
24
 * A console command that lists all the existing users.
25
 *
26
 * To use this command, open a terminal window, enter into your project directory
27
 * and execute the following:
28
 *
29
 *     $ php bin/console app:list-users
30
 *
31
 * See https://symfony.com/doc/current/cookbook/console/console_command.html
32
 * For more advanced uses, commands can be defined as services too. See
33
 * https://symfony.com/doc/current/console/commands_as_services.html
34
 *
35
 * @author Javier Eguiluz <[email protected]>
36
 */
37
class ListUsersCommand extends Command
38
{
39
    // a good practice is to use the 'app:' prefix to group all your custom application commands
40
    protected static $defaultName = 'app:list-users';
41
42
    private $mailer;
43
    private $emailSender;
44
    private $users;
45
46
    public function __construct(\Swift_Mailer $mailer, $emailSender, UserRepository $users)
47
    {
48
        parent::__construct();
49
50
        $this->mailer = $mailer;
51
        $this->emailSender = $emailSender;
52
        $this->users = $users;
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    protected function configure()
59
    {
60
        $this
61
            ->setDescription('Lists all the existing users')
62
            ->setHelp(<<<'HELP'
63
The <info>%command.name%</info> command lists all the users registered in the application:
64
65
  <info>php %command.full_name%</info>
66
67
By default the command only displays the 50 most recent users. Set the number of
68
results to display with the <comment>--max-results</comment> option:
69
70
  <info>php %command.full_name%</info> <comment>--max-results=2000</comment>
71
72
In addition to displaying the user list, you can also send this information to
73
the email address specified in the <comment>--send-to</comment> option:
74
75
  <info>php %command.full_name%</info> <comment>[email protected]</comment>
76
77
HELP
78
            )
79
            // commands can optionally define arguments and/or options (mandatory and optional)
80
            // see https://symfony.com/doc/current/components/console/console_arguments.html
81
            ->addOption('max-results', null, InputOption::VALUE_OPTIONAL, 'Limits the number of users listed', 50)
82
            ->addOption('send-to', null, InputOption::VALUE_OPTIONAL, 'If set, the result is sent to the given email address')
83
        ;
84
    }
85
86
    /**
87
     * This method is executed after initialize(). It usually contains the logic
88
     * to execute to complete this command task.
89
     */
90
    protected function execute(InputInterface $input, OutputInterface $output)
91
    {
92
        $maxResults = $input->getOption('max-results');
93
        // Use ->findBy() instead of ->findAll() to allow result sorting and limiting
94
        $allUsers = $this->users->findBy([], ['id' => 'DESC'], $maxResults);
95
96
        // Doctrine query returns an array of objects and we need an array of plain arrays
97
        $usersAsPlainArrays = array_map(function (User $user) {
98
            return [
99
                $user->getId(),
100
                $user->getFullName(),
101
                $user->getUsername(),
102
                $user->getEmail(),
103
                implode(', ', $user->getRoles()),
104
            ];
105
        }, $allUsers);
106
107
        // In your console commands you should always use the regular output type,
108
        // which outputs contents directly in the console window. However, this
109
        // command uses the BufferedOutput type instead, to be able to get the output
110
        // contents before displaying them. This is needed because the command allows
111
        // to send the list of users via email with the '--send-to' option
112
        $bufferedOutput = new BufferedOutput();
113
        $io = new SymfonyStyle($input, $bufferedOutput);
114
        $io->table(
115
            ['ID', 'Full Name', 'Username', 'Email', 'Roles'],
116
            $usersAsPlainArrays
117
        );
118
119
        // instead of just displaying the table of users, store its contents in a variable
120
        $usersAsATable = $bufferedOutput->fetch();
121
        $output->write($usersAsATable);
122
123
        if (null !== $email = $input->getOption('send-to')) {
124
            $this->sendReport($usersAsATable, $email);
125
        }
126
    }
127
128
    /**
129
     * Sends the given $contents to the $recipient email address.
130
     *
131
     * @param string $contents
132
     * @param string $recipient
133
     */
134
    private function sendReport($contents, $recipient)
135
    {
136
        // See https://symfony.com/doc/current/cookbook/email/email.html
137
        $message = $this->mailer->createMessage()
138
            ->setSubject(sprintf('app:list-users report (%s)', date('Y-m-d H:i:s')))
139
            ->setFrom($this->emailSender)
140
            ->setTo($recipient)
141
            ->setBody($contents, 'text/plain')
142
        ;
143
144
        $this->mailer->send($message);
145
    }
146
}
147