forked from drush-ops/drush
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UserCommands.php
392 lines (372 loc) · 14.5 KB
/
UserCommands.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
<?php
namespace Drush\Drupal\Commands\core;
use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\CommandError;
use Consolidation\OutputFormatters\Options\FormatterOptions;
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\user\Entity\User;
use Drush\Commands\DrushCommands;
use Drush\Drush;
use Drush\Utils\StringUtils;
class UserCommands extends DrushCommands
{
/**
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
public function __construct($dateFormatter)
{
$this->dateFormatter = $dateFormatter;
}
/**
* Print information about the specified user(s).
*
* @command user:information
*
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases uinf,user-information
* @usage drush user:information someguy,somegal
* Display information about the someguy and somegal user accounts.
* @usage drush user:information --mail=someguy@somegal.com
* Display information for a given email account.
* @usage drush user:information --uid=5
* Display information for a given user id.
* @usage drush uinf --uid=$(drush sqlq "SELECT GROUP_CONCAT(entity_id) FROM user__roles WHERE roles_target_id = 'administrator'")
* Display information for all administrators.
* @field-labels
* uid: User ID
* name: User name
* pass: Password
* mail: User mail
* theme: User theme
* signature: Signature
* signature_format: Signature format
* user_created: User created
* created: Created
* user_access: User last access
* access: Last access
* user_login: User last login
* login: Last login
* user_status: User status
* status: Status
* timezone: Time zone
* picture: User picture
* init: Initial user mail
* roles: User roles
* group_audience: Group Audience
* langcode: Language code
* uuid: Uuid
* @table-style default
* @default-fields uid,name,mail,roles,user_status
*
* @filter-default-field name
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
*/
public function information($names = '', $options = ['format' => 'table', 'uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = [];
if ($mails = StringUtils::csvToArray($options['mail'])) {
foreach ($mails as $mail) {
if ($account = user_load_by_mail($mail)) {
$accounts[$account->id()] = $account;
}
}
}
if ($uids = StringUtils::csvToArray($options['uid'])) {
if ($loaded = User::loadMultiple($uids)) {
$accounts += $loaded;
}
}
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$accounts[$account->id()] = $account;
}
}
}
if (empty($accounts)) {
throw new \Exception(dt('Unable to find a matching user'));
}
foreach ($accounts as $id => $account) {
$outputs[$id] = $this->infoArray($account);
}
$result = new RowsOfFields($outputs);
$result->addRendererFunction([$this, 'renderRolesCell']);
return $result;
}
public function renderRolesCell($key, $cellData, FormatterOptions $options)
{
if (is_array($cellData)) {
return implode("\n", $cellData);
}
return $cellData;
}
/**
* Block the specified user(s).
*
* @command user:block
*
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases ublk,user-block
* @usage drush user:block user3
* Block the users whose name is user3
*/
public function block($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->block();
$account->save();
$this->logger->success(dt('Blocked user(s): !user', ['!user' => $account->getAccountName()]));
}
}
/**
* UnBlock the specified user(s).
*
* @command user:unblock
*
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases uublk,user-unblock
* @usage drush user:unblock user3
* Unblock the users with name user3
*/
public function unblock($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->activate();
$account->save();
$this->logger->success(dt('Unblocked user(s): !user', ['!user' => $account->getAccountName()]));
}
}
/**
* Add a role to the specified user accounts.
*
* @command user:role:add
*
* @validate-entity-load user_role role
* @param string $role The machine name of the role to add.
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases urol,user-add-role
* @usage drush user-add-role "editor" user3
* Add the editor role to user3
*/
public function addRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->addRole($role);
$account->save();
$this->logger->success(dt('Added !role role to !user', [
'!role' => $role,
'!user' => $account->getAccountName(),
]));
}
}
/**
* Remove a role from the specified user accounts.
*
* @command user:role:remove
*
* @validate-entity-load user_role role
* @param string $role The name of the role to add
* @param string $names A comma delimited list of user names.
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases urrol,user-remove-role
* @usage drush user:remove-role "power user" user3
* Remove the "power user" role from user3
*/
public function removeRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
$account->removeRole($role);
$account->save();
$this->logger->success(dt('Removed !role role from !user', [
'!role' => $role,
'!user' => $account->getAccountName(),
]));
}
}
/**
* Create a user account.
*
* @command user:create
*
* @param string $name The name of the account to add
* @option password The password for the new account
* @option mail The email address for the new account
* @aliases ucrt,user-create
* @usage drush user:create newuser --mail="person@example.com" --password="letmein"
* Create a new user account with the name newuser, the email address person@example.com, and the password letmein
*/
public function create($name, $options = ['password' => self::REQ, 'mail' => self::REQ])
{
$new_user = [
'name' => $name,
'pass' => $options['password'],
'mail' => $options['mail'],
'access' => '0',
'status' => 1,
];
if (!$this->getConfig()->simulate()) {
if ($account = User::create($new_user)) {
$account->save();
$this->logger()->success(dt('Created a new user with uid !uid', ['!uid' => $account->id()]));
} else {
return new CommandError("Could not create a new user account with the name " . $name . ".");
}
}
}
/**
* Assure that provided username is available.
*
* @hook validate user-create
*/
public function createValidate(CommandData $commandData)
{
if ($mail = $commandData->input()->getOption('mail')) {
if (user_load_by_mail($mail)) {
throw new \Exception(dt('There is already a user account with the email !mail', ['!mail' => $mail]));
}
}
$name = $commandData->input()->getArgument('name');
if (user_load_by_name($name)) {
throw new \Exception((dt('There is already a user account with the name !name', ['!name' => $name])));
}
}
/**
* Cancel user account(s) with the specified name(s).
*
* @command user:cancel
*
* @param string $names A comma delimited list of user names.
* @option delete-content Delete the user, and all content created by the user
* @option $uid A comma delimited list of user ids to lookup (an alternative to names).
* @option $mail A comma delimited list of emails to lookup (an alternative to names).
* @aliases ucan,user-cancel
* @usage drush user:cancel username
* Cancel the user account with the name username and anonymize all content created by that user.
* @usage drush user:cancel --delete-content username
* Delete the user account with the name username and delete all content created by that user.
*/
public function cancel($names, $options = ['delete-content' => false, 'uid' => self::REQ, 'mail' => self::REQ])
{
$accounts = $this->getAccounts($names, $options);
foreach ($accounts as $id => $account) {
if ($options['delete-content']) {
$this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getAccountName()]));
}
if ($this->io()->confirm('Cancel user account?: ')) {
$method = $options['delete-content'] ? 'user_cancel_delete' : 'user_cancel_block';
user_cancel([], $account->id(), $method);
drush_backend_batch_process();
// Drupal logs a message for us.
}
}
}
/**
* Set the password for the user account with the specified name.
*
* @command user:password
*
* @param string $name The name of the account to modify.
* @param string $password The new password for the account.
* @aliases upwd,user-password
* @usage drush user:password someuser "correct horse battery staple"
* Set the password for the username someuser. See https://xkcd.com/936
*/
public function password($name, $password)
{
if ($account = user_load_by_name($name)) {
if (!$this->getConfig()->simulate()) {
$account->setpassword($password);
$account->save();
$this->logger()->success(dt('Changed password for !name.', ['!name' => $name]));
}
} else {
throw new \Exception(dt('Unable to load user: !user', ['!user' => $name]));
}
}
/**
* A flatter and simpler array presentation of a Drupal $user object.
*
* @param $account A user account
* @return array
*/
public function infoArray($account)
{
return [
'uid' => $account->id(),
'name' => $account->getAccountName(),
'pass' => $account->getPassword(),
'mail' => $account->getEmail(),
'user_created' => $account->getCreatedTime(),
'created' => $this->dateFormatter->format($account->getCreatedTime()),
'user_access' => $account->getLastAccessedTime(),
'access' => $this->dateFormatter->format($account->getLastAccessedTime()),
'user_login' => $account->getLastLoginTime(),
'login' => $this->dateFormatter->format($account->getLastLoginTime()),
'user_status' => $account->get('status')->value,
'status' => $account->isActive() ? 'active' : 'blocked',
'timezone' => $account->getTimeZone(),
'roles' => $account->getRoles(),
'langcode' => $account->getPreferredLangcode(),
'uuid' => $account->uuid->value,
];
}
/**
* Get accounts from name variables or uid & mail options.
*
* @param string $names
* @param array $options
*
* @return array
* A array of loaded accounts.
* @throws \Exception
*/
protected function getAccounts($names = '', $options = [])
{
$accounts = [];
if ($mails = StringUtils::csvToArray($options['mail'])) {
foreach ($mails as $mail) {
if ($account = user_load_by_mail($mail)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !mail', ['!mail' => $mail]));
}
}
}
if ($uids = StringUtils::csvToArray($options['uid'])) {
foreach ($uids as $uid) {
if ($account = User::load($uid)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !uid', ['!uid' => $uid]));
}
}
}
if ($names = StringUtils::csvToArray($names)) {
foreach ($names as $name) {
if ($account = user_load_by_name($name)) {
$accounts[$account->id()] = $account;
} else {
$this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
}
}
}
if (empty($accounts)) {
throw new \Exception(dt('Unable to find any matching user'));
}
return $accounts;
}
}