Test Setup Failed
Pull Request — master (#4181)
by Craig
04:57
created

GenerateTestUsersCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 19
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 23
rs 9.6333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\Bundle\CoreBundle\Command;
15
16
use Doctrine\DBAL\Connection;
17
use Doctrine\DBAL\DBALException;
18
use Symfony\Component\Console\Command\Command;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console\Style\SymfonyStyle;
24
use Zikula\UsersModule\Constant as UsersConstant;
25
use Zikula\ZAuthModule\ZAuthConstant;
26
27
class GenerateTestUsersCommand extends Command
28
{
29
    /**
30
     * @var Connection
31
     */
32
    private $conn;
33
34
    /**
35
     * @var \DateTime
36
     */
37
    private $nowUTC;
38
39
    /**
40
     * @var \DateTime
41
     */
42
    private $startUTC;
43
44
    /**
45
     * @var int
46
     */
47
    private $active;
48
49
    /**
50
     * @var int
51
     */
52
    private $verified;
53
54
    protected static $defaultName = 'zikula:users:generate';
55
56
    public function __construct(
57
        Connection $connection
58
    ) {
59
        parent::__construct();
60
        $this->conn = $connection;
61
        $utcTZ = new \DateTimeZone('UTC');
62
        $this->nowUTC = new \DateTime('now', $utcTZ);
63
        $this->startUTC = new \DateTime('1970-01-01 00:00:00', $utcTZ);
64
    }
65
66
    protected function configure()
67
    {
68
        $this
69
            ->setDefinition([
70
                new InputArgument('amount', InputArgument::REQUIRED, 'The number of users to create'),
71
            ])
72
            ->addOption(
73
                'active',
74
                null,
75
                InputOption::VALUE_REQUIRED,
76
                'All the users are 1=active, 0=inactive, 2=random choice 0|1',
77
                UsersConstant::ACTIVATED_ACTIVE
78
            )
79
            ->addOption(
80
                'verified',
81
                null,
82
                InputOption::VALUE_REQUIRED,
83
                'All the user emails marked as 1=verified, 0=unverified, 2=random choice 0|1',
84
                1
85
            )
86
            ->setDescription('Generates users for testing purposes')
87
            ->setHelp(
88
                <<<'EOT'
89
The <info>%command.name%</info> command generates users in order to fill a database for testing purposes.
90
These users will not be able to login. The users are placed into a newly created group, not the standard users group.
91
92
<info>php %command.full_name% 1000</info>
93
94
This will generate 1000 randomly named users using all the default values.
95
96
Options:
97
<info>--active (-a)</info> 0|1|2 (default: 1) 1=all users active, 0=all users inactive, 2=random assignment 0|1
98
99
<info>--verified (-v)</info> 0|1|2 (default: 1) 1=all user emails verified, 0=all user emails unverified, 2=random assignment 0|1
100
101
<info>php %command.full_name% 1000 --active=0 --verified=2</info>
102
103
EOT
104
            );
105
    }
106
107
    protected function execute(InputInterface $input, OutputInterface $output): int
108
    {
109
        $io = new SymfonyStyle($input, $output);
110
        $amount = (int) abs($input->getArgument('amount'));
111
        $key = bin2hex(random_bytes(3));
112
        $groupId = $this->createGroup($key);
113
        $divisor = (int) ceil($amount / 100);
114
        $this->active = in_array((int) $input->getOption('active'), [0, 1, 2]) ? (int) $input->getOption('active') : UsersConstant::ACTIVATED_ACTIVE;
115
        $this->verified = in_array((int) $input->getOption('verified'), [0, 1, 2]) ? (int) $input->getOption('verified') : 1;
116
117
        $io->title('User generation utility');
118
        $io->text('Generating users...');
119
        $io->progressStart($amount);
120
121
        for ($i = 1; $i <= $amount; $i++) {
122
            $uname = 'user' . $key . $i;
123
            $this->insertUser($uname);
124
            $uid = (int) $this->conn->lastInsertId();
125
            $this->insertAttributes($uid);
126
            $this->insertMapping($uid, $uname);
127
            $this->insertGroup($uid, $groupId);
128
            if (0 === $i % $divisor) {
129
                $io->progressAdvance((int) ceil($amount / $divisor));
130
            }
131
        }
132
133
        $io->progressFinish();
134
        $io->success('User generation complete!');
135
        $io->text(sprintf('%d users created (group name: <info>group%s</info>).', $amount, $key));
136
137
        return 0;
138
    }
139
140
    private function insertUser(string $uname): void
141
    {
142
        $types = [\PDO::PARAM_STR, \PDO::PARAM_STR, \PDO::PARAM_INT, 'datetime', \PDO::PARAM_INT, 'datetime', 'datetime', \PDO::PARAM_STR, \PDO::PARAM_STR];
143
        try {
144
            $this->conn->insert('users', [
145
                'uname' => $uname,
146
                'email' => $uname . '@example.com',
147
                'activated' => 2 === $this->active ? random_int(0, 1) : $this->active,
148
                'approved_date' => $this->nowUTC,
149
                'approved_by' => 2,
150
                'user_regdate' => $this->nowUTC,
151
                'lastlogin' => $this->startUTC,
152
                'tz' => '',
153
                'locale' => ''
154
            ], $types);
155
        } catch (DBALException $exception) {
156
            // do nothing?
157
        }
158
    }
159
160
    private function insertAttributes(int $uid): void
161
    {
162
        $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR];
163
        try {
164
            $this->conn->insert('users_attributes', [
165
                'name' => UsersConstant::AUTHENTICATION_METHOD_ATTRIBUTE_KEY,
166
                'user_id' => $uid,
167
                'value' => ZAuthConstant::AUTHENTICATION_METHOD_EITHER,
168
            ], $types);
169
        } catch (DBALException $exception) {
170
            // do nothing?
171
        }
172
    }
173
174
    private function insertMapping(int $uid, string $uname): void
175
    {
176
        $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR];
177
        try {
178
            $this->conn->insert('zauth_authentication_mapping', [
179
                'method' => ZAuthConstant::AUTHENTICATION_METHOD_EITHER,
180
                'uid' => $uid,
181
                'uname' => $uname,
182
                'email' => $uname . '@example.com',
183
                'verifiedEmail' => 2 === $this->verified ? random_int(0, 1) : $this->verified,
184
                'pass' => '',
185
            ], $types);
186
        } catch (DBALException $exception) {
187
            // do nothing?
188
        }
189
    }
190
191
    private function createGroup(string $key): int
192
    {
193
        $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_INT];
194
        try {
195
            $this->conn->insert('groups', [
196
                'name' => 'group' . $key,
197
                'gtype' => 0,
198
                'description' => 'temp group for testing',
199
                'state' => 0,
200
                'nbumax' => 0,
201
            ], $types);
202
        } catch (DBALException $exception) {
203
            // do nothing?
204
        }
205
206
        return (int) $this->conn->lastInsertId();
207
    }
208
209
    private function insertGroup(int $uid, int $gid): void
210
    {
211
        $types = [\PDO::PARAM_INT, \PDO::PARAM_INT];
212
        try {
213
            $this->conn->insert('group_membership', [
214
                'uid' => $uid,
215
                'gid' => $gid,
216
            ], $types);
217
        } catch (DBALException $exception) {
218
            // do nothing?
219
        }
220
    }
221
}
222