Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Oleg/feature/prune users #504

Closed
wants to merge 16 commits into from

2 participants

jellydoughnut and others added some commits
@jellydoughnut jellydoughnut [feature/prune-users] Rework user_delete() functions_user.php
user_delete now uses fewer queries to delete a set of users of size > 1 by
accepting an array of users rather than a single user at a time.  This required
changing the third parameter, however the function retains its former behavior
with the old-style parameters.

PHPBB3-9622
e7e0ab9
@p p [feature/prune-users] Apply e6ed55a.
This was done in PHPBB3-9872.

PHPBB3-9622
04a6303
@jellydoughnut jellydoughnut [feature/prune-users] Adjust some language strings for new features
Adjust two language strings for ACP prune feature to include descriptions for
new features.

PHPBB3-9622
fe347ec
@p p Merge commit '441755bf170e49799e311c71b2123ff263970d62' into feature/…
…prune-users

* commit '441755bf170e49799e311c71b2123ff263970d62':
  [ticket/9874] view_log() performs unneeded count query over all log entries.
e345c35
@p p Merge commit '47dc492839ea44cb9aa3d0ad23f09dd2fd0b4ed9' into feature/…
…prune-users

* commit '47dc492839ea44cb9aa3d0ad23f09dd2fd0b4ed9':
  [ticket/9997] Fixed an inconsistency in the Moderator Control Panel
21d32f4
@p p Merge commit 'e6ed55a9c1ceb07ab2e87d4a53f9e688fda319c5' into feature/…
…prune-users

* commit 'e6ed55a9c1ceb07ab2e87d4a53f9e688fda319c5':
  [ticket/9872] Removed some useless code that broke delete_posts

These changes have already been applied in an earlier commit.
Therefore this commit is empty. Merge was done using 'ours' strategy.
a93d58a
@p p [feature/prune-users] Apply 904bcb8.
This was done in PHPBB3-7834.

PHPBB3-9622
bf27d61
@p p Merge commit '904bcb86a054ab6256da565098eb9bd8ab20414b' into feature/…
…prune-users

* commit '904bcb86a054ab6256da565098eb9bd8ab20414b':
  [ticket/7834] Topic time didn't update when first post was deleted
92e140e
@p p Merge commit 'ee0db1a1d5f0150016d0971057f889f2366f9856' into feature/…
…prune-users

* commit 'ee0db1a1d5f0150016d0971057f889f2366f9856':
9c6660a
@p p Merge branch 'develop' into feature/prune-users
* develop: (170 commits)
  [ticket/10145] Always recompile all templates when DEBUG_EXTRA is defined.
  [feature/attachment-management-no-reassignment] Handle privacy and some more.
  [ticket/10148] Turn TEMPLATE_BITFIELD into an instance variable.
  [ticket/10147] Corrected a typo in includes/functions_template.php.
  [ticket/10141] Save a hash lookup when value is not in cache.
  [ticket/10143] Added tests for storing a previously deleted value in db cache.
  [ticket/10105] Update AIM express link.
  [ticket/10105] Update AIM application download link.
  [ticket/10137] Remove unintended space at end of PHP_URL_FOPEN_SUPPORT_EXPLAIN.
  [ticket/10141] Split double-assignment into conditional and unconditional part.
  [ticket/10141] Use a cache in $auth->_fill_acl() for better performance.
  [ticket/9961] Create log entries when users are activated.
  [ticket/10139] Make signatures of set_atomic() consistent by using $new_value.
  [ticket/10139] Rename $cache to $use_cache to avoid confusion with cache object
  [ticket/10006] Remove unneeded if statements
  [ticket/10006] Remove return values
  [ticket/10006] More testing
  [ticket/10006] Tweak the tests a bit
  [ticket/10006] Add phpbb_config::delete
  [ticket/7941] Added @return to generate_board_url docstring.
  ...
ab44fe5
@p p [feature/prune-users] Fixed whitespace in language file.
PHPBB3-9622
33c7bb4
@p p [feature/prune-users] Call sql_is_set for user ids once in user_delete.
PHPBB3-9622
44f524a
@p p [feature/prune-users] Replaced missed occurrences of $user_id with $u…
…ser_ids.

PHPBB3-9622
0f17d5d
@p p [feature/prune-users] Call sql_is_set once for author ids in user_del…
…ete.

