예제 #1
0
/**
 * 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);
}
예제 #2
0
/**
 * Approve a batch of posts (or topics in their own right)
 *
 * @param int[] $messages
 * @param mixed[] $messageDetails
 * @param string $type = replies
 */
function approveMessages($messages, $messageDetails, $type = 'replies')
{
    if ($type == 'topics') {
        approveTopics($messages);
        // and tell the world about it
        foreach ($messages as $topic) {
            logAction('approve_topic', array('topic' => $topic, 'subject' => $messageDetails[$topic]['subject'], 'member' => $messageDetails[$topic]['member'], 'board' => $messageDetails[$topic]['board']));
        }
    } else {
        require_once SUBSDIR . '/Post.subs.php';
        approvePosts($messages);
        // and tell the world about it again
        foreach ($messages as $post) {
            logAction('approve', array('topic' => $messageDetails[$post]['topic'], 'subject' => $messageDetails[$post]['subject'], 'member' => $messageDetails[$post]['member'], 'board' => $messageDetails[$post]['board']));
        }
    }
}
예제 #3
0
function approveMessages($messages, $messageDetails, $current_view = 'replies')
{
    global $sourcedir;
    require_once $sourcedir . '/lib/Subs-Post.php';
    if ($current_view == 'topics') {
        approveTopics($messages);
        // and tell the world about it
        foreach ($messages as $topic) {
            logAction('approve_topic', array('topic' => $topic, 'subject' => $messageDetails[$topic]['subject'], 'member' => $messageDetails[$topic]['member'], 'board' => $messageDetails[$topic]['board']));
        }
    } else {
        approvePosts($messages);
        // and tell the world about it again
        foreach ($messages as $post) {
            logAction('approve', array('topic' => $messageDetails[$post]['topic'], 'subject' => $messageDetails[$post]['subject'], 'member' => $messageDetails[$post]['member'], 'board' => $messageDetails[$post]['board']));
        }
    }
}
예제 #4
0
function ApproveMessage()
{
    global $user_info, $topic, $board, $sourcedir, $smcFunc;
    checkSession('get');
    $_REQUEST['msg'] = (int) $_REQUEST['msg'];
    require_once $sourcedir . '/Subs-Post.php';
    isAllowedTo('approve_posts');
    $request = $smcFunc['db_query']('', '
		SELECT t.id_member_started, t.id_first_msg, m.id_member, m.subject, m.approved
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
		WHERE m.id_msg = {int:id_msg}
			AND m.id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic, 'id_msg' => $_REQUEST['msg']));
    list($starter, $first_msg, $poster, $subject, $approved) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // If it's the first in a topic then the whole topic gets approved!
    if ($first_msg == $_REQUEST['msg']) {
        approveTopics($topic, !$approved);
        if ($starter != $user_info['id']) {
            logAction('approve_topic', array('topic' => $topic, 'subject' => $subject, 'member' => $starter, 'board' => $board));
        }
    } else {
        approvePosts($_REQUEST['msg'], !$approved);
        if ($poster != $user_info['id']) {
            logAction('approve', array('topic' => $topic, 'subject' => $subject, 'member' => $poster, 'board' => $board));
        }
    }
    redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']);
}
예제 #5
0
 /**
  * Approve a post, just the one.
  */
 public function action_approve()
 {
     global $user_info, $topic, $board;
     checkSession('get');
     $current_msg = (int) $_REQUEST['msg'];
     require_once SUBSDIR . '/Topic.subs.php';
     require_once SUBSDIR . '/Post.subs.php';
     require_once SUBSDIR . '/Messages.subs.php';
     isAllowedTo('approve_posts');
     $message_info = basicMessageInfo($current_msg, false, true);
     // If it's the first in a topic then the whole topic gets approved!
     if ($message_info['id_first_msg'] == $current_msg) {
         approveTopics($topic, !$message_info['approved']);
         if ($message_info['id_member_started'] != $user_info['id']) {
             logAction(($message_info['approved'] ? 'un' : '') . 'approve_topic', array('topic' => $topic, 'subject' => $message_info['subject'], 'member' => $message_info['id_member_started'], 'board' => $board));
         }
     } else {
         approvePosts($current_msg, !$message_info['approved']);
         if ($message_info['id_member'] != $user_info['id']) {
             logAction(($message_info['approved'] ? 'un' : '') . 'approve', array('topic' => $topic, 'subject' => $message_info['subject'], 'member' => $message_info['id_member'], 'board' => $board));
         }
     }
     cache_put_data('num_menu_errors', null, 900);
     redirectexit('topic=' . $topic . '.msg' . $current_msg . '#msg' . $current_msg);
 }