/** * Split topic */ function split_topic($action, $topic_id, $to_forum_id, $subject) { global $db, $template, $user, $phpEx, $src_root_path, $auth, $config; $post_id_list = request_var('post_id_list', array(0)); $forum_id = request_var('forum_id', 0); $start = request_var('start', 0); if (!sizeof($post_id_list)) { $template->assign_var('MESSAGE', $user->lang['NO_POST_SELECTED']); return; } if (!src_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_split'))) { return; } $post_id = $post_id_list[0]; $post_info = src_get_post_data(array($post_id)); if (!sizeof($post_info)) { $template->assign_var('MESSAGE', $user->lang['NO_POST_SELECTED']); return; } $post_info = $post_info[$post_id]; $subject = trim($subject); // Make some tests if (!$subject) { $template->assign_var('MESSAGE', $user->lang['EMPTY_SUBJECT']); return; } if ($to_forum_id <= 0) { $template->assign_var('MESSAGE', $user->lang['NO_DESTINATION_FORUM']); return; } $forum_info = src_get_forum_data(array($to_forum_id), 'f_post'); if (!sizeof($forum_info)) { $template->assign_var('MESSAGE', $user->lang['USER_CANNOT_POST']); return; } $forum_info = $forum_info[$to_forum_id]; if ($forum_info['forum_type'] != FORUM_POST) { $template->assign_var('MESSAGE', $user->lang['FORUM_NOT_POSTABLE']); return; } $redirect = request_var('redirect', build_url(array('quickmod'))); $s_hidden_fields = build_hidden_fields(array('i' => 'main', 'post_id_list' => $post_id_list, 'f' => $forum_id, 'mode' => 'topic_view', 'start' => $start, 'action' => $action, 't' => $topic_id, 'redirect' => $redirect, 'subject' => $subject, 'to_forum_id' => $to_forum_id, 'icon' => request_var('icon', 0))); $success_msg = $return_link = ''; if (confirm_box(true)) { if ($action == 'split_beyond') { $sort_days = $total = 0; $sort_key = $sort_dir = ''; $sort_by_sql = $sort_order_sql = array(); src_mcp_sorting('viewtopic', $sort_days, $sort_key, $sort_dir, $sort_by_sql, $sort_order_sql, $total, $forum_id, $topic_id); $limit_time_sql = $sort_days ? 'AND t.topic_last_post_time >= ' . (time() - $sort_days * 86400) : ''; if ($sort_order_sql[0] == 'u') { $sql = 'SELECT p.post_id, p.forum_id, p.post_visibility FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\t\t\t\tWHERE p.topic_id = {$topic_id}\n\t\t\t\t\t\tAND p.poster_id = u.user_id\n\t\t\t\t\t\t{$limit_time_sql}\n\t\t\t\t\tORDER BY {$sort_order_sql}"; } else { $sql = 'SELECT p.post_id, p.forum_id, p.post_visibility FROM ' . POSTS_TABLE . " p\n\t\t\t\t\tWHERE p.topic_id = {$topic_id}\n\t\t\t\t\t\t{$limit_time_sql}\n\t\t\t\t\tORDER BY {$sort_order_sql}"; } $result = $db->sql_query_limit($sql, 0, $start); $store = false; $post_id_list = array(); while ($row = $db->sql_fetchrow($result)) { // If split from selected post (split_beyond), we split the unapproved items too. if (($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) && !$auth->acl_get('m_approve', $row['forum_id'])) { // continue; } // Start to store post_ids as soon as we see the first post that was selected if ($row['post_id'] == $post_id) { $store = true; } if ($store) { $post_id_list[] = $row['post_id']; } } $db->sql_freeresult($result); } if (!sizeof($post_id_list)) { trigger_error('NO_POST_SELECTED'); } $icon_id = request_var('icon', 0); $sql_ary = array('forum_id' => $to_forum_id, 'topic_title' => $subject, 'icon_id' => $icon_id, 'topic_visibility' => 1); $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $db->sql_query($sql); $to_topic_id = $db->sql_nextid(); move_posts($post_id_list, $to_topic_id); $topic_info = src_get_topic_data(array($topic_id)); $topic_info = $topic_info[$topic_id]; add_log('mod', $to_forum_id, $to_topic_id, 'LOG_SPLIT_DESTINATION', $subject); add_log('mod', $forum_id, $topic_id, 'LOG_SPLIT_SOURCE', $topic_info['topic_title']); // Change topic title of first post $sql = 'UPDATE ' . POSTS_TABLE . "\n\t\t\tSET post_subject = '" . $db->sql_escape($subject) . "'\n\t\t\tWHERE post_id = {$post_id_list[0]}"; $db->sql_query($sql); // Copy topic subscriptions to new topic $sql = 'SELECT user_id, notify_status FROM ' . TOPICS_WATCH_TABLE . ' WHERE topic_id = ' . $topic_id; $result = $db->sql_query($sql); $sql_ary = array(); while ($row = $db->sql_fetchrow($result)) { $sql_ary[] = array('topic_id' => (int) $to_topic_id, 'user_id' => (int) $row['user_id'], 'notify_status' => (int) $row['notify_status']); } $db->sql_freeresult($result); if (sizeof($sql_ary)) { $db->sql_multi_insert(TOPICS_WATCH_TABLE, $sql_ary); } // Copy bookmarks to new topic $sql = 'SELECT user_id FROM ' . BOOKMARKS_TABLE . ' WHERE topic_id = ' . $topic_id; $result = $db->sql_query($sql); $sql_ary = array(); while ($row = $db->sql_fetchrow($result)) { $sql_ary[] = array('topic_id' => (int) $to_topic_id, 'user_id' => (int) $row['user_id']); } $db->sql_freeresult($result); if (sizeof($sql_ary)) { $db->sql_multi_insert(BOOKMARKS_TABLE, $sql_ary); } $success_msg = 'TOPIC_SPLIT_SUCCESS'; // Update forum statistics set_config_count('num_topics', 1, true); // Link back to both topics $return_link = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$src_root_path}viewtopic.{$phpEx}", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']) . '">', '</a>') . '<br /><br />' . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$src_root_path}viewtopic.{$phpEx}", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>'); $redirect = request_var('redirect', "{$src_root_path}viewtopic.{$phpEx}?f={$to_forum_id}&t={$to_topic_id}"); $redirect = reapply_sid($redirect); meta_refresh(3, $redirect); trigger_error($user->lang[$success_msg] . '<br /><br />' . $return_link); } else { confirm_box(false, $action == 'split_all' ? 'SPLIT_TOPIC_ALL' : 'SPLIT_TOPIC_BEYOND', $s_hidden_fields); } }
/** * Change a post's poster */ function change_poster(&$post_info, $userdata) { global $auth, $db, $config, $src_root_path, $phpEx, $user; if (empty($userdata) || $userdata['user_id'] == $post_info['user_id']) { return; } $post_id = $post_info['post_id']; $sql = 'UPDATE ' . POSTS_TABLE . "\n\t\tSET poster_id = {$userdata['user_id']}\n\t\tWHERE post_id = {$post_id}"; $db->sql_query($sql); // Resync topic/forum if needed if ($post_info['topic_last_post_id'] == $post_id || $post_info['forum_last_post_id'] == $post_id || $post_info['topic_first_post_id'] == $post_id) { sync('topic', 'topic_id', $post_info['topic_id'], false, false); sync('forum', 'forum_id', $post_info['forum_id'], false, false); } // Adjust post counts... only if the post is approved (else, it was not added the users post count anyway) if ($post_info['post_postcount'] && $post_info['post_visibility'] == ITEM_APPROVED) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - 1 WHERE user_id = ' . $post_info['user_id'] . ' AND user_posts > 0'; $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts + 1 WHERE user_id = ' . $userdata['user_id']; $db->sql_query($sql); } // Add posted to information for this topic for the new user markread('post', $post_info['forum_id'], $post_info['topic_id'], time(), $userdata['user_id']); // Remove the dotted topic option if the old user has no more posts within this topic if ($config['load_db_track'] && $post_info['user_id'] != ANONYMOUS) { $sql = 'SELECT topic_id FROM ' . POSTS_TABLE . ' WHERE topic_id = ' . $post_info['topic_id'] . ' AND poster_id = ' . $post_info['user_id']; $result = $db->sql_query_limit($sql, 1); $topic_id = (int) $db->sql_fetchfield('topic_id'); $db->sql_freeresult($result); if (!$topic_id) { $sql = 'DELETE FROM ' . TOPICS_POSTED_TABLE . ' WHERE user_id = ' . $post_info['user_id'] . ' AND topic_id = ' . $post_info['topic_id']; $db->sql_query($sql); } } // change the poster_id within the attachments table, else the data becomes out of sync and errors displayed because of wrong ownership if ($post_info['post_attachment']) { $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET poster_id = ' . $userdata['user_id'] . ' WHERE poster_id = ' . $post_info['user_id'] . ' AND post_msg_id = ' . $post_info['post_id'] . ' AND topic_id = ' . $post_info['topic_id']; $db->sql_query($sql); } // refresh search cache of this post $search_type = $config['search_type']; if (class_exists($search_type)) { // We do some additional checks in the module to ensure it can actually be utilised $error = false; $search = new $search_type($error, $src_root_path, $phpEx, $auth, $config, $db, $user, $src_dispatcher); if (!$error && method_exists($search, 'destroy_cache')) { $search->destroy_cache(array(), array($post_info['user_id'], $userdata['user_id'])); } } $from_username = $post_info['username']; $to_username = $userdata['username']; // Renew post info $post_info = src_get_post_data(array($post_id), false, true); if (!sizeof($post_info)) { trigger_error('POST_NOT_EXIST'); } $post_info = $post_info[$post_id]; // Now add log entry add_log('mod', $post_info['forum_id'], $post_info['topic_id'], 'LOG_MCP_CHANGE_POSTER', $post_info['topic_title'], $from_username, $to_username); }
/** * Delete Posts */ function mcp_delete_post($post_ids, $is_soft = false, $soft_delete_reason = '', $action = 'delete_post') { global $auth, $user, $db, $phpEx, $src_root_path, $request, $src_container; $check_permission = $is_soft ? 'm_softdelete' : 'm_delete'; if (!src_check_ids($post_ids, POSTS_TABLE, 'post_id', array($check_permission))) { return; } $redirect = $request->variable('redirect', build_url(array('action', 'quickmod'))); $forum_id = $request->variable('f', 0); $s_hidden_fields = array('post_id_list' => $post_ids, 'f' => $forum_id, 'action' => $action, 'redirect' => $redirect); $success_msg = ''; if (confirm_box(true) && $is_soft) { $post_info = src_get_post_data($post_ids); $topic_info = $approve_log = array(); // Group the posts by topic_id foreach ($post_info as $post_id => $post_data) { if ($post_data['post_visibility'] != ITEM_APPROVED) { continue; } $topic_id = (int) $post_data['topic_id']; $topic_info[$topic_id]['posts'][] = (int) $post_id; $topic_info[$topic_id]['forum_id'] = (int) $post_data['forum_id']; if ($post_id == $post_data['topic_first_post_id']) { $topic_info[$topic_id]['first_post'] = true; } if ($post_id == $post_data['topic_last_post_id']) { $topic_info[$topic_id]['last_post'] = true; } $approve_log[] = array('forum_id' => $post_data['forum_id'], 'topic_id' => $post_data['topic_id'], 'post_subject' => $post_data['post_subject'], 'poster_id' => $post_data['poster_id'], 'post_username' => $post_data['post_username'], 'username' => $post_data['username']); } $src_content_visibility = $src_container->get('content.visibility'); foreach ($topic_info as $topic_id => $topic_data) { $src_content_visibility->set_post_visibility(ITEM_DELETED, $topic_data['posts'], $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), $soft_delete_reason, isset($topic_data['first_post']), isset($topic_data['last_post'])); } $affected_topics = sizeof($topic_info); // None of the topics is really deleted, so a redirect won't hurt much. $deleted_topics = 0; $success_msg = sizeof($post_info) == 1 ? $user->lang['POST_DELETED_SUCCESS'] : $user->lang['POSTS_DELETED_SUCCESS']; foreach ($approve_log as $row) { $post_username = $row['poster_id'] == ANONYMOUS && !empty($row['post_username']) ? $row['post_username'] : $row['username']; add_log('mod', $row['forum_id'], $row['topic_id'], 'LOG_SOFTDELETE_POST', $row['post_subject'], $post_username, $soft_delete_reason); } $topic_id = $request->variable('t', 0); // Return links $return_link = array(); if ($affected_topics == 1 && $topic_id) { $return_link[] = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$src_root_path}viewtopic.{$phpEx}", "f={$forum_id}&t={$topic_id}") . '">', '</a>'); } $return_link[] = sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$src_root_path}viewforum.{$phpEx}", 'f=' . $forum_id) . '">', '</a>'); } else { if (confirm_box(true)) { if (!function_exists('delete_posts')) { include $src_root_path . 'includes/functions_admin.' . $phpEx; } // Count the number of topics that are affected // I did not use COUNT(DISTINCT ...) because I remember having problems // with it on older versions of MySQL -- Ashe $sql = 'SELECT DISTINCT topic_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('post_id', $post_ids); $result = $db->sql_query($sql); $topic_id_list = array(); while ($row = $db->sql_fetchrow($result)) { $topic_id_list[] = $row['topic_id']; } $affected_topics = sizeof($topic_id_list); $db->sql_freeresult($result); $post_data = src_get_post_data($post_ids); foreach ($post_data as $id => $row) { $post_username = $row['poster_id'] == ANONYMOUS && !empty($row['post_username']) ? $row['post_username'] : $row['username']; add_log('mod', $row['forum_id'], $row['topic_id'], 'LOG_DELETE_POST', $row['post_subject'], $post_username, $soft_delete_reason); } // Now delete the posts, topics and forums are automatically resync'ed delete_posts('post_id', $post_ids); $sql = 'SELECT COUNT(topic_id) AS topics_left FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', $topic_id_list); $result = $db->sql_query_limit($sql, 1); $deleted_topics = ($row = $db->sql_fetchrow($result)) ? $affected_topics - $row['topics_left'] : $affected_topics; $db->sql_freeresult($result); $topic_id = $request->variable('t', 0); // Return links $return_link = array(); if ($affected_topics == 1 && !$deleted_topics && $topic_id) { $return_link[] = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$src_root_path}viewtopic.{$phpEx}", "f={$forum_id}&t={$topic_id}") . '">', '</a>'); } $return_link[] = sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$src_root_path}viewforum.{$phpEx}", 'f=' . $forum_id) . '">', '</a>'); if (sizeof($post_ids) == 1) { if ($deleted_topics) { // We deleted the only post of a topic, which in turn has // been removed from the database $success_msg = $user->lang['TOPIC_DELETED_SUCCESS']; } else { $success_msg = $user->lang['POST_DELETED_SUCCESS']; } } else { if ($deleted_topics) { // Some of topics disappeared $success_msg = $user->lang['POSTS_DELETED_SUCCESS'] . '<br /><br />' . $user->lang['EMPTY_TOPICS_REMOVED_WARNING']; } else { $success_msg = $user->lang['POSTS_DELETED_SUCCESS']; } } } else { global $template; $user->add_lang('posting'); $only_softdeleted = false; if ($auth->acl_get('m_delete', $forum_id) && $auth->acl_get('m_softdelete', $forum_id)) { // If there are only soft deleted posts, we display a message why the option is not available $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('post_id', $post_ids) . ' AND post_visibility <> ' . ITEM_DELETED; $result = $db->sql_query_limit($sql, 1); $only_softdeleted = !$db->sql_fetchfield('post_id'); $db->sql_freeresult($result); } $template->assign_vars(array('S_SOFTDELETED' => $only_softdeleted, 'S_ALLOWED_DELETE' => $auth->acl_get('m_delete', $forum_id), 'S_ALLOWED_SOFTDELETE' => $auth->acl_get('m_softdelete', $forum_id))); $l_confirm = sizeof($post_ids) == 1 ? 'DELETE_POST' : 'DELETE_POSTS'; if ($only_softdeleted) { $l_confirm .= '_PERMANENTLY'; $s_hidden_fields['delete_permanent'] = '1'; } else { if (!$auth->acl_get('m_softdelete', $forum_id)) { $s_hidden_fields['delete_permanent'] = '1'; } } confirm_box(false, $l_confirm, build_hidden_fields($s_hidden_fields), 'confirm_delete_body.html'); } } $redirect = $request->variable('redirect', "index.{$phpEx}"); $redirect = reapply_sid($redirect); if (!$success_msg) { redirect($redirect); } else { if ($affected_topics != 1 || $deleted_topics || !$topic_id) { $redirect = append_sid("{$src_root_path}mcp.{$phpEx}", "f={$forum_id}&i=main&mode=forum_view", false); } meta_refresh(3, $redirect); trigger_error($success_msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . '<br /><br />' . implode('<br /><br />', $return_link)); } }
function main($id, $mode) { global $db, $user, $auth, $template, $request, $src_dispatcher; global $src_root_path, $phpEx; include $src_root_path . 'includes/functions_user.' . $phpEx; // Include the admin banning interface... include $src_root_path . 'includes/acp/acp_ban.' . $phpEx; $bansubmit = $request->is_set_post('bansubmit'); $unbansubmit = $request->is_set_post('unbansubmit'); $user->add_lang(array('acp/ban', 'acp/users')); $this->tpl_name = 'mcp_ban'; /** * Use this event to pass perform actions when a ban is issued or revoked * * @event core.mcp_ban_main * @var bool bansubmit True if a ban is issued * @var bool unbansubmit True if a ban is removed * @var string mode Mode of the ban that is being worked on * @since 3.1.0-RC5 */ $vars = array('bansubmit', 'unbansubmit', 'mode'); extract($src_dispatcher->trigger_event('core.mcp_ban_main', compact($vars))); // Ban submitted? if ($bansubmit) { // Grab the list of entries $ban = $request->variable('ban', '', $mode === 'user'); $ban_length = $request->variable('banlength', 0); $ban_length_other = $request->variable('banlengthother', ''); $ban_exclude = $request->variable('banexclude', 0); $ban_reason = $request->variable('banreason', '', true); $ban_give_reason = $request->variable('bangivereason', '', true); if ($ban) { if (confirm_box(true)) { $abort_ban = false; /** * Use this event to modify the ban details before the ban is performed * * @event core.mcp_ban_before * @var string mode One of the following: user, ip, email * @var string ban Either string or array with usernames, ips or email addresses * @var int ban_length Ban length in minutes * @var string ban_length_other Ban length as a date (YYYY-MM-DD) * @var bool ban_exclude Are we banning or excluding from another ban * @var string ban_reason Ban reason displayed to moderators * @var string ban_give_reason Ban reason displayed to the banned user * @var mixed abort_ban Either false, or an error message that is displayed to the user. * If a string is given the bans are not issued. * @since 3.1.0-RC5 */ $vars = array('mode', 'ban', 'ban_length', 'ban_length_other', 'ban_exclude', 'ban_reason', 'ban_give_reason', 'abort_ban'); extract($src_dispatcher->trigger_event('core.mcp_ban_before', compact($vars))); if ($abort_ban) { trigger_error($abort_ban); } user_ban($mode, $ban, $ban_length, $ban_length_other, $ban_exclude, $ban_reason, $ban_give_reason); /** * Use this event to perform actions after the ban has been performed * * @event core.mcp_ban_after * @var string mode One of the following: user, ip, email * @var string ban Either string or array with usernames, ips or email addresses * @var int ban_length Ban length in minutes * @var string ban_length_other Ban length as a date (YYYY-MM-DD) * @var bool ban_exclude Are we banning or excluding from another ban * @var string ban_reason Ban reason displayed to moderators * @var string ban_give_reason Ban reason displayed to the banned user * @since 3.1.0-RC5 */ $vars = array('mode', 'ban', 'ban_length', 'ban_length_other', 'ban_exclude', 'ban_reason', 'ban_give_reason'); extract($src_dispatcher->trigger_event('core.mcp_ban_after', compact($vars))); trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . '<br /><br /><a href="' . $this->u_action . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>'); } else { $hidden_fields = array('mode' => $mode, 'ban' => $ban, 'bansubmit' => true, 'banlength' => $ban_length, 'banlengthother' => $ban_length_other, 'banexclude' => $ban_exclude, 'banreason' => $ban_reason, 'bangivereason' => $ban_give_reason); /** * Use this event to pass data from the ban form to the confirmation screen * * @event core.mcp_ban_confirm * @var array hidden_fields Hidden fields that are passed through the confirm screen * @since 3.1.0-RC5 */ $vars = array('hidden_fields'); extract($src_dispatcher->trigger_event('core.mcp_ban_confirm', compact($vars))); confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($hidden_fields)); } } } else { if ($unbansubmit) { $ban = $request->variable('unban', array('')); if ($ban) { if (confirm_box(true)) { user_unban($mode, $ban); trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . '<br /><br /><a href="' . $this->u_action . '">« ' . $user->lang['BACK_TO_PREV'] . '</a>'); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array('mode' => $mode, 'unbansubmit' => true, 'unban' => $ban))); } } } } // Ban length options $ban_end_text = array(0 => $user->lang['PERMANENT'], 30 => $user->lang['30_MINS'], 60 => $user->lang['1_HOUR'], 360 => $user->lang['6_HOURS'], 1440 => $user->lang['1_DAY'], 10080 => $user->lang['7_DAYS'], 20160 => $user->lang['2_WEEKS'], 40320 => $user->lang['1_MONTH'], -1 => $user->lang['UNTIL'] . ' -> '); $ban_end_options = ''; foreach ($ban_end_text as $length => $text) { $ban_end_options .= '<option value="' . $length . '">' . $text . '</option>'; } // Define language vars $this->page_title = $user->lang[strtoupper($mode) . '_BAN']; $l_ban_explain = $user->lang[strtoupper($mode) . '_BAN_EXPLAIN']; $l_ban_exclude_explain = $user->lang[strtoupper($mode) . '_BAN_EXCLUDE_EXPLAIN']; $l_unban_title = $user->lang[strtoupper($mode) . '_UNBAN']; $l_unban_explain = $user->lang[strtoupper($mode) . '_UNBAN_EXPLAIN']; $l_no_ban_cell = $user->lang[strtoupper($mode) . '_NO_BANNED']; switch ($mode) { case 'user': $l_ban_cell = $user->lang['USERNAME']; break; case 'ip': $l_ban_cell = $user->lang['IP_HOSTNAME']; break; case 'email': $l_ban_cell = $user->lang['EMAIL_ADDRESS']; break; } acp_ban::display_ban_options($mode); $template->assign_vars(array('L_TITLE' => $this->page_title, 'L_EXPLAIN' => $l_ban_explain, 'L_UNBAN_TITLE' => $l_unban_title, 'L_UNBAN_EXPLAIN' => $l_unban_explain, 'L_BAN_CELL' => $l_ban_cell, 'L_BAN_EXCLUDE_EXPLAIN' => $l_ban_exclude_explain, 'L_NO_BAN_CELL' => $l_no_ban_cell, 'S_USERNAME_BAN' => $mode == 'user' ? true : false, 'U_ACTION' => $this->u_action, 'U_FIND_USERNAME' => append_sid("{$src_root_path}memberlist.{$phpEx}", 'mode=searchuser&form=mcp_ban&field=ban'))); if ($mode === 'email' && !$auth->acl_get('a_user')) { return; } // As a "service" we will check if any post id is specified and populate the username of the poster id if given $post_id = $request->variable('p', 0); $user_id = $request->variable('u', 0); $pre_fill = false; if ($user_id && $user_id != ANONYMOUS) { $sql = 'SELECT username, user_email, user_ip FROM ' . USERS_TABLE . ' WHERE user_id = ' . $user_id; $result = $db->sql_query($sql); switch ($mode) { case 'user': $pre_fill = (string) $db->sql_fetchfield('username'); break; case 'ip': $pre_fill = (string) $db->sql_fetchfield('user_ip'); break; case 'email': $pre_fill = (string) $db->sql_fetchfield('user_email'); break; } $db->sql_freeresult($result); } else { if ($post_id) { $post_info = src_get_post_data($post_id, 'm_ban'); if (sizeof($post_info) && !empty($post_info[$post_id])) { switch ($mode) { case 'user': $pre_fill = $post_info[$post_id]['username']; break; case 'ip': $pre_fill = $post_info[$post_id]['poster_ip']; break; case 'email': $pre_fill = $post_info[$post_id]['user_email']; break; } } } } if ($pre_fill) { // left for legacy template compatibility $template->assign_var('USERNAMES', $pre_fill); $template->assign_var('BAN_QUANTIFIER', $pre_fill); } }
/** * Disapprove Post * * @param $post_id_list array IDs of the posts to disapprove/delete * @param $id mixed Category of the current active module * @param $mode string Active module * @return null */ public static function disapprove_posts($post_id_list, $id, $mode) { global $db, $template, $user, $config, $src_container, $src_dispatcher; global $phpEx, $src_root_path, $request; if (!src_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) { trigger_error('NOT_AUTHORISED'); } $redirect = $request->variable('redirect', build_url(array('t', 'mode', 'quickmod')) . "&mode={$mode}"); $redirect = reapply_sid($redirect); $reason = $request->variable('reason', '', true); $reason_id = $request->variable('reason_id', 0); $success_msg = $additional_msg = ''; $s_hidden_fields = build_hidden_fields(array('i' => $id, 'mode' => $mode, 'post_id_list' => $post_id_list, 'action' => 'disapprove', 'redirect' => $redirect)); $notify_poster = $request->is_set('notify_poster'); $disapprove_reason = ''; if ($reason_id) { $sql = 'SELECT reason_title, reason_description FROM ' . REPORTS_REASONS_TABLE . "\n\t\t\t\tWHERE reason_id = {$reason_id}"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row || !$reason && strtolower($row['reason_title']) == 'other') { $additional_msg = $user->lang['NO_REASON_DISAPPROVAL']; $request->overwrite('confirm', null, \src\request\request_interface::POST); $request->overwrite('confirm_key', null, \src\request\request_interface::POST); $request->overwrite('confirm_key', null, \src\request\request_interface::REQUEST); } else { // If the reason is defined within the language file, we will use the localized version, else just use the database entry... $disapprove_reason = strtolower($row['reason_title']) != 'other' ? isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])] : $row['reason_description'] : ''; $disapprove_reason .= $reason ? "\n\n" . $reason : ''; if (isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) { $disapprove_reason_lang = strtoupper($row['reason_title']); } } } $post_info = src_get_post_data($post_id_list, 'm_approve'); $is_disapproving = false; foreach ($post_info as $post_id => $post_data) { if ($post_data['post_visibility'] == ITEM_DELETED) { continue; } $is_disapproving = true; } if (confirm_box(true)) { $disapprove_log = $disapprove_log_topics = $disapprove_log_posts = array(); $topic_posts_unapproved = $post_disapprove_list = $topic_information = array(); // Build a list of posts to be disapproved and get the related topics real replies count foreach ($post_info as $post_id => $post_data) { $post_disapprove_list[$post_id] = $post_data['topic_id']; if (!isset($topic_posts_unapproved[$post_data['topic_id']])) { $topic_information[$post_data['topic_id']] = $post_data; $topic_posts_unapproved[$post_data['topic_id']] = 0; } $topic_posts_unapproved[$post_data['topic_id']]++; } // Now we build the log array foreach ($post_disapprove_list as $post_id => $topic_id) { // If the count of disapproved posts for the topic is equal // to the number of unapproved posts in the topic, and there are no different // posts, we disapprove the hole topic if ($topic_information[$topic_id]['topic_posts_approved'] == 0 && $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 && $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id]) { // Don't write the log more than once for every topic if (!isset($disapprove_log_topics[$topic_id])) { // Build disapproved topics log $disapprove_log_topics[$topic_id] = array('type' => 'topic', 'post_subject' => $post_info[$post_id]['topic_title'], 'forum_id' => $post_info[$post_id]['forum_id'], 'topic_id' => 0, 'post_username' => $post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username']) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username']); } } else { // Build disapproved posts log $disapprove_log_posts[] = array('type' => 'post', 'post_subject' => $post_info[$post_id]['post_subject'], 'forum_id' => $post_info[$post_id]['forum_id'], 'topic_id' => $post_info[$post_id]['topic_id'], 'post_username' => $post_info[$post_id]['poster_id'] == ANONYMOUS && !empty($post_info[$post_id]['post_username']) ? $post_info[$post_id]['post_username'] : $post_info[$post_id]['username']); } } // Get disapproved posts/topics counts separately $num_disapproved_topics = sizeof($disapprove_log_topics); $num_disapproved_posts = sizeof($disapprove_log_posts); // Build the whole log $disapprove_log = array_merge($disapprove_log_topics, $disapprove_log_posts); // Unset unneeded arrays unset($post_data, $disapprove_log_topics, $disapprove_log_posts); // Let's do the job - delete disapproved posts if (sizeof($post_disapprove_list)) { if (!function_exists('delete_posts')) { include $src_root_path . 'includes/functions_admin.' . $phpEx; } // We do not check for permissions here, because the moderator allowed approval/disapproval should be allowed to delete the disapproved posts // Note: function delete_posts triggers related forums/topics sync, // so we don't need to call update_post_information later and to adjust real topic replies or forum topics count manually delete_posts('post_id', array_keys($post_disapprove_list)); foreach ($disapprove_log as $log_data) { if ($is_disapproving) { $l_log_message = $log_data['type'] == 'topic' ? 'LOG_TOPIC_DISAPPROVED' : 'LOG_POST_DISAPPROVED'; add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $disapprove_reason, $log_data['post_username']); } else { $l_log_message = $log_data['type'] == 'topic' ? 'LOG_DELETE_TOPIC' : 'LOG_DELETE_POST'; add_log('mod', $log_data['forum_id'], $log_data['topic_id'], $l_log_message, $log_data['post_subject'], $log_data['post_username']); } } } $src_notifications = $src_container->get('notification_manager'); $lang_reasons = array(); foreach ($post_info as $post_id => $post_data) { $disapprove_all_posts_in_topic = $topic_information[$topic_id]['topic_posts_approved'] == 0 && $topic_information[$topic_id]['topic_posts_softdeleted'] == 0 && $topic_information[$topic_id]['topic_posts_unapproved'] == $topic_posts_unapproved[$topic_id]; $src_notifications->delete_notifications('notification.type.post_in_queue', $post_id); // Do we disapprove the whole topic? Remove potential notifications if ($disapprove_all_posts_in_topic) { $src_notifications->delete_notifications('notification.type.topic_in_queue', $post_data['topic_id']); } // Notify Poster? if ($notify_poster) { if ($post_data['poster_id'] == ANONYMOUS) { continue; } $post_data['disapprove_reason'] = ''; if (isset($disapprove_reason_lang)) { // Okay we need to get the reason from the posters language if (!isset($lang_reasons[$post_data['user_lang']])) { // Assign the current users translation as the default, this is not ideal but getting the srcrd default adds another layer of complexity. $lang_reasons[$post_data['user_lang']] = $user->lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; // Only load up the language pack if the language is different to the current one if ($post_data['user_lang'] != $user->lang_name && file_exists($src_root_path . '/language/' . $post_data['user_lang'] . '/mcp.' . $phpEx)) { // Load up the language pack $lang = array(); @(include $src_root_path . '/language/' . basename($post_data['user_lang']) . '/mcp.' . $phpEx); // If we find the reason in this language pack use it if (isset($lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang])) { $lang_reasons[$post_data['user_lang']] = $lang['report_reasons']['DESCRIPTION'][$disapprove_reason_lang]; } unset($lang); // Free memory } } $post_data['disapprove_reason'] = $lang_reasons[$post_data['user_lang']]; $post_data['disapprove_reason'] .= $reason ? "\n\n" . $reason : ''; } if ($disapprove_all_posts_in_topic && $topic_information[$topic_id]['topic_posts_unapproved'] == 1) { // If there is only 1 post when disapproving the topic, // we send the user a "disapprove topic" notification... $src_notifications->add_notifications('notification.type.disapprove_topic', $post_data); } else { // ... otherwise there are multiple unapproved posts and // all of them are disapproved as posts. $src_notifications->add_notifications('notification.type.disapprove_post', $post_data); } } } if ($num_disapproved_topics) { $success_msg = $num_disapproved_topics == 1 ? 'TOPIC' : 'TOPICS'; } else { $success_msg = $num_disapproved_posts == 1 ? 'POST' : 'POSTS'; } if ($is_disapproving) { $success_msg .= '_DISAPPROVED_SUCCESS'; } else { $success_msg .= '_DELETED_SUCCESS'; } // If we came from viewtopic, we try to go back to it. if (strpos($redirect, $src_root_path . 'viewtopic.' . $phpEx) === 0) { if ($num_disapproved_topics == 0) { // So we need to remove the post id part from the Url $redirect = str_replace("&p={$post_id_list[0]}#p{$post_id_list[0]}", '', $redirect); } else { // However this is only possible if the topic still exists, // Otherwise we go back to the viewforum page $redirect = append_sid($src_root_path . 'viewforum.' . $phpEx, 'f=' . $request->variable('f', 0)); } } /** * Perform additional actions during post(s) disapproval * * @event core.disapprove_posts_after * @var array post_info Array containing info for all posts being disapproved * @var array topic_information Array containing information for the topics * @var array topic_posts_unapproved Array containing list of topic ids and the count of disapproved posts in them * @var array post_disapprove_list Array containing list of posts and their topic id * @var int num_disapproved_topics Variable containing the number of disapproved topics * @var int num_disapproved_posts Variable containing the number of disapproved posts * @var array lang_reasons Array containing the language keys for reasons * @var string disapprove_reason Variable containing the language key for the success message * @var string disapprove_reason_lang Variable containing the language key for the success message * @var bool is_disapproving Variable telling if anything is going to be disapproved * @var bool notify_poster Variable telling if the post should be notified or not * @var string success_msg Variable containing the language key for the success message * @var string redirect Variable containing the redirect url * @since 3.1.4-RC1 */ $vars = array('post_info', 'topic_information', 'topic_posts_unapproved', 'post_disapprove_list', 'num_disapproved_topics', 'num_disapproved_posts', 'lang_reasons', 'disapprove_reason', 'disapprove_reason_lang', 'is_disapproving', 'notify_poster', 'success_msg', 'redirect'); extract($src_dispatcher->trigger_event('core.disapprove_posts_after', compact($vars))); unset($lang_reasons, $post_info, $disapprove_reason, $disapprove_reason_lang); meta_refresh(3, $redirect); $message = $user->lang[$success_msg]; if ($request->is_ajax()) { $json_response = new \src\json_response(); $json_response->send(array('MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TEXT' => $message, 'REFRESH_DATA' => null, 'visible' => false)); } $message .= '<br /><br />' . $user->lang('RETURN_PAGE', '<a href="' . $redirect . '">', '</a>'); trigger_error($message); } else { if (!function_exists('display_reasons')) { include $src_root_path . 'includes/functions_display.' . $phpEx; } $show_notify = false; foreach ($post_info as $post_data) { if ($post_data['poster_id'] == ANONYMOUS) { continue; } else { $show_notify = true; break; } } $l_confirm_msg = 'DISAPPROVE_POST'; $confirm_template = 'mcp_approve.html'; if ($is_disapproving) { display_reasons($reason_id); } else { $user->add_lang('posting'); $l_confirm_msg = 'DELETE_POST_PERMANENTLY'; $confirm_template = 'confirm_delete_body.html'; } $l_confirm_msg .= sizeof($post_id_list) == 1 ? '' : 'S'; $template->assign_vars(array('S_NOTIFY_POSTER' => $show_notify, 'S_APPROVE' => false, 'REASON' => $is_disapproving ? $reason : '', 'ADDITIONAL_MSG' => $additional_msg)); confirm_box(false, $l_confirm_msg, $s_hidden_fields, $confirm_template); } redirect($redirect); }