Failed Conditions
Push — issue#702 ( 91bd46...0b5bf0 )
by Guilherme
19:37 queued 12:15
created

AbstractPersonBlockCommand::execute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 2
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\CoreBundle\Command;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use libphonenumber\PhoneNumberFormat;
15
use libphonenumber\PhoneNumberUtil;
16
use LoginCidadao\CoreBundle\Mailer\TwigSwiftMailer;
17
use LoginCidadao\CoreBundle\Model\PersonInterface;
18
use LoginCidadao\CoreBundle\Security\User\Manager\UserManager;
19
use SimpleThings\EntityAudit\AuditConfiguration;
20
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Console\Style\SymfonyStyle;
25
26
/**
27
 * Class AbstractPersonBlockCommand
28
 * @package LoginCidadao\CoreBundle\Command
29
 * @codeCoverageIgnore
30
 */
31
abstract class AbstractPersonBlockCommand extends ContainerAwareCommand
32
{
33
    /** @var PhoneNumberUtil|null */
34
    private $phoneUtil;
35
36
    /**
37
     * @param SymfonyStyle $io
38
     * @param InputInterface $input
39
     * @param OutputInterface $output
40
     * @return PersonInterface[]
41
     */
42
    abstract protected function getUsers(SymfonyStyle $io, InputInterface $input, OutputInterface $output);
43
44
    protected function configure()
45
    {
46
        $this->addOption(
47
            'dry-run',
48
            null,
49
            InputOption::VALUE_NONE,
50
            'Do NOT persist changes.');
51
    }
52
53
    /**
54
     * @return EntityManagerInterface|object
55
     */
56
    protected function getEntityManager()
57
    {
58
        return $this->getContainer()->get('doctrine.orm.entity_manager');
59
    }
60
61
    /**
62
     * @return UserManager|object
63
     */
64
    protected function getUserManager()
65
    {
66
        return $this->getContainer()->get('lc.user_manager');
67
    }
68
69
    protected function getPhoneUtil()
70
    {
71
        if (!$this->phoneUtil instanceof PhoneNumberUtil) {
72
            $this->phoneUtil = PhoneNumberUtil::getInstance();
73
        }
74
75
        return $this->phoneUtil;
76
    }
77
78
    protected function execute(InputInterface $input, OutputInterface $output)
79
    {
80
        $io = new SymfonyStyle($input, $output);
81
82
        $users = $this->getUsers($io, $input, $output);
83
84
        if (empty($users)) {
85
            $io->note("No users found...");
86
87
            return;
88
        }
89
        $dryRun = $input->getOption('dry-run');
90
91
        $this->prepareAudit();
92
93
        $blockedUsers = $this->blockUsers($io, $users, $dryRun);
94
        $this->listBlocked($io, $blockedUsers);
95
96
        if (!empty($blockedUsers)) {
97
            $this->notifyUsers($io, $blockedUsers, $dryRun);
98
        }
99
    }
100
101
    /**
102
     * @param SymfonyStyle $io
103
     * @param PersonInterface[] $users
104
     * @param bool $dryRun
105
     * @return array
106
     */
107
    private function blockUsers(SymfonyStyle $io, $users, $dryRun = true)
108
    {
109
        $count = count($users);
110
111
        $io->section("Blocking {$count} users...");
112
113
        if ($dryRun) {
114
            $io->note("This is a DRY RUN. Users won't actually be blocked!");
115
        } elseif (!$io->confirm("Are you sure you want to BLOCK {$count} users?", false)) {
116
            return [];
117
        }
118
119
        $userManager = $this->getUserManager();
120
        $io->progressStart($count);
121
        $blockedUsers = [];
122
        foreach ($users as $user) {
123
            $user = $userManager->blockPerson($user);
124
            if ($user instanceof PersonInterface) {
125
                $blockedUsers[] = $user;
126
            }
127
            $io->progressAdvance();
128
        }
129
        $io->progressFinish();
130
        if (!$dryRun) {
131
            $em = $this->getEntityManager();
132
            $em->flush();
133
        }
134
135
        return $blockedUsers;
136
    }
137
138
    /**
139
     * @param SymfonyStyle $io
140
     * @param PersonInterface[] $blockedUsers
141
     */
142
    private function listBlocked(SymfonyStyle $io, $blockedUsers)
143
    {
144
        if (empty($blockedUsers)) {
145
            $io->note("No users were blocked");
146
147
            return;
148
        }
149
150
        $io->section("Blocked Users");
151
        $tableData = array_map(function (PersonInterface $user) {
152
            return [
153
                'firstName' => $user->getFirstName(),
154
                'lastName' => $user->getSurname(),
155
                'email' => $user->getEmail(),
156
                'mobile' => $this->getPhoneUtil()->format($user->getMobile(), PhoneNumberFormat::E164),
157
                'cpf' => $user->getCpf(),
158
            ];
159
        }, $blockedUsers);
160
        $io->table(['First Name', 'Last Name', 'Email', 'Phone', 'CPF'], $tableData);
161
    }
162
163
    private function prepareAudit()
164
    {
165
        /** @var AuditConfiguration $auditConfig */
166
        $auditConfig = $this->getContainer()->get('simplethings_entityaudit.config');
167
        $auditConfig->setUsernameCallable(function () {
168
            $hostname = gethostname();
169
170
            return "# CLI: {$hostname}";
171
        });
172
    }
173
174
    /**
175
     * @return TwigSwiftMailer|object
176
     */
177
    private function getMailer()
178
    {
179
        return $this->getContainer()->get('lc.mailer');
180
    }
181
182
    /**
183
     * @param SymfonyStyle $io
184
     * @param PersonInterface[] $blockedUsers
185
     * @param bool $dryRun
186
     */
187
    private function notifyUsers(SymfonyStyle $io, array $blockedUsers, $dryRun = true)
188
    {
189
        $io->section("Sending Emails");
190
191
        if ($dryRun) {
192
            $io->note("This is a DRY RUN. Emails won't be sent!");
193
        }
194
195
        $mailer = $this->getMailer();
196
197
        $io->progressStart(count($blockedUsers));
198
        foreach ($blockedUsers as $user) {
199
            if ($dryRun || !$user->getEmailConfirmedAt() instanceof \DateTime) {
200
                continue;
201
            }
202
            $mailer->sendAccountBlockedMessage($user);
203
            $io->progressAdvance();
204
        }
205
        $io->progressFinish();
206
    }
207
}
208