/** * Remove User * * @param string $mode Either 'retain' or 'remove' * @param mixed $user_ids Either an array of integers or an integer * @param bool $retain_username * @return bool */ function user_delete($mode, $user_ids, $retain_username = true) { global $cache, $config, $db, $user, $phpbb_dispatcher, $phpbb_container; global $phpbb_root_path, $phpEx; $db->sql_transaction('begin'); $user_rows = array(); if (!is_array($user_ids)) { $user_ids = array($user_ids); } $user_id_sql = $db->sql_in_set('user_id', $user_ids); $sql = 'SELECT * FROM ' . USERS_TABLE . ' WHERE ' . $user_id_sql; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $user_rows[(int) $row['user_id']] = $row; } $db->sql_freeresult($result); if (empty($user_rows)) { return false; } /** * Event before a user is deleted * * @event core.delete_user_before * @var string mode Mode of deletion (retain/delete posts) * @var array user_ids IDs of the deleted user * @var mixed retain_username True if username should be retained * or false if not * @since 3.1.0-a1 */ $vars = array('mode', 'user_ids', 'retain_username'); extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars))); // Before we begin, we will remove the reports the user issued. $sql = 'SELECT r.post_id, p.topic_id FROM ' . REPORTS_TABLE . ' r, ' . POSTS_TABLE . ' p WHERE ' . $db->sql_in_set('r.user_id', $user_ids) . ' AND p.post_id = r.post_id'; $result = $db->sql_query($sql); $report_posts = $report_topics = array(); while ($row = $db->sql_fetchrow($result)) { $report_posts[] = $row['post_id']; $report_topics[] = $row['topic_id']; } $db->sql_freeresult($result); if (sizeof($report_posts)) { $report_posts = array_unique($report_posts); $report_topics = array_unique($report_topics); // Get a list of topics that still contain reported posts $sql = 'SELECT DISTINCT topic_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $report_topics) . ' AND post_reported = 1 AND ' . $db->sql_in_set('post_id', $report_posts, true); $result = $db->sql_query($sql); $keep_report_topics = array(); while ($row = $db->sql_fetchrow($result)) { $keep_report_topics[] = $row['topic_id']; } $db->sql_freeresult($result); if (sizeof($keep_report_topics)) { $report_topics = array_diff($report_topics, $keep_report_topics); } unset($keep_report_topics); // Now set the flags back $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_reported = 0 WHERE ' . $db->sql_in_set('post_id', $report_posts); $db->sql_query($sql); if (sizeof($report_topics)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_reported = 0 WHERE ' . $db->sql_in_set('topic_id', $report_topics); $db->sql_query($sql); } } // Remove reports $db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE ' . $user_id_sql); $num_users_delta = 0; // Get auth provider collection in case accounts might need to be unlinked $provider_collection = $phpbb_container->get('auth.provider_collection'); // Some things need to be done in the loop (if the query changes based // on which user is currently being deleted) $added_guest_posts = 0; foreach ($user_rows as $user_id => $user_row) { if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == 'avatar.driver.upload') { avatar_delete('user', $user_row); } // Unlink accounts foreach ($provider_collection as $provider_name => $auth_provider) { $provider_data = $auth_provider->get_auth_link_data($user_id); if ($provider_data !== null) { $link_data = array('user_id' => $user_id, 'link_method' => 'user_delete'); // BLOCK_VARS might contain hidden fields necessary for unlinking accounts if (isset($provider_data['BLOCK_VARS']) && is_array($provider_data['BLOCK_VARS'])) { foreach ($provider_data['BLOCK_VARS'] as $provider_service) { if (!array_key_exists('HIDDEN_FIELDS', $provider_service)) { $provider_service['HIDDEN_FIELDS'] = array(); } $auth_provider->unlink_account(array_merge($link_data, $provider_service['HIDDEN_FIELDS'])); } } else { $auth_provider->unlink_account($link_data); } } } // Decrement number of users if this user is active if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE) { --$num_users_delta; } switch ($mode) { case 'retain': if ($retain_username === false) { $post_username = $user->lang['GUEST']; } else { $post_username = $user_row['username']; } // If the user is inactive and newly registered // we assume no posts from the user, and save // the queries if ($user_row['user_type'] != USER_INACTIVE || $user_row['user_inactive_reason'] != INACTIVE_REGISTER || $user_row['user_posts']) { // When we delete these users and retain the posts, we must assign all the data to the guest user $sql = 'UPDATE ' . FORUMS_TABLE . ' SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = ''\n\t\t\t\t\t\tWHERE forum_last_poster_id = {$user_id}"; $db->sql_query($sql); $sql = 'UPDATE ' . POSTS_TABLE . ' SET poster_id = ' . ANONYMOUS . ", post_username = '******'\n\t\t\t\t\t\tWHERE poster_id = {$user_id}"; $db->sql_query($sql); $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = ''\n\t\t\t\t\t\tWHERE topic_poster = {$user_id}"; $db->sql_query($sql); $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = ''\n\t\t\t\t\t\tWHERE topic_last_poster_id = {$user_id}"; $db->sql_query($sql); // Since we change every post by this author, we need to count this amount towards the anonymous user if ($user_row['user_posts']) { $added_guest_posts += $user_row['user_posts']; } } break; case 'remove': // there is nothing variant specific to deleting posts break; } } if ($num_users_delta != 0) { set_config_count('num_users', $num_users_delta, true); } // Now do the invariant tasks // all queries performed in one call of this function are in a single transaction // so this is kosher if ($mode == 'retain') { // Assign more data to the Anonymous user $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET poster_id = ' . ANONYMOUS . ' WHERE ' . $db->sql_in_set('poster_id', $user_ids); $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts + ' . $added_guest_posts . ' WHERE user_id = ' . ANONYMOUS; $db->sql_query($sql); } else { if ($mode == 'remove') { if (!function_exists('delete_posts')) { include $phpbb_root_path . 'includes/functions_admin.' . $phpEx; } // Delete posts, attachments, etc. // delete_posts can handle any number of IDs in its second argument delete_posts('poster_id', $user_ids); } } $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE, PRIVMSGS_FOLDER_TABLE, PRIVMSGS_RULES_TABLE); // Delete the miscellaneous (non-post) data for the user foreach ($table_ary as $table) { $sql = "DELETE FROM {$table}\n\t\t\tWHERE " . $user_id_sql; $db->sql_query($sql); } $cache->destroy('sql', MODERATOR_CACHE_TABLE); // Change user_id to anonymous for posts edited by this user $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_edit_user = '******' WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); $db->sql_query($sql); // Change user_id to anonymous for pms edited by this user $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' SET message_edit_user = '******' WHERE ' . $db->sql_in_set('message_edit_user', $user_ids); $db->sql_query($sql); // Change user_id to anonymous for posts deleted by this user $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_delete_user = '******' WHERE ' . $db->sql_in_set('post_delete_user', $user_ids); $db->sql_query($sql); // Change user_id to anonymous for topics deleted by this user $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_delete_user = '******' WHERE ' . $db->sql_in_set('topic_delete_user', $user_ids); $db->sql_query($sql); // Delete user log entries about this user $sql = 'DELETE FROM ' . LOG_TABLE . ' WHERE ' . $db->sql_in_set('reportee_id', $user_ids); $db->sql_query($sql); // Change user_id to anonymous for this users triggered events $sql = 'UPDATE ' . LOG_TABLE . ' SET user_id = ' . ANONYMOUS . ' WHERE ' . $user_id_sql; $db->sql_query($sql); // Delete the user_id from the zebra table $sql = 'DELETE FROM ' . ZEBRA_TABLE . ' WHERE ' . $user_id_sql . ' OR ' . $db->sql_in_set('zebra_id', $user_ids); $db->sql_query($sql); // Delete the user_id from the banlist $sql = 'DELETE FROM ' . BANLIST_TABLE . ' WHERE ' . $db->sql_in_set('ban_userid', $user_ids); $db->sql_query($sql); // Delete the user_id from the session table $sql = 'DELETE FROM ' . SESSIONS_TABLE . ' WHERE ' . $db->sql_in_set('session_user_id', $user_ids); $db->sql_query($sql); // Clean the private messages tables from the user if (!function_exists('phpbb_delete_user_pms')) { include $phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx; } phpbb_delete_users_pms($user_ids); $phpbb_notifications = $phpbb_container->get('notification_manager'); $phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_ids); $db->sql_transaction('commit'); /** * Event after a user is deleted * * @event core.delete_user_after * @var string mode Mode of deletion (retain/delete posts) * @var array user_ids IDs of the deleted user * @var mixed retain_username True if username should be retained * or false if not * @since 3.1.0-a1 */ $vars = array('mode', 'user_ids', 'retain_username'); extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars))); // Reset newest user info if appropriate if (in_array($config['newest_user_id'], $user_ids)) { update_last_username(); } return false; }
/** * Delete all PM(s) for a given user and delete the ones without references * * @param int $user_id ID of the user whose private messages we want to delete * * @return boolean False if there were no pms found, true otherwise. */ function phpbb_delete_user_pms($user_id) { global $db, $user, $phpbb_root_path, $phpEx; $user_id = (int) $user_id; if (!$user_id) { return false; } return phpbb_delete_users_pms(array($user_id)); }
/** * Delete all PM(s) for a given user and delete the ones without references * * @param int $user_id ID of the user whose private messages we want to delete * * @return boolean False if there were no pms found, true otherwise. */ function phpbb_delete_user_pms($user_id) { $user_id = (int) $user_id; if (!$user_id) { return false; } return phpbb_delete_users_pms(array($user_id)); }