PHPBB3-9622
f65556e
@p p [feature/prune-users] Fixed user id check in undelivered users loop.
There is now $user_ids instead of one $user_id.

PHPBB3-9622
e23868f
@p p [feature/prune_users] Moved set_config_count out of user loop.
PHPBB3-9622
9f32cae
@jellydoughnut

Thanks for taking care of that; I'll give it a look this weekend.

@p p referenced this pull request
Merged

Feature/prune users #622

@p p closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 8, 2011
  1. @jellydoughnut @p

    [feature/prune-users] Rework user_delete() functions_user.php

    jellydoughnut authored p committed
    user_delete now uses fewer queries to delete a set of users of size > 1 by
    accepting an array of users rather than a single user at a time.  This required
    changing the third parameter, however the function retains its former behavior
    with the old-style parameters.
    
    PHPBB3-9622
  2. @p

    [feature/prune-users] Apply e6ed55a.

    p authored
    This was done in PHPBB3-9872.
    
    PHPBB3-9622
  3. @jellydoughnut @p

    [feature/prune-users] Adjust some language strings for new features

    jellydoughnut authored p committed
    Adjust two language strings for ACP prune feature to include descriptions for
    new features.
    
    PHPBB3-9622
  4. @p

    Merge commit '441755bf170e49799e311c71b2123ff263970d62' into feature/…

    p authored
    …prune-users
    
    * commit '441755bf170e49799e311c71b2123ff263970d62':
      [ticket/9874] view_log() performs unneeded count query over all log entries.
  5. @p

    Merge commit '47dc492839ea44cb9aa3d0ad23f09dd2fd0b4ed9' into feature/…

    p authored
    …prune-users
    
    * commit '47dc492839ea44cb9aa3d0ad23f09dd2fd0b4ed9':
      [ticket/9997] Fixed an inconsistency in the Moderator Control Panel
  6. @p

    Merge commit 'e6ed55a9c1ceb07ab2e87d4a53f9e688fda319c5' into feature/…

    p authored
    …prune-users
    
    * commit 'e6ed55a9c1ceb07ab2e87d4a53f9e688fda319c5':
      [ticket/9872] Removed some useless code that broke delete_posts
    
    These changes have already been applied in an earlier commit.
    Therefore this commit is empty. Merge was done using 'ours' strategy.
  7. @p

    [feature/prune-users] Apply 904bcb8.

    p authored
    This was done in PHPBB3-7834.
    
    PHPBB3-9622
  8. @p

    Merge commit '904bcb86a054ab6256da565098eb9bd8ab20414b' into feature/…

    p authored
    …prune-users
    
    * commit '904bcb86a054ab6256da565098eb9bd8ab20414b':
      [ticket/7834] Topic time didn't update when first post was deleted
  9. @p

    Merge commit 'ee0db1a1d5f0150016d0971057f889f2366f9856' into feature/…

    p authored
    …prune-users
    
    * commit 'ee0db1a1d5f0150016d0971057f889f2366f9856':
  10. @p

    Merge branch 'develop' into feature/prune-users

    p authored
    * develop: (170 commits)
      [ticket/10145] Always recompile all templates when DEBUG_EXTRA is defined.
      [feature/attachment-management-no-reassignment] Handle privacy and some more.
      [ticket/10148] Turn TEMPLATE_BITFIELD into an instance variable.
      [ticket/10147] Corrected a typo in includes/functions_template.php.
      [ticket/10141] Save a hash lookup when value is not in cache.
      [ticket/10143] Added tests for storing a previously deleted value in db cache.
      [ticket/10105] Update AIM express link.
      [ticket/10105] Update AIM application download link.
      [ticket/10137] Remove unintended space at end of PHP_URL_FOPEN_SUPPORT_EXPLAIN.
      [ticket/10141] Split double-assignment into conditional and unconditional part.
      [ticket/10141] Use a cache in $auth->_fill_acl() for better performance.
      [ticket/9961] Create log entries when users are activated.
      [ticket/10139] Make signatures of set_atomic() consistent by using $new_value.
      [ticket/10139] Rename $cache to $use_cache to avoid confusion with cache object
      [ticket/10006] Remove unneeded if statements
      [ticket/10006] Remove return values
      [ticket/10006] More testing
      [ticket/10006] Tweak the tests a bit
      [ticket/10006] Add phpbb_config::delete
      [ticket/7941] Added @return to generate_board_url docstring.
      ...
  11. @p
  12. @p
  13. @p
  14. @p
  15. @p

    [feature/prune-users] Fixed user id check in undelivered users loop.

    p authored
    There is now $user_ids instead of one $user_id.
    
    PHPBB3-9622
  16. @p
