mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 14:18:52 +00:00
Merge remote-tracking branch 'github-p/feature/prune-users' into develop
* github-p/feature/prune-users: (21 commits) [feature/prune-users] $author_id_sql is no longer needed here. [feature/prune-users] Move quote to the correct line. [feature/prune-users] Split one line into two lines for readability. [feature/prune-users] Use empty for checking array size. [feature/prune-users] Fix issues with queries pointed out by bantu. [feature/prune-users] Add spaces inside brackets. [feature/prune-users] Use a map instead of performing array scans. [feature/prune-users] Fix incorrect condition when deleting log entries. [feature/prune-users] Non-cosmetic changes per bantu's review. [feature/prune-users] Cosmetic changes per bantu's review. [feature/prune-users] Minor UI adjustment and bug fixes [feature/prune_users] Moved set_config_count out of user loop. [feature/prune-users] Fixed user id check in undelivered users loop. [feature/prune-users] Call sql_is_set once for author ids in user_delete. [feature/prune-users] Replaced missed occurrences of $user_id with $user_ids. [feature/prune-users] Call sql_is_set for user ids once in user_delete. [feature/prune-users] Fixed whitespace in language file. [feature/prune-users] Apply904bcb86a0
. [feature/prune-users] Adjust some language strings for new features [feature/prune-users] Applye6ed55a9c1
. ...
This commit is contained in:
commit
128eae7217
7 changed files with 334 additions and 173 deletions
|
@ -9,7 +9,7 @@
|
|||
<form id="acp_prune" method="post" action="{U_ACTION}">
|
||||
|
||||
<fieldset>
|
||||
<legend>{L_ACP_PRUNE_USERS}</legend>
|
||||
<legend>{L_CRITERIA}</legend>
|
||||
<dl>
|
||||
<dt><label for="username">{L_USERNAME}:</label></dt>
|
||||
<dd><input type="text" id="username" name="username" /></dd>
|
||||
|
@ -18,9 +18,16 @@
|
|||
<dt><label for="email">{L_EMAIL}:</label></dt>
|
||||
<dd><input type="text" id="email" name="email" /></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><label for="email">{L_WEBSITE}:</label></dt>
|
||||
<dd><input type="text" id="website" name="website" /></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><label for="joined">{L_JOINED}:</label><br /><span>{L_JOINED_EXPLAIN}</span></dt>
|
||||
<dd><select name="joined_select">{S_JOINED_OPTIONS}</select> <input type="text" id="joined" name="joined" /></dd>
|
||||
<dd>
|
||||
<strong>{L_AFTER}</strong> <input type="text" id="joined_after" name="joined_after" />
|
||||
<br /> <br /> <strong>{L_BEFORE}</strong> <input type="text" id="joined_before" name="joined_before" />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><label for="active">{L_LAST_ACTIVE}:</label><br /><span>{L_LAST_ACTIVE_EXPLAIN}</span></dt>
|
||||
|
@ -30,11 +37,29 @@
|
|||
<dt><label for="count">{L_POSTS}:</label></dt>
|
||||
<dd><select name="count_select">{S_COUNT_OPTIONS}</select> <input type="text" id="count" name="count" /></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt><label for="posts_on_queue">{L_POSTS_ON_QUEUE}:</label></dt>
|
||||
<dd><select name="queue_select">{S_COUNT_OPTIONS}</select> <input type="text" id="posts_on_queue" name="posts_on_queue" /></select>
|
||||
</dl>
|
||||
<!-- IF S_GROUP_LIST -->
|
||||
<dl>
|
||||
<dt><label for="group_id">{L_GROUP}:</label><br /><span>{L_PRUNE_USERS_GROUP_EXPLAIN}</dt>
|
||||
<dd><select name="group_id">{S_GROUP_LIST}</select></dd>
|
||||
</dl>
|
||||
<!-- ENDIF -->
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{L_USERNAMES}</legend>
|
||||
<dl>
|
||||
<dt><label for="users">{L_ACP_PRUNE_USERS}:</label><br /><span>{L_SELECT_USERS_EXPLAIN}</span></dt>
|
||||
<dd><textarea id="users" name="users" cols="40" rows="5"></textarea></dd>
|
||||
<dd>[ <a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a> ]</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{L_OPTIONS}</legend>
|
||||
<dl>
|
||||
<dt><label for="deleteposts">{L_DELETE_USER_POSTS}:</label><br /><span>{L_DELETE_USER_POSTS_EXPLAIN}</span></dt>
|
||||
<dd><label><input type="radio" class="radio" name="deleteposts" value="1" /> {L_YES}</label>
|
||||
|
|
|
@ -2,6 +2,23 @@
|
|||
|
||||
<form id="confirm" method="post" action="{S_CONFIRM_ACTION}">
|
||||
|
||||
<fieldset id="userlist">
|
||||
<h2>{L_PRUNE_USERS_LIST}</h2>
|
||||
<!-- IF S_DEACTIVATE --><p>{L_PRUNE_USERS_LIST_DEACTIVATE}</p><!-- ELSE --><p>{L_PRUNE_USERS_LIST_DELETE}</p><!-- ENDIF -->
|
||||
|
||||
<br />
|
||||
<!-- BEGIN users -->
|
||||
» <input type="checkbox" name="user_ids[]" value="{users.USER_ID}" checked="checked" />
|
||||
<a href="{users.U_PROFILE}">{users.USERNAME}</a>
|
||||
<!-- IF users.U_USER_ADMIN --> [ <a href="{users.U_USER_ADMIN}">{L_USER_ADMIN}</a> ]<!-- ENDIF --><br />
|
||||
<!-- END users -->
|
||||
<br />
|
||||
<span class="small">
|
||||
<a href="#" onclick="marklist('userlist', 'user_ids', true)">{L_MARK_ALL}</a> •
|
||||
<a href="#" onclick="marklist('userlist', 'user_ids', false)">{L_UNMARK_ALL}</a>
|
||||
</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<h1>{MESSAGE_TITLE}</h1>
|
||||
<p>{MESSAGE_TEXT}</p>
|
||||
|
@ -12,17 +29,6 @@
|
|||
<input type="submit" name="confirm" value="{L_YES}" class="button2" />
|
||||
<input type="submit" name="cancel" value="{L_NO}" class="button2" />
|
||||
</div>
|
||||
|
||||
<h2>{L_PRUNE_USERS_LIST}</h2>
|
||||
<!-- IF S_DEACTIVATE --><p>{L_PRUNE_USERS_LIST_DEACTIVATE}</p><!-- ELSE --><p>{L_PRUNE_USERS_LIST_DELETE}</p><!-- ENDIF -->
|
||||
|
||||
<br />
|
||||
<!-- BEGIN users -->
|
||||
» <a href="{users.U_PROFILE}">{users.USERNAME}</a><!-- IF users.U_USER_ADMIN --> [<a href="{users.U_USER_ADMIN}">{L_USER_ADMIN}</a>]<!-- ENDIF --><br />
|
||||
<!-- END users -->
|
||||
|
||||
<br /><br />
|
||||
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -155,10 +155,7 @@ class acp_inactive
|
|||
trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
foreach ($mark as $user_id)
|
||||
{
|
||||
user_delete('retain', $user_id, $user_affected[$user_id]);
|
||||
}
|
||||
user_delete('retain', $mark, true);
|
||||
|
||||
add_log('admin', 'LOG_INACTIVE_' . strtoupper($action), implode(', ', $user_affected));
|
||||
|
||||
|
|
|
@ -242,8 +242,8 @@ class acp_prune
|
|||
if (confirm_box(true))
|
||||
{
|
||||
$user_ids = $usernames = array();
|
||||
$this->get_prune_users($user_ids, $usernames);
|
||||
|
||||
$this->get_prune_users($user_ids, $usernames);
|
||||
if (sizeof($user_ids))
|
||||
{
|
||||
if ($action == 'deactivate')
|
||||
|
@ -255,19 +255,13 @@ class acp_prune
|
|||
{
|
||||
if ($deleteposts)
|
||||
{
|
||||
foreach ($user_ids as $user_id)
|
||||
{
|
||||
user_delete('remove', $user_id);
|
||||
}
|
||||
user_delete('remove', $user_ids);
|
||||
|
||||
$l_log = 'LOG_PRUNE_USER_DEL_DEL';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($user_ids as $user_id)
|
||||
{
|
||||
user_delete('retain', $user_id, $usernames[$user_id]);
|
||||
}
|
||||
user_delete('retain', $user_ids, true);
|
||||
|
||||
$l_log = 'LOG_PRUNE_USER_DEL_ANON';
|
||||
}
|
||||
|
@ -299,6 +293,7 @@ class acp_prune
|
|||
{
|
||||
$template->assign_block_vars('users', array(
|
||||
'USERNAME' => $usernames[$user_id],
|
||||
'USER_ID' => $user_id,
|
||||
'U_PROFILE' => append_sid($phpbb_root_path . 'memberlist.' . $phpEx, 'mode=viewprofile&u=' . $user_id),
|
||||
'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&u=' . $user_id, true, $user->session_id) : '',
|
||||
));
|
||||
|
@ -314,17 +309,7 @@ class acp_prune
|
|||
'mode' => $mode,
|
||||
'prune' => 1,
|
||||
|
||||
'users' => utf8_normalize_nfc(request_var('users', '', true)),
|
||||
'username' => utf8_normalize_nfc(request_var('username', '', true)),
|
||||
'email' => request_var('email', ''),
|
||||
'joined_select' => request_var('joined_select', ''),
|
||||
'joined' => request_var('joined', ''),
|
||||
'active_select' => request_var('active_select', ''),
|
||||
'active' => request_var('active', ''),
|
||||
'count_select' => request_var('count_select', ''),
|
||||
'count' => request_var('count', ''),
|
||||
'deleteposts' => request_var('deleteposts', 0),
|
||||
|
||||
'action' => request_var('action', ''),
|
||||
)), 'confirm_body_prune.html');
|
||||
}
|
||||
|
@ -340,22 +325,29 @@ class acp_prune
|
|||
}
|
||||
|
||||
$find_time = array('lt' => $user->lang['BEFORE'], 'gt' => $user->lang['AFTER']);
|
||||
$s_find_join_time = '';
|
||||
foreach ($find_time as $key => $value)
|
||||
{
|
||||
$s_find_join_time .= '<option value="' . $key . '">' . $value . '</option>';
|
||||
}
|
||||
|
||||
$s_find_active_time = '';
|
||||
foreach ($find_time as $key => $value)
|
||||
{
|
||||
$s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>';
|
||||
}
|
||||
|
||||
$s_group_list = '';
|
||||
$sql = 'SELECT group_id, group_name
|
||||
FROM ' . GROUPS_TABLE . '
|
||||
WHERE group_type <> ' . GROUP_SPECIAL . '
|
||||
ORDER BY group_name ASC';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</select>';
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
$template->assign_vars(array(
|
||||
'U_ACTION' => $this->u_action,
|
||||
'S_JOINED_OPTIONS' => $s_find_join_time,
|
||||
'S_ACTIVE_OPTIONS' => $s_find_active_time,
|
||||
'S_GROUP_LIST' => $s_group_list,
|
||||
'S_COUNT_OPTIONS' => $s_find_count,
|
||||
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'),
|
||||
));
|
||||
|
@ -368,42 +360,80 @@ class acp_prune
|
|||
{
|
||||
global $user, $db;
|
||||
|
||||
$users = utf8_normalize_nfc(request_var('users', '', true));
|
||||
|
||||
if ($users)
|
||||
$users_by_name = request_var('users', '', true);
|
||||
$users_by_id = request_var('user_ids', array(0));
|
||||
$group_id = request_var('group_id', 0);
|
||||
$posts_on_queue = request_var('posts_on_queue', 0);
|
||||
|
||||
if ($users_by_name)
|
||||
{
|
||||
$users = explode("\n", $users);
|
||||
$users = explode("\n", $users_by_name);
|
||||
$where_sql = ' AND ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', $users));
|
||||
}
|
||||
else if (!empty($users_by_id))
|
||||
{
|
||||
$user_ids = $users_by_id;
|
||||
user_get_id_name($user_ids, $usernames);
|
||||
|
||||
$where_sql = ' AND ' . $db->sql_in_set('user_id', $user_ids);
|
||||
}
|
||||
else
|
||||
{
|
||||
$username = utf8_normalize_nfc(request_var('username', '', true));
|
||||
$username = request_var('username', '', true);
|
||||
$email = request_var('email', '');
|
||||
$website = request_var('website', '');
|
||||
|
||||
$joined_select = request_var('joined_select', 'lt');
|
||||
$active_select = request_var('active_select', 'lt');
|
||||
$count_select = request_var('count_select', 'eq');
|
||||
$joined = request_var('joined', '');
|
||||
$queue_select = request_var('queue_select', 'gt');
|
||||
$joined_before = request_var('joined_before', '');
|
||||
$joined_after = request_var('joined_after', '');
|
||||
$active = request_var('active', '');
|
||||
|
||||
$active = ($active) ? explode('-', $active) : array();
|
||||
$joined = ($joined) ? explode('-', $joined) : array();
|
||||
$count = request_var('count', 0);
|
||||
|
||||
if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined) && sizeof($joined) != 3))
|
||||
$active = ($active) ? explode('-', $active) : array();
|
||||
$joined_before = ($joined_before) ? explode('-', $joined_before) : array();
|
||||
$joined_after = ($joined_after) ? explode('-', $joined_after) : array();
|
||||
|
||||
// calculate the conditions required by the join time criteria
|
||||
$joined_sql = '';
|
||||
if (!empty($joined_before) && !empty($joined_after))
|
||||
{
|
||||
// if the two entered dates are equal, we need to adjust
|
||||
// so that our time range is a full day instead of 1 second
|
||||
if ($joined_after == $joined_before)
|
||||
{
|
||||
$joined_after[2] += 1;
|
||||
}
|
||||
|
||||
$joined_sql = ' AND user_regdate BETWEEN ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]) .
|
||||
' AND ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]);
|
||||
}
|
||||
else if (empty($joined_before) && !empty($joined_after))
|
||||
{
|
||||
$joined_sql = ' AND user_regdate > ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]);
|
||||
}
|
||||
else if (empty($joined_after) && !empty($joined_before))
|
||||
{
|
||||
$joined_sql = ' AND user_regdate < ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]);
|
||||
}
|
||||
// implicit else when both arrays are empty do nothing
|
||||
|
||||
if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined_before) && sizeof($joined_before) != 3) || (sizeof($joined_after) && sizeof($joined_after) != 3))
|
||||
{
|
||||
trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$count = request_var('count', '');
|
||||
|
||||
$key_match = array('lt' => '<', 'gt' => '>', 'eq' => '=');
|
||||
$sort_by_types = array('username', 'user_email', 'user_posts', 'user_regdate', 'user_lastvisit');
|
||||
|
||||
$where_sql = '';
|
||||
$where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($username))) : '';
|
||||
$where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->any_char, $email)) . ' ' : '';
|
||||
$where_sql .= (sizeof($joined)) ? " AND user_regdate " . $key_match[$joined_select] . ' ' . gmmktime(0, 0, 0, (int) $joined[1], (int) $joined[2], (int) $joined[0]) : '';
|
||||
$where_sql .= ($count !== '') ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : '';
|
||||
$where_sql .= ($website) ? ' AND user_website ' . $db->sql_like_expression(str_replace('*', $db->any_char, $website)) . ' ' : '';
|
||||
$where_sql .= $joined_sql;
|
||||
$where_sql .= ($count) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : '';
|
||||
|
||||
// First handle pruning of users who never logged in, last active date is 0000-00-00
|
||||
if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0)
|
||||
|
@ -446,7 +476,6 @@ class acp_prune
|
|||
$where_sql";
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
$where_sql = '';
|
||||
$user_ids = $usernames = array();
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
|
@ -459,5 +488,53 @@ class acp_prune
|
|||
}
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if ($group_id)
|
||||
{
|
||||
$sql = 'SELECT user_id
|
||||
FROM ' . USER_GROUP_TABLE . '
|
||||
WHERE group_id = ' . (int) $group_id . '
|
||||
AND user_pending = 0
|
||||
AND ' . $db->sql_in_set('user_id', $user_ids, false, true);
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
// we're performing an intersection operation, so all the relevant users
|
||||
// come from this most recent query (which was limited to the results of the
|
||||
// previous query)
|
||||
$user_ids = $usernames = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$user_ids[] = $row['poster_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// only get usernames if they are needed (not part of some later query)
|
||||
if (!$posts_on_queue)
|
||||
{
|
||||
// this is an additional query aginst the users table
|
||||
user_get_id_name($user_ids, $usernames);
|
||||
}
|
||||
}
|
||||
|
||||
if ($posts_on_queue)
|
||||
{
|
||||
$sql = 'SELECT poster_id, COUNT(post_id) AS queue_posts
|
||||
FROM ' . POSTS_TABLE . '
|
||||
WHERE ' . $db->sql_in_set('poster_id', $user_ids, false, true) . '
|
||||
GROUP BY poster_id
|
||||
HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue;
|
||||
$result = $db->sql_query($result);
|
||||
|
||||
// same intersection logic as the above group ID portion
|
||||
$user_ids = $usernames = array();
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$user_ids[] = $row['poster_id'];
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// do an additional query to get the correct set of usernames
|
||||
user_get_id_name($user_ids, $usernames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,46 +269,46 @@ function check_rule(&$rules, &$rule_row, &$message_row, $user_id)
|
|||
case RULE_IS_LIKE:
|
||||
$result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS_NOT_LIKE:
|
||||
$result = !preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS:
|
||||
$result = ($check0 == $rule_row['rule_string']);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS_NOT:
|
||||
$result = ($check0 != $rule_row['rule_string']);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_BEGINS_WITH:
|
||||
$result = preg_match("/^" . preg_quote($rule_row['rule_string'], '/') . '/i', $check0);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_ENDS_WITH:
|
||||
$result = preg_match("/" . preg_quote($rule_row['rule_string'], '/') . '$/i', $check0);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS_FRIEND:
|
||||
case RULE_IS_FOE:
|
||||
case RULE_ANSWERED:
|
||||
case RULE_FORWARDED:
|
||||
$result = ($check0 == 1);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS_USER:
|
||||
$result = ($check0 == $rule_row['rule_user_id']);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_IS_GROUP:
|
||||
$result = in_array($rule_row['rule_group_id'], $check0);
|
||||
break;
|
||||
|
||||
|
||||
case RULE_TO_GROUP:
|
||||
$result = (in_array('g_' . $message_row[$check_ary['check2']], $check0) || in_array('g_' . $message_row[$check_ary['check2']], $message_row[$check_ary['check1']]));
|
||||
break;
|
||||
|
||||
|
||||
case RULE_TO_ME:
|
||||
$result = (in_array('u_' . $user_id, $check0) || in_array('u_' . $user_id, $message_row[$check_ary['check1']]));
|
||||
break;
|
||||
|
@ -1145,6 +1145,23 @@ function phpbb_delete_user_pms($user_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
return phpbb_delete_users_pms(array($user_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all PM(s) for given users and delete the ones without references
|
||||
*
|
||||
* @param array $user_ids IDs of the users whose private messages we want to delete
|
||||
*
|
||||
* @return boolean False if there were no pms found, true otherwise.
|
||||
*/
|
||||
function phpbb_delete_users_pms($user_ids)
|
||||
{
|
||||
global $db, $user, $phpbb_root_path, $phpEx;
|
||||
|
||||
$user_id_sql = $db->sql_in_set('user_id', $user_ids);
|
||||
$author_id_sql = $db->sql_in_set('author_id', $user_ids);
|
||||
|
||||
// Get PM Information for later deleting
|
||||
// The two queries where split, so we can use our indexes
|
||||
$undelivered_msg = $delete_ids = array();
|
||||
|
@ -1152,7 +1169,7 @@ function phpbb_delete_user_pms($user_id)
|
|||
// Part 1: get PMs the user received
|
||||
$sql = 'SELECT msg_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE user_id = ' . $user_id;
|
||||
WHERE ' . $user_id_sql;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
|
@ -1162,12 +1179,12 @@ function phpbb_delete_user_pms($user_id)
|
|||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
// Part 2: get PMs the user sent, but have yet to be received
|
||||
// We cannot simply delete them. First we have to check,
|
||||
// Part 2: get PMs the users sent, but are yet to be received.
|
||||
// We cannot simply delete them. First we have to check
|
||||
// whether another user already received and read the message.
|
||||
$sql = 'SELECT msg_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE author_id = ' . $user_id . '
|
||||
WHERE ' . $author_id_sql . '
|
||||
AND folder_id = ' . PRIVMSGS_NO_BOX;
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
|
@ -1193,7 +1210,7 @@ function phpbb_delete_user_pms($user_id)
|
|||
// received them.
|
||||
$sql = 'SELECT msg_id
|
||||
FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE author_id = ' . $user_id . '
|
||||
WHERE ' . $author_id_sql . '
|
||||
AND folder_id <> ' . PRIVMSGS_NO_BOX . '
|
||||
AND folder_id <> ' . PRIVMSGS_OUTBOX . '
|
||||
AND folder_id <> ' . PRIVMSGS_SENTBOX;
|
||||
|
@ -1213,7 +1230,7 @@ function phpbb_delete_user_pms($user_id)
|
|||
// Count the messages we delete, so we can correct the user pm data
|
||||
$sql = 'SELECT user_id, COUNT(msg_id) as num_undelivered_privmsgs
|
||||
FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE author_id = ' . $user_id . '
|
||||
WHERE ' . $author_id_sql . '
|
||||
AND folder_id = ' . PRIVMSGS_NO_BOX . '
|
||||
AND ' . $db->sql_in_set('msg_id', array_merge($undelivered_msg, $delivered_msg)) . '
|
||||
GROUP BY user_id';
|
||||
|
@ -1271,12 +1288,12 @@ function phpbb_delete_user_pms($user_id)
|
|||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET user_new_privmsg = 0,
|
||||
user_unread_privmsg = 0
|
||||
WHERE user_id = ' . $user_id;
|
||||
WHERE ' . $user_id_sql;
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Delete private message data of the user
|
||||
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
|
||||
WHERE user_id = ' . (int) $user_id;
|
||||
WHERE ' . $user_id_sql;
|
||||
$db->sql_query($sql);
|
||||
|
||||
if (!empty($delete_ids))
|
||||
|
@ -1313,12 +1330,12 @@ function phpbb_delete_user_pms($user_id)
|
|||
// This way users are still able to read messages from users being removed
|
||||
$sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
|
||||
SET author_id = ' . ANONYMOUS . '
|
||||
WHERE author_id = ' . $user_id;
|
||||
WHERE ' . $author_id_sql;
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
|
||||
SET author_id = ' . ANONYMOUS . '
|
||||
WHERE author_id = ' . $user_id;
|
||||
WHERE ' . $author_id_sql;
|
||||
$db->sql_query($sql);
|
||||
|
||||
$db->sql_transaction('commit');
|
||||
|
|
|
@ -350,20 +350,34 @@ function user_add($user_row, $cp_data = false)
|
|||
|
||||
/**
|
||||
* Remove User
|
||||
* @param $mode Either 'retain' or 'remove'
|
||||
*/
|
||||
function user_delete($mode, $user_id, $post_username = false)
|
||||
function user_delete($mode, $user_ids, $retain_username = true)
|
||||
{
|
||||
global $cache, $config, $db, $user, $auth, $phpbb_dispatcher;
|
||||
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 = ' . $user_id;
|
||||
WHERE ' . $user_id_sql;
|
||||
$result = $db->sql_query($sql);
|
||||
$user_row = $db->sql_fetchrow($result);
|
||||
while ($row = $db->sql_fetchrow($result))
|
||||
{
|
||||
$user_rows[(int) $row['user_id']] = $row;
|
||||
}
|
||||
$db->sql_freeresult($result);
|
||||
|
||||
if (!$user_row)
|
||||
if (empty($user_rows))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -383,7 +397,7 @@ function user_delete($mode, $user_id, $post_username = false)
|
|||
// 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 r.user_id = ' . $user_id . '
|
||||
WHERE ' . $db->sql_in_set('r.user_id', $user_ids) . '
|
||||
AND p.post_id = r.post_id';
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
|
@ -437,97 +451,124 @@ function user_delete($mode, $user_id, $post_username = false)
|
|||
}
|
||||
|
||||
// Remove reports
|
||||
$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE user_id = ' . $user_id);
|
||||
$db->sql_query('DELETE FROM ' . REPORTS_TABLE . ' WHERE ' . $user_id_sql);
|
||||
|
||||
if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD)
|
||||
$num_users_delta = 0;
|
||||
|
||||
// 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)
|
||||
{
|
||||
avatar_delete('user', $user_row);
|
||||
}
|
||||
if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD)
|
||||
{
|
||||
avatar_delete('user', $user_row);
|
||||
}
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case 'retain':
|
||||
// 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;
|
||||
}
|
||||
|
||||
$db->sql_transaction('begin');
|
||||
|
||||
if ($post_username === false)
|
||||
{
|
||||
$post_username = $user->lang['GUEST'];
|
||||
}
|
||||
|
||||
// If the user is inactive and newly registered we assume no posts from this user being there...
|
||||
if ($user_row['user_type'] == USER_INACTIVE && $user_row['user_inactive_reason'] == INACTIVE_REGISTER && !$user_row['user_posts'])
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'UPDATE ' . FORUMS_TABLE . '
|
||||
SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = ''
|
||||
WHERE forum_last_poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . '
|
||||
SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
|
||||
WHERE poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . '
|
||||
SET post_edit_user = ' . ANONYMOUS . "
|
||||
WHERE post_edit_user = $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 = ''
|
||||
WHERE 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 = ''
|
||||
WHERE topic_last_poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
|
||||
SET poster_id = ' . ANONYMOUS . "
|
||||
WHERE 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
|
||||
|
||||
// Update the post count for the anonymous user
|
||||
if ($user_row['user_posts'])
|
||||
switch ($mode)
|
||||
{
|
||||
case 'retain':
|
||||
if ($retain_username === false)
|
||||
{
|
||||
$sql = 'UPDATE ' . USERS_TABLE . '
|
||||
SET user_posts = user_posts + ' . $user_row['user_posts'] . '
|
||||
WHERE user_id = ' . ANONYMOUS;
|
||||
$db->sql_query($sql);
|
||||
$post_username = $user->lang['GUEST'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$post_username = $user_row['username'];
|
||||
}
|
||||
}
|
||||
|
||||
$db->sql_transaction('commit');
|
||||
// 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 = ''
|
||||
WHERE forum_last_poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
break;
|
||||
$sql = 'UPDATE ' . POSTS_TABLE . '
|
||||
SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
|
||||
WHERE poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
case 'remove':
|
||||
$sql = 'UPDATE ' . TOPICS_TABLE . '
|
||||
SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = ''
|
||||
WHERE topic_poster = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
if (!function_exists('delete_posts'))
|
||||
{
|
||||
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
|
||||
}
|
||||
$sql = 'UPDATE ' . TOPICS_TABLE . '
|
||||
SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = ''
|
||||
WHERE topic_last_poster_id = $user_id";
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Delete posts, attachments, etc.
|
||||
delete_posts('poster_id', $user_id);
|
||||
// Since we change every post by this author, we need to count this amount towards the anonymous user
|
||||
|
||||
break;
|
||||
if ($user_row['user_posts'])
|
||||
{
|
||||
$added_guest_posts += $user_row['user_posts'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
// there is nothing variant specific to deleting posts
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$db->sql_transaction('begin');
|
||||
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 ' . POSTS_TABLE . '
|
||||
SET post_edit_user = ' . ANONYMOUS . '
|
||||
WHERE ' . $db->sql_in_set('post_edit_user', $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
|
||||
WHERE user_id = $user_id";
|
||||
WHERE " . $user_id_sql;
|
||||
$db->sql_query($sql);
|
||||
}
|
||||
|
||||
|
@ -535,29 +576,29 @@ function user_delete($mode, $user_id, $post_username = false)
|
|||
|
||||
// Delete user log entries about this user
|
||||
$sql = 'DELETE FROM ' . LOG_TABLE . '
|
||||
WHERE reportee_id = ' . $user_id;
|
||||
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 = ' . $user_id;
|
||||
WHERE ' . $user_id_sql;
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Delete the user_id from the zebra table
|
||||
$sql = 'DELETE FROM ' . ZEBRA_TABLE . '
|
||||
WHERE user_id = ' . $user_id . '
|
||||
OR zebra_id = ' . $user_id;
|
||||
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 ban_userid = ' . $user_id;
|
||||
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 session_user_id = ' . $user_id;
|
||||
WHERE ' . $db->sql_in_set('session_user_id', $user_ids);
|
||||
$db->sql_query($sql);
|
||||
|
||||
// Clean the private messages tables from the user
|
||||
|
@ -565,7 +606,7 @@ function user_delete($mode, $user_id, $post_username = false)
|
|||
{
|
||||
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
|
||||
}
|
||||
phpbb_delete_user_pms($user_id);
|
||||
phpbb_delete_users_pms($user_ids);
|
||||
|
||||
$db->sql_transaction('commit');
|
||||
|
||||
|
@ -582,17 +623,11 @@ function user_delete($mode, $user_id, $post_username = false)
|
|||
extract($phpbb_dispatcher->trigger_event('core.delete_user_after', compact($vars)));
|
||||
|
||||
// Reset newest user info if appropriate
|
||||
if ($config['newest_user_id'] == $user_id)
|
||||
if (in_array($config['newest_user_id'], $user_ids))
|
||||
{
|
||||
update_last_username();
|
||||
}
|
||||
|
||||
// Decrement number of users if this user is active
|
||||
if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE)
|
||||
{
|
||||
set_config_count('num_users', -1, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ if (empty($lang) || !is_array($lang))
|
|||
|
||||
// User pruning
|
||||
$lang = array_merge($lang, array(
|
||||
'ACP_PRUNE_USERS_EXPLAIN' => 'This section allows you to delete or deactivate users on your board. Accounts can be filtered in a variety of ways; by post count, most recent activity, etc. Criteria may be combined to narrow down which accounts are affected. For example, you can prune users with fewer than 10 posts, who were also inactive after 2002-01-01. Alternatively, you may skip the criteria selection completely by entering a list of users (each on a separate line) into the text field. Take care with this facility! Once a user is deleted, there is no way to reverse the action.',
|
||||
'ACP_PRUNE_USERS_EXPLAIN' => 'This section allows you to delete or deactivate users on your board. Accounts can be filtered in a variety of ways; by post count, most recent activity, etc. Criteria may be combined to narrow down which accounts are affected. For example, you can prune users with fewer than 10 posts, who were also inactive after 2002-01-01. Use * as a wildcard for text fields. Alternatively, you may skip the criteria selection completely by entering a list of users (each on a separate line) into the text field. Take care with this facility! Once a user is deleted, there is no way to reverse the action.',
|
||||
|
||||
'CRITERIA' => 'Criteria',
|
||||
|
||||
'DEACTIVATE_DELETE' => 'Deactivate or delete',
|
||||
'DEACTIVATE_DELETE_EXPLAIN' => 'Choose whether to deactivate users or delete them entirely. Please note that deleted users cannot be restored!',
|
||||
|
@ -44,15 +46,17 @@ $lang = array_merge($lang, array(
|
|||
'DELETE_USER_POSTS' => 'Delete pruned user posts',
|
||||
'DELETE_USER_POSTS_EXPLAIN' => 'Removes posts made by deleted users, has no effect if users are deactivated.',
|
||||
|
||||
'JOINED_EXPLAIN' => 'Enter a date in <kbd>YYYY-MM-DD</kbd> format.',
|
||||
'JOINED_EXPLAIN' => 'Enter a date in <kbd>YYYY-MM-DD</kbd> format. You may use both fields to specify an interval, or leave one blank for an open date range.',
|
||||
|
||||
'LAST_ACTIVE_EXPLAIN' => 'Enter a date in <kbd>YYYY-MM-DD</kbd> format. Enter <kbd>0000-00-00</kbd> to prune users who never logged in, <em>Before</em> and <em>After</em> conditions will be ignored.',
|
||||
|
||||
'POSTS_ON_QUEUE' => 'Posts Awaiting Approval',
|
||||
'PRUNE_USERS_GROUP_EXPLAIN' => 'Selects all members of the group for pruning.',
|
||||
'PRUNE_USERS_LIST' => 'Users to be pruned',
|
||||
'PRUNE_USERS_LIST_DELETE' => 'With the selected critera for pruning users the following accounts will be removed.',
|
||||
'PRUNE_USERS_LIST_DEACTIVATE' => 'With the selected critera for pruning users the following accounts will be deactivated.',
|
||||
'PRUNE_USERS_LIST_DELETE' => 'With the selected critera for pruning users the following accounts will be removed. You can remove individual users from the deletion list by unchecking the box next to their username.',
|
||||
'PRUNE_USERS_LIST_DEACTIVATE' => 'With the selected critera for pruning users the following accounts will be deactivated. You can remove individual users from the deactivation list by unchecking the box next to their username.',
|
||||
|
||||
'SELECT_USERS_EXPLAIN' => 'Enter specific usernames here, they will be used in preference to the criteria above. Founders cannot be pruned.',
|
||||
'SELECT_USERS_EXPLAIN' => 'Enter specific usernames here. They will be used in preference to the criteria above. Founders cannot be pruned.',
|
||||
|
||||
'USER_DEACTIVATE_SUCCESS' => 'The selected users have been deactivated successfully.',
|
||||
'USER_DELETE_SUCCESS' => 'The selected users have been deleted successfully.',
|
||||
|
|
Loading…
Add table
Reference in a new issue