/** * Remove post(s) */ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true, $post_count_sync = true, $call_delete_topics = true) { global $db, $config, $phpbb_root_path, $phpEx, $auth, $user, $phpbb_container, $phpbb_dispatcher; // Notifications types to delete $delete_notifications_types = array('notification.type.quote', 'notification.type.approve_post', 'notification.type.post_in_queue', 'notification.type.report_post'); /** * Perform additional actions before post(s) deletion * * @event core.delete_posts_before * @var string where_type Variable containing posts deletion mode * @var mixed where_ids Array or comma separated list of posts ids to delete * @var bool auto_sync Flag indicating if topics/forums should be synchronized * @var bool posted_sync Flag indicating if topics_posted table should be resynchronized * @var bool post_count_sync Flag indicating if posts count should be resynchronized * @var bool call_delete_topics Flag indicating if topics having no posts should be deleted * @var array delete_notifications_types Array with notifications types to delete * @since 3.1.0-a4 */ $vars = array('where_type', 'where_ids', 'auto_sync', 'posted_sync', 'post_count_sync', 'call_delete_topics', 'delete_notifications_types'); extract($phpbb_dispatcher->trigger_event('core.delete_posts_before', compact($vars))); if ($where_type === 'range') { $where_clause = $where_ids; } else { if (is_array($where_ids)) { $where_ids = array_unique($where_ids); } else { $where_ids = array($where_ids); } if (!sizeof($where_ids)) { return false; } $where_ids = array_map('intval', $where_ids); /* Possible code for splitting post deletion if (sizeof($where_ids) >= 1001) { // Split into chunks of 1000 $chunks = array_chunk($where_ids, 1000); foreach ($chunks as $_where_ids) { delete_posts($where_type, $_where_ids, $auto_sync, $posted_sync, $post_count_sync, $call_delete_topics); } return; }*/ $where_clause = $db->sql_in_set($where_type, $where_ids); } $approved_posts = 0; $post_ids = $topic_ids = $forum_ids = $post_counts = $remove_topics = array(); $sql = 'SELECT post_id, poster_id, post_visibility, post_postcount, topic_id, forum_id FROM ' . POSTS_TABLE . ' WHERE ' . $where_clause; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $post_ids[] = (int) $row['post_id']; $poster_ids[] = (int) $row['poster_id']; $topic_ids[] = (int) $row['topic_id']; $forum_ids[] = (int) $row['forum_id']; if ($row['post_postcount'] && $post_count_sync && $row['post_visibility'] == ITEM_APPROVED) { $post_counts[$row['poster_id']] = !empty($post_counts[$row['poster_id']]) ? $post_counts[$row['poster_id']] + 1 : 1; } if ($row['post_visibility'] == ITEM_APPROVED) { $approved_posts++; } } $db->sql_freeresult($result); if (!sizeof($post_ids)) { return false; } $db->sql_transaction('begin'); $table_ary = array(POSTS_TABLE, REPORTS_TABLE); /** * Perform additional actions during post(s) deletion before running the queries * * @event core.delete_posts_in_transaction_before * @var array post_ids Array with deleted posts' ids * @var array poster_ids Array with deleted posts' author ids * @var array topic_ids Array with deleted posts' topic ids * @var array forum_ids Array with deleted posts' forum ids * @var string where_type Variable containing posts deletion mode * @var mixed where_ids Array or comma separated list of post ids to delete * @var array delete_notifications_types Array with notifications types to delete * @var array table_ary Array with table names to delete data from * @since 3.1.7-RC1 */ $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types', 'table_ary'); extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction_before', compact($vars))); foreach ($table_ary as $table) { $sql = "DELETE FROM {$table}\n\t\t\tWHERE " . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } unset($table_ary); // Adjust users post counts if (sizeof($post_counts) && $post_count_sync) { 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); } } // Remove topics now having no posts? if (sizeof($topic_ids)) { $sql = 'SELECT topic_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . ' GROUP BY topic_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $remove_topics[] = $row['topic_id']; } $db->sql_freeresult($result); // Actually, those not within remove_topics should be removed. ;) $remove_topics = array_diff($topic_ids, $remove_topics); } // Remove the message from the search index $search_type = $config['search_type']; if (!class_exists($search_type)) { trigger_error('NO_SUCH_SEARCH_MODULE'); } $error = false; $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); if ($error) { trigger_error($error); } $search->index_remove($post_ids, $poster_ids, $forum_ids); /** @var \phpbb\attachment\manager $attachment_manager */ $attachment_manager = $phpbb_container->get('attachment.manager'); $attachment_manager->delete('post', $post_ids, false); unset($attachment_manager); /** * Perform additional actions during post(s) deletion * * @event core.delete_posts_in_transaction * @var array post_ids Array with deleted posts' ids * @var array poster_ids Array with deleted posts' author ids * @var array topic_ids Array with deleted posts' topic ids * @var array forum_ids Array with deleted posts' forum ids * @var string where_type Variable containing posts deletion mode * @var mixed where_ids Array or comma separated list of posts ids to delete * @var array delete_notifications_types Array with notifications types to delete * @since 3.1.0-a4 */ $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types'); extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction', compact($vars))); $db->sql_transaction('commit'); /** * Perform additional actions after post(s) deletion * * @event core.delete_posts_after * @var array post_ids Array with deleted posts' ids * @var array poster_ids Array with deleted posts' author ids * @var array topic_ids Array with deleted posts' topic ids * @var array forum_ids Array with deleted posts' forum ids * @var string where_type Variable containing posts deletion mode * @var mixed where_ids Array or comma separated list of posts ids to delete * @var array delete_notifications_types Array with notifications types to delete * @since 3.1.0-a4 */ $vars = array('post_ids', 'poster_ids', 'topic_ids', 'forum_ids', 'where_type', 'where_ids', 'delete_notifications_types'); extract($phpbb_dispatcher->trigger_event('core.delete_posts_after', compact($vars))); // Resync topics_posted table if ($posted_sync) { update_posted_info($topic_ids); } if ($auto_sync) { sync('topic_reported', 'topic_id', $topic_ids); sync('topic', 'topic_id', $topic_ids, true); sync('forum', 'forum_id', $forum_ids, true, true); } if ($approved_posts && $post_count_sync) { $config->increment('num_posts', $approved_posts * -1, false); } // We actually remove topics now to not be inconsistent (the delete_topics function calls this function too) if (sizeof($remove_topics) && $call_delete_topics) { delete_topics('topic_id', $remove_topics, $auto_sync, $post_count_sync, false); } /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); $phpbb_notifications->delete_notifications($delete_notifications_types, $post_ids); return sizeof($post_ids); }
/** * Remove post(s) */ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true) { global $db, $config, $phpbb_root_path, $phpEx; if (is_array($where_ids)) { $where_ids = array_unique($where_ids); } if (empty($where_ids)) { return false; } $post_ids = $topic_ids = $forum_ids = array(); $sql = 'SELECT post_id, poster_id, topic_id, forum_id FROM ' . POSTS_TABLE . "\n\t\tWHERE {$where_type} " . (!is_array($where_ids) ? '= ' . (int) $where_ids : 'IN (' . implode(', ', array_map('intval', $where_ids)) . ')'); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $post_ids[] = $row['post_id']; $poster_ids[] = $row['poster_id']; $topic_ids[] = $row['topic_id']; $forum_ids[] = $row['forum_id']; } $db->sql_freeresult($result); if (!sizeof($post_ids)) { return false; } $sql_where = implode(', ', $post_ids); $db->sql_transaction('begin'); $table_ary = array(POSTS_TABLE, REPORTS_TABLE); foreach ($table_ary as $table) { $sql = "DELETE FROM {$table} \n\t\t\tWHERE post_id IN ({$sql_where})"; $db->sql_query($sql); } unset($table_ary); // Remove the message from the search index $search_type = basename($config['search_type']); if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) { trigger_error('NO_SUCH_SEARCH_MODULE'); } require "{$phpbb_root_path}includes/search/{$search_type}.{$phpEx}"; $error = false; $search = new $search_type($error); if ($error) { trigger_error($error); } $search->index_remove($post_ids, $poster_ids); delete_attachments('post', $post_ids, false); $db->sql_transaction('commit'); // Resync topics_posted table if ($posted_sync) { update_posted_info($topic_ids); } if ($auto_sync) { sync('topic_reported', 'topic_id', $topic_ids); sync('topic', 'topic_id', $topic_ids, true); sync('forum', 'forum_id', $forum_ids, true); } return sizeof($post_ids); }
/** * Remove post(s) */ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = true, $post_count_sync = true, $call_delete_topics = true) { global $db, $config, $phpbb_root_path, $phpEx; if ($where_type === 'range') { $where_clause = $where_ids; } else { if (is_array($where_ids)) { $where_ids = array_unique($where_ids); } else { $where_ids = array($where_ids); } if (!sizeof($where_ids)) { return false; } $where_clause = $db->sql_in_set($where_type, array_map('intval', $where_ids)); } $approved_posts = 0; $post_ids = $topic_ids = $forum_ids = $post_counts = $remove_topics = array(); $sql = 'SELECT post_id, poster_id, post_approved, post_postcount, topic_id, forum_id FROM ' . POSTS_TABLE . ' WHERE ' . $where_clause; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $post_ids[] = $row['post_id']; $poster_ids[] = $row['poster_id']; $topic_ids[] = $row['topic_id']; $forum_ids[] = $row['forum_id']; if ($row['post_postcount'] && $post_count_sync && $row['post_approved']) { $post_counts[$row['poster_id']] = !empty($post_counts[$row['poster_id']]) ? $post_counts[$row['poster_id']] + 1 : 1; } if ($row['post_approved']) { $approved_posts++; } } $db->sql_freeresult($result); if (!sizeof($post_ids)) { return false; } $db->sql_transaction('begin'); $table_ary = array(POSTS_TABLE, REPORTS_TABLE); foreach ($table_ary as $table) { $sql = "DELETE FROM {$table}\n\t\t\tWHERE " . $db->sql_in_set('post_id', $post_ids); $db->sql_query($sql); } unset($table_ary); // Adjust users post counts if (sizeof($post_counts) && $post_count_sync) { 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); } } // Remove topics now having no posts? if (sizeof($topic_ids)) { $sql = 'SELECT topic_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_ids) . ' GROUP BY topic_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $remove_topics[] = $row['topic_id']; } $db->sql_freeresult($result); // Actually, those not within remove_topics should be removed. ;) $remove_topics = array_diff($topic_ids, $remove_topics); } // Remove the message from the search index $search_type = basename($config['search_type']); if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) { trigger_error('NO_SUCH_SEARCH_MODULE'); } include_once "{$phpbb_root_path}includes/search/{$search_type}.{$phpEx}"; $error = false; $search = new $search_type($error); if ($error) { trigger_error($error); } $search->index_remove($post_ids, $poster_ids, $forum_ids); delete_attachments('post', $post_ids, false); $db->sql_transaction('commit'); // Resync topics_posted table if ($posted_sync) { update_posted_info($topic_ids); } if ($auto_sync) { sync('topic_reported', 'topic_id', $topic_ids); sync('topic', 'topic_id', $topic_ids, true); sync('forum', 'forum_id', $forum_ids, true, true); } if ($approved_posts) { set_config('num_posts', $config['num_posts'] - $approved_posts, true); } // We actually remove topics now to not be inconsistent (the delete_topics function calls this function too) if (sizeof($remove_topics) && $call_delete_topics) { delete_topics('topic_id', $remove_topics, $auto_sync, $post_count_sync, false); } return sizeof($post_ids); }
function delete_posts($where_type, $where_ids, $auto_sync = true) { global $_CLASS; if (is_array($where_ids)) { $where_ids = array_unique($where_ids); } if (empty($where_ids)) { return false; } $post_ids = $topic_ids = $forum_ids = $post_counts = array(); $sql = 'SELECT post_id, poster_id, post_postcount, topic_id, forum_id FROM ' . FORUMS_POSTS_TABLE . "\n\t\tWHERE {$where_type} " . (!is_array($where_ids) ? "= {$where_ids}" : 'IN (' . implode(', ', $where_ids) . ')'); $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $post_ids[] = $row['post_id']; $poster_ids[] = $row['poster_id']; $topic_ids[] = $row['topic_id']; $forum_ids[] = $row['forum_id']; if ($row['post_postcount']) { $post_counts[$row['poster_id']] = !empty($post_counts[$row['poster_id']]) ? $post_counts[$row['poster_id']] + 1 : 1; } } $_CLASS['core_db']->free_result(); if (empty($post_ids)) { return false; } $sql_where = implode(', ', $post_ids); $_CLASS['core_db']->transaction(); $table_ary = array(FORUMS_POSTS_TABLE, FORUMS_REPORTS_TABLE); foreach ($table_ary as $table) { $sql = "DELETE FROM {$table} \n\t\t\tWHERE post_id IN ({$sql_where})"; $_CLASS['core_db']->query($sql); } unset($table_ary); // Adjust users post counts if (!empty($post_counts)) { foreach ($post_counts as $poster_id => $substract) { $sql = 'UPDATE ' . CORE_USERS_TABLE . ' SET user_posts = user_posts - ' . $substract . ' WHERE user_id = ' . $poster_id; $_CLASS['core_db']->query($sql); } } // Remove the message from the search index $search_type = basename($config['search_type']); if (!file_exists(SITE_FILE_ROOT . 'includes/forums/search/', $search_type, '.php')) { trigger_error('NO_SUCH_SEARCH_MODULE'); } require_once SITE_FILE_ROOT . 'includes/forums/search/' . $search_type . '.php'; $error = false; $search = new $search_type($error); if ($error) { trigger_error($error); } $search->index_remove($post_ids, $poster_ids, $forum_ids); delete_attachments('post', $post_ids, false); $_CLASS['core_db']->transaction('commit'); // Resync topics_posted table if ($posted_sync) { update_posted_info($topic_ids); } if ($auto_sync) { sync('topic_reported', $where_type, $where_ids); sync('topic', 'topic_id', $topic_ids, true); sync('forum', 'forum_id', $forum_ids, true); } set_config('num_posts', $config['num_posts'] - sizeof($post_ids), true); return count($post_ids); }