This page is out of date. Refresh to see the latest.
View
27 phpBB/adm/style/acp_prune_users.html
@@ -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>
@@ -19,8 +19,15 @@
<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>
@@ -31,10 +38,26 @@
<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>
+<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>
+</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>
View
28 phpBB/adm/style/confirm_body_prune.html
@@ -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 -->
+ &raquo; <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> &bull;
+ <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" />&nbsp;
<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 -->
- &raquo; <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>
View
5 phpBB/includes/acp/acp_inactive.php
@@ -157,10 +157,7 @@ function main($id, $mode)
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));
}
View
142 phpBB/includes/acp/acp_prune.php
@@ -243,6 +243,7 @@ function prune_users($id, $mode)
if (confirm_box(true))
{
$user_ids = $usernames = array();
+
$this->get_prune_users($user_ids, $usernames);
if (sizeof($user_ids))
@@ -256,19 +257,13 @@ function prune_users($id, $mode)
{
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';
}
@@ -300,6 +295,7 @@ function prune_users($id, $mode)
{
$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&amp;u=' . $user_id),
'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $user_id, true, $user->session_id) : '',
));
@@ -315,8 +311,8 @@ function prune_users($id, $mode)
'mode' => $mode,
'prune' => 1,
- 'users' => utf8_normalize_nfc(request_var('users', '', true)),
- 'username' => utf8_normalize_nfc(request_var('username', '', true)),
+ 'users' => request_var('users', '', true),
+ 'username' => request_var('username', '', true),
'email' => request_var('email', ''),
'joined_select' => request_var('joined_select', ''),
'joined' => request_var('joined', ''),
@@ -341,22 +337,27 @@ function prune_users($id, $mode)
}
$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 = '<option value="0" selected="selected">' . $user->lang['SELECT_OPTION'] . '</option>';
+ $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>';
+ }
+
$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&amp;form=acp_prune&amp;field=users'),
));
@@ -369,33 +370,68 @@ function get_prune_users(&$user_ids, &$usernames)
{
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));
+
+ 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', '');
+ $count = request_var('count', 0);
+ $posts_on_queue = request_var('posts_on_queue', 0);
+
$active = ($active) ? explode('-', $active) : array();
- $joined = ($joined) ? explode('-', $joined) : array();
+ $joined_before = ($joined_before) ? explode('-', $joined_before) : array();
+ $joined_after = ($joined_after) ? explode('-', $joined_after) : array();
- if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined) && sizeof($joined) != 3))
+ // calculate the conditions required by the join time criteria
+ $joined_sql = '';
+ if (!empty($joined_before) && !empty($joined_after))
{
- trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING);
+ // 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_after[2]++;
+ }
+
+ $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[3]);
+ }
+ // implicit else when both arrays are empty do nothing
- $count = request_var('count', '');
+ 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);
+ }
$key_match = array('lt' => '<', 'gt' => '>', 'eq' => '=');
$sort_by_types = array('username', 'user_email', 'user_posts', 'user_regdate', 'user_lastvisit');
@@ -403,8 +439,9 @@ function get_prune_users(&$user_ids, &$usernames)
$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)
@@ -447,7 +484,6 @@ function get_prune_users(&$user_ids, &$usernames)
$where_sql";
$result = $db->sql_query($sql);
- $where_sql = '';
$user_ids = $usernames = array();
while ($row = $db->sql_fetchrow($result))
@@ -460,5 +496,49 @@ function get_prune_users(&$user_ids, &$usernames)
}
}
$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'];
+ }
+
+ // 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'];
+ }
+
+ // do an additional query to get the correct set of usernames
+ user_get_id_name($user_ids, $usernames);
+ }
}
}
View
219 phpBB/includes/functions_user.php
@@ -330,20 +330,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;
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[$row['user_id']] = $row;
+ }
$db->sql_freeresult($result);
- if (!$user_row)
+ if (!$user_rows)
{
return false;
}
@@ -351,7 +365,8 @@ 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) . //r.user_id = ' . $user_id . '
+ '
AND p.post_id = r.post_id';
$result = $db->sql_query($sql);
@@ -405,133 +420,163 @@ 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)
- {
- avatar_delete('user', $user_row);
- }
+ $num_users_delta = 0;
- switch ($mode)
+ // 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)
{
- case 'retain':
-
- $db->sql_transaction('begin');
-
- if ($post_username === false)
- {
- $post_username = $user->lang['GUEST'];
- }
+ if ($user_row['user_avatar'] && $user_row['user_avatar_type'] == AVATAR_UPLOAD)
+ {
+ avatar_delete('user', $user_row);
+ }
- // 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);
+ // 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;
+ }
- $sql = 'UPDATE ' . POSTS_TABLE . '
- SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
- WHERE poster_id = $user_id";
- $db->sql_query($sql);
+ switch ($mode)
+ {
+ case 'retain':
+ if ($retain_username === false)
+ {
+ $post_username = $user->lang['GUEST'];
+ }
+ else
+ {
+ $post_username = $user_row['username'];
+ }
- $sql = 'UPDATE ' . POSTS_TABLE . '
- SET post_edit_user = ' . ANONYMOUS . "
- WHERE post_edit_user = $user_id";
- $db->sql_query($sql);
+ // 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'])
+ {
+ }
+ else
+ {
+ // 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);
- $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 ' . POSTS_TABLE . '
+ SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
+ WHERE poster_id = $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 ' . 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 ' . ATTACHMENTS_TABLE . '
- SET poster_id = ' . ANONYMOUS . "
- WHERE poster_id = $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);
- // Since we change every post by this author, we need to count this amount towards the anonymous user
+ // 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'])
- {
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_posts = user_posts + ' . $user_row['user_posts'] . '
- WHERE user_id = ' . ANONYMOUS;
- $db->sql_query($sql);
+ if ($user_row['user_posts'])
+ {
+ $added_guest_posts += $user_row['user_posts'];
+ }
}
- }
-
- $db->sql_transaction('commit');
+ break;
- break;
+ case 'remove':
+ // there is nothing variant specific to deleting posts
+ break;
+ }
+ }
- case 'remove':
+ if ($num_users_delta != 0)
+ {
+ set_config_count('num_users', $num_users_delta, true);
+ }
- if (!function_exists('delete_posts'))
- {
- include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
- }
+ // 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);
- // Delete posts, attachments, etc.
- delete_posts('poster_id', $user_id);
+ $sql = 'UPDATE ' . POSTS_TABLE . '
+ SET post_edit_user = ' . ANONYMOUS . '
+ WHERE ' . $db->sql_in_set('post_edit_user', $user_ids);
+ $db->sql_query($sql);
- break;
+ $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);
+ }
- $db->sql_transaction('begin');
+ // 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);
}
$cache->destroy('sql', MODERATOR_CACHE_TABLE);
+ $author_id_sql = $db->sql_in_set('author_id', $user_ids);
+
// Delete user log entries about this user
$sql = 'DELETE FROM ' . LOG_TABLE . '
- WHERE reportee_id = ' . $user_id;
+ WHERE ' . $user_id_sql; //reportee_id = ' . $user_id;
$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; //user_id = ' . $user_id;
$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 . //user_id = ' . $user_id . '
+ ' 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);
// Remove any undelivered mails...
$sql = 'SELECT msg_id, user_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);
@@ -551,29 +596,29 @@ function user_delete($mode, $user_id, $post_username = false)
}
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
- WHERE author_id = ' . $user_id . '
+ WHERE ' . $author_id_sql . '
AND folder_id = ' . PRIVMSGS_NO_BOX;
$db->sql_query($sql);
// Delete all to-information
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
- WHERE user_id = ' . $user_id;
+ WHERE ' . $user_id_sql;
$db->sql_query($sql);
// Set the remaining author id to anonymous - 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);
foreach ($undelivered_user as $_user_id => $ary)
{
- if ($_user_id == $user_id)
+ if (in_array($_user_id, $user_ids))
{
continue;
}
@@ -588,17 +633,11 @@ function user_delete($mode, $user_id, $post_username = false)
$db->sql_transaction('commit');
// 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;
}
View
14 phpBB/language/en/acp/prune.php
@@ -37,7 +37,9 @@
// 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!',
@@ -45,15 +47,17 @@
'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.',
Something went wrong with that request. Please try again.