[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 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. ;)
$sql = 'SELECT poster_id
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':
case 'mysqli':
$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:
$sql = 'SELECT t.topic_id
FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
WHERE t.topic_moved_id = t2.topic_id
AND t.topic_time < ' . (time() - $max_age)
. $where;
$result = $db->sql_query($sql);
$topic_ids = array();
while ($row = $db->sql_fetchrow($result))
{
$topic_ids[] = $row['topic_id'];
}
$db->sql_freeresult($result);
if (sizeof($topic_ids))
{
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
$db->sql_query($sql);
}
break;
// Nothing to do.
return;
}
// Set of affected forums we have to resync
$sync_forum_ids = array();
// Amount of topics we select and delete at once.
$batch_size = 500;
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();
while ($row = $db->sql_fetchrow($result))
{
$topic_ids[] = (int) $row['topic_id'];
$sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id'];
}
$db->sql_freeresult($result);
if (!empty($topic_ids))
{
$sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
$db->sql_query($sql);
}
}
while (sizeof($topic_ids) == $batch_size);
if ($auto_sync)
{
$where_type = ($forum_id) ? 'forum_id' : '';
sync('forum', $where_type, $forum_id, true, true);
sync('forum', 'forum_id', $sync_forum_ids, true, true);
}
return $sync_forum_ids;
}
/**