/** * Cleanup data we no longer need at the end of the tests in this class. * tearDown() is run automatically by the testing framework after each test method. */ function tearDown() { // remove temporary test data require_once SUBSDIR . '/Topic.subs.php'; removeTopics($this->id_topic); // it should remove the likes too }
/** * Cleanup data we no longer need at the end of the tests in this class. * tearDown() is run automatically by the testing framework after each test method. */ function tearDown() { // remove temporary test data require_once SUBSDIR . '/Topic.subs.php'; removeTopics($this->id_topic); // it'll remove the poll too, if any }
/** * Take a load of messages from one place and stick them in a topic. */ function mergePosts($msgs = array(), $from_topic, $target_topic) { global $context, $smcFunc, $modSettings, $sourcedir; //!!! This really needs to be rewritten to take a load of messages from ANY topic, it's also inefficient. // Is it an array? if (!is_array($msgs)) { $msgs = array($msgs); } // Lets make sure they are int. foreach ($msgs as $key => $msg) { $msgs[$key] = (int) $msg; } // Get the source information. $request = $smcFunc['db_query']('', ' SELECT t.id_board, t.id_first_msg, t.num_replies, t.unapproved_posts FROM {db_prefix}topics AS t INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) WHERE t.id_topic = {int:from_topic}', array('from_topic' => $from_topic)); list($from_board, $from_first_msg, $from_replies, $from_unapproved_posts) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Get some target topic and board stats. $request = $smcFunc['db_query']('', ' SELECT t.id_board, t.id_first_msg, t.num_replies, t.unapproved_posts, b.count_posts FROM {db_prefix}topics AS t INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) WHERE t.id_topic = {int:target_topic}', array('target_topic' => $target_topic)); list($target_board, $target_first_msg, $target_replies, $target_unapproved_posts, $count_posts) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Lets see if the board that we are returning to has post count enabled. if (empty($count_posts)) { // Lets get the members that need their post count restored. $request = $smcFunc['db_query']('', ' SELECT id_member FROM {db_prefix}messages WHERE id_msg IN ({array_int:messages}) AND approved = {int:is_approved}', array('messages' => $msgs, 'is_approved' => 1)); while ($row = $smcFunc['db_fetch_assoc']($request)) { updateMemberData($row['id_member'], array('posts' => '+')); } } // Time to move the messages. $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET id_topic = {int:target_topic}, id_board = {int:target_board}, icon = {string:icon} WHERE id_msg IN({array_int:msgs})', array('target_topic' => $target_topic, 'target_board' => $target_board, 'icon' => $target_board == $modSettings['recycle_board'] ? 'recycled' : 'xx', 'msgs' => $msgs)); // Fix the id_first_msg and id_last_msg for the target topic. $target_topic_data = array('num_replies' => 0, 'unapproved_posts' => 0, 'id_first_msg' => 9999999999); $request = $smcFunc['db_query']('', ' SELECT MIN(id_msg) AS id_first_msg, MAX(id_msg) AS id_last_msg, COUNT(*) AS message_count, approved FROM {db_prefix}messages WHERE id_topic = {int:target_topic} GROUP BY id_topic, approved ORDER BY approved ASC LIMIT 2', array('target_topic' => $target_topic)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_first_msg'] < $target_topic_data['id_first_msg']) { $target_topic_data['id_first_msg'] = $row['id_first_msg']; } $target_topic_data['id_last_msg'] = $row['id_last_msg']; if (!$row['approved']) { $target_topic_data['unapproved_posts'] = $row['message_count']; } else { $target_topic_data['num_replies'] = max(0, $row['message_count'] - 1); } } $smcFunc['db_free_result']($request); // We have a new post count for the board. $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_posts = num_posts + {int:diff_replies}, unapproved_posts = unapproved_posts + {int:diff_unapproved_posts} WHERE id_board = {int:target_board}', array('diff_replies' => $target_topic_data['num_replies'] - $target_replies, 'diff_unapproved_posts' => $target_topic_data['unapproved_posts'] - $target_unapproved_posts, 'target_board' => $target_board)); // In some cases we merged the only post in a topic so the topic data is left behind in the topic table. $request = $smcFunc['db_query']('', ' SELECT id_topic FROM {db_prefix}messages WHERE id_topic = {int:from_topic}', array('from_topic' => $from_topic)); // Remove the topic if it doesn't have any messages. $topic_exists = true; if ($smcFunc['db_num_rows']($request) == 0) { removeTopics($from_topic, false, true); $topic_exists = false; } $smcFunc['db_free_result']($request); // Recycled topic. if ($topic_exists == true) { // Fix the id_first_msg and id_last_msg for the source topic. $source_topic_data = array('num_replies' => 0, 'unapproved_posts' => 0, 'id_first_msg' => 9999999999); $request = $smcFunc['db_query']('', ' SELECT MIN(id_msg) AS id_first_msg, MAX(id_msg) AS id_last_msg, COUNT(*) AS message_count, approved, subject FROM {db_prefix}messages WHERE id_topic = {int:from_topic} GROUP BY id_topic, approved ORDER BY approved ASC LIMIT 2', array('from_topic' => $from_topic)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_first_msg'] < $source_topic_data['id_first_msg']) { $source_topic_data['id_first_msg'] = $row['id_first_msg']; } $source_topic_data['id_last_msg'] = $row['id_last_msg']; if (!$row['approved']) { $source_topic_data['unapproved_posts'] = $row['message_count']; } else { $source_topic_data['num_replies'] = max(0, $row['message_count'] - 1); } } $smcFunc['db_free_result']($request); // Update the topic details for the source topic. $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_first_msg = {int:id_first_msg}, id_last_msg = {int:id_last_msg}, num_replies = {int:num_replies}, unapproved_posts = {int:unapproved_posts} WHERE id_topic = {int:from_topic}', array('id_first_msg' => $source_topic_data['id_first_msg'], 'id_last_msg' => $source_topic_data['id_last_msg'], 'num_replies' => $source_topic_data['num_replies'], 'unapproved_posts' => $source_topic_data['unapproved_posts'], 'from_topic' => $from_topic)); // We have a new post count for the source board. $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_posts = num_posts + {int:diff_replies}, unapproved_posts = unapproved_posts + {int:diff_unapproved_posts} WHERE id_board = {int:from_board}', array('diff_replies' => $source_topic_data['num_replies'] - $from_replies, 'diff_unapproved_posts' => $source_topic_data['unapproved_posts'] - $from_unapproved_posts, 'from_board' => $from_board)); } // Finally get around to updating the destination topic, now all indexes etc on the source are fixed. $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_first_msg = {int:id_first_msg}, id_last_msg = {int:id_last_msg}, num_replies = {int:num_replies}, unapproved_posts = {int:unapproved_posts} WHERE id_topic = {int:target_topic}', array('id_first_msg' => $target_topic_data['id_first_msg'], 'id_last_msg' => $target_topic_data['id_last_msg'], 'num_replies' => $target_topic_data['num_replies'], 'unapproved_posts' => $target_topic_data['unapproved_posts'], 'target_topic' => $target_topic)); // Need it to update some stats. require_once $sourcedir . '/Subs-Post.php'; // Update stats. updateStats('topic'); updateStats('message'); // Subject cache? $cache_updates = array(); if ($target_first_msg != $target_topic_data['id_first_msg']) { $cache_updates[] = $target_topic_data['id_first_msg']; } if (!empty($source_topic_data['id_first_msg']) && $from_first_msg != $source_topic_data['id_first_msg']) { $cache_updates[] = $source_topic_data['id_first_msg']; } if (!empty($cache_updates)) { $request = $smcFunc['db_query']('', ' SELECT id_topic, subject FROM {db_prefix}messages WHERE id_msg IN ({array_int:first_messages})', array('first_messages' => $cache_updates)); while ($row = $smcFunc['db_fetch_assoc']($request)) { updateStats('subject', $row['id_topic'], $row['subject']); } $smcFunc['db_free_result']($request); } updateLastMessages(array($from_board, $target_board)); }
function deleteAccount2($profile_vars, $post_errors, $memID) { global $user_info, $sourcedir, $context, $cur_profile, $modSettings, $smcFunc; // Try get more time... @set_time_limit(600); // !!! Add a way to delete pms as well? if (!$context['user']['is_owner']) { isAllowedTo('profile_remove_any'); } elseif (!allowedTo('profile_remove_any')) { isAllowedTo('profile_remove_own'); } checkSession(); $old_profile =& $cur_profile; // Too often, people remove/delete their own only account. if (in_array(1, explode(',', $old_profile['additional_groups'])) || $old_profile['id_group'] == 1) { // Are you allowed to administrate the forum, as they are? isAllowedTo('admin_forum'); $request = $smcFunc['db_query']('', ' SELECT id_member FROM {db_prefix}members WHERE (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0) AND id_member != {int:selected_member} LIMIT 1', array('admin_group' => 1, 'selected_member' => $memID)); list($another) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); if (empty($another)) { fatal_lang_error('at_least_one_admin', 'critical'); } } // This file is needed for the deleteMembers function. require_once $sourcedir . '/Subs-Members.php'; // Do you have permission to delete others profiles, or is that your profile you wanna delete? if ($memID != $user_info['id']) { isAllowedTo('profile_remove_any'); // Now, have you been naughty and need your posts deleting? // !!! Should this check board permissions? if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum')) { // Include RemoveTopics - essential for this type of work! require_once $sourcedir . '/RemoveTopic.php'; // First off we delete any topics the member has started - if they wanted topics being done. if ($_POST['remove_type'] == 'topics') { // Fetch all topics started by this user within the time period. $request = $smcFunc['db_query']('', ' SELECT t.id_topic FROM {db_prefix}topics AS t WHERE t.id_member_started = {int:selected_member}', array('selected_member' => $memID)); $topicIDs = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $topicIDs[] = $row['id_topic']; } $smcFunc['db_free_result']($request); // Actually remove the topics. // !!! This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had. removeTopics($topicIDs); } // Now delete the remaining messages. $request = $smcFunc['db_query']('', ' SELECT m.id_msg FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic AND t.id_first_msg != m.id_msg) WHERE m.id_member = {int:selected_member}', array('selected_member' => $memID)); // This could take a while... but ya know it's gonna be worth it in the end. while ($row = $smcFunc['db_fetch_assoc']($request)) { if (function_exists('apache_reset_timeout')) { @apache_reset_timeout(); } removeMessage($row['id_msg']); } $smcFunc['db_free_result']($request); } // Only delete this poor members account if they are actually being booted out of camp. if (isset($_POST['deleteAccount'])) { deleteMembers($memID); } } elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum')) { // Setup their account for deletion ;) updateMemberData($memID, array('is_activated' => 4)); // Another account needs approval... updateSettings(array('unapprovedMembers' => true), true); } elseif (empty($post_errors)) { deleteMembers($memID); require_once $sourcedir . '/LogInOut.php'; LogOut(true); redirectExit(); } }
/** * Remove a batch of messages (or topics) * * @param int[] $messages * @param mixed[] $messageDetails * @param string $type = replies */ function removeMessages($messages, $messageDetails, $type = 'replies') { global $modSettings; // @todo something's not right, removeMessage() does check permissions, // removeTopics() doesn't if ($type == 'topics') { removeTopics($messages); // and tell the world about it foreach ($messages as $topic) { // Note, only log topic ID in native form if it's not gone forever. logAction('remove', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $messageDetails[$topic]['board'] ? 'topic' : 'old_topic_id' => $topic, 'subject' => $messageDetails[$topic]['subject'], 'member' => $messageDetails[$topic]['member'], 'board' => $messageDetails[$topic]['board'])); } } else { require_once SUBSDIR . '/Messages.subs.php'; foreach ($messages as $post) { removeMessage($post); logAction('delete', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $messageDetails[$post]['board'] ? 'topic' : 'old_topic_id' => $messageDetails[$post]['topic'], 'subject' => $messageDetails[$post]['subject'], 'member' => $messageDetails[$post]['member'], 'board' => $messageDetails[$post]['board'])); } } }
function mob_m_delete_topic($rpcmsg) { global $mobdb, $context, $sourcedir, $topic, $board, $user_info; require_once $sourcedir . '/RemoveTopic.php'; require_once $sourcedir . '/Subs-Post.php'; $topicinfo = get_topicinfo($rpcmsg->getScalarValParam(0)); if (empty($topicinfo)) { mob_error('topic not found'); } $topic = $topicinfo['id_topic']; $board = $topicinfo['id_board']; loadBoard(); loadPermissions(); // Check for permissions if (!(allowedTo('remove_any') || $topicinfo['id_member_started'] == $user_info['id'] && allowedTo('remove_own'))) { mob_error('cannot remove topic'); } // Remove the topic logAction('remove', array('topic' => $topic)); sendNotifications($topic, 'remove'); removeTopics(array($topic)); return new xmlrpcresp(new xmlrpcval(array('result' => new xmlrpcval(true, 'boolean')), 'struct')); }
function deleteBoards($boards_to_remove, $moveChildrenTo = null) { global $sourcedir, $boards, $smcFunc; // No boards to delete? Return! if (empty($boards_to_remove)) { return; } getBoardTree(); // If $moveChildrenTo is set to null, include the children in the removal. if ($moveChildrenTo === null) { // Get a list of the child boards that will also be removed. $child_boards_to_remove = array(); foreach ($boards_to_remove as $board_to_remove) { recursiveBoards($child_boards_to_remove, $boards[$board_to_remove]['tree']); } // Merge the children with their parents. if (!empty($child_boards_to_remove)) { $boards_to_remove = array_unique(array_merge($boards_to_remove, $child_boards_to_remove)); } } else { foreach ($boards_to_remove as $id_board) { // !!! Separate category? if ($moveChildrenTo === 0) { fixChildren($id_board, 0, 0); } else { fixChildren($id_board, $boards[$moveChildrenTo]['level'] + 1, $moveChildrenTo); } } } // Delete ALL topics in the selected boards (done first so topics can't be marooned.) $request = $smcFunc['db_query']('', ' SELECT id_topic FROM {db_prefix}topics WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); $topics = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $topics[] = $row['id_topic']; } $smcFunc['db_free_result']($request); require_once $sourcedir . '/RemoveTopic.php'; removeTopics($topics, false); // Delete the board's logs. $smcFunc['db_query']('', ' DELETE FROM {db_prefix}log_mark_read WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); $smcFunc['db_query']('', ' DELETE FROM {db_prefix}log_boards WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); $smcFunc['db_query']('', ' DELETE FROM {db_prefix}log_notify WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); // Delete this board's moderators. $smcFunc['db_query']('', ' DELETE FROM {db_prefix}moderators WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); // Delete any extra events in the calendar. $smcFunc['db_query']('', ' DELETE FROM {db_prefix}calendar WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); // Delete any message icons that only appear on these boards. $smcFunc['db_query']('', ' DELETE FROM {db_prefix}message_icons WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); // Delete the boards. $smcFunc['db_query']('', ' DELETE FROM {db_prefix}boards WHERE id_board IN ({array_int:boards_to_remove})', array('boards_to_remove' => $boards_to_remove)); // Latest message/topic might not be there anymore. updateStats('message'); updateStats('topic'); updateSettings(array('calendar_updated' => time())); // Plus reset the cache to stop people getting odd results. updateSettings(array('settings_updated' => time())); // Clean the cache as well. clean_cache('data'); // Let's do some serious logging. foreach ($boards_to_remove as $id_board) { logAction('delete_board', array('boardname' => $boards[$id_board]['name']), 'admin'); } reorderBoards(); }
function deleteAccount2($profile_vars, $post_errors, $memID) { global $ID_MEMBER, $user_info, $sourcedir, $context, $db_prefix, $user_profile, $modSettings; // !!! Add a way to delete pms as well? if (!$context['user']['is_owner']) { isAllowedTo('profile_remove_any'); } elseif (!allowedTo('profile_remove_any')) { isAllowedTo('profile_remove_own'); } checkSession(); $old_profile =& $user_profile[$memID]; // Too often, people remove/delete their own only account. if (in_array(1, explode(',', $old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1) { // Are you allowed to administrate the forum, as they are? isAllowedTo('admin_forum'); $request = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}members\n\t\t\tWHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))\n\t\t\t\tAND ID_MEMBER != {$memID}\n\t\t\tLIMIT 1", __FILE__, __LINE__); list($another) = mysql_fetch_row($request); mysql_free_result($request); if (empty($another)) { fatal_lang_error('at_least_one_admin'); } } // This file is needed for the deleteMembers function. require_once $sourcedir . '/Subs-Members.php'; // Do you have permission to delete others profiles, or is that your profile you wanna delete? if ($memID != $ID_MEMBER) { isAllowedTo('profile_remove_any'); // Now, have you been naughty and need your posts deleting? // !!! Should this check board permissions? if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum')) { // Include RemoveTopics - essential for this type of work! require_once $sourcedir . '/RemoveTopic.php'; // First off we delete any topics the member has started - if they wanted topics being done. if ($_POST['remove_type'] == 'topics') { // Fetch all topics started by this user within the time period. $request = db_query("\n\t\t\t\t\tSELECT t.ID_TOPIC\n\t\t\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\t\tWHERE t.ID_MEMBER_STARTED = {$memID}", __FILE__, __LINE__); $topicIDs = array(); while ($row = mysql_fetch_assoc($request)) { $topicIDs[] = $row['ID_TOPIC']; } mysql_free_result($request); // Actually remove the topics. // !!! This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had. removeTopics($topicIDs); } // Now delete the remaining messages. $request = db_query("\n\t\t\t\tSELECT m.ID_MSG\n\t\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\t\tWHERE m.ID_MEMBER = {$memID}\n\t\t\t\t\tAND m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND t.ID_FIRST_MSG != m.ID_MSG", __FILE__, __LINE__); // This could take a while... but ya know it's gonna be worth it in the end. while ($row = mysql_fetch_assoc($request)) { removeMessage($row['ID_MSG']); } mysql_free_result($request); } // Only delete this poor members account if they are actually being booted out of camp. if (isset($_POST['deleteAccount'])) { deleteMembers($memID); } } elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum')) { // Setup their account for deletion ;) updateMemberData($memID, array('is_activated' => 4)); // Another account needs approval... updateSettings(array('unapprovedMembers' => true), true); } elseif (empty($post_errors)) { deleteMembers($memID); } }
function removeMessages($messages, $messageDetails, $current_view = 'replies') { global $sourcedir, $modSettings; require_once $sourcedir . '/RemoveTopic.php'; if ($current_view == 'topics') { removeTopics($messages); // and tell the world about it foreach ($messages as $topic) { // Note, only log topic ID in native form if it's not gone forever. logAction('remove', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $messageDetails[$topic]['board'] ? 'topic' : 'old_topic_id' => $topic, 'subject' => $messageDetails[$topic]['subject'], 'member' => $messageDetails[$topic]['member'], 'board' => $messageDetails[$topic]['board'])); } } else { foreach ($messages as $post) { removeMessage($post); logAction('delete', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $messageDetails[$post]['board'] ? 'topic' : 'old_topic_id' => $messageDetails[$post]['topic'], 'subject' => $messageDetails[$post]['subject'], 'member' => $messageDetails[$post]['member'], 'board' => $messageDetails[$post]['board'])); } } }
/** * Remove a specific message. * !! This includes permission checks. * * - normally, local and global should be the localCookies and globalCookies settings, respectively. * - uses boardurl to determine these two things. * * @param int $message The message id * @param bool $decreasePostCount if true users' post count will be reduced */ function removeMessage($message, $decreasePostCount = true) { global $board, $modSettings, $user_info; $db = database(); if (empty($message) || !is_numeric($message)) { return false; } $request = $db->query('', ' SELECT m.id_member, m.icon, m.poster_time, m.subject,' . (empty($modSettings['search_custom_index_config']) ? '' : ' m.body,') . ' m.approved, t.id_topic, t.id_first_msg, t.id_last_msg, t.num_replies, t.id_board, t.id_member_started AS id_member_poster, b.count_posts FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) WHERE m.id_msg = {int:id_msg} LIMIT 1', array('id_msg' => $message)); if ($db->num_rows($request) == 0) { return false; } $row = $db->fetch_assoc($request); $db->free_result($request); if (empty($board) || $row['id_board'] != $board) { $delete_any = boardsAllowedTo('delete_any'); if (!in_array(0, $delete_any) && !in_array($row['id_board'], $delete_any)) { $delete_own = boardsAllowedTo('delete_own'); $delete_own = in_array(0, $delete_own) || in_array($row['id_board'], $delete_own); $delete_replies = boardsAllowedTo('delete_replies'); $delete_replies = in_array(0, $delete_replies) || in_array($row['id_board'], $delete_replies); if ($row['id_member'] == $user_info['id']) { if (!$delete_own) { if ($row['id_member_poster'] == $user_info['id']) { if (!$delete_replies) { fatal_lang_error('cannot_delete_replies', 'permission'); } } else { fatal_lang_error('cannot_delete_own', 'permission'); } } elseif (($row['id_member_poster'] != $user_info['id'] || !$delete_replies) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } } elseif ($row['id_member_poster'] == $user_info['id']) { if (!$delete_replies) { fatal_lang_error('cannot_delete_replies', 'permission'); } } else { fatal_lang_error('cannot_delete_any', 'permission'); } } // Can't delete an unapproved message, if you can't see it! if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !(in_array(0, $delete_any) || in_array($row['id_board'], $delete_any))) { $approve_posts = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts'); if (!in_array(0, $approve_posts) && !in_array($row['id_board'], $approve_posts)) { return false; } } } else { // Check permissions to delete this message. if ($row['id_member'] == $user_info['id']) { if (!allowedTo('delete_own')) { if ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) { isAllowedTo('delete_replies'); } elseif (!allowedTo('delete_any')) { isAllowedTo('delete_own'); } } elseif (!allowedTo('delete_any') && ($row['id_member_poster'] != $user_info['id'] || !allowedTo('delete_replies')) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) { isAllowedTo('delete_replies'); } else { isAllowedTo('delete_any'); } if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !allowedTo('delete_own')) { isAllowedTo('approve_posts'); } } // Delete the *whole* topic, but only if the topic consists of one message. if ($row['id_first_msg'] == $message) { if (empty($board) || $row['id_board'] != $board) { $remove_any = boardsAllowedTo('remove_any'); $remove_any = in_array(0, $remove_any) || in_array($row['id_board'], $remove_any); if (!$remove_any) { $remove_own = boardsAllowedTo('remove_own'); $remove_own = in_array(0, $remove_own) || in_array($row['id_board'], $remove_own); } if ($row['id_member'] != $user_info['id'] && !$remove_any) { fatal_lang_error('cannot_remove_any', 'permission'); } elseif (!$remove_any && !$remove_own) { fatal_lang_error('cannot_remove_own', 'permission'); } } else { // Check permissions to delete a whole topic. if ($row['id_member'] != $user_info['id']) { isAllowedTo('remove_any'); } elseif (!allowedTo('remove_any')) { isAllowedTo('remove_own'); } } // ...if there is only one post. if (!empty($row['num_replies'])) { fatal_lang_error('delFirstPost', false); } // This needs to be included for topic functions require_once SUBSDIR . '/Topic.subs.php'; removeTopics($row['id_topic']); return true; } // Deleting a recycled message can not lower anyone's post count. if ($row['icon'] == 'recycled') { $decreasePostCount = false; } // This is the last post, update the last post on the board. if ($row['id_last_msg'] == $message) { // Find the last message, set it, and decrease the post count. $request = $db->query('', ' SELECT id_msg, id_member FROM {db_prefix}messages WHERE id_topic = {int:id_topic} AND id_msg != {int:id_msg} ORDER BY ' . ($modSettings['postmod_active'] ? 'approved DESC, ' : '') . 'id_msg DESC LIMIT 1', array('id_topic' => $row['id_topic'], 'id_msg' => $message)); $row2 = $db->fetch_assoc($request); $db->free_result($request); $db->query('', ' UPDATE {db_prefix}topics SET id_last_msg = {int:id_last_msg}, id_member_updated = {int:id_member_updated}' . (!$modSettings['postmod_active'] || $row['approved'] ? ', num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : ', unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . ' WHERE id_topic = {int:id_topic}', array('id_last_msg' => $row2['id_msg'], 'id_member_updated' => $row2['id_member'], 'no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic'])); } else { $db->query('', ' UPDATE {db_prefix}topics SET ' . ($row['approved'] ? ' num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : ' unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . ' WHERE id_topic = {int:id_topic}', array('no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic'])); } // Default recycle to false. $recycle = false; // If recycle topics has been set, make a copy of this message in the recycle board. // Make sure we're not recycling messages that are already on the recycle board. if (!empty($modSettings['recycle_enable']) && $row['id_board'] != $modSettings['recycle_board'] && $row['icon'] != 'recycled') { // Check if the recycle board exists and if so get the read status. $request = $db->query('', ' SELECT (IFNULL(lb.id_msg, 0) >= b.id_msg_updated) AS is_seen, id_last_msg FROM {db_prefix}boards AS b LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member}) WHERE b.id_board = {int:recycle_board}', array('current_member' => $user_info['id'], 'recycle_board' => $modSettings['recycle_board'])); if ($db->num_rows($request) == 0) { fatal_lang_error('recycle_no_valid_board'); } list($isRead, $last_board_msg) = $db->fetch_row($request); $db->free_result($request); // Is there an existing topic in the recycle board to group this post with? $request = $db->query('', ' SELECT id_topic, id_first_msg, id_last_msg FROM {db_prefix}topics WHERE id_previous_topic = {int:id_previous_topic} AND id_board = {int:recycle_board}', array('id_previous_topic' => $row['id_topic'], 'recycle_board' => $modSettings['recycle_board'])); list($id_recycle_topic, $first_topic_msg, $last_topic_msg) = $db->fetch_row($request); $db->free_result($request); // Insert a new topic in the recycle board if $id_recycle_topic is empty. if (empty($id_recycle_topic)) { $db->insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'id_previous_topic' => 'int'), array($modSettings['recycle_board'], $row['id_member'], $row['id_member'], $message, $message, 0, 1, $row['id_topic']), array('id_topic')); } // Capture the ID of the new topic... $topicID = empty($id_recycle_topic) ? $db->insert_id('{db_prefix}topics', 'id_topic') : $id_recycle_topic; // If the topic creation went successful, move the message. if ($topicID > 0) { $db->query('', ' UPDATE {db_prefix}messages SET id_topic = {int:id_topic}, id_board = {int:recycle_board}, icon = {string:recycled}, approved = {int:is_approved} WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message, 'recycled' => 'recycled', 'is_approved' => 1)); // Take any reported posts with us... $db->query('', ' UPDATE {db_prefix}log_reported SET id_topic = {int:id_topic}, id_board = {int:recycle_board} WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message)); // Mark recycled topic as read. if (!$user_info['is_guest']) { require_once SUBSDIR . '/Topic.subs.php'; markTopicsRead(array($user_info['id'], $topicID, $modSettings['maxMsgID'], 0), true); } // Mark recycle board as seen, if it was marked as seen before. if (!empty($isRead) && !$user_info['is_guest']) { require_once SUBSDIR . '/Boards.subs.php'; markBoardsRead($modSettings['recycle_board']); } // Add one topic and post to the recycle bin board. $db->query('', ' UPDATE {db_prefix}boards SET num_topics = num_topics + {int:num_topics_inc}, num_posts = num_posts + 1' . ($message > $last_board_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . ' WHERE id_board = {int:recycle_board}', array('num_topics_inc' => empty($id_recycle_topic) ? 1 : 0, 'recycle_board' => $modSettings['recycle_board'], 'id_merged_msg' => $message)); // Lets increase the num_replies, and the first/last message ID as appropriate. if (!empty($id_recycle_topic)) { $db->query('', ' UPDATE {db_prefix}topics SET num_replies = num_replies + 1' . ($message > $last_topic_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . ($message < $first_topic_msg ? ', id_first_msg = {int:id_merged_msg}' : '') . ' WHERE id_topic = {int:id_recycle_topic}', array('id_recycle_topic' => $id_recycle_topic, 'id_merged_msg' => $message)); } // Make sure this message isn't getting deleted later on. $recycle = true; // Make sure we update the search subject index. updateSubjectStats($topicID, $row['subject']); } // If it wasn't approved don't keep it in the queue. if (!$row['approved']) { $db->query('', ' DELETE FROM {db_prefix}approval_queue WHERE id_msg = {int:id_msg} AND id_attach = {int:id_attach}', array('id_msg' => $message, 'id_attach' => 0)); } } $db->query('', ' UPDATE {db_prefix}boards SET ' . ($row['approved'] ? ' num_posts = CASE WHEN num_posts = {int:no_posts} THEN 0 ELSE num_posts - 1 END' : ' unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . ' WHERE id_board = {int:id_board}', array('no_posts' => 0, 'no_unapproved' => 0, 'id_board' => $row['id_board'])); // If the poster was registered and the board this message was on incremented // the member's posts when it was posted, decrease his or her post count. if (!empty($row['id_member']) && $decreasePostCount && empty($row['count_posts']) && $row['approved']) { updateMemberData($row['id_member'], array('posts' => '-')); } // Only remove posts if they're not recycled. if (!$recycle) { // Remove the likes! $db->query('', ' DELETE FROM {db_prefix}message_likes WHERE id_msg = {int:id_msg}', array('id_msg' => $message)); // Remove the mentions! $db->query('', ' DELETE FROM {db_prefix}log_mentions WHERE id_msg = {int:id_msg}', array('id_msg' => $message)); // Remove the message! $db->query('', ' DELETE FROM {db_prefix}messages WHERE id_msg = {int:id_msg}', array('id_msg' => $message)); if (!empty($modSettings['search_custom_index_config'])) { $customIndexSettings = unserialize($modSettings['search_custom_index_config']); $words = text2words($row['body'], $customIndexSettings['bytes_per_word'], true); if (!empty($words)) { $db->query('', ' DELETE FROM {db_prefix}log_search_words WHERE id_word IN ({array_int:word_list}) AND id_msg = {int:id_msg}', array('word_list' => $words, 'id_msg' => $message)); } } // Delete attachment(s) if they exist. require_once SUBSDIR . '/ManageAttachments.subs.php'; $attachmentQuery = array('attachment_type' => 0, 'id_msg' => $message); removeAttachments($attachmentQuery); // Delete follow-ups too require_once SUBSDIR . '/FollowUps.subs.php'; // If it is an entire topic if ($row['id_first_msg'] == $message) { $db->query('', ' DELETE FROM {db_prefix}follow_ups WHERE follow_ups IN ({array_int:topics})', array('topics' => $row['id_topic'])); } // Allow mods to remove message related data of their own (likes, maybe?) call_integration_hook('integrate_remove_message', array($message)); } // Update the pesky statistics. updateMessageStats(); updateStats('topic'); updateSettings(array('calendar_updated' => time())); // And now to update the last message of each board we messed with. require_once SUBSDIR . '/Post.subs.php'; if ($recycle) { updateLastMessages(array($row['id_board'], $modSettings['recycle_board'])); } else { updateLastMessages($row['id_board']); } // Close any moderation reports for this message. require_once SUBSDIR . '/Moderation.subs.php'; $updated_reports = updateReportsStatus($message, 'close', 1); if ($updated_reports != 0) { updateSettings(array('last_mod_report_action' => time())); recountOpenReports(); } return false; }
function DeleteDownload() { global $boarddir, $user_info, $smcFunc, $sourcedir, $adkFolder; //Check the session checkSession('get'); if (!empty($_REQUEST['id']) && is_numeric($_REQUEST['id'])) { $id = (int) $_REQUEST['id']; } else { fatal_lang_error('adkfatal_require_id_file', false); } //Select some important info $sql = $smcFunc['db_query']('', ' SELECT id_cat, id_member, id_topic FROM {db_prefix}adk_down_file WHERE id_file = {int:file}', array('file' => $id)); $row = $smcFunc['db_fetch_assoc']($sql); $id_cat = $row['id_cat']; $id_topic = $row['id_topic']; $smcFunc['db_free_result']($sql); //mmm May be you don't have the right permissions to delete this. if ($user_info['id'] != $row['id_member'] && !allowedTo('adk_downloads_manage')) { fatal_lang_error('adkfatal_not_permission', false); } //Delete entry from adk_down_file deleteEntry('adk_down_file', 'id_file = {int:file}', array('file' => $id)); //Let's load filenames $sql = $smcFunc['db_query']('', ' SELECT filename FROM {db_prefix}adk_down_attachs WHERE id_file = {int:file}', array('file' => $id)); //Unlink if file_exists while ($row = $smcFunc['db_fetch_assoc']($sql)) { if (file_exists($adkFolder['eds'] . '/' . $row['filename'])) { @unlink($adkFolder['eds'] . '/' . $row['filename']); } } //Delete attachs deleteEntry('adk_down_attachs', 'id_file = {int:file}', array('file' => $id)); //Delete topic if (!empty($id_topic)) { //Load Main File to removeTopic require_once $sourcedir . '/RemoveTopic.php'; //Ajam.... it's done removeTopics(array($id_topic)); } //Update category TotalCategoryUpdate($id_cat); redirectexit('action=downloads;cat=' . $id_cat); }
function removeMessage($message, $decreasePostCount = true) { global $db_prefix, $board, $sourcedir, $modSettings, $ID_MEMBER, $user_info; if (empty($message) || !is_numeric($message)) { return false; } $request = db_query("\n\t\tSELECT\n\t\t\tm.ID_MEMBER, m.icon, m.posterTime, m.subject," . (empty($modSettings['search_custom_index_config']) ? '' : ' m.body,') . "\n\t\t\tt.ID_TOPIC, t.ID_FIRST_MSG, t.ID_LAST_MSG, t.numReplies, t.ID_BOARD,\n\t\t\tt.ID_MEMBER_STARTED AS ID_MEMBER_POSTER,\n\t\t\tb.countPosts\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\tWHERE m.ID_MSG = {$message}\n\t\t\tAND t.ID_TOPIC = m.ID_TOPIC\n\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\tLIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { return false; } $row = mysql_fetch_assoc($request); mysql_free_result($request); if (empty($board) || $row['ID_BOARD'] != $board) { $delete_any = boardsAllowedTo('delete_any'); if (!in_array(0, $delete_any) && !in_array($row['ID_BOARD'], $delete_any)) { $delete_own = boardsAllowedTo('delete_own'); $delete_own = in_array(0, $delete_own) || in_array($row['ID_BOARD'], $delete_own); $delete_replies = boardsAllowedTo('delete_replies'); $delete_replies = in_array(0, $delete_replies) || in_array($row['ID_BOARD'], $delete_replies); if ($row['ID_MEMBER'] == $ID_MEMBER) { if (!$delete_own) { if ($row['ID_MEMBER_POSTER'] == $ID_MEMBER) { if (!$delete_replies) { fatal_lang_error('cannot_delete_replies'); } } else { fatal_lang_error('cannot_delete_own'); } } elseif (($row['ID_MEMBER_POSTER'] != $ID_MEMBER || !$delete_replies) && !empty($modSettings['edit_disable_time']) && $row['posterTime'] + $modSettings['edit_disable_time'] * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER) { if (!$delete_replies) { fatal_lang_error('cannot_delete_replies'); } } else { fatal_lang_error('cannot_delete_any'); } } } else { // Check permissions to delete this message. if ($row['ID_MEMBER'] == $ID_MEMBER) { if (!allowedTo('delete_own')) { if ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('delete_any')) { isAllowedTo('delete_replies'); } elseif (!allowedTo('delete_any')) { isAllowedTo('delete_own'); } } elseif (!allowedTo('delete_any') && ($row['ID_MEMBER_POSTER'] != $ID_MEMBER || !allowedTo('delete_replies')) && !empty($modSettings['edit_disable_time']) && $row['posterTime'] + $modSettings['edit_disable_time'] * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('delete_any')) { isAllowedTo('delete_replies'); } else { isAllowedTo('delete_any'); } } // Delete the *whole* topic, but only if the topic consists of one message. if ($row['ID_FIRST_MSG'] == $message) { if (empty($board) || $row['ID_BOARD'] != $board) { $remove_any = boardsAllowedTo('remove_any'); $remove_any = in_array(0, $remove_any) || in_array($row['ID_BOARD'], $remove_any); if (!$remove_any) { $remove_own = boardsAllowedTo('remove_own'); $remove_own = in_array(0, $remove_own) || in_array($row['ID_BOARD'], $remove_own); } if ($row['ID_MEMBER'] != $ID_MEMBER && !$remove_any) { fatal_lang_error('cannot_remove_any'); } elseif (!$remove_any && !$remove_own) { fatal_lang_error('cannot_remove_own'); } } else { // Check permissions to delete a whole topic. if ($row['ID_MEMBER'] != $ID_MEMBER) { isAllowedTo('remove_any'); } elseif (!allowedTo('remove_any')) { isAllowedTo('remove_own'); } } // ...if there is only one post. if (!empty($row['numReplies'])) { fatal_lang_error('delFirstPost', false); } removeTopics($row['ID_TOPIC']); return true; } // Default recycle to false. $recycle = false; // If recycle topics has been set, make a copy of this message in the recycle board. // Make sure we're not recycling messages that are already on the recycle board. if (!empty($modSettings['recycle_enable']) && $row['ID_BOARD'] != $modSettings['recycle_board'] && $row['icon'] != 'recycled') { // Check if the recycle board exists and if so get the read status. $request = db_query("\n\t\t\tSELECT (IFNULL(lb.ID_MSG, 0) >= b.ID_MSG_UPDATED) AS isSeen\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\tLEFT JOIN {$db_prefix}log_boards AS lb ON (lb.ID_BOARD = b.ID_BOARD AND lb.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE b.ID_BOARD = {$modSettings['recycle_board']}", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { fatal_lang_error('recycle_no_valid_board'); } list($isRead) = mysql_fetch_row($request); mysql_free_result($request); // Insert a new topic in the recycle board. db_query("\n\t\t\tINSERT INTO {$db_prefix}topics\n\t\t\t\t(ID_BOARD, ID_MEMBER_STARTED, ID_MEMBER_UPDATED, ID_FIRST_MSG, ID_LAST_MSG)\n\t\t\tVALUES ({$modSettings['recycle_board']}, {$row['ID_MEMBER']}, {$row['ID_MEMBER']}, {$message}, {$message})", __FILE__, __LINE__); // Capture the ID of the new topic... $topicID = db_insert_id(); // If the topic creation went successful, move the message. if ($topicID > 0) { db_query("\n\t\t\t\tUPDATE {$db_prefix}messages\n\t\t\t\tSET \n\t\t\t\t\tID_TOPIC = {$topicID},\n\t\t\t\t\tID_BOARD = {$modSettings['recycle_board']},\n\t\t\t\t\ticon = 'recycled'\n\t\t\t\tWHERE ID_MSG = {$message}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); // Mark recycled topic as read. if (!$user_info['is_guest']) { db_query("\n\t\t\t\t\tREPLACE INTO {$db_prefix}log_topics\n\t\t\t\t\t\t(ID_TOPIC, ID_MEMBER, ID_MSG)\n\t\t\t\t\tVALUES ({$topicID}, {$ID_MEMBER}, {$modSettings['maxMsgID']})", __FILE__, __LINE__); } // Mark recycle board as seen, if it was marked as seen before. if (!empty($isRead) && !$user_info['is_guest']) { db_query("\n\t\t\t\t\tREPLACE INTO {$db_prefix}log_boards\n\t\t\t\t\t\t(ID_BOARD, ID_MEMBER, ID_MSG)\n\t\t\t\t\tVALUES ({$modSettings['recycle_board']}, {$ID_MEMBER}, {$modSettings['maxMsgID']})", __FILE__, __LINE__); } // Add one topic and post to the recycle bin board. db_query("\n\t\t\t\tUPDATE {$db_prefix}boards\n\t\t\t\tSET\n\t\t\t\t\tnumTopics = numTopics + 1,\n\t\t\t\t\tnumPosts = numPosts + 1\n\t\t\t\tWHERE ID_BOARD = {$modSettings['recycle_board']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); // Make sure this message isn't getting deleted later on. $recycle = true; // Make sure we update the search subject index. updateStats('subject', $topicID, $row['subject']); } } // Deleting a recycled message can not lower anyone's post count. if ($row['icon'] == 'recycled') { $decreasePostCount = false; } // This is the last post, update the last post on the board. if ($row['ID_LAST_MSG'] == $message) { // Find the last message, set it, and decrease the post count. $request = db_query("\n\t\t\tSELECT ID_MSG, ID_MEMBER\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}\n\t\t\t\tAND ID_MSG != {$message}\n\t\t\tORDER BY ID_MSG DESC\n\t\t\tLIMIT 1", __FILE__, __LINE__); $row2 = mysql_fetch_assoc($request); mysql_free_result($request); db_query("\n\t\t\tUPDATE {$db_prefix}topics\n\t\t\tSET\n\t\t\t\tID_LAST_MSG = {$row2['ID_MSG']},\n\t\t\t\tnumReplies = IF(numReplies = 0, 0, numReplies - 1),\n\t\t\t\tID_MEMBER_UPDATED = {$row2['ID_MEMBER']}\n\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}\n\t\t\tLIMIT 1", __FILE__, __LINE__); } else { db_query("\n\t\t\tUPDATE {$db_prefix}topics\n\t\t\tSET numReplies = IF(numReplies = 0, 0, numReplies - 1)\n\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}\n\t\t\tLIMIT 1", __FILE__, __LINE__); } db_query("\n\t\tUPDATE {$db_prefix}boards\n\t\tSET numPosts = IF(numPosts = 0, 0, numPosts - 1)\n\t\tWHERE ID_BOARD = {$row['ID_BOARD']}\n\t\tLIMIT 1", __FILE__, __LINE__); // If the poster was registered and the board this message was on incremented // the member's posts when it was posted, decrease his or her post count. if (!empty($row['ID_MEMBER']) && $decreasePostCount && empty($row['countPosts'])) { updateMemberData($row['ID_MEMBER'], array('posts' => '-')); } // Only remove posts if they're not recycled. if (!$recycle) { // Remove the message! db_query("\n\t\t\tDELETE FROM {$db_prefix}messages\n\t\t\tWHERE ID_MSG = {$message}\n\t\t\tLIMIT 1", __FILE__, __LINE__); if (!empty($modSettings['search_custom_index_config'])) { $customIndexSettings = unserialize($modSettings['search_custom_index_config']); $words = text2words($row['body'], $customIndexSettings['bytes_per_word'], true); if (!empty($words)) { db_query("\n\t\t\t\t\tDELETE FROM {$db_prefix}log_search_words\n\t\t\t\t\tWHERE ID_WORD IN (" . implode(', ', $words) . ")\n\t\t\t\t\t\tAND ID_MSG = {$message}", __FILE__, __LINE__); } } // Delete attachment(s) if they exist. require_once $sourcedir . '/ManageAttachments.php'; removeAttachments('a.attachmentType = 0 AND a.ID_MSG = ' . $message); } // Update the pesky statistics. updateStats('message'); updateStats('topic'); updateStats('calendar'); // And now to update the last message of each board we messed with. require_once $sourcedir . '/Subs-Post.php'; if ($recycle) { updateLastMessages(array($row['ID_BOARD'], $modSettings['recycle_board'])); } else { updateLastMessages($row['ID_BOARD']); } return false; }
function deleteBoards($boards_to_remove, $moveChildrenTo = null) { global $db_prefix, $sourcedir, $boards, $modSettings; // No boards to delete? Return! if (empty($boards_to_remove)) { return; } getBoardTree(); // If $moveChildrenTo is set to null, include the children in the removal. if ($moveChildrenTo === null) { // Get a list of the child boards that will also be removed. $child_boards_to_remove = array(); foreach ($boards_to_remove as $board_to_remove) { recursiveBoards($child_boards_to_remove, $boards[$board_to_remove]['tree']); } // Merge the children with their parents. if (!empty($child_boards_to_remove)) { $boards_to_remove = array_unique(array_merge($boards_to_remove, $child_boards_to_remove)); } } else { foreach ($boards_to_remove as $id_board) { // !!! Separate category? if ($moveChildrenTo === 0) { fixChildren($id_board, 0, 0); } else { fixChildren($id_board, $boards[$moveChildrenTo]['level'] + 1, $moveChildrenTo); } } } // Delete ALL topics in the selected boards (done first so topics can't be marooned.) $request = db_query("\n\t\tSELECT ID_TOPIC\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); $topics = array(); while ($row = mysql_fetch_assoc($request)) { $topics[] = $row['ID_TOPIC']; } mysql_free_result($request); require_once $sourcedir . '/RemoveTopic.php'; removeTopics($topics, false); // Delete the board's logs. db_query("\n\t\tDELETE FROM {$db_prefix}log_mark_read\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); db_query("\n\t\tDELETE FROM {$db_prefix}log_boards\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); db_query("\n\t\tDELETE FROM {$db_prefix}log_notify\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); // Delete this board's moderators. db_query("\n\t\tDELETE FROM {$db_prefix}moderators\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); // Delete any extra events in the calendar. db_query("\n\t\tDELETE FROM {$db_prefix}calendar\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); // Delete any permissions associated with these boards. db_query("\n\t\tDELETE FROM {$db_prefix}board_permissions\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); // Delete any message icons that only appear on these boards. db_query("\n\t\tDELETE FROM {$db_prefix}message_icons\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ')', __FILE__, __LINE__); // Delete the boards. db_query("\n\t\tDELETE FROM {$db_prefix}boards\n\t\tWHERE ID_BOARD IN (" . implode(', ', $boards_to_remove) . ")\n\t\tLIMIT " . count($boards_to_remove), __FILE__, __LINE__); // Latest message/topic might not be there anymore. updateStats('message'); updateStats('topic'); updateStats('calendar'); // Did they by chance delete the recycle board? If so deal with that! if (!empty($modSettings['recycle_board']) && in_array($modSettings['recycle_board'], $boards_to_remove)) { updateSettings(array('recycle_board' => 0, 'recycle_enable' => 0)); } reorderBoards(); }
/** * Check for move topic notices that have past their best by date: * * - remove them if the time has expired. */ public function remove_topic_redirect() { $db = database(); // Init $topics = array(); // We will need this for lanaguage files loadEssentialThemeData(); // Find all of the old MOVE topic notices that were set to expire $request = $db->query('', ' SELECT id_topic FROM {db_prefix}topics WHERE redirect_expires <= {int:redirect_expires} AND redirect_expires <> 0', array('redirect_expires' => time())); while ($row = $db->fetch_row($request)) { $topics[] = $row[0]; } $db->free_result($request); // Zap, you're gone if (count($topics) > 0) { require_once SUBSDIR . '/Topic.subs.php'; removeTopics($topics, false, true); } return true; }
/** * Allows for moderation from the message index. * @todo refactor this... */ function QuickModeration() { global $sourcedir, $board, $user_info, $modSettings, $smcFunc, $context; // Check the session = get or post. checkSession('request'); // Lets go straight to the restore area. if (isset($_REQUEST['qaction']) && $_REQUEST['qaction'] == 'restore' && !empty($_REQUEST['topics'])) { redirectexit('action=restoretopic;topics=' . implode(',', $_REQUEST['topics']) . ';' . $context['session_var'] . '=' . $context['session_id']); } if (isset($_SESSION['topicseen_cache'])) { $_SESSION['topicseen_cache'] = array(); } // This is going to be needed to send off the notifications and for updateLastMessages(). require_once $sourcedir . '/Subs-Post.php'; // Remember the last board they moved things to. if (isset($_REQUEST['move_to'])) { $_SESSION['move_to_topic'] = $_REQUEST['move_to']; } // Only a few possible actions. $possibleActions = array(); if (!empty($board)) { $boards_can = array('make_sticky' => allowedTo('make_sticky') ? array($board) : array(), 'move_any' => allowedTo('move_any') ? array($board) : array(), 'move_own' => allowedTo('move_own') ? array($board) : array(), 'remove_any' => allowedTo('remove_any') ? array($board) : array(), 'remove_own' => allowedTo('remove_own') ? array($board) : array(), 'lock_any' => allowedTo('lock_any') ? array($board) : array(), 'lock_own' => allowedTo('lock_own') ? array($board) : array(), 'merge_any' => allowedTo('merge_any') ? array($board) : array(), 'approve_posts' => allowedTo('approve_posts') ? array($board) : array()); $redirect_url = 'board=' . $board . '.' . $_REQUEST['start']; } else { /** * @todo Ugly. There's no getting around this, is there? * @todo Maybe just do this on the actions people want to use? */ $boards_can = boardsAllowedTo(array('make_sticky', 'move_any', 'move_own', 'remove_any', 'remove_own', 'lock_any', 'lock_own', 'merge_any', 'approve_posts'), true, false); $redirect_url = isset($_POST['redirect_url']) ? $_POST['redirect_url'] : (isset($_SESSION['old_url']) ? $_SESSION['old_url'] : ''); } if (!$user_info['is_guest']) { $possibleActions[] = 'markread'; } if (!empty($boards_can['make_sticky']) && !empty($modSettings['enableStickyTopics'])) { $possibleActions[] = 'sticky'; } if (!empty($boards_can['move_any']) || !empty($boards_can['move_own'])) { $possibleActions[] = 'move'; } if (!empty($boards_can['remove_any']) || !empty($boards_can['remove_own'])) { $possibleActions[] = 'remove'; } if (!empty($boards_can['lock_any']) || !empty($boards_can['lock_own'])) { $possibleActions[] = 'lock'; } if (!empty($boards_can['merge_any'])) { $possibleActions[] = 'merge'; } if (!empty($boards_can['approve_posts'])) { $possibleActions[] = 'approve'; } // Two methods: $_REQUEST['actions'] (id_topic => action), and $_REQUEST['topics'] and $_REQUEST['qaction']. // (if action is 'move', $_REQUEST['move_to'] or $_REQUEST['move_tos'][$topic] is used.) if (!empty($_REQUEST['topics'])) { // If the action isn't valid, just quit now. if (empty($_REQUEST['qaction']) || !in_array($_REQUEST['qaction'], $possibleActions)) { redirectexit($redirect_url); } // Merge requires all topics as one parameter and can be done at once. if ($_REQUEST['qaction'] == 'merge') { // Merge requires at least two topics. if (empty($_REQUEST['topics']) || count($_REQUEST['topics']) < 2) { redirectexit($redirect_url); } require_once $sourcedir . '/SplitTopics.php'; return MergeExecute($_REQUEST['topics']); } // Just convert to the other method, to make it easier. foreach ($_REQUEST['topics'] as $topic) { $_REQUEST['actions'][(int) $topic] = $_REQUEST['qaction']; } } // Weird... how'd you get here? if (empty($_REQUEST['actions'])) { redirectexit($redirect_url); } // Validate each action. $temp = array(); foreach ($_REQUEST['actions'] as $topic => $action) { if (in_array($action, $possibleActions)) { $temp[(int) $topic] = $action; } } $_REQUEST['actions'] = $temp; if (!empty($_REQUEST['actions'])) { // Find all topics... $request = $smcFunc['db_query']('', ' SELECT id_topic, id_member_started, id_board, locked, approved, unapproved_posts FROM {db_prefix}topics WHERE id_topic IN ({array_int:action_topic_ids}) LIMIT ' . count($_REQUEST['actions']), array('action_topic_ids' => array_keys($_REQUEST['actions']))); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (!empty($board)) { if ($row['id_board'] != $board || $modSettings['postmod_active'] && !$row['approved'] && !allowedTo('approve_posts')) { unset($_REQUEST['actions'][$row['id_topic']]); } } else { // Don't allow them to act on unapproved posts they can't see... if ($modSettings['postmod_active'] && !$row['approved'] && !in_array(0, $boards_can['approve_posts']) && !in_array($row['id_board'], $boards_can['approve_posts'])) { unset($_REQUEST['actions'][$row['id_topic']]); } elseif ($_REQUEST['actions'][$row['id_topic']] == 'sticky' && !in_array(0, $boards_can['make_sticky']) && !in_array($row['id_board'], $boards_can['make_sticky'])) { unset($_REQUEST['actions'][$row['id_topic']]); } elseif ($_REQUEST['actions'][$row['id_topic']] == 'move' && !in_array(0, $boards_can['move_any']) && !in_array($row['id_board'], $boards_can['move_any']) && ($row['id_member_started'] != $user_info['id'] || !in_array(0, $boards_can['move_own']) && !in_array($row['id_board'], $boards_can['move_own']))) { unset($_REQUEST['actions'][$row['id_topic']]); } elseif ($_REQUEST['actions'][$row['id_topic']] == 'remove' && !in_array(0, $boards_can['remove_any']) && !in_array($row['id_board'], $boards_can['remove_any']) && ($row['id_member_started'] != $user_info['id'] || !in_array(0, $boards_can['remove_own']) && !in_array($row['id_board'], $boards_can['remove_own']))) { unset($_REQUEST['actions'][$row['id_topic']]); } elseif ($_REQUEST['actions'][$row['id_topic']] == 'lock' && !in_array(0, $boards_can['lock_any']) && !in_array($row['id_board'], $boards_can['lock_any']) && ($row['id_member_started'] != $user_info['id'] || $row['locked'] == 1 || !in_array(0, $boards_can['lock_own']) && !in_array($row['id_board'], $boards_can['lock_own']))) { unset($_REQUEST['actions'][$row['id_topic']]); } elseif ($_REQUEST['actions'][$row['id_topic']] == 'approve' && (!$row['unapproved_posts'] || !in_array(0, $boards_can['approve_posts']) && !in_array($row['id_board'], $boards_can['approve_posts']))) { unset($_REQUEST['actions'][$row['id_topic']]); } } } $smcFunc['db_free_result']($request); } $stickyCache = array(); $moveCache = array(0 => array(), 1 => array()); $removeCache = array(); $lockCache = array(); $markCache = array(); $approveCache = array(); // Separate the actions. foreach ($_REQUEST['actions'] as $topic => $action) { $topic = (int) $topic; if ($action == 'markread') { $markCache[] = $topic; } elseif ($action == 'sticky') { $stickyCache[] = $topic; } elseif ($action == 'move') { require_once $sourcedir . '/MoveTopic.php'; moveTopicConcurrence(); // $moveCache[0] is the topic, $moveCache[1] is the board to move to. $moveCache[1][$topic] = (int) (isset($_REQUEST['move_tos'][$topic]) ? $_REQUEST['move_tos'][$topic] : $_REQUEST['move_to']); if (empty($moveCache[1][$topic])) { continue; } $moveCache[0][] = $topic; } elseif ($action == 'remove') { $removeCache[] = $topic; } elseif ($action == 'lock') { $lockCache[] = $topic; } elseif ($action == 'approve') { $approveCache[] = $topic; } } if (empty($board)) { $affectedBoards = array(); } else { $affectedBoards = array($board => array(0, 0)); } // Do all the stickies... if (!empty($stickyCache)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET is_sticky = CASE WHEN is_sticky = {int:is_sticky} THEN 0 ELSE 1 END WHERE id_topic IN ({array_int:sticky_topic_ids})', array('sticky_topic_ids' => $stickyCache, 'is_sticky' => 1)); // Get the board IDs and Sticky status $request = $smcFunc['db_query']('', ' SELECT id_topic, id_board, is_sticky FROM {db_prefix}topics WHERE id_topic IN ({array_int:sticky_topic_ids}) LIMIT ' . count($stickyCache), array('sticky_topic_ids' => $stickyCache)); $stickyCacheBoards = array(); $stickyCacheStatus = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $stickyCacheBoards[$row['id_topic']] = $row['id_board']; $stickyCacheStatus[$row['id_topic']] = empty($row['is_sticky']); } $smcFunc['db_free_result']($request); } // Move sucka! (this is, by the by, probably the most complicated part....) if (!empty($moveCache[0])) { // I know - I just KNOW you're trying to beat the system. Too bad for you... we CHECK :P. $request = $smcFunc['db_query']('', ' SELECT t.id_topic, t.id_board, b.count_posts FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board) WHERE t.id_topic IN ({array_int:move_topic_ids})' . (!empty($board) && !allowedTo('move_any') ? ' AND t.id_member_started = {int:current_member}' : '') . ' LIMIT ' . count($moveCache[0]), array('current_member' => $user_info['id'], 'move_topic_ids' => $moveCache[0])); $moveTos = array(); $moveCache2 = array(); $countPosts = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $to = $moveCache[1][$row['id_topic']]; if (empty($to)) { continue; } // Does this topic's board count the posts or not? $countPosts[$row['id_topic']] = empty($row['count_posts']); if (!isset($moveTos[$to])) { $moveTos[$to] = array(); } $moveTos[$to][] = $row['id_topic']; // For reporting... $moveCache2[] = array($row['id_topic'], $row['id_board'], $to); } $smcFunc['db_free_result']($request); $moveCache = $moveCache2; require_once $sourcedir . '/MoveTopic.php'; // Do the actual moves... foreach ($moveTos as $to => $topics) { moveTopics($topics, $to); } // Does the post counts need to be updated? if (!empty($moveTos)) { $topicRecounts = array(); $request = $smcFunc['db_query']('', ' SELECT id_board, count_posts FROM {db_prefix}boards WHERE id_board IN ({array_int:move_boards})', array('move_boards' => array_keys($moveTos))); while ($row = $smcFunc['db_fetch_assoc']($request)) { $cp = empty($row['count_posts']); // Go through all the topics that are being moved to this board. foreach ($moveTos[$row['id_board']] as $topic) { // If both boards have the same value for post counting then no adjustment needs to be made. if ($countPosts[$topic] != $cp) { // If the board being moved to does count the posts then the other one doesn't so add to their post count. $topicRecounts[$topic] = $cp ? '+' : '-'; } } } $smcFunc['db_free_result']($request); if (!empty($topicRecounts)) { $members = array(); // Get all the members who have posted in the moved topics. $request = $smcFunc['db_query']('', ' SELECT id_member, id_topic FROM {db_prefix}messages WHERE id_topic IN ({array_int:moved_topic_ids})', array('moved_topic_ids' => array_keys($topicRecounts))); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (!isset($members[$row['id_member']])) { $members[$row['id_member']] = 0; } if ($topicRecounts[$row['id_topic']] === '+') { $members[$row['id_member']] += 1; } else { $members[$row['id_member']] -= 1; } } $smcFunc['db_free_result']($request); // And now update them member's post counts foreach ($members as $id_member => $post_adj) { updateMemberData($id_member, array('posts' => 'posts + ' . $post_adj)); } } } } // Now delete the topics... if (!empty($removeCache)) { // They can only delete their own topics. (we wouldn't be here if they couldn't do that..) $result = $smcFunc['db_query']('', ' SELECT id_topic, id_board FROM {db_prefix}topics WHERE id_topic IN ({array_int:removed_topic_ids})' . (!empty($board) && !allowedTo('remove_any') ? ' AND id_member_started = {int:current_member}' : '') . ' LIMIT ' . count($removeCache), array('current_member' => $user_info['id'], 'removed_topic_ids' => $removeCache)); $removeCache = array(); $removeCacheBoards = array(); while ($row = $smcFunc['db_fetch_assoc']($result)) { $removeCache[] = $row['id_topic']; $removeCacheBoards[$row['id_topic']] = $row['id_board']; } $smcFunc['db_free_result']($result); // Maybe *none* were their own topics. if (!empty($removeCache)) { // Gotta send the notifications *first*! foreach ($removeCache as $topic) { // Only log the topic ID if it's not in the recycle board. logAction('remove', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $removeCacheBoards[$topic] ? 'topic' : 'old_topic_id' => $topic, 'board' => $removeCacheBoards[$topic])); sendNotifications($topic, 'remove'); } require_once $sourcedir . '/RemoveTopic.php'; removeTopics($removeCache); } } // Approve the topics... if (!empty($approveCache)) { // We need unapproved topic ids and their authors! $request = $smcFunc['db_query']('', ' SELECT id_topic, id_member_started FROM {db_prefix}topics WHERE id_topic IN ({array_int:approve_topic_ids}) AND approved = {int:not_approved} LIMIT ' . count($approveCache), array('approve_topic_ids' => $approveCache, 'not_approved' => 0)); $approveCache = array(); $approveCacheMembers = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $approveCache[] = $row['id_topic']; $approveCacheMembers[$row['id_topic']] = $row['id_member_started']; } $smcFunc['db_free_result']($request); // Any topics to approve? if (!empty($approveCache)) { // Handle the approval part... approveTopics($approveCache); // Time for some logging! foreach ($approveCache as $topic) { logAction('approve_topic', array('topic' => $topic, 'member' => $approveCacheMembers[$topic])); } } } // And (almost) lastly, lock the topics... if (!empty($lockCache)) { $lockStatus = array(); // Gotta make sure they CAN lock/unlock these topics... if (!empty($board) && !allowedTo('lock_any')) { // Make sure they started the topic AND it isn't already locked by someone with higher priv's. $result = $smcFunc['db_query']('', ' SELECT id_topic, locked, id_board FROM {db_prefix}topics WHERE id_topic IN ({array_int:locked_topic_ids}) AND id_member_started = {int:current_member} AND locked IN (2, 0) LIMIT ' . count($lockCache), array('current_member' => $user_info['id'], 'locked_topic_ids' => $lockCache)); $lockCache = array(); $lockCacheBoards = array(); while ($row = $smcFunc['db_fetch_assoc']($result)) { $lockCache[] = $row['id_topic']; $lockCacheBoards[$row['id_topic']] = $row['id_board']; $lockStatus[$row['id_topic']] = empty($row['locked']); } $smcFunc['db_free_result']($result); } else { $result = $smcFunc['db_query']('', ' SELECT id_topic, locked, id_board FROM {db_prefix}topics WHERE id_topic IN ({array_int:locked_topic_ids}) LIMIT ' . count($lockCache), array('locked_topic_ids' => $lockCache)); $lockCacheBoards = array(); while ($row = $smcFunc['db_fetch_assoc']($result)) { $lockStatus[$row['id_topic']] = empty($row['locked']); $lockCacheBoards[$row['id_topic']] = $row['id_board']; } $smcFunc['db_free_result']($result); } // It could just be that *none* were their own topics... if (!empty($lockCache)) { // Alternate the locked value. $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET locked = CASE WHEN locked = {int:is_locked} THEN ' . (allowedTo('lock_any') ? '1' : '2') . ' ELSE 0 END WHERE id_topic IN ({array_int:locked_topic_ids})', array('locked_topic_ids' => $lockCache, 'is_locked' => 0)); } } if (!empty($markCache)) { $markArray = array(); foreach ($markCache as $topic) { $markArray[] = array($modSettings['maxMsgID'], $user_info['id'], $topic); } $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'), $markArray, array('id_member', 'id_topic')); } foreach ($moveCache as $topic) { // Didn't actually move anything! if (!isset($topic[0])) { break; } logAction('move', array('topic' => $topic[0], 'board_from' => $topic[1], 'board_to' => $topic[2])); sendNotifications($topic[0], 'move'); } foreach ($lockCache as $topic) { logAction($lockStatus[$topic] ? 'lock' : 'unlock', array('topic' => $topic, 'board' => $lockCacheBoards[$topic])); sendNotifications($topic, $lockStatus[$topic] ? 'lock' : 'unlock'); } foreach ($stickyCache as $topic) { logAction($stickyCacheStatus[$topic] ? 'unsticky' : 'sticky', array('topic' => $topic, 'board' => $stickyCacheBoards[$topic])); sendNotifications($topic, 'sticky'); } updateStats('topic'); updateStats('message'); updateSettings(array('calendar_updated' => time())); if (!empty($affectedBoards)) { updateLastMessages(array_keys($affectedBoards)); } redirectexit($redirect_url); }
function UnapprovedPosts() { global $txt, $scripturl, $context, $user_info, $sourcedir, $smcFunc; $context['current_view'] = isset($_GET['sa']) && $_GET['sa'] == 'topics' ? 'topics' : 'replies'; $context['page_title'] = $txt['mc_unapproved_posts']; // Work out what boards we can work in! $approve_boards = boardsAllowedTo('approve_posts'); // If we filtered by board remove ones outside of this board. //!!! Put a message saying we're filtered? if (isset($_REQUEST['brd'])) { $filter_board = array((int) $_REQUEST['brd']); $approve_boards = $approve_boards == array(0) ? $filter_board : array_intersect($approve_boards, $filter_board); } if ($approve_boards == array(0)) { $approve_query = ''; } elseif (!empty($approve_boards)) { $approve_query = ' AND m.id_board IN (' . implode(',', $approve_boards) . ')'; } else { $approve_query = ' AND 0'; } // We also need to know where we can delete topics and/or replies to. if ($context['current_view'] == 'topics') { $delete_own_boards = boardsAllowedTo('remove_own'); $delete_any_boards = boardsAllowedTo('remove_any'); $delete_own_replies = array(); } else { $delete_own_boards = boardsAllowedTo('delete_own'); $delete_any_boards = boardsAllowedTo('delete_any'); $delete_own_replies = boardsAllowedTo('delete_own_replies'); } $toAction = array(); // Check if we have something to do? if (isset($_GET['approve'])) { $toAction[] = (int) $_GET['approve']; } elseif (isset($_GET['delete'])) { $toAction[] = (int) $_GET['delete']; } elseif (isset($_POST['item'])) { foreach ($_POST['item'] as $item) { $toAction[] = (int) $item; } } // What are we actually doing. if (isset($_GET['approve']) || isset($_POST['do']) && $_POST['do'] == 'approve') { $curAction = 'approve'; } elseif (isset($_GET['delete']) || isset($_POST['do']) && $_POST['do'] == 'delete') { $curAction = 'delete'; } // Right, so we have something to do? if (!empty($toAction) && isset($curAction)) { checkSession('request'); // Handy shortcut. $any_array = $curAction == 'approve' ? $approve_boards : $delete_any_boards; // Now for each message work out whether it's actually a topic, and what board it's on. $request = $smcFunc['db_query']('', ' SELECT m.id_msg, m.id_member, m.id_board, t.id_topic, t.id_first_msg, t.id_member_started FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) LEFT JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board) WHERE m.id_msg IN ({array_int:message_list}) AND m.approved = {int:not_approved} AND {query_see_board}', array('message_list' => $toAction, 'not_approved' => 0)); $toAction = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { // If it's not within what our view is ignore it... if ($row['id_msg'] == $row['id_first_msg'] && $context['current_view'] != 'topics' || $row['id_msg'] != $row['id_first_msg'] && $context['current_view'] != 'replies') { continue; } $can_add = false; // If we're approving this is simple. if ($curAction == 'approve' && ($any_array == array(0) || in_array($row['id_board'], $any_array))) { $can_add = true; } elseif ($curAction == 'delete') { // Own post is easy! if ($row['id_member'] == $user_info['id'] && ($delete_own_boards == array(0) || in_array($row['id_board'], $delete_own_boards))) { $can_add = true; } elseif ($row['id_member'] == $row['id_member_started'] && $row['id_msg'] != $row['id_first_msg'] && ($delete_own_replies == array(0) || in_array($row['id_board'], $delete_own_replies))) { $can_add = true; } elseif ($row['id_member'] != $user_info['id'] && ($delete_any_boards == array(0) || in_array($row['id_board'], $delete_any_boards))) { $can_add = true; } } if ($can_add) { $toAction[] = $context['current_view'] == 'topics' ? $row['id_topic'] : $row['id_msg']; } } $smcFunc['db_free_result']($request); // If we have anything left we can actually do the approving (etc). if (!empty($toAction)) { if ($curAction == 'approve') { require_once $sourcedir . '/Subs-Post.php'; if ($context['current_view'] == 'topics') { approveTopics($toAction); } else { approvePosts($toAction); } } else { require_once $sourcedir . '/RemoveTopic.php'; if ($context['current_view'] == 'topics') { removeTopics($toAction); } else { foreach ($toAction as $id) { removeMessage($id); } } } } } // How many unapproved posts are there? $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic AND t.id_first_msg != m.id_msg) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) WHERE m.approved = {int:not_approved} AND {query_see_board} ' . $approve_query, array('not_approved' => 0)); list($context['total_unapproved_posts']) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // What about topics? Normally we'd use the table alias t for topics but lets use m so we don't have to redo our approve query. $request = $smcFunc['db_query']('', ' SELECT COUNT(m.id_topic) FROM {db_prefix}topics AS m INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) WHERE m.approved = {int:not_approved} AND {query_see_board} ' . $approve_query, array('not_approved' => 0)); list($context['total_unapproved_topics']) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=postmod;sa=' . $context['current_view'] . (isset($_REQUEST['brd']) ? ';brd=' . (int) $_REQUEST['brd'] : ''), $_GET['start'], $context['current_view'] == 'topics' ? $context['total_unapproved_topics'] : $context['total_unapproved_posts'], 10); $context['start'] = $_GET['start']; // We have enough to make some pretty tabs! $context[$context['moderation_menu_name']]['tab_data'] = array('title' => $txt['mc_unapproved_posts'], 'help' => 'postmod', 'description' => $txt['mc_unapproved_posts_desc']); // Update the tabs with the correct number of posts. $context['menu_data_' . $context['moderation_menu_id']]['sections']['posts']['areas']['postmod']['subsections']['posts']['label'] .= ' (' . $context['total_unapproved_posts'] . ')'; $context['menu_data_' . $context['moderation_menu_id']]['sections']['posts']['areas']['postmod']['subsections']['topics']['label'] .= ' (' . $context['total_unapproved_topics'] . ')'; // If we are filtering some boards out then make sure to send that along with the links. if (isset($_REQUEST['brd'])) { $context['menu_data_' . $context['moderation_menu_id']]['sections']['posts']['areas']['postmod']['subsections']['posts']['add_params'] = ';brd=' . (int) $_REQUEST['brd']; $context['menu_data_' . $context['moderation_menu_id']]['sections']['posts']['areas']['postmod']['subsections']['topics']['add_params'] = ';brd=' . (int) $_REQUEST['brd']; } // Get all unapproved posts. $request = $smcFunc['db_query']('', ' SELECT m.id_msg, m.id_topic, m.id_board, m.subject, m.body, m.id_member, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.smileys_enabled, t.id_member_started, t.id_first_msg, b.name AS board_name, c.id_cat, c.name AS cat_name FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) WHERE m.approved = {int:not_approved} AND t.id_first_msg ' . ($context['current_view'] == 'topics' ? '=' : '!=') . ' m.id_msg AND {query_see_board} ' . $approve_query . ' LIMIT ' . $context['start'] . ', 10', array('not_approved' => 0)); $context['unapproved_items'] = array(); for ($i = 1; $row = $smcFunc['db_fetch_assoc']($request); $i++) { // Can delete is complicated, let's solve it first... is it their own post? if ($row['id_member'] == $user_info['id'] && ($delete_own_boards == array(0) || in_array($row['id_board'], $delete_own_boards))) { $can_delete = true; } elseif ($row['id_member'] == $row['id_member_started'] && $row['id_msg'] != $row['id_first_msg'] && ($delete_own_replies == array(0) || in_array($row['id_board'], $delete_own_replies))) { $can_delete = true; } elseif ($row['id_member'] != $user_info['id'] && ($delete_any_boards == array(0) || in_array($row['id_board'], $delete_any_boards))) { $can_delete = true; } else { $can_delete = false; } $context['unapproved_items'][] = array('id' => $row['id_msg'], 'alternate' => $i % 2, 'counter' => $context['start'] + $i, 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'subject' => $row['subject'], 'body' => parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), 'time' => timeformat($row['poster_time']), 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member']), 'topic' => array('id' => $row['id_topic']), 'board' => array('id' => $row['id_board'], 'name' => $row['board_name']), 'category' => array('id' => $row['id_cat'], 'name' => $row['cat_name']), 'can_delete' => $can_delete); } $smcFunc['db_free_result']($request); $context['sub_template'] = 'unapproved_posts'; }
/** * Actually delete an account. */ public function action_deleteaccount2() { global $user_info, $context, $cur_profile, $user_profile, $modSettings; // Try get more time... @set_time_limit(600); // @todo Add a way to delete pms as well? if (!$context['user']['is_owner']) { isAllowedTo('profile_remove_any'); } elseif (!allowedTo('profile_remove_any')) { isAllowedTo('profile_remove_own'); } checkSession(); $memID = currentMemberID(); // Check we got here as we should have! if ($cur_profile != $user_profile[$memID]) { fatal_lang_error('no_access', false); } $old_profile =& $cur_profile; // This file is needed for our utility functions. require_once SUBSDIR . '/Members.subs.php'; // Too often, people remove/delete their own only administrative account. if (in_array(1, explode(',', $old_profile['additional_groups'])) || $old_profile['id_group'] == 1) { // Are you allowed to administrate the forum, as they are? isAllowedTo('admin_forum'); $another = isAnotherAdmin($memID); if (empty($another)) { fatal_lang_error('at_least_one_admin', 'critical'); } } // Do you have permission to delete others profiles, or is that your profile you wanna delete? if ($memID != $user_info['id']) { isAllowedTo('profile_remove_any'); // Now, have you been naughty and need your posts deleting? // @todo Should this check board permissions? if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum')) { // Include subs/Topic.subs.php - essential for this type of work! require_once SUBSDIR . '/Topic.subs.php'; require_once SUBSDIR . '/Messages.subs.php'; // First off we delete any topics the member has started - if they wanted topics being done. if ($_POST['remove_type'] == 'topics') { // Fetch all topics started by this user. $topicIDs = topicsStartedBy($memID); // Actually remove the topics. // @todo This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had. removeTopics($topicIDs); } // Now delete the remaining messages. removeNonTopicMessages($memID); } // Only delete this poor member's account if they are actually being booted out of camp. if (isset($_POST['deleteAccount'])) { deleteMembers($memID); } } elseif (!empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum')) { // Setup their account for deletion ;) updateMemberData($memID, array('is_activated' => 4)); // Another account needs approval... updateSettings(array('unapprovedMembers' => true), true); } else { deleteMembers($memID); require_once CONTROLLERDIR . '/Auth.controller.php'; $controller = new Auth_Controller(); $controller->action_logout(true); redirectexit(); } }
function updateTopics($onInstall = false) { if (!$onInstall) { // Don't need to display anything if installing echo "<link rel='stylesheet' type='text/css' media='screen' href='" . XOOPS_URL . "/xoops.css' />\r\n <link rel='stylesheet' type='text/css' media='screen' href='" . xoops_getcss() . "' />\r\n <link rel='stylesheet' type='text/css' media='screen' href='../system/style.css' />"; echo "<table width='100%' border='1' cellpadding='0' cellspacing='2' class='formButton'>"; echo "<tr><th>" . _MI_XHELP_ANNOUNCEMENTS . "</th></tr>"; echo "<tr class='head'><td>" . _XHELP_TEXT_TOPICS_ADDED . "</td></tr>"; } if (!($xhelp_config = removeTopics())) { return false; } //Retrieve list of topics from DB global $xoopsDB; $ret = $xoopsDB->query("SELECT topic_id, topic_title FROM " . $xoopsDB->prefix('topics')); $myTopics = array(); $myTopics[_MI_XHELP_ANNOUNCEMENTS_NONE] = 0; while ($arr = $xoopsDB->fetchArray($ret)) { $myTopics[$arr['topic_title']] = $arr['topic_id']; } $class = 'odd'; foreach ($myTopics as $topic => $value) { $xhelp_id = $xoopsDB->genId($xoopsDB->prefix('configoption') . '_uid_seq'); $sql = sprintf("INSERT INTO %s (confop_id, confop_name, confop_value, conf_id) VALUES (%u, %s, %s, %u)", $xoopsDB->prefix('configoption'), $xhelp_id, $xoopsDB->quoteString($topic), $xoopsDB->quoteString($value), $xhelp_config); if (!($result = $xoopsDB->queryF($sql))) { return false; } if (empty($xhelp_id)) { $xhelp_id = $xoopsDB->getInsertId(); } if (!$onInstall) { // Don't need to display anything if installing echo "<tr class='" . $class . "'><td>" . $topic . "</td></tr>"; $class = $class == 'odd' ? 'even' : 'odd'; } } if (!$onInstall) { // Don't need to display anything if installing echo "<tr class='foot'><td>" . _XHELP_TEXT_UPDATE_COMP . "<br /><br /><input type='button' name='closeWindow' value='" . _XHELP_TEXT_CLOSE_WINDOW . "' class='formButton' onClick=\"javascript:window.opener.location=window.opener.location;window.close();\" /></td></tr>"; echo "</table>"; } }