diff --git a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php b/src/Drupal/Commands/sql/SanitizeUserTableCommands.php index b896047715..c545dc11a3 100644 --- a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php +++ b/src/Drupal/Commands/sql/SanitizeUserTableCommands.php @@ -74,6 +74,29 @@ public function sanitize($result, CommandData $commandData): void $messages[] = dt('User emails sanitized.'); } + // Sanitize usernames. + if ($this->isEnabled($options['sanitize-usernames'])) { + if (str_contains($options['sanitize-usernames'], '%')) { + $sql = SqlBase::create($commandData->input()->getOptions()); + $db_driver = $sql->scheme(); + if ($db_driver === 'pgsql') { + $username_map = ['%uid' => "' || uid || '"]; + $new_username = "'" . str_replace(array_keys($username_map), array_values($username_map), $options['sanitize-usernames']) . "'"; + } elseif ($db_driver === 'mssql') { + $username_map = ['%uid' => "' + uid + '"]; + $new_username = "'" . str_replace(array_keys($username_map), array_values($username_map), $options['sanitize-email']) . "'"; + } else { + $username_map = ['%uid' => "', uid, '"]; + $new_username = "concat('" . str_replace(array_keys($username_map), array_values($username_map), $options['sanitize-usernames']) . "')"; + } + $query->condition('name', "root", '<>') + ->expression('name', $new_username); + } else { + $query->fields(['name' => $options['sanitize-usernames']]); + } + $messages[] = dt('Usernames sanitized.'); + } + if (!empty($options['ignored-roles'])) { $roles = explode(',', $options['ignored-roles']); /** @var \Drupal\Core\Database\Query\SelectInterface $roles_query */ @@ -102,8 +125,9 @@ public function sanitize($result, CommandData $commandData): void #[CLI\Hook(type: HookManager::OPTION_HOOK, target: SanitizeCommands::SANITIZE)] #[CLI\Option(name: 'sanitize-email', description: 'The pattern for test email addresses in the sanitization operation, or no to keep email addresses unchanged. May contain replacement patterns %uid, %mail or %name.')] #[CLI\Option(name: 'sanitize-password', description: 'By default, passwords are randomized. Specify no to disable that. Specify any other value to set all passwords to that value.')] + #[CLI\Option(name: 'sanitize-usernames', description: 'Sanitize the names of users by replacing the originals with user+UID, or no to keep usernames unchanged.')] #[CLI\Option(name: 'ignored-roles', description: 'A comma delimited list of roles. Users with at least one of the roles will be exempt from sanitization.')] - public function options($options = ['sanitize-email' => 'user+%uid@localhost.localdomain', 'sanitize-password' => null, 'ignored-roles' => null]): void + public function options($options = ['sanitize-email' => 'user+%uid@localhost.localdomain', 'sanitize-password' => null, 'sanitize-usernames' => 'user+%uid', 'ignored-roles' => null]): void { } @@ -117,6 +141,9 @@ public function messages(&$messages, InputInterface $input): void if ($this->isEnabled($options['sanitize-email'])) { $messages[] = dt('Sanitize user emails.'); } + if ($this->isEnabled($options['sanitize-usernames'])) { + $messages[] = dt('Sanitize usernames.'); + } if (in_array('ignored-roles', $options)) { $messages[] = dt('Preserve user emails and passwords for the specified roles.'); }