1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-02-23 19:45:10 +01:00

Merge branch 'ticket/10605' into develop-olympus

* ticket/10605:
  [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

Conflicts:
	phpBB/install/database_update.php
This commit is contained in:
Andreas Fischer 2012-05-14 00:38:54 +02:00
commit 86fa185a1b
3 changed files with 203 additions and 55 deletions

View File

@ -1083,6 +1083,166 @@ function delete_pm($user_id, $msg_ids, $folder_id)
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
*/

View File

@ -528,62 +528,12 @@ function user_delete($mode, $user_id, $post_username = false)
WHERE session_user_id = ' . $user_id;
$db->sql_query($sql);
// Remove any undelivered mails...
$sql = 'SELECT msg_id, user_id
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))
// Clean the private messages tables from the user
if (!function_exists('phpbb_delete_user_pms'))
{
$undelivered_msg[] = $row['msg_id'];
$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);
include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
}
phpbb_delete_user_pms($user_id);
$db->sql_transaction('commit');

View File

@ -2026,7 +2026,7 @@ function change_database_data(&$no_updates, $version)
// No changes from 3.0.10-RC3 to 3.0.10
case '3.0.10-RC3':
break;
// Changes from 3.0.10 to 3.0.11-RC1
case '3.0.10':
// Updates users having current style a deactivated one
@ -2050,6 +2050,44 @@ function change_database_data(&$no_updates, $version)
_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;
break;
}