function delete_forum_content($forum_id)
{
global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
include_once $phpbb_root_path . 'includes/functions_posting.' . $phpEx;
$db->sql_transaction('begin');
// Select then delete all attachments
$sql = 'SELECT a.topic_id
FROM ' . POSTS_TABLE . ' p, ' . ATTACHMENTS_TABLE . " a\n\t\t\tWHERE p.forum_id = {$forum_id}\n\t\t\t\tAND a.in_message = 0\n\t\t\t\tAND a.topic_id = p.topic_id";
$result = $db->sql_query($sql);
$topic_ids = array();
while ($row = $db->sql_fetchrow($result)) {
$topic_ids[] = $row['topic_id'];
}
$db->sql_freeresult($result);
/** @var \phpbb\attachment\manager $attachment_manager */
$attachment_manager = $phpbb_container->get('attachment.manager');
$attachment_manager->delete('topic', $topic_ids, false);
unset($attachment_manager);
// 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 . '
WHERE forum_id = ' . $forum_id . '
AND post_postcount = 1
AND post_visibility = ' . ITEM_APPROVED;
$result = $db->sql_query($sql);
$post_counts = array();
while ($row = $db->sql_fetchrow($result)) {
$post_counts[$row['poster_id']] = !empty($post_counts[$row['poster_id']]) ? $post_counts[$row['poster_id']] + 1 : 1;
}
$db->sql_freeresult($result);
switch ($db->get_sql_layer()) {
case 'mysql4':
case 'mysqli':
// Delete everything else and thank MySQL for offering multi-table deletion
$tables_ary = array(SEARCH_WORDMATCH_TABLE => 'post_id', REPORTS_TABLE => 'post_id', WARNINGS_TABLE => 'post_id', BOOKMARKS_TABLE => 'topic_id', TOPICS_WATCH_TABLE => 'topic_id', TOPICS_POSTED_TABLE => 'topic_id', POLL_OPTIONS_TABLE => 'topic_id', POLL_VOTES_TABLE => 'topic_id');
$sql = 'DELETE ' . POSTS_TABLE;
$sql_using = "\nFROM " . POSTS_TABLE;
$sql_where = "\nWHERE " . POSTS_TABLE . ".forum_id = {$forum_id}\n";
foreach ($tables_ary as $table => $field) {
$sql .= ", {$table} ";
$sql_using .= ", {$table} ";
$sql_where .= "\nAND {$table}.{$field} = " . POSTS_TABLE . ".{$field}";
}
$db->sql_query($sql . $sql_using . $sql_where);
break;
default:
// Delete everything else and curse your DB for not offering multi-table deletion
$tables_ary = array('post_id' => array(SEARCH_WORDMATCH_TABLE, REPORTS_TABLE, WARNINGS_TABLE), 'topic_id' => array(BOOKMARKS_TABLE, TOPICS_WATCH_TABLE, TOPICS_POSTED_TABLE, POLL_OPTIONS_TABLE, POLL_VOTES_TABLE));
// Amount of rows we select and delete in one iteration.
$batch_size = 500;
foreach ($tables_ary as $field => $tables) {
$start = 0;
do {
$sql = "SELECT {$field}\n\t\t\t\t\t\t\tFROM " . POSTS_TABLE . '
WHERE forum_id = ' . $forum_id;
$result = $db->sql_query_limit($sql, $batch_size, $start);
$ids = array();
while ($row = $db->sql_fetchrow($result)) {
$ids[] = $row[$field];
}
$db->sql_freeresult($result);
if (sizeof($ids)) {
$start += sizeof($ids);
foreach ($tables as $table) {
$db->sql_query("DELETE FROM {$table} WHERE " . $db->sql_in_set($field, $ids));
}
}
} while (sizeof($ids) == $batch_size);
}
unset($ids);
break;
}
$table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, LOG_TABLE, MODERATOR_CACHE_TABLE, POSTS_TABLE, TOPICS_TABLE, TOPICS_TRACK_TABLE);
/**
* Perform additional actions before forum content deletion
*
* @event core.delete_forum_content_before_query
* @var array table_ary Array of tables from which all rows will be deleted that hold the forum_id
* @var int forum_id the forum id
* @var array topic_ids Array of the topic ids from the forum to be deleted
* @var array post_counts Array of counts of posts in the forum, by poster_id
* @since 3.1.6-RC1
*/
$vars = array('table_ary', 'forum_id', 'topic_ids', 'post_counts');
extract($phpbb_dispatcher->trigger_event('core.delete_forum_content_before_query', compact($vars)));
foreach ($table_ary as $table) {
$db->sql_query("DELETE FROM {$table} WHERE forum_id = {$forum_id}");
}
// Set forum ids to 0
$table_ary = array(DRAFTS_TABLE);
foreach ($table_ary as $table) {
$db->sql_query("UPDATE {$table} SET forum_id = 0 WHERE forum_id = {$forum_id}");
}
// Adjust users post counts
if (sizeof($post_counts)) {
foreach ($post_counts as $poster_id => $substract) {
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_posts = 0
WHERE user_id = ' . $poster_id . '
AND user_posts < ' . $substract;
$db->sql_query($sql);
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_posts = user_posts - ' . $substract . '
WHERE user_id = ' . $poster_id . '
AND user_posts >= ' . $substract;
$db->sql_query($sql);
}
}
$db->sql_transaction('commit');
// Make sure the overall post/topic count is correct...
$sql = 'SELECT COUNT(post_id) AS stat
FROM ' . POSTS_TABLE . '
WHERE post_visibility = ' . ITEM_APPROVED;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$config->set('num_posts', (int) $row['stat'], false);
$sql = 'SELECT COUNT(topic_id) AS stat
FROM ' . TOPICS_TABLE . '
WHERE topic_visibility = ' . ITEM_APPROVED;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$config->set('num_topics', (int) $row['stat'], false);
$sql = 'SELECT COUNT(attach_id) as stat
FROM ' . ATTACHMENTS_TABLE;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$config->set('num_files', (int) $row['stat'], false);
$sql = 'SELECT SUM(filesize) as stat
FROM ' . ATTACHMENTS_TABLE;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$config->set('upload_dir_size', (double) $row['stat'], false);
return array();
}