[ticket/9167] Remove shadow topics from remaining forums when deleting a forum

including posts.

The function delete_topic_shadows() had to be reimplemented.
It was there but it was completly broken and hasn't been used at all.

PHPBB3-9167
This commit is contained in:
Andreas Fischer 2010-04-04 16:34:29 +02:00
parent a5b238019b
commit 30891ffb46
2 changed files with 53 additions and 38 deletions

View file

@ -1642,6 +1642,9 @@ class acp_forums
delete_attachments('topic', $topic_ids, false); delete_attachments('topic', $topic_ids, false);
// Delete shadow topics pointing to topics in this forum
delete_topic_shadows($forum_id);
// Before we remove anything we make sure we are able to adjust the post counts later. ;) // Before we remove anything we make sure we are able to adjust the post counts later. ;)
$sql = 'SELECT poster_id $sql = 'SELECT poster_id
FROM ' . POSTS_TABLE . ' FROM ' . POSTS_TABLE . '

View file

@ -1125,53 +1125,65 @@ function delete_attachments($mode, $ids, $resync = true)
} }
/** /**
* Remove topic shadows * Deletes shadow topics pointing to a specified forum.
*
* @param int $forum_id The forum id
* @param string $sql_more Additional WHERE statement, e.g. t.topic_time < (time() - 1234)
* @param bool $auto_sync Will call sync() if this is true
*
* @return array Array with affected forums
*
* @author bantu
*/ */
function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true) function delete_topic_shadows($forum_id, $sql_more = '', $auto_sync = true)
{ {
$where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : ''); global $db;
switch ($db->sql_layer) if (!$forum_id)
{ {
case 'mysql4': // Nothing to do.
case 'mysqli': return;
$sql = 'DELETE t.* }
FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
WHERE t.topic_moved_id = t2.topic_id
AND t.topic_time < ' . (time() - $max_age)
. $where;
$db->sql_query($sql);
break;
default: // Set of affected forums we have to resync
$sql = 'SELECT t.topic_id $sync_forum_ids = array();
FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
WHERE t.topic_moved_id = t2.topic_id // Amount of topics we select and delete at once.
AND t.topic_time < ' . (time() - $max_age) $batch_size = 500;
. $where;
$result = $db->sql_query($sql); do
{
$sql = 'SELECT t2.forum_id, t2.topic_id
FROM ' . TOPICS_TABLE . ' t2, ' . TOPICS_TABLE . ' t
WHERE t2.topic_moved_id = t.topic_id
AND t.forum_id = ' . (int) $forum_id . '
' . (($sql_more) ? 'AND ' . $sql_more : '');
$result = $db->sql_query_limit($sql, $batch_size);
$topic_ids = array(); $topic_ids = array();
while ($row = $db->sql_fetchrow($result)) while ($row = $db->sql_fetchrow($result))
{ {
$topic_ids[] = $row['topic_id']; $topic_ids[] = (int) $row['topic_id'];
$sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id'];
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
if (sizeof($topic_ids)) if (!empty($topic_ids))
{ {
$sql = 'DELETE FROM ' . TOPICS_TABLE . ' $sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $topic_ids); WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
$db->sql_query($sql); $db->sql_query($sql);
} }
break;
} }
while (sizeof($topic_ids) == $batch_size);
if ($auto_sync) if ($auto_sync)
{ {
$where_type = ($forum_id) ? 'forum_id' : ''; sync('forum', 'forum_id', $sync_forum_ids, true, true);
sync('forum', $where_type, $forum_id, true, true);
} }
return $sync_forum_ids;
} }
/** /**