diff options
author | Andreas Fischer <bantu@phpbb.com> | 2012-05-14 00:40:20 +0200 |
---|---|---|
committer | Andreas Fischer <bantu@phpbb.com> | 2012-05-14 00:40:20 +0200 |
commit | f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e (patch) | |
tree | 5197957d1b922229ea14e7e2f21dae79fdc82e57 /phpBB | |
parent | 9b96c1fb78c1cfcbc57e2206cd5d6f24f0c5922c (diff) | |
parent | 86fa185a1ba4754b6c2dc9769b826aa9d57aa148 (diff) | |
download | forums-f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e.tar forums-f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e.tar.gz forums-f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e.tar.bz2 forums-f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e.tar.xz forums-f3d33bf9d7858ad6ed9d82f3f794f4ec0266d68e.zip |
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
Diffstat (limited to 'phpBB')
-rw-r--r-- | phpBB/includes/functions_privmsgs.php | 160 | ||||
-rw-r--r-- | phpBB/includes/functions_user.php | 58 | ||||
-rw-r--r-- | phpBB/install/database_update.php | 38 |
3 files changed, 202 insertions, 54 deletions
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 434349714b..96e27303ee 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1128,6 +1128,166 @@ function delete_pm($user_id, $msg_ids, $folder_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) +{ + 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 */ function rebuild_header($check_ary) diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 5b05c3a78d..9b102b7387 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -527,62 +527,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)) - { - $undelivered_msg[] = $row['msg_id']; - $undelivered_user[$row['user_id']][] = true; - } - $db->sql_freeresult($result); - - if (sizeof($undelivered_msg)) + // Clean the private messages tables from the user + if (!function_exists('phpbb_delete_user_pms')) { - $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'); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 665db1f2f0..ac304f24c6 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2164,6 +2164,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; |