--- /dev/null
+<?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
+{
+
+ /**
+ * 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.
+ * @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
+ *
+ * @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.
+ * @aliases ublk,user-block
+ * @usage drush user:block user3
+ * Block the users whose name is user3
+ */
+ public function block($names)
+ {
+ if ($names = StringUtils::csvToArray($names)) {
+ foreach ($names as $name) {
+ if ($account = user_load_by_name($name)) {
+ $account->block();
+ $account->save();
+ $this->logger->success(dt('Blocked user(s): !user', ['!user' => $name]));
+ } else {
+ $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
+ }
+ }
+ }
+ }
+
+ /**
+ * UnBlock the specified user(s).
+ *
+ * @command user:unblock
+ *
+ * @param string $names A comma delimited list of user names.
+ * @aliases uublk,user-unblock
+ * @usage drush user:unblock user3
+ * Unblock the users with name user3
+ */
+ public function unblock($names)
+ {
+ if ($names = StringUtils::csvToArray($names)) {
+ foreach ($names as $name) {
+ if ($account = user_load_by_name($name)) {
+ $account->activate();
+ $account->save();
+ $this->logger->success(dt('Unblocked user(s): !user', ['!user' => $name]));
+ } else {
+ $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a role to the specified user accounts.
+ *
+ * @command user:role:add
+ *
+ * @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.
+ * @aliases urol,user-add-role
+ * @usage drush user:add-role "power user" user3
+ * Add the "power user" role to user3
+ */
+ public function addRole($role, $names)
+ {
+ if ($names = StringUtils::csvToArray($names)) {
+ foreach ($names as $name) {
+ if ($account = user_load_by_name($name)) {
+ $account->addRole($role);
+ $account->save();
+ $this->logger->success(dt('Added !role role to !user', [
+ '!role' => $role,
+ '!user' => $name,
+ ]));
+ } else {
+ $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
+ }
+ }
+ }
+ }
+
+ /**
+ * 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.
+ * @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)
+ {
+ if ($names = StringUtils::csvToArray($names)) {
+ foreach ($names as $name) {
+ if ($account = user_load_by_name($name)) {
+ $account->removeRole($role);
+ $account->save();
+ $this->logger->success(dt('Removed !role role from !user', [
+ '!role' => $role,
+ '!user' => $name,
+ ]));
+ } else {
+ $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name]));
+ }
+ }
+ }
+ }
+
+ /**
+ * 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 (!Drush::simulate()) {
+ if ($account = User::create($new_user)) {
+ $account->save();
+ drush_backend_set_result($this->infoArray($account));
+ $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 all content created by the user
+ * @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
+ * Cancel the user account with the name username and delete all content created by that user.
+ */
+ public function cancel($names, $options = ['delete-content' => false])
+ {
+ if ($names = StringUtils::csvToArray($names)) {
+ foreach ($names as $name) {
+ if ($account = user_load_by_name($name)) {
+ if ($options['delete-content']) {
+ $this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getUsername()]));
+ }
+ 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.
+ }
+ } else {
+ $this->logger()->warning(dt('Unable to load user: !user', ['!user' => $name]));
+ }
+ }
+ }
+ }
+
+ /**
+ * 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 xkcd.com/936
+ */
+ public function password($name, $password)
+ {
+ if ($account = user_load_by_name($name)) {
+ if (!Drush::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->getUsername(),
+ 'pass' => $account->getPassword(),
+ 'mail' => $account->getEmail(),
+ 'user_created' => $account->getCreatedTime(),
+ 'created' => format_date($account->getCreatedTime()),
+ 'user_access' => $account->getLastAccessedTime(),
+ 'access' => format_date($account->getLastAccessedTime()),
+ 'user_login' => $account->getLastLoginTime(),
+ 'login' => format_date($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,
+ ];
+ }
+}