diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml index b7288e2ec7..8b9dcbc5f0 100644 --- a/phpBB/config/default/container/services_console.yml +++ b/phpBB/config/default/container/services_console.yml @@ -281,13 +281,17 @@ services: tags: - { name: console.command } - console.command.user.delete_ids: - class: phpbb\console\command\user\delete_ids + console.command.user.delete_id: + class: phpbb\console\command\user\delete_id arguments: + - '@dbal.conn' - '@language' - '@log' - '@user' - '@user_loader' + - '%tables.bots%' + - '%tables.user_group%' + - '%tables.users%' - '%core.root_path%' - '%core.php_ext%' tags: diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php index e271380a2f..b2fdbebd3a 100644 --- a/phpBB/language/en/cli.php +++ b/phpBB/language/en/cli.php @@ -108,6 +108,8 @@ $lang = array_merge($lang, array( 'CLI_DESCRIPTION_USER_ADD_OPTION_NOTIFY' => 'Send account activation email to the new user (not sent by default)', 'CLI_DESCRIPTION_USER_DELETE' => 'Delete a user account.', 'CLI_DESCRIPTION_USER_DELETE_USERNAME' => 'Username of the user to delete', + 'CLI_DESCRIPTION_USER_DELETE_ID' => 'Delete user accounts by ID.', + 'CLI_DESCRIPTION_USER_DELETE_ID_OPTION_ID' => 'User IDs of the users to delete', 'CLI_DESCRIPTION_USER_DELETE_OPTION_POSTS' => 'Delete all posts by the user. Without this option, the user’s posts will be retained.', 'CLI_DESCRIPTION_USER_RECLEAN' => 'Re-clean usernames.', diff --git a/phpBB/phpbb/console/command/user/delete_ids.php b/phpBB/phpbb/console/command/user/delete_id.php similarity index 73% rename from phpBB/phpbb/console/command/user/delete_ids.php rename to phpBB/phpbb/console/command/user/delete_id.php index ee5bfe8c6f..2dda64e7d7 100644 --- a/phpBB/phpbb/console/command/user/delete_ids.php +++ b/phpBB/phpbb/console/command/user/delete_id.php @@ -14,6 +14,7 @@ namespace phpbb\console\command\user; use phpbb\console\command\command; +use phpbb\db\driver\driver_interface; use phpbb\language\language; use phpbb\log\log_interface; use phpbb\user; @@ -25,8 +26,11 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; -class delete_ids extends command +class delete_id extends command { + /** @var driver_interface */ + protected $db; + /** @var language */ protected $language; @@ -36,6 +40,15 @@ class delete_ids extends command /** @var user_loader */ protected $user_loader; + /** @var string Bots table */ + protected $bots_table; + + /** @var string User group table */ + protected $user_group_table; + + /** @var string Users table */ + protected $users_table; + /** @var string phpBB root path */ protected $phpbb_root_path; @@ -45,18 +58,27 @@ class delete_ids extends command /** * Construct method * + * @param driver_interface $db * @param language $language * @param log_interface $log * @param user $user * @param user_loader $user_loader + * @param string $bots_table + * @param string $user_group_table + * @param string $users_table * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(language $language, log_interface $log, user $user, user_loader $user_loader, string $phpbb_root_path, string $php_ext) + public function __construct(driver_interface $db, language $language, log_interface $log, user $user, user_loader $user_loader, + string $bots_table, string $user_group_table, string $users_table, string $phpbb_root_path, string $php_ext) { + $this->db = $db; $this->language = $language; $this->log = $log; $this->user_loader = $user_loader; + $this->bots_table = $bots_table; + $this->user_group_table = $user_group_table; + $this->users_table = $users_table; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -73,11 +95,11 @@ class delete_ids extends command { $this ->setName('user:delete_ids') - ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_DELETE_IDS')) + ->setDescription($this->language->lang('CLI_DESCRIPTION_USER_DELETE_ID')) ->addArgument( 'user_ids', InputArgument::REQUIRED | InputArgument::IS_ARRAY, - $this->language->lang('CLI_DESCRIPTION_USER_DELETE_IDS_LIST') + $this->language->lang('CLI_DESCRIPTION_USER_DELETE_ID_OPTION_ID') ) ->addOption( 'delete-posts', @@ -119,6 +141,11 @@ class delete_ids extends command { continue; } + else if ($user_row['user_type'] == USER_IGNORE) + { + $this->delete_bot_user($user_row); + continue; + } if (!function_exists('user_delete')) { @@ -170,4 +197,25 @@ class delete_ids extends command } } } + + /** + * Deletes a bot user + * + * @param array $user_row + * @return void + */ + protected function delete_bot_user(array $user_row): void + { + $sql = 'DELETE FROM ' . $this->bots_table . ' + WHERE user_id = ' . (int) $user_row['user_id']; + $this->db->sql_query($sql); + + $delete_tables = [$this->user_group_table, $this->users_table]; + foreach ($delete_tables as $table) + { + $sql = "DELETE FROM $table + WHERE user_id = " . (int) $user_row['user_id']; + $this->db->sql_query($sql); + } + } } diff --git a/tests/console/user/delete_ids_test.php b/tests/console/user/delete_id_test.php similarity index 65% rename from tests/console/user/delete_ids_test.php rename to tests/console/user/delete_id_test.php index 0595271b6b..a579312552 100644 --- a/tests/console/user/delete_ids_test.php +++ b/tests/console/user/delete_id_test.php @@ -13,7 +13,7 @@ use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; -use phpbb\console\command\user\delete_ids; +use phpbb\console\command\user\delete_id; require_once __DIR__ . '/base.php'; @@ -22,11 +22,15 @@ class phpbb_console_user_delete_ids_test extends phpbb_console_user_base public function get_command_tester() { $application = new Application(); - $application->add(new delete_ids( + $application->add(new delete_id( + $this->db, $this->language, $this->log, $this->user, $this->user_loader, + BOTS_TABLE, + USER_GROUP_TABLE, + USERS_TABLE, $this->phpbb_root_path, $this->php_ext )); @@ -55,6 +59,42 @@ class phpbb_console_user_delete_ids_test extends phpbb_console_user_base $this->assertStringContainsString('CLI_USER_DELETE_IDS_SUCCESS', $command_tester->getDisplay()); } + public function test_delete_one() + { + $command_tester = $this->get_command_tester(); + + $command_tester->setInputs(['yes', '']); + + $command_tester->execute(array( + 'command' => $this->command_name, + 'user_ids' => [3], + '--delete-posts' => false, + )); + + $this->assertNull($this->get_user_id('Test')); + $this->assertNotNull($this->get_user_id('Test 2')); + $this->assertStringContainsString('CLI_USER_DELETE_IDS_SUCCESS', $command_tester->getDisplay()); + } + + public function test_delete_bot() + { + $command_tester = $this->get_command_tester(); + + $this->assertNotNull($this->get_user_id('Test Bot')); + + $command_tester->setInputs(['yes', '']); + + $command_tester->execute(array( + 'command' => $this->command_name, + 'user_ids' => [3, 6], + '--delete-posts' => false, + )); + + $this->assertNull($this->get_user_id('Test')); + $this->assertNull($this->get_user_id('Test Bot')); + $this->assertStringContainsString('CLI_USER_DELETE_IDS_SUCCESS', $command_tester->getDisplay()); + } + public function test_delete_non_user() { $command_tester = $this->get_command_tester(); diff --git a/tests/console/user/fixtures/config.xml b/tests/console/user/fixtures/config.xml index a988ba463f..eba2eba637 100644 --- a/tests/console/user/fixtures/config.xml +++ b/tests/console/user/fixtures/config.xml @@ -47,6 +47,14 @@ 0 + + 6 + + Test Bot + Test Bot + + 2 + group_id @@ -59,5 +67,23 @@ 3foobar + + 6 + BOTS + 3 + + +
+ + group_id + user_id + group_leader + user_pending + + 6 + 6 + 0 + 0 +