1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-05-05 15:16:16 +02:00

Merge branch 'develop-olympus' into develop

* develop-olympus:
  [ticket/10605] Use database updater function _sql() instead of $db->sql_query()
  [ticket/10605] Put end of array on its own line because start of array is too.
  [ticket/10605] Add parameter documentation to phpbb_delete_user_pms
  [ticket/10605] Fix left join usage.
  [ticket/10605] Add a section for updating from 3.0.10 to schema updates.
  [ticket/10605] Fix syntax error in database updater.
  [ticket/10605] Reset user´s pm count to 0 when deleting his PMs
  [ticket/10605] Split query to be able to use indexes
  [ticket/10605] Rename $delete_rows to $delete_ids.
  [ticket/10605] Break long comment into multiple lines 80 chars short.
  [ticket/10605] Remove unnecessary $delete_ids array.
  [ticket/10605] Remove unnecessary array_keys calls on $delete_rows.
  [ticket/10605] Remove unused variable declarations.
  [ticket/10605] Turn $undelivered_user into a real array of counters.
  [ticket/10605] Use unset() instead of checking user_id over and over again.
  [ticket/10605] Prefix function with phpbb_ and use true instead of 1
  [ticket/10605] Delete orphan private messages on update
  [ticket/10605] Check for orphan privmsgs when deleting a user
This commit is contained in:
Andreas Fischer 2012-05-14 00:40:20 +02:00
commit f3d33bf9d7
3 changed files with 202 additions and 54 deletions

View File

@ -1127,6 +1127,166 @@ function delete_pm($user_id, $msg_ids, $folder_id)
return true; return true;
} }
/**
* 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;
}
// Get PM Information for later deleting
// The two queries where split, so we can use our indexes
// Part 1: get PMs the user received
$sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE user_id = ' . $user_id;
$result = $db->sql_query($sql);
$undelivered_msg = $undelivered_user = $delete_ids = array();
while ($row = $db->sql_fetchrow($result))
{
if ($row['author_id'] == $user_id && $row['folder_id'] == PRIVMSGS_NO_BOX)
{
// Undelivered messages
$undelivered_msg[] = $row['msg_id'];
if (isset($undelivered_user[$row['user_id']]))
{
++$undelivered_user[$row['user_id']];
}
else
{
$undelivered_user[$row['user_id']] = 1;
}
}
$delete_ids[(int) $row['msg_id']] = (int) $row['msg_id'];
}
$db->sql_freeresult($result);
// Part 2: get PMs the user sent
$sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE author_id = ' . $user_id . '
AND folder_id = ' . PRIVMSGS_NO_BOX;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if ($row['author_id'] == $user_id && $row['folder_id'] == PRIVMSGS_NO_BOX)
{
// Undelivered messages
$undelivered_msg[] = $row['msg_id'];
if (isset($undelivered_user[$row['user_id']]))
{
++$undelivered_user[$row['user_id']];
}
else
{
$undelivered_user[$row['user_id']] = 1;
}
}
$delete_ids[(int) $row['msg_id']] = (int) $row['msg_id'];
}
$db->sql_freeresult($result);
if (empty($delete_ids))
{
return false;
}
$db->sql_transaction('begin');
if (sizeof($undelivered_msg))
{
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
$db->sql_query($sql);
}
// Reset the user´s pm count to 0
if (isset($undelivered_user[$user_id]))
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = 0,
user_unread_privmsg = 0
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
unset($undelivered_user[$user_id]);
}
foreach ($undelivered_user as $_user_id => $count)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = user_new_privmsg - ' . $count . ',
user_unread_privmsg = user_unread_privmsg - ' . $count . '
WHERE user_id = ' . $_user_id;
$db->sql_query($sql);
}
// Delete private message data
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . "
WHERE user_id = $user_id
AND " . $db->sql_in_set('msg_id', $delete_ids);
$db->sql_query($sql);
// Now we have to check which messages we can delete completely
$sql = 'SELECT msg_id
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
unset($delete_ids[$row['msg_id']]);
}
$db->sql_freeresult($result);
if (!empty($delete_ids))
{
// Check if there are any attachments we need to remove
if (!function_exists('delete_attachments'))
{
include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
}
delete_attachments('message', $delete_ids, false);
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_ids);
$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;
$db->sql_query($sql);
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET author_id = ' . ANONYMOUS . '
WHERE author_id = ' . $user_id;
$db->sql_query($sql);
$db->sql_transaction('commit');
return true;
}
/** /**
* Rebuild message header * Rebuild message header
*/ */

View File

@ -527,62 +527,12 @@ function user_delete($mode, $user_id, $post_username = false)
WHERE session_user_id = ' . $user_id; WHERE session_user_id = ' . $user_id;
$db->sql_query($sql); $db->sql_query($sql);
// Remove any undelivered mails... // Clean the private messages tables from the user
$sql = 'SELECT msg_id, user_id if (!function_exists('phpbb_delete_user_pms'))
FROM ' . PRIVMSGS_TO_TABLE . '
WHERE author_id = ' . $user_id . '
AND folder_id = ' . PRIVMSGS_NO_BOX;
$result = $db->sql_query($sql);
$undelivered_msg = $undelivered_user = array();
while ($row = $db->sql_fetchrow($result))
{ {
$undelivered_msg[] = $row['msg_id']; include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
$undelivered_user[$row['user_id']][] = true;
}
$db->sql_freeresult($result);
if (sizeof($undelivered_msg))
{
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
$db->sql_query($sql);
}
$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
WHERE author_id = ' . $user_id . '
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;
$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;
$db->sql_query($sql);
$sql = 'UPDATE ' . PRIVMSGS_TABLE . '
SET author_id = ' . ANONYMOUS . '
WHERE author_id = ' . $user_id;
$db->sql_query($sql);
foreach ($undelivered_user as $_user_id => $ary)
{
if ($_user_id == $user_id)
{
continue;
}
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ',
user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . '
WHERE user_id = ' . $_user_id;
$db->sql_query($sql);
} }
phpbb_delete_user_pms($user_id);
$db->sql_transaction('commit'); $db->sql_transaction('commit');

View File

@ -2164,6 +2164,44 @@ function change_database_data(&$no_updates, $version)
_sql($sql, $errored, $error_ary); _sql($sql, $errored, $error_ary);
} }
// Delete orphan private messages
$batch_size = 500;
$sql_array = array(
'SELECT' => 'p.msg_id',
'FROM' => array(
PRIVMSGS_TABLE => 'p',
),
'LEFT_JOIN' => array(
array(
'FROM' => array(PRIVMSGS_TO_TABLE => 't'),
'ON' => 'p.msg_id = t.msg_id',
),
),
'WHERE' => 't.user_id IS NULL',
);
$sql = $db->sql_build_query('SELECT', $sql_array);
do
{
$result = $db->sql_query_limit($sql, $batch_size);
$delete_pms = array();
while ($row = $db->sql_fetchrow($result))
{
$delete_pms[] = (int) $row['msg_id'];
}
$db->sql_freeresult($result);
if (!empty($delete_pms))
{
$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
WHERE ' . $db->sql_in_set('msg_id', $delete_pms);
_sql($sql, $errored, $error_ary);
}
}
while (sizeof($delete_pms) == $batch_size);
$no_updates = false; $no_updates = false;
break; break;