/**
  * Completely remove an entire topic.
  * Redirects to the board when completed.
  * Accessed by ?action=removetopic2
  */
 public function action_removetopic2()
 {
     global $user_info, $topic, $board, $modSettings;
     // Make sure they aren't being lead around by someone. (:@)
     checkSession('get');
     // This file needs to be included for sendNotifications().
     require_once SUBSDIR . '/Notification.subs.php';
     // This needs to be included for all the topic db functions
     require_once SUBSDIR . '/Topic.subs.php';
     // Trying to fool us around, are we?
     if (empty($topic)) {
         redirectexit();
     }
     $this->removeDeleteConcurrence();
     $topic_info = getTopicInfo($topic, 'message');
     if ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('remove_any')) {
         isAllowedTo('remove_own');
     } else {
         isAllowedTo('remove_any');
     }
     // Can they see the topic?
     if ($modSettings['postmod_active'] && !$topic_info['approved'] && $topic_info['id_member_started'] != $user_info['id']) {
         isAllowedTo('approve_posts');
     }
     // Notify people that this topic has been removed.
     sendNotifications($topic, 'remove');
     removeTopics($topic);
     // Note, only log topic ID in native form if it's not gone forever.
     if (allowedTo('remove_any') || allowedTo('remove_own') && $topic_info['id_member_started'] == $user_info['id']) {
         logAction('remove', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $board ? 'topic' : 'old_topic_id' => $topic, 'subject' => $topic_info['subject'], 'member' => $topic_info['id_member_started'], 'board' => $board));
     }
     redirectexit('board=' . $board . '.0');
 }
Example #2
0
/**
 * Completely remove an entire topic.
 * Redirects to the board when completed.
 */
function RemoveTopic2()
{
    global $user_info, $topic, $board, $sourcedir, $smcFunc, $context, $modSettings;
    // Make sure they aren't being lead around by someone. (:@)
    checkSession('get');
    // This file needs to be included for sendNotifications().
    require_once $sourcedir . '/Subs-Post.php';
    // Trying to fool us around, are we?
    if (empty($topic)) {
        redirectexit();
    }
    removeDeleteConcurrence();
    $request = $smcFunc['db_query']('', '
		SELECT t.id_member_started, ms.subject, t.approved
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic));
    list($starter, $subject, $approved) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    if ($starter == $user_info['id'] && !allowedTo('remove_any')) {
        isAllowedTo('remove_own');
    } else {
        isAllowedTo('remove_any');
    }
    // Can they see the topic?
    if ($modSettings['postmod_active'] && !$approved && $starter != $user_info['id']) {
        isAllowedTo('approve_posts');
    }
    // Notify people that this topic has been removed.
    sendNotifications($topic, 'remove');
    removeTopics($topic);
    // Note, only log topic ID in native form if it's not gone forever.
    if (allowedTo('remove_any') || allowedTo('remove_own') && $starter == $user_info['id']) {
        logAction('remove', array(empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $board ? 'topic' : 'old_topic_id' => $topic, 'subject' => $subject, 'member' => $starter, 'board' => $board));
    }
    redirectexit('board=' . $board . '.0');
}
Example #3
0
function RemoveTopic2()
{
    global $ID_MEMBER, $db_prefix, $topic, $board, $sourcedir;
    // Make sure they aren't being lead around by someone. (:@)
    checkSession('get');
    // This file needs to be included for sendNotifications().
    require_once $sourcedir . '/Subs-Post.php';
    $request = db_query("\n\t\tSELECT t.ID_MEMBER_STARTED, ms.subject\n\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS ms)\n\t\tWHERE t.ID_TOPIC = {$topic}\n\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\tLIMIT 1", __FILE__, __LINE__);
    list($starter, $subject) = mysql_fetch_row($request);
    mysql_free_result($request);
    if ($starter == $ID_MEMBER && !allowedTo('remove_any')) {
        isAllowedTo('remove_own');
    } else {
        isAllowedTo('remove_any');
    }
    // Notify people that this topic has been removed.
    sendNotifications($topic, 'remove');
    removeTopics($topic);
    if (allowedTo('remove_any') && (!allowedTo('remove_own') || $starter != $ID_MEMBER)) {
        logAction('remove', array('topic' => $topic, 'subject' => $subject, 'member' => $starter));
    }
    redirectexit('board=' . $board . '.0');
}
Example #4
0
function mob_m_move_topic($rpcmsg)
{
    global $mobdb, $context, $sourcedir, $topic, $board, $user_info;
    require_once $sourcedir . '/Subs-Post.php';
    require_once $sourcedir . '/Subs-Boards.php';
    $topicinfo = get_topicinfo($rpcmsg->getScalarValParam(0));
    $newboard = get_boardinfo($rpcmsg->getScalarValParam(1));
    if (empty($topicinfo) || empty($newboard)) {
        mob_error('topic not found');
    }
    $topic = $topicinfo['id_topic'];
    $board = $topicinfo['id_board'];
    loadBoard();
    loadPermissions();
    if (!(allowedTo('move_any') || allowedTo('move_own') && $topicinfo['id_member_started'] == $user_info['id']) || $board == $newboard['id_board']) {
        mob_error('cannot move topic');
    }
    // Send the notifications
    logAction('move', array('topic' => $topicinfo['id_topic'], 'board_from' => $board, 'board_to' => $newboard['id_board']));
    sendNotifications($topic, 'move');
    move_topic($topic, $board, $newboard, $topicinfo);
    // Return the true response
    return new xmlrpcresp(new xmlrpcval(array('result' => new xmlrpcval(true, 'boolean')), 'struct'));
}
    /**
     * Set merge options and do the actual merge of two or more topics.
     *
     * the merge options screen:
     * * shows topics to be merged and allows to set some merge options.
     * * is accessed by ?action=mergetopics;sa=options.and can also internally be called by action_quickmod().
     * * uses 'merge_extra_options' sub template of the MergeTopics template.
     *
     * the actual merge:
     * * is accessed with ?action=mergetopics;sa=execute.
     * * updates the statistics to reflect the merge.
     * * logs the action in the moderation log.
     * * sends a notification is sent to all users monitoring this topic.
     * * redirects to ?action=mergetopics;sa=done.
     *
     * @param int[] $topics = array() of topic ids
     */
    public function action_mergeExecute($topics = array())
    {
        global $user_info, $txt, $context, $scripturl, $modSettings;
        $db = database();
        // Check the session.
        checkSession('request');
        require_once SUBSDIR . '/Topic.subs.php';
        require_once SUBSDIR . '/Post.subs.php';
        // Handle URLs from action_mergeIndex.
        if (!empty($_GET['from']) && !empty($_GET['to'])) {
            $topics = array((int) $_GET['from'], (int) $_GET['to']);
        }
        // If we came from a form, the topic IDs came by post.
        if (!empty($_POST['topics']) && is_array($_POST['topics'])) {
            $topics = $_POST['topics'];
        }
        // There's nothing to merge with just one topic...
        if (empty($topics) || !is_array($topics) || count($topics) == 1) {
            fatal_lang_error('merge_need_more_topics');
        }
        // Make sure every topic is numeric, or some nasty things could be done with the DB.
        foreach ($topics as $id => $topic) {
            $topics[$id] = (int) $topic;
        }
        // Joy of all joys, make sure they're not pi**ing about with unapproved topics they can't see :P
        if ($modSettings['postmod_active']) {
            $can_approve_boards = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts');
        }
        // Get info about the topics and polls that will be merged.
        $request = $db->query('', '
			SELECT
				t.id_topic, t.id_board, t.id_poll, t.num_views, t.is_sticky, t.approved, t.num_replies, t.unapproved_posts,
				m1.subject, m1.poster_time AS time_started, IFNULL(mem1.id_member, 0) AS id_member_started, IFNULL(mem1.real_name, m1.poster_name) AS name_started,
				m2.poster_time AS time_updated, IFNULL(mem2.id_member, 0) AS id_member_updated, IFNULL(mem2.real_name, m2.poster_name) AS name_updated
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg)
				INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg)
				LEFT JOIN {db_prefix}members AS mem1 ON (mem1.id_member = m1.id_member)
				LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
			WHERE t.id_topic IN ({array_int:topic_list})
			ORDER BY t.id_first_msg
			LIMIT ' . count($topics), array('topic_list' => $topics));
        if ($db->num_rows($request) < 2) {
            fatal_lang_error('no_topic_id');
        }
        $num_views = 0;
        $is_sticky = 0;
        $boardTotals = array();
        $topic_data = array();
        $boards = array();
        $polls = array();
        $firstTopic = 0;
        while ($row = $db->fetch_assoc($request)) {
            // Make a note for the board counts...
            if (!isset($boardTotals[$row['id_board']])) {
                $boardTotals[$row['id_board']] = array('num_posts' => 0, 'num_topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
            }
            // We can't see unapproved topics here?
            if ($modSettings['postmod_active'] && !$row['approved'] && $can_approve_boards != array(0) && in_array($row['id_board'], $can_approve_boards)) {
                continue;
            } elseif (!$row['approved']) {
                $boardTotals[$row['id_board']]['unapproved_topics']++;
            } else {
                $boardTotals[$row['id_board']]['num_topics']++;
            }
            $boardTotals[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts'];
            $boardTotals[$row['id_board']]['num_posts'] += $row['num_replies'] + ($row['approved'] ? 1 : 0);
            $topic_data[$row['id_topic']] = array('id' => $row['id_topic'], 'board' => $row['id_board'], 'poll' => $row['id_poll'], 'num_views' => $row['num_views'], 'subject' => $row['subject'], 'started' => array('time' => standardTime($row['time_started']), 'html_time' => htmlTime($row['time_started']), 'timestamp' => forum_time(true, $row['time_started']), 'href' => empty($row['id_member_started']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_started'], 'link' => empty($row['id_member_started']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_started'] . '">' . $row['name_started'] . '</a>'), 'updated' => array('time' => standardTime($row['time_updated']), 'html_time' => htmlTime($row['time_updated']), 'timestamp' => forum_time(true, $row['time_updated']), 'href' => empty($row['id_member_updated']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_updated'], 'link' => empty($row['id_member_updated']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_updated'] . '">' . $row['name_updated'] . '</a>'));
            $num_views += $row['num_views'];
            $boards[] = $row['id_board'];
            // If there's no poll, id_poll == 0...
            if ($row['id_poll'] > 0) {
                $polls[] = $row['id_poll'];
            }
            // Store the id_topic with the lowest id_first_msg.
            if (empty($firstTopic)) {
                $firstTopic = $row['id_topic'];
            }
            $is_sticky = max($is_sticky, $row['is_sticky']);
        }
        $db->free_result($request);
        // If we didn't get any topics then they've been messing with unapproved stuff.
        if (empty($topic_data)) {
            fatal_lang_error('no_topic_id');
        }
        $boards = array_values(array_unique($boards));
        // The parameters of action_mergeExecute were set, so this must've been an internal call.
        if (!empty($topics)) {
            isAllowedTo('merge_any', $boards);
            loadTemplate('MergeTopics');
        }
        // Get the boards a user is allowed to merge in.
        $merge_boards = boardsAllowedTo('merge_any');
        if (empty($merge_boards)) {
            fatal_lang_error('cannot_merge_any', 'user');
        }
        require_once SUBSDIR . '/Boards.subs.php';
        // Make sure they can see all boards....
        $query_boards = array('boards' => $boards);
        if (!in_array(0, $merge_boards)) {
            $query_boards['boards'] = array_merge($query_boards['boards'], $merge_boards);
        }
        // Saved in a variable to (potentially) save a query later
        $boards_info = fetchBoardsInfo($query_boards);
        // This happens when a member is moderator of a board he cannot see
        foreach ($boards as $board) {
            if (!isset($boards_info[$board])) {
                fatal_lang_error('no_board');
            }
        }
        if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options') {
            if (count($polls) > 1) {
                $request = $db->query('', '
					SELECT t.id_topic, t.id_poll, m.subject, p.question
					FROM {db_prefix}polls AS p
						INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
						INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
					WHERE p.id_poll IN ({array_int:polls})
					LIMIT ' . count($polls), array('polls' => $polls));
                while ($row = $db->fetch_assoc($request)) {
                    $context['polls'][] = array('id' => $row['id_poll'], 'topic' => array('id' => $row['id_topic'], 'subject' => $row['subject']), 'question' => $row['question'], 'selected' => $row['id_topic'] == $firstTopic);
                }
                $db->free_result($request);
            }
            if (count($boards) > 1) {
                foreach ($boards_info as $row) {
                    $context['boards'][] = array('id' => $row['id_board'], 'name' => $row['name'], 'selected' => $row['id_board'] == $topic_data[$firstTopic]['board']);
                }
            }
            $context['topics'] = $topic_data;
            foreach ($topic_data as $id => $topic) {
                $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic;
            }
            $context['page_title'] = $txt['merge'];
            $context['sub_template'] = 'merge_extra_options';
            return;
        }
        // Determine target board.
        $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];
        if (!in_array($target_board, $boards)) {
            fatal_lang_error('no_board');
        }
        // Determine which poll will survive and which polls won't.
        $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0);
        if ($target_poll > 0 && !in_array($target_poll, $polls)) {
            fatal_lang_error('no_access', false);
        }
        $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll));
        // Determine the subject of the newly merged topic - was a custom subject specified?
        if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '') {
            $target_subject = strtr(Util::htmltrim(Util::htmlspecialchars($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
            // Keep checking the length.
            if (Util::strlen($target_subject) > 100) {
                $target_subject = Util::substr($target_subject, 0, 100);
            }
            // Nothing left - odd but pick the first topics subject.
            if ($target_subject == '') {
                $target_subject = $topic_data[$firstTopic]['subject'];
            }
        } elseif (!empty($topic_data[(int) $_POST['subject']]['subject'])) {
            $target_subject = $topic_data[(int) $_POST['subject']]['subject'];
        } else {
            $target_subject = $topic_data[$firstTopic]['subject'];
        }
        // Get the first and last message and the number of messages....
        $request = $db->query('', '
			SELECT approved, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg, COUNT(*) AS message_count
			FROM {db_prefix}messages
			WHERE id_topic IN ({array_int:topics})
			GROUP BY approved
			ORDER BY approved DESC', array('topics' => $topics));
        $topic_approved = 1;
        $first_msg = 0;
        while ($row = $db->fetch_assoc($request)) {
            // If this is approved, or is fully unapproved.
            if ($row['approved'] || !isset($first_msg)) {
                $first_msg = $row['first_msg'];
                $last_msg = $row['last_msg'];
                if ($row['approved']) {
                    $num_replies = $row['message_count'] - 1;
                    $num_unapproved = 0;
                } else {
                    $topic_approved = 0;
                    $num_replies = 0;
                    $num_unapproved = $row['message_count'];
                }
            } else {
                // If this has a lower first_msg then the first post is not approved and hence the number of replies was wrong!
                if ($first_msg > $row['first_msg']) {
                    $first_msg = $row['first_msg'];
                    $num_replies++;
                    $topic_approved = 0;
                }
                $num_unapproved = $row['message_count'];
            }
        }
        $db->free_result($request);
        // Ensure we have a board stat for the target board.
        if (!isset($boardTotals[$target_board])) {
            $boardTotals[$target_board] = array('num_posts' => 0, 'num_topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
        }
        // Fix the topic count stuff depending on what the new one counts as.
        if ($topic_approved) {
            $boardTotals[$target_board]['num_topics']--;
        } else {
            $boardTotals[$target_board]['unapproved_topics']--;
        }
        $boardTotals[$target_board]['unapproved_posts'] -= $num_unapproved;
        $boardTotals[$target_board]['num_posts'] -= $topic_approved ? $num_replies + 1 : $num_replies;
        // Get the member ID of the first and last message.
        $request = $db->query('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_msg IN ({int:first_msg}, {int:last_msg})
			ORDER BY id_msg
			LIMIT 2', array('first_msg' => $first_msg, 'last_msg' => $last_msg));
        list($member_started) = $db->fetch_row($request);
        list($member_updated) = $db->fetch_row($request);
        // First and last message are the same, so only row was returned.
        if ($member_updated === null) {
            $member_updated = $member_started;
        }
        $db->free_result($request);
        // Obtain all the message ids we are going to affect.
        $affected_msgs = messagesInTopics($topics);
        // Assign the first topic ID to be the merged topic.
        $id_topic = min($topics);
        // Grab the response prefix (like 'Re: ') in the default forum language.
        $context['response_prefix'] = response_prefix();
        $enforce_subject = isset($_POST['enforce_subject']) ? Util::htmlspecialchars(trim($_POST['enforce_subject'])) : '';
        // Merge topic notifications.
        $notifications = isset($_POST['notifications']) && is_array($_POST['notifications']) ? array_intersect($topics, $_POST['notifications']) : array();
        fixMergedTopics($first_msg, $topics, $id_topic, $target_board, $target_subject, $enforce_subject, $notifications);
        // Asssign the properties of the newly merged topic.
        $db->query('', '
			UPDATE {db_prefix}topics
			SET
				id_board = {int:id_board},
				id_member_started = {int:id_member_started},
				id_member_updated = {int:id_member_updated},
				id_first_msg = {int:id_first_msg},
				id_last_msg = {int:id_last_msg},
				id_poll = {int:id_poll},
				num_replies = {int:num_replies},
				unapproved_posts = {int:unapproved_posts},
				num_views = {int:num_views},
				is_sticky = {int:is_sticky},
				approved = {int:approved}
			WHERE id_topic = {int:id_topic}', array('id_board' => $target_board, 'is_sticky' => $is_sticky, 'approved' => $topic_approved, 'id_topic' => $id_topic, 'id_member_started' => $member_started, 'id_member_updated' => $member_updated, 'id_first_msg' => $first_msg, 'id_last_msg' => $last_msg, 'id_poll' => $target_poll, 'num_replies' => $num_replies, 'unapproved_posts' => $num_unapproved, 'num_views' => $num_views));
        // Get rid of the redundant polls.
        if (!empty($deleted_polls)) {
            require_once SUBSDIR . '/Poll.subs.php';
            removePoll($deleted_polls);
        }
        // Cycle through each board...
        foreach ($boardTotals as $id_board => $stats) {
            decrementBoard($id_board, $stats);
        }
        // Determine the board the final topic resides in
        $topic_info = getTopicInfo($id_topic);
        $id_board = $topic_info['id_board'];
        // Update all the statistics.
        updateStats('topic');
        updateStats('subject', $id_topic, $target_subject);
        updateLastMessages($boards);
        logAction('merge', array('topic' => $id_topic, 'board' => $id_board));
        // Notify people that these topics have been merged?
        require_once SUBSDIR . '/Notification.subs.php';
        sendNotifications($id_topic, 'merge');
        // If there's a search index that needs updating, update it...
        require_once SUBSDIR . '/Search.subs.php';
        $searchAPI = findSearchAPI();
        if (is_callable(array($searchAPI, 'topicMerge'))) {
            $searchAPI->topicMerge($id_topic, $topics, $affected_msgs, empty($enforce_subject) ? null : array($context['response_prefix'], $target_subject));
        }
        // Send them to the all done page.
        redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board);
    }
Example #6
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);
}
Example #7
0
function Sticky()
{
    global $modSettings, $topic, $board, $sourcedir;
    // Make sure the user can sticky it, and they are stickying *something*.
    isAllowedTo('make_sticky');
    // You shouldn't be able to (un)sticky a topic if the setting is disabled.
    if (empty($modSettings['enableStickyTopics'])) {
        fatal_lang_error('cannot_make_sticky', false);
    }
    // You can't sticky a board or something!
    if (empty($topic)) {
        fatal_lang_error('not_a_topic', false);
    }
    checkSession('get');
    // We need Subs-Post.php for the sendNotifications() function.
    require_once $sourcedir . '/lib/Subs-Post.php';
    // Is this topic already stickied, or no?
    $request = smf_db_query('
		SELECT is_sticky
		FROM {db_prefix}topics
		WHERE id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic));
    list($is_sticky) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Toggle the sticky value.... pretty simple ;).
    smf_db_query('
		UPDATE {db_prefix}topics
		SET is_sticky = {int:is_sticky}
		WHERE id_topic = {int:current_topic}', array('current_topic' => $topic, 'is_sticky' => empty($is_sticky) ? 1 : 0));
    // Log this sticky action - always a moderator thing.
    logAction(empty($is_sticky) ? 'sticky' : 'unsticky', array('topic' => $topic, 'board' => $board));
    // Notify people that this topic has been stickied?
    if (empty($is_sticky)) {
        sendNotifications($topic, 'sticky');
    }
    // Take them back to the now stickied topic.
    redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
}
Example #8
0
function displayForm($formframe, $entry = "", $mainform = "", $done_dest = "", $button_text = "", $settings = "", $titleOverride = "", $overrideValue = "", $overrideMulti = "", $overrideSubMulti = "", $viewallforms = 0, $profileForm = 0, $printall = 0, $screen = null)
{
    include_once XOOPS_ROOT_PATH . '/modules/formulize/include/functions.php';
    include_once XOOPS_ROOT_PATH . '/modules/formulize/include/extract.php';
    formulize_benchmark("Start of formDisplay.");
    if ($titleOverride == "formElementsOnly") {
        $titleOverride = "all";
        $formElementsOnly = true;
    }
    if (!is_numeric($titleOverride) and $titleOverride != "" and $titleOverride != "all") {
        // we can pass in a text title for the form, and that will cause the $titleOverride "all" behaviour to be invoked, and meanwhile we will use this title for the top of the form
        $passedInTitle = $titleOverride;
        $titleOverride = "all";
    }
    //syntax:
    //displayform($formframe, $entry, $mainform)
    //$formframe is the id of the form OR title of the form OR name of the framework.  Can also be an array.  If it is an array, then flag 'formframe' is the $formframe variable, and flag 'elements' is an array of all the elements that are to be displayed.
    //the array option is intended for displaying only part of a form at a time
    //$entry is the numeric entry to display in the form -- if $entry is the word 'proxy' then it is meant to force a new form entry when the form is a single-entry form that the user already may have an entry in
    //$mainform is the starting form to use, if this is a framework (can be specified by form id or by handle)
    //$done_dest is the URL to go to after the form has been submitted
    //Steps:
    //1. identify form or framework
    //2. if framework, check for unified display options
    //3. if entry specified, then get data for that entry
    //4. drawform with data if necessary
    global $xoopsDB, $xoopsUser, $myts;
    global $sfidsDrawn;
    if (!is_array($sfidsDrawn)) {
        $sfidsDrawn = array();
    }
    $groups = $xoopsUser ? $xoopsUser->getGroups() : array(0 => XOOPS_GROUP_ANONYMOUS);
    $original_entry = $entry;
    // flag used to tell whether the function was called with an actual entry specified, ie: we're supposed to be editing this entry, versus the entry being set by coming back form a sub_form or other situation.
    $mid = getFormulizeModId();
    $currentURL = getCurrentURL();
    /* Alter currentURL if necessary.
     * Display list of entries screen on-click of form buttons "Save and Leave" and "Leave Page".
     */
    if (isset($_GET['sid'])) {
        $curr_screen = xoops_getmodulehandler('screen', 'formulize')->get($_GET['sid']);
        if ($curr_screen->getVar('type') == 'form') {
            $currentURL = $_SERVER['PHP_SELF'] . "?fid=" . $curr_screen->form_id();
        }
    } elseif (isset($_GET['ve']) && isset($_GET['fid'])) {
        $currentURL = $_SERVER['PHP_SELF'] . "?fid=" . $_GET['fid'];
    }
    // identify form or framework
    $elements_allowed = "";
    // if a screen object is passed in, select the elements for display based on the screen's settings
    if ($screen and is_a($screen, "formulizeFormScreen")) {
        $elements_allowed = $screen->getVar("formelements");
    }
    if (is_array($formframe)) {
        $elements_allowed = $formframe['elements'];
        $printViewPages = isset($formframe['pages']) ? $formframe['pages'] : "";
        $printViewPageTitles = isset($formframe['pagetitles']) ? $formframe['pagetitles'] : "";
        $formframetemp = $formframe['formframe'];
        unset($formframe);
        $formframe = $formframetemp;
    }
    list($fid, $frid) = getFormFramework($formframe, $mainform);
    if ($_POST['deletesubsflag']) {
        // if deletion of sub entries requested
        foreach ($_POST as $k => $v) {
            if (strstr($k, "delbox")) {
                $subs_to_del[] = $v;
            }
        }
        if (count($subs_to_del) > 0) {
            deleteFormEntries($subs_to_del, intval($_POST['deletesubsflag']));
            // deletesubsflag will be the sub form id
            sendNotifications($_POST['deletesubsflag'], "delete_entry", $subs_to_del, $mid, $groups);
        }
    }
    if ($_POST['parent_form']) {
        // if we're coming back from a subform
        $entry = $_POST['parent_entry'];
        $fid = $_POST['parent_form'];
    }
    if ($_POST['go_back_form']) {
        // we just received a subform submission
        $entry = $_POST['sub_submitted'];
        $fid = $_POST['sub_fid'];
        $go_back['form'] = $_POST['go_back_form'];
        $go_back['entry'] = $_POST['go_back_entry'];
    }
    // set $entry in the case of a form_submission where we were editing an entry (just in case that entry is not what is used to call this function in the first place -- ie: we're on a subform and the mainform has no entry specified, or we're clicking submit over again on a single-entry form where we started with no entry)
    $entrykey = "entry" . $fid;
    if ((!$entry or $entry == "proxy") and $_POST[$entrykey]) {
        // $entrykey will only be set when *editing* an entry, not on new saves
        $entry = $_POST[$entrykey];
    }
    // this is probably not necessary any more, due to architecture changes in Formulize 3
    // formulize_newEntryIds is set when saving data
    if (!$entry and isset($GLOBALS['formulize_newEntryIds'][$fid])) {
        $entry = $GLOBALS['formulize_newEntryIds'][$fid][0];
    }
    $member_handler =& xoops_gethandler('member');
    $gperm_handler =& xoops_gethandler('groupperm');
    if ($profileForm === "new") {
        // spoof the $groups array based on the settings for the regcode that has been validated by register.php
        $reggroupsq = q("SELECT reg_codes_groups FROM " . XOOPS_DB_PREFIX . "_reg_codes WHERE reg_codes_code=\"" . $GLOBALS['regcode'] . "\"");
        $groups = explode("&8(%\$", $reggroupsq[0]['reg_codes_groups']);
        if ($groups[0] === "") {
            unset($groups);
        }
        // if a code has no groups associated with it, then kill the null value that will be in position 0 in the groups array.
        $groups[] = XOOPS_GROUP_USERS;
        $groups[] = XOOPS_GROUP_ANONYMOUS;
    }
    $uid = $xoopsUser ? $xoopsUser->getVar('uid') : '0';
    $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid);
    $single = $single_result['flag'];
    // if we're looking at a single entry form with no entry specified and where the user has no entry of their own, or it's an anonymous user, then set the entry based on a cookie if one is present
    // want to do this check here and override $entry prior to the security check since we don't like trusting cookies!
    $cookie_entry = (isset($_COOKIE['entryid_' . $fid]) and !$entry and $single and ($single_result['entry'] == "" or intval($uid) === 0)) ? $_COOKIE['entryid_' . $fid] : "";
    include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php";
    $data_handler = new formulizeDataHandler($fid);
    if ($cookie_entry) {
        // check to make sure the cookie_entry exists...
        //$check_cookie_entry = q("SELECT id_req FROM " . $xoopsDB->prefix("formulize_form") . " WHERE id_req=" . intval($cookie_entry));
        //if($check_cookie_entry[0]['id_req'] > 0) {
        if ($data_handler->entryExists(intval($cookie_entry))) {
            $entry = $cookie_entry;
        } else {
            $cookie_entry = "";
        }
    }
    $owner = ($cookie_entry and $uid) ? $uid : getEntryOwner($entry, $fid);
    // if we're pulling a cookie value and there is a valid UID in effect, then assume this user owns the entry, otherwise, figure out who does own the entry
    $owner_groups = $data_handler->getEntryOwnerGroups($entry);
    if ($single and !$entry and !$overrideMulti and $profileForm !== "new") {
        // only adjust the active entry if we're not already looking at an entry, and there is no overrideMulti which can be used to display a new blank form even on a single entry form -- useful for when multiple anonymous users need to be able to enter information in a form that is "one per user" for registered users. -- the pressence of a cookie on the hard drive of a user will override other settings
        $entry = $single_result['entry'];
        $owner = getEntryOwner($entry, $fid);
        unset($owner_groups);
        //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE);
        $owner_groups = $data_handler->getEntryOwnerGroups($entry);
    }
    if ($entry == "proxy") {
        $entry = "";
    }
    // convert the proxy flag to the actual null value expected for new entry situations (do this after the single check!)
    $editing = is_numeric($entry);
    // will be true if there is an entry we're looking at already
    if (!($scheck = security_check($fid, $entry, $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms and !$profileForm) {
        print "<p>" . _NO_PERM . "</p>";
        return;
    }
    // main security check passed, so let's initialize flags
    $go_back['url'] = substr($done_dest, 0, 1) == "/" ? XOOPS_URL . $done_dest : $done_dest;
    // set these arrays for the one form, and they are added to by the framework if it is in effect
    $fids[0] = $fid;
    if ($entry) {
        $entries[$fid][0] = $entry;
    } else {
        $entries[$fid][0] = "";
    }
    if ($frid) {
        $linkResults = checkForLinks($frid, $fids, $fid, $entries, $gperm_handler, $owner_groups, $mid, $member_handler, $owner, true);
        // final true means only include entries from unified display linkages
        unset($entries);
        unset($fids);
        $fids = $linkResults['fids'];
        $entries = $linkResults['entries'];
        $sub_fids = $linkResults['sub_fids'];
        $sub_entries = $linkResults['sub_entries'];
    }
    // need to handle submission of entries
    $formulize_mgr =& xoops_getmodulehandler('elements', 'formulize');
    $info_received_msg = 0;
    $info_continue = 0;
    if ($entries[$fid][0]) {
        $info_continue = 1;
    }
    $add_own_entry = $gperm_handler->checkRight("add_own_entry", $fid, $groups, $mid);
    $add_proxy_entries = $gperm_handler->checkRight("add_proxy_entries", $fid, $groups, $mid);
    if ($_POST['form_submitted'] and $profileForm !== "new" and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
        $info_received_msg = "1";
        // flag for display of info received message
        if (!isset($GLOBALS['formulize_readElementsWasRun'])) {
            include_once XOOPS_ROOT_PATH . "/modules/formulize/include/readelements.php";
        }
        $temp_entries = $GLOBALS['formulize_allWrittenEntryIds'];
        // set in readelements.php
        if (!$formElementsOnly and ($single or $_POST['target_sub'] or $entries[$fid][0] and ($original_entry or $_POST[$entrykey] and !$_POST['back_from_sub']) or $overrideMulti or $_POST['go_back_form'] and $overrideSubMulti)) {
            // if we just did a submission on a single form, or we just edited a multi, then assume the identity of the new entry.  Can be overridden by values passed to this function, to force multi forms to redisplay the just-saved entry.  Back_from_sub is used to override the override, when we're saving after returning from a multi-which is like editing an entry since entries are saved prior to going to a sub. -- Sept 4 2006: adding an entry in a subform forces us to stay on the same page too! -- Dec 21 2011: added check for !$formElementsOnly so that when we're getting just the elements in the form, we ignore any possible overriding, since that is an API driven situation where the called entry is the only one we want to display, period.
            $entry = $temp_entries[$fid][0];
            unset($entries);
            foreach ($fids as $thisWrittenFid) {
                $entries[$thisWrittenFid] = $temp_entries[$thisWrittenFid];
            }
            // also remove any fids that aren't part of the $temp_entries...added Oct 26 2011...checkforlinks now can return the mainform when we're on a sub!  It's smarter, but displayForm (and possibly other places) were not built to assume it was that smart.
            $writtenFids = array_keys($temp_entries);
            $fids = array_intersect($fids, $writtenFids);
            $owner = getEntryOwner($entry, $fid);
            unset($owner_groups);
            $owner_groups = $data_handler->getEntryOwnerGroups($entry);
            //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE);
            $info_continue = 1;
        } elseif (!$_POST['target_sub']) {
            // as long as the form was submitted and we're not going to a sub form, then display the info received message and carry on with a blank form
            if (!$original_entry) {
                // if we're on a multi-form where the display form function was called without an entry, then clear the entries and behave as if we're doing a new add
                unset($entries);
                unset($sub_entries);
                $entries[$fid][0] = "";
                $sub_entries[$sub_fids[0]][0] = "";
            }
            $info_continue = 2;
        }
    }
    $sub_entries_synched = synchSubformBlankDefaults($fid, $entry);
    foreach ($sub_entries_synched as $synched_sfid => $synched_ids) {
        foreach ($synched_ids as $synched_id) {
            $sub_entries[$synched_sfid][] = $synched_id;
        }
    }
    if (count($sub_entries_synched) > 0) {
        formulize_updateDerivedValues($entry, $fid, $frid);
    }
    // special use of $settings added August 2 2006 -- jwe -- break out of form if $settings so indicates
    // used to allow saving of information when you don't want the form itself to reappear
    if ($settings == "{RETURNAFTERSAVE}" and $_POST['form_submitted']) {
        return "returning_after_save";
    }
    // need to add code here to switch some things around if we're on a subform for the first time (add)
    // note: double nested sub forms will not work currently, since on the way back to the intermediate level, the go_back values will not be set correctly
    // target_sub is only set when adding a sub entry, and adding sub entries is now down by the subform ui
    //if($_POST['target_sub'] OR $_POST['goto_sfid']) {
    if ($_POST['goto_sfid']) {
        $info_continue = 0;
        if ($_POST['goto_sfid']) {
            $new_fid = $_POST['goto_sfid'];
        } else {
            $new_fid = $_POST['target_sub'];
        }
        $go_back['form'] = $fid;
        $go_back['entry'] = $temp_entries[$fid][0];
        unset($entries);
        unset($fids);
        unset($sub_fids);
        unset($sub_entries);
        $fid = $new_fid;
        $fids[0] = $new_fid;
        if ($_POST['target_sub']) {
            // if we're adding a new entry
            $entries[$new_fid][0] = "";
        } else {
            // if we're going to an existing entry
            $entries[$new_fid][0] = $_POST['goto_sub'];
        }
        $entry = $entries[$new_fid][0];
        $single_result = getSingle($fid, $uid, $groups, $member_handler, $gperm_handler, $mid);
        $single = $single_result['flag'];
        if ($single and !$entry) {
            $entry = $single_result['entry'];
            unset($entries);
            $entries[$fid][0] = $entry;
        }
        unset($owner);
        $owner = getEntryOwner($entries[$new_fid][0], $new_fid);
        $editing = is_numeric($entry);
        unset($owner_groups);
        //$owner_groups =& $member_handler->getGroupsByUser($owner, FALSE);
        $newFidData_handler = new formulizeDataHandler($new_fid);
        $owner_groups = $newFidData_handler->getEntryOwnerGroups($entries[$new_fid][0]);
        $info_received_msg = 0;
        // never display this message when a subform is displayed the first time.
        if ($entry) {
            $info_continue = 1;
        }
        if (!($scheck = security_check($fid, $entries[$fid][0], $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) {
            print "<p>" . _NO_PERM . "</p>";
            return;
        }
    }
    // there are several points above where $entry is set, and now that we have a final value, store in ventry
    if ($entry > 0 and (!isset($settings['ventry']) or "addnew" != $settings['ventry'])) {
        $settings['ventry'] = $entry;
    }
    // set the alldoneoverride if necessary -- August 22 2006
    $config_handler =& xoops_gethandler('config');
    $formulizeConfig = $config_handler->getConfigsByCat(0, $mid);
    // remove the all done button if the config option says 'no', and we're on a single-entry form, or the function was called to look at an existing entry, or we're on an overridden Multi-entry form
    $allDoneOverride = (!$formulizeConfig['all_done_singles'] and !$profileForm and (($single or $overrideMulti or $original_entry) and !$_POST['target_sub'] and !$_POST['goto_sfid'] and !$_POST['deletesubsflag'] and !$_POST['parent_form'])) ? true : false;
    if (($allDoneOverride or isset($_POST['save_and_leave']) and $_POST['save_and_leave']) and $_POST['form_submitted']) {
        drawGoBackForm($go_back, $currentURL, $settings, $entry);
        print "<script type=\"text/javascript\">window.document.go_parent.submit();</script>\n";
        return;
    } else {
        // only do all this stuff below, the normal form displaying stuff, if we are not leaving this page now due to the all done button being overridden
        // we cannot have the back logic above invoked when dealing with a subform, but if the override is supposed to be in place, then we need to invoke it
        if (!$allDoneOverride and !$formulizeConfig['all_done_singles'] and !$profileForm and ($_POST['target_sub'] or $_POST['goto_sfid'] or $_POST['deletesubsflag'] or $_POST['parent_form']) and ($single or $original_entry or $overrideMulti)) {
            $allDoneOverride = true;
        }
        /*if($uid==1) {
        		print "Forms: ";
        		print_r($fids);
        		print "<br>Entries: ";
        		print_r($entries);
        		print "<br>Subforms: ";
        		print_r($sub_fids);
        		print "<br>Subentries: ";
        		print_r($sub_entries); // debug block - ONLY VISIBLE TO USER 1 RIGHT NOW 
        		} */
        formulize_benchmark("Ready to start building form.");
        $title = "";
        foreach ($fids as $this_fid) {
            if (!($scheck = security_check($this_fid, $entries[$this_fid][0], $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) {
                continue;
            }
            // if there is more than one form, try to make the 1-1 links
            // and if we made any, then include the newly linked up entries
            // in the index of entries that we're keeping track of
            if (count($fids) > 1) {
                list($form1s, $form2s, $form1EntryIds, $form2EntryIds) = formulize_makeOneToOneLinks($frid, $this_fid);
                foreach ($form1EntryIds as $i => $form1EntryId) {
                    // $form1EntryId set above, now set other values for this iteration based on the key
                    $form2EntryId = $form2EntryIds[$i];
                    $form1 = $form1s[$i];
                    $form2 = $form2s[$i];
                    if ($form1EntryId) {
                        $entries[$form1][0] = $form1EntryId;
                    }
                    if ($form2EntryId) {
                        $entries[$form2][0] = $form2EntryId;
                    }
                }
            }
            unset($prevEntry);
            // if there is an entry, then get the data for that entry
            if ($entries[$this_fid]) {
                $groupEntryWithUpdateRights = ($single == "group" and $gperm_handler->checkRight("update_own_entry", $fid, $groups, $mid) and $entry == $single_result['entry']);
                $prevEntry = getEntryValues($entries[$this_fid][0], $formulize_mgr, $groups, $this_fid, $elements_allowed, $mid, $uid, $owner, $groupEntryWithUpdateRights);
            }
            // display the form
            //get the form title: (do only once)
            $firstform = 0;
            if (!$form) {
                $firstform = 1;
                $title = isset($passedInTitle) ? $passedInTitle : trans(getFormTitle($this_fid));
                if ($screen) {
                    $title = trans($screen->getVar('title'));
                }
                unset($form);
                if ($formElementsOnly) {
                    $form = new formulize_elementsOnlyForm($title, 'formulize', "{$currentURL}", "post", true);
                } else {
                    // extended class that puts formulize element names into the tr tags for the table, so we can show/hide them as required
                    $form = new formulize_themeForm($title, 'formulize', "{$currentURL}", "post", true);
                    // necessary to trigger the proper reloading of the form page, until Done is called and that form does not have this flag.
                    if (!isset($settings['ventry'])) {
                        $settings['ventry'] = 'new';
                    }
                    $form->addElement(new XoopsFormHidden('ventry', $settings['ventry']));
                }
                $form->setExtra("enctype='multipart/form-data'");
                // impératif!
                if (is_array($settings)) {
                    $form = writeHiddenSettings($settings, $form);
                }
                // include who the entry belongs to and the date
                // include acknowledgement that information has been updated if we have just done a submit
                // form_meta includes: last_update, created, last_update_by, created_by
                $breakHTML = "";
                if (!$profileForm and $titleOverride != "all") {
                    // build the break HTML and then add the break to the form
                    if (!strstr($currentURL, "printview.php")) {
                        $breakHTML .= "<center class=\"no-print\">";
                        $breakHTML .= "<p><b>";
                        if ($info_received_msg) {
                            $breakHTML .= _formulize_INFO_SAVED . "&nbsp;";
                        }
                        if ($info_continue == 1 and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
                            $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_CONTINUE1 . "</p>";
                        } elseif ($info_continue == 2) {
                            $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_CONTINUE2 . "</p>";
                        } elseif (!$entry and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
                            $breakHTML .= "<p class=\"no-print\">" . _formulize_INFO_MAKENEW . "</p>";
                        }
                        $breakHTML .= "</b></p>";
                        $breakHTML .= "</center>";
                    }
                    $breakHTML .= "<table cellpadding=5 width=100%><tr><td width=50% style=\"vertical-align: bottom;\">";
                    $breakHTML .= "<p><b>" . _formulize_FD_ABOUT . "</b><br>";
                    if ($entries[$this_fid][0]) {
                        $form_meta = getMetaData($entries[$this_fid][0], $member_handler, $this_fid);
                        $breakHTML .= _formulize_FD_CREATED . $form_meta['created_by'] . " " . formulize_formatDateTime($form_meta['created']) . "<br>" . _formulize_FD_MODIFIED . $form_meta['last_update_by'] . " " . formulize_formatDateTime($form_meta['last_update']) . "</p>";
                    } else {
                        $breakHTML .= _formulize_FD_NEWENTRY . "</p>";
                    }
                    $breakHTML .= "</td><td width=50% style=\"vertical-align: bottom;\">";
                    if (strstr($currentURL, "printview.php") or !formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
                        $breakHTML .= "<p>";
                    } else {
                        // get save and button button options
                        $save_button_text = "";
                        $done_button_text = "";
                        if (is_array($button_text)) {
                            $save_button_text = $button_text[1];
                            $done_button_text = $button_text[0];
                        } else {
                            $done_button_text = $button_text;
                        }
                        if (!$done_button_text and !$allDoneOverride) {
                            $done_button_text = _formulize_INFO_DONE1 . _formulize_DONE . _formulize_INFO_DONE2;
                        } elseif ($done_button_text != "{NOBUTTON}" and !$allDoneOverride) {
                            $done_button_text = _formulize_INFO_DONE1 . $done_button_text . _formulize_INFO_DONE2;
                            // check to see if the user is allowed to modify the existing entry, and if they're not, then we have to draw in the all done button so they have a way of getting back where they're going
                        } elseif ($entry and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry) or !$entry) {
                            $done_button_text = "";
                        } else {
                            $done_button_text = _formulize_INFO_DONE1 . _formulize_DONE . _formulize_INFO_DONE2;
                        }
                        $nosave = false;
                        if (!$save_button_text and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
                            $save_button_text = _formulize_INFO_SAVEBUTTON;
                        } elseif ($save_button_text != "{NOBUTTON}" and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
                            $save_button_text = _formulize_INFO_SAVE1 . $save_button_text . _formulize_INFO_SAVE2;
                        } else {
                            $save_button_text = _formulize_INFO_NOSAVE;
                            $nosave = true;
                        }
                        $breakHTML .= "<p class='no-print'>" . $save_button_text;
                        if ($done_button_text) {
                            $breakHTML .= "<br>" . $done_button_text;
                        }
                    }
                    $breakHTML .= "</p></td></tr></table>";
                    $form->insertBreak($breakHTML, "even");
                } elseif ($profileForm) {
                    // if we have a profile form, put the profile fields at the top of the form, populated based on the DB values from the _users table
                    $form = addProfileFields($form, $profileForm);
                }
            }
            if ($titleOverride == "1" and !$firstform) {
                // set onetooneTitle flag to 1 when function invoked to force drawing of the form title over again
                $title = trans(getFormTitle($this_fid));
                $form->insertBreak("<table><th>{$title}</th></table>", "");
            }
            // if this form has a parent, then determine the $parentLinks
            if ($go_back['form'] and !$parentLinks[$this_fid]) {
                $parentLinks[$this_fid] = getParentLinks($this_fid, $frid);
            }
            formulize_benchmark("Before Compile Elements.");
            $form = compileElements($this_fid, $form, $formulize_mgr, $prevEntry, $entries[$this_fid][0], $go_back, $parentLinks[$this_fid], $owner_groups, $groups, $overrideValue, $elements_allowed, $profileForm, $frid, $mid, $sub_entries, $sub_fids, $member_handler, $gperm_handler, $title, $screen, $printViewPages, $printViewPageTitles);
            formulize_benchmark("After Compile Elements.");
        }
        // end of for each fids
        if (!is_object($form)) {
            exit("Error: the form cannot be displayed.  Does the current group have permission to access the form?");
        }
        // DRAW IN THE SPECIAL UI FOR A SUBFORM LINK (ONE TO MANY)
        if (count($sub_fids) > 0) {
            // if there are subforms, then draw them in...only once we have a bonafide entry in place already
            // draw in special params for this form, but only once per page
            global $formulize_subformHiddenFieldsDrawn;
            if ($formulize_subformHiddenFieldsDrawn != true) {
                $formulize_subformHiddenFieldsDrawn = true;
                $form->addElement(new XoopsFormHidden('target_sub', ''));
                $form->addElement(new XoopsFormHidden('target_sub_instance', ''));
                $form->addElement(new XoopsFormHidden('numsubents', 1));
                $form->addElement(new XoopsFormHidden('del_subs', ''));
                $form->addElement(new XoopsFormHidden('goto_sub', ''));
                $form->addElement(new XoopsFormHidden('goto_sfid', ''));
            }
            foreach ($sub_fids as $subform_id) {
                // only draw in the subform UI if the subform hasn't been drawn in previously, courtesy of a subform element in the form.
                // Subform elements are recommended since they provide 1. specific placement, 2. custom captions, 3. direct choice of form elements to include
                if (in_array($subform_id, $sfidsDrawn) or $elements_allowed or !($scheck = security_check($subform_id, "", $uid, $owner, $groups, $mid, $gperm_handler)) and !$viewallforms) {
                    // no entry passed so this will simply check whether they have permission for the form or not
                    continue;
                }
                $subUICols = drawSubLinks($subform_id, $sub_entries, $uid, $groups, $frid, $mid, $fid, $entry);
                unset($subLinkUI);
                if (isset($subUICols['single'])) {
                    $form->insertBreak($subUICols['single'], "even");
                } else {
                    $subLinkUI = new XoopsFormLabel($subUICols['c1'], $subUICols['c2']);
                    $form->addElement($subLinkUI);
                }
            }
        }
        // draw in proxy box if necessary (only if they have permission and only on new entries, not on edits)
        if (!strstr($_SERVER['PHP_SELF'], "formulize/printview.php")) {
            if ($gperm_handler->checkRight("add_proxy_entries", $fid, $groups, $mid) and !$entries[$fid][0]) {
                $form = addOwnershipList($form, $groups, $member_handler, $gperm_handler, $fid, $mid);
            } elseif ($entries[$fid][0] and $gperm_handler->checkRight("update_entry_ownership", $fid, $groups, $mid)) {
                $form = addOwnershipList($form, $groups, $member_handler, $gperm_handler, $fid, $mid, $entries[$fid][0]);
            }
        }
        // draw in the submitbutton if necessary
        if (!$formElementsOnly and formulizePermHandler::user_can_edit_entry($fid, $uid, $entry)) {
            $form = addSubmitButton($form, _formulize_SAVE, $go_back, $currentURL, $button_text, $settings, $temp_entries[$this_fid][0], $fids, $formframe, $mainform, $entry, $profileForm, $elements_allowed, $allDoneOverride, $printall, $screen);
        }
        if (!$formElementsOnly) {
            // add flag to indicate that the form has been submitted
            $form->addElement(new XoopsFormHidden('form_submitted', "1"));
            if ($go_back['form']) {
                // if this is set, then we're doing a subform, so put in a flag to prevent the parent from being drawn again on submission
                $form->addElement(new XoopsFormHidden('sub_fid', $fid));
                $form->addElement(new XoopsFormHidden('sub_submitted', $entries[$fid][0]));
                $form->addElement(new XoopsFormHidden('go_back_form', $go_back['form']));
                $form->addElement(new XoopsFormHidden('go_back_entry', $go_back['entry']));
            } else {
                // drawing a main form...put in the scroll position flag
                $form->addElement(new XoopsFormHidden('yposition', 0));
            }
            // saving message
            print "<div id=savingmessage style=\"display: none; position: absolute; width: 100%; right: 0px; text-align: center; padding-top: 50px;\">\n";
            global $xoopsConfig;
            if (file_exists(XOOPS_ROOT_PATH . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif")) {
                print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-" . $xoopsConfig['language'] . ".gif\">\n";
            } else {
                print "<img src=\"" . XOOPS_URL . "/modules/formulize/images/saving-english.gif\">\n";
            }
            print "</div>\n";
            drawJavascript($nosave);
            if (count($GLOBALS['formulize_renderedElementHasConditions']) > 0) {
                drawJavascriptForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $entries, $sub_entries);
            }
            print $form->addElement(new xoopsFormHidden('save_and_leave', 0));
            // lastly, put in a hidden element, that will tell us what the first, primary form was that we were working with on this form submission
            $form->addElement(new XoopsFormHidden('primaryfid', $fids[0]));
        }
        global $formulize_governingElements;
        global $formulize_oneToOneElements;
        global $formulize_oneToOneMetaData;
        if (!is_array($formulize_governingElements)) {
            $formulize_governingElements = array();
        }
        if (!is_array($formulize_oneToOneElements)) {
            $oneToOneElements = array();
        }
        if (!is_array($oneToOneMetaData)) {
            $oneToOneMetaData = array();
        }
        if (count($GLOBALS['formulize_renderedElementHasConditions']) > 0) {
            $governingElements1 = compileGoverningElementsForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $entries, $sub_entries);
            foreach ($governingElements1 as $key => $value) {
                $oneToOneElements[$key] = false;
            }
            $formulize_governingElements = mergeGoverningElements($formulize_governingElements, $governingElements1);
        }
        // add in any onetoone elements that we need to deal with at the same time (in case their joining key value changes on the fly)
        if (count($fids) > 1) {
            $i = 1;
            while ($i <= count($fids)) {
                $relationship_handler = xoops_getmodulehandler('frameworks', 'formulize');
                $relationship = $relationship_handler->get($frid);
                foreach ($relationship->getVar('links') as $thisLink) {
                    if ($thisLink->getVar('form1') == $fids[$i]) {
                        $keyElement = $thisLink->getVar('key2');
                        break;
                    } elseif ($thisLink->getVar('form2') == $fids[$i]) {
                        $keyElement = $thisLink->getVar('key1');
                        break;
                    }
                }
                // prepare to loop through elements for the rendered entry, or 'new', if there is no rendered entry
                $entryToLoop = isset($entries[$fids[$i]][0]) ? $entries[$fids[$i]][0] : null;
                if (!$entryToLoop and isset($GLOBALS['formulize_renderedElementsForForm'][$fids[$i]]['new'])) {
                    $entryToLoop = 'new';
                }
                foreach ($GLOBALS['formulize_renderedElementsForForm'][$fids[$i]][$entryToLoop] as $renderedMarkupName => $thisElement) {
                    $GLOBALS['formulize_renderedElementHasConditions'][$renderedMarkupName] = $thisElement;
                    $governingElements2 = _compileGoverningElements($entries, _getElementObject($keyElement), $renderedMarkupName);
                    foreach ($governingElements2 as $key => $value) {
                        $formulize_oneToOneElements[$key] = true;
                        $formulize_oneToOneMetaData[$key] = array('onetoonefrid' => $frid, 'onetoonefid' => $fid, 'onetooneentries' => urlencode(serialize($entries)), 'onetoonefids' => urlencode(serialize($fids)));
                    }
                    $formulize_governingElements = mergeGoverningElements($formulize_governingElements, $governingElements2);
                }
                $i++;
            }
        }
        if (count($formulize_governingElements) > 0 and !$formElementsOnly) {
            // render this once at the end of rendering the main form!
            drawJavascriptForConditionalElements($GLOBALS['formulize_renderedElementHasConditions'], $formulize_governingElements, $formulize_oneToOneElements, $formulize_oneToOneMetaData);
        }
        $idForForm = $formElementsOnly ? "" : "id=\"formulizeform\"";
        // when rendering disembodied forms, don't use the master id!
        print "<div {$idForForm}>" . $form->render() . "</div><!-- end of formulizeform -->";
        // note, security token is included in the form by the xoops themeform render method, that's why there's no explicity references to the token in the compiling/generation of the main form object
        // floating save button
        if ($printall != 2 and $formulizeConfig['floatSave'] and !strstr($currentURL, "printview.php") and !$formElementsOnly) {
            print "<div id=floattest></div>";
            if ($done_text != "{NOBUTTON}" or $save_text != "{NOBUTTON}") {
                print "<div id=floatingsave>";
                if ($subButtonText == _formulize_SAVE) {
                    if ($save_text) {
                        $subButtonText = $save_text;
                    }
                    if ($subButtonText != "{NOBUTTON}") {
                        print "<input type='button' name='submitx' id='submitx' class=floatingsavebuttons onclick=javascript:validateAndSubmit(); value='" . _formulize_SAVE . "' >";
                        print "<input type='button' name='submit_save_and_leave' id='submit_save_and_leave' class=floatingsavebuttons onclick=javascript:validateAndSubmit('leave'); value='" . _formulize_SAVE_AND_LEAVE . "' >";
                    }
                }
                if (($button_text != "{NOBUTTON}" and !$done_text or isset($done_text) and $done_text != "{NOBUTTON}") and !$allDoneOverride) {
                    if ($done_text) {
                        $button_text = $done_text_temp;
                    }
                    print "<input type='button' class=floatingsavebuttons onclick=javascript:verifyDone(); value='" . _formulize_DONE . "' >";
                }
                print "</div>";
            }
        }
        // end floating save button
        // if we're in Drupal, include the main XOOPS js file, so the calendar will work if present...
        // assumption is that the calendar javascript has already been included by the datebox due to no
        // $xoopsTpl being in effect in Drupal -- this assumption will fail if Drupal is displaying a pageworks
        // page that uses the $xoopsTpl, for instance.  (Date select box file itself checks for $xoopsTpl)
        global $user;
        static $includedXoopsJs = false;
        if (is_object($user) and !$includedXoopsJs) {
            print "<script type=\"text/javascript\" src=\"" . XOOPS_URL . "/include/xoops.js\"></script>\n";
            $includedXoopsJs = true;
        }
    }
    // end of if we're not going back to the prev page because of an all done button override
}
Example #9
0
 /**
  * Execute the move of a topic.
  * It is called on the submit of action_movetopic.
  * This function logs that topics have been moved in the moderation log.
  * If the member is the topic starter requires the move_own permission,
  * otherwise requires the move_any permission.
  * Upon successful completion redirects to message index.
  * Accessed via ?action=movetopic2.
  *
  * @uses subs/Post.subs.php.
  */
 public function action_movetopic2()
 {
     global $txt, $board, $topic, $scripturl, $context, $language, $user_info;
     if (empty($topic)) {
         fatal_lang_error('no_access', false);
     }
     // You can't choose to have a redirection topic and use an empty reason.
     if (isset($_POST['postRedirect']) && (!isset($_POST['reason']) || trim($_POST['reason']) == '')) {
         fatal_lang_error('movetopic_no_reason', false);
     }
     // You have to tell us were you are moving to
     if (!isset($_POST['toboard'])) {
         fatal_lang_error('movetopic_no_board', false);
     }
     // We will need this
     require_once SUBSDIR . '/Topic.subs.php';
     moveTopicConcurrence();
     // Make sure this form hasn't been submitted before.
     checkSubmitOnce('check');
     // Get the basic details on this topic
     $topic_info = getTopicInfo($topic);
     $context['is_approved'] = $topic_info['approved'];
     // Can they see it?
     if (!$context['is_approved']) {
         isAllowedTo('approve_posts');
     }
     // Can they move topics on this board?
     if (!allowedTo('move_any')) {
         if ($topic_info['id_member_started'] == $user_info['id']) {
             isAllowedTo('move_own');
         } else {
             isAllowedTo('move_any');
         }
     }
     checkSession();
     require_once SUBSDIR . '/Post.subs.php';
     require_once SUBSDIR . '/Boards.subs.php';
     // The destination board must be numeric.
     $toboard = (int) $_POST['toboard'];
     // Make sure they can see the board they are trying to move to (and get whether posts count in the target board).
     $board_info = boardInfo($toboard, $topic);
     if (empty($board_info)) {
         fatal_lang_error('no_board');
     }
     // Remember this for later.
     $_SESSION['move_to_topic'] = array('move_to' => $toboard);
     // Rename the topic...
     if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '') {
         $custom_subject = strtr(Util::htmltrim(Util::htmlspecialchars($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
         // Keep checking the length.
         if (Util::strlen($custom_subject) > 100) {
             $custom_subject = Util::substr($custom_subject, 0, 100);
         }
         // If it's still valid move onwards and upwards.
         if ($custom_subject != '') {
             $all_messages = isset($_POST['enforce_subject']);
             if ($all_messages) {
                 // Get a response prefix, but in the forum's default language.
                 $context['response_prefix'] = response_prefix();
                 topicSubject($topic_info, $custom_subject, $context['response_prefix'], $all_messages);
             } else {
                 topicSubject($topic_info, $custom_subject);
             }
             // Fix the subject cache.
             updateStats('subject', $topic, $custom_subject);
         }
     }
     // Create a link to this in the old board.
     // @todo Does this make sense if the topic was unapproved before? I'd just about say so.
     if (isset($_POST['postRedirect'])) {
         // Should be in the boardwide language.
         if ($user_info['language'] != $language) {
             loadLanguage('index', $language);
         }
         $reason = Util::htmlspecialchars($_POST['reason'], ENT_QUOTES);
         preparsecode($reason);
         // Add a URL onto the message.
         $reason = strtr($reason, array($txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $toboard . '.0]' . $board_info['name'] . '[/url]', $txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'));
         // Auto remove this MOVED redirection topic in the future?
         $redirect_expires = !empty($_POST['redirect_expires']) ? (int) $_POST['redirect_expires'] : 0;
         // Redirect to the MOVED topic from topic list?
         $redirect_topic = isset($_POST['redirect_topic']) ? $topic : 0;
         // And remember the last expiry period too.
         $_SESSION['move_to_topic']['redirect_topic'] = $redirect_topic;
         $_SESSION['move_to_topic']['redirect_expires'] = $redirect_expires;
         $msgOptions = array('subject' => $txt['moved'] . ': ' . $board_info['subject'], 'body' => $reason, 'icon' => 'moved', 'smileys_enabled' => 1);
         $topicOptions = array('board' => $board, 'lock_mode' => 1, 'mark_as_read' => true, 'redirect_expires' => empty($redirect_expires) ? 0 : $redirect_expires * 60 + time(), 'redirect_topic' => $redirect_topic);
         $posterOptions = array('id' => $user_info['id'], 'update_post_count' => empty($board_info['count_posts']));
         createPost($msgOptions, $topicOptions, $posterOptions);
     }
     $board_from = boardInfo($board);
     if ($board_from['count_posts'] != $board_info['count_posts']) {
         $posters = postersCount($topic);
         foreach ($posters as $id_member => $posts) {
             // The board we're moving from counted posts, but not to.
             if (empty($board_from['count_posts'])) {
                 updateMemberData($id_member, array('posts' => 'posts - ' . $posts));
             } else {
                 updateMemberData($id_member, array('posts' => 'posts + ' . $posts));
             }
         }
     }
     // Do the move (includes statistics update needed for the redirect topic).
     moveTopics($topic, $toboard);
     // Log that they moved this topic.
     if (!allowedTo('move_own') || $topic_info['id_member_started'] != $user_info['id']) {
         logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $toboard));
     }
     // Notify people that this topic has been moved?
     require_once SUBSDIR . '/Notification.subs.php';
     sendNotifications($topic, 'move');
     // Why not go back to the original board in case they want to keep moving?
     if (!isset($_REQUEST['goback'])) {
         redirectexit('board=' . $board . '.0');
     } else {
         redirectexit('topic=' . $topic . '.0');
     }
 }
Example #10
0
function MoveTopic2()
{
    global $txt, $board, $topic, $scripturl, $sourcedir, $modSettings, $context;
    global $db_prefix, $ID_MEMBER, $board, $language, $user_info, $func;
    // Make sure this form hasn't been submitted before.
    checkSubmitOnce('check');
    $request = db_query("\n\t\tSELECT ID_MEMBER_STARTED, ID_FIRST_MSG\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_TOPIC = {$topic}\n\t\tLIMIT 1", __FILE__, __LINE__);
    list($ID_MEMBER_STARTED, $ID_FIRST_MSG) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Can they move topics on this board?
    if (!allowedTo('move_any')) {
        if ($ID_MEMBER_STARTED == $ID_MEMBER) {
            isAllowedTo('move_own');
            $boards = array_merge(boardsAllowedTo('move_own'), boardsAllowedTo('move_any'));
        } else {
            isAllowedTo('move_any');
        }
    } else {
        $boards = boardsAllowedTo('move_any');
    }
    checkSession();
    require_once $sourcedir . '/Subs-Post.php';
    // The destination board must be numeric.
    $_POST['toboard'] = (int) $_POST['toboard'];
    // !!!
    /*if (!in_array($_POST['toboard'], $boards) && !in_array(0, $boards))
    		fatal_lang_error('smf232');*/
    // Make sure they can see the board they are trying to move to (and get whether posts count in the target board).
    $request = db_query("\n\t\tSELECT b.countPosts, b.name, m.subject\n\t\tFROM ({$db_prefix}boards AS b, {$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\tWHERE {$user_info['query_see_board']}\n\t\t\tAND b.ID_BOARD = {$_POST['toboard']}\n\t\t\tAND t.ID_TOPIC = {$topic}\n\t\t\tAND m.ID_MSG = t.ID_FIRST_MSG\n\t\tLIMIT 1", __FILE__, __LINE__);
    if (mysql_num_rows($request) == 0) {
        fatal_lang_error('smf232');
    }
    list($pcounter, $board_name, $subject) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Remember this for later.
    $_SESSION['move_to_topic'] = $_POST['toboard'];
    // Rename the topic...
    if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '') {
        $_POST['custom_subject'] = $func['htmlspecialchars']($_POST['custom_subject']);
        if (isset($_POST['enforce_subject'])) {
            // Get a response prefix, but in the forum's default language.
            if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
                if ($language === $user_info['language']) {
                    $context['response_prefix'] = $txt['response_prefix'];
                } else {
                    loadLanguage('index', $language, false);
                    $context['response_prefix'] = $txt['response_prefix'];
                    loadLanguage('index');
                }
                cache_put_data('response_prefix', $context['response_prefix'], 600);
            }
            db_query("\n\t\t\t\tUPDATE {$db_prefix}messages\n\t\t\t\tSET subject = '{$context['response_prefix']}{$_POST['custom_subject']}'\n\t\t\t\tWHERE ID_TOPIC = {$topic}", __FILE__, __LINE__);
        }
        db_query("\n\t\t\tUPDATE {$db_prefix}messages\n\t\t\tSET subject = '{$_POST['custom_subject']}'\n\t\t\tWHERE ID_MSG = {$ID_FIRST_MSG}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        // Fix the subject cache.
        updateStats('subject', $topic, $_POST['custom_subject']);
    }
    // Create a link to this in the old board.
    if (isset($_POST['postRedirect'])) {
        // Should be in the boardwide language.
        if ($user_info['language'] != $language) {
            loadLanguage('index', $language);
        }
        $_POST['reason'] = $func['htmlspecialchars']($_POST['reason'], ENT_QUOTES);
        preparsecode($_POST['reason']);
        // Add a URL onto the message.
        $_POST['reason'] = strtr($_POST['reason'], array($txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . ']' . addslashes($board_name) . '[/url]', $txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'));
        $msgOptions = array('subject' => addslashes($txt['smf56'] . ': ' . $subject), 'body' => $_POST['reason'], 'icon' => 'moved', 'smileys_enabled' => 1);
        $topicOptions = array('board' => $board, 'lock_mode' => 1, 'mark_as_read' => true);
        $posterOptions = array('id' => $ID_MEMBER, 'update_post_count' => !empty($pcounter));
        createPost($msgOptions, $topicOptions, $posterOptions);
    }
    $request = db_query("\n\t\tSELECT countPosts\n\t\tFROM {$db_prefix}boards\n\t\tWHERE ID_BOARD = {$board}\n\t\tLIMIT 1", __FILE__, __LINE__);
    list($pcounter_from) = mysql_fetch_row($request);
    mysql_free_result($request);
    if ($pcounter_from != $pcounter) {
        $request = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_TOPIC = {$topic}", __FILE__, __LINE__);
        $posters = array();
        while ($row = mysql_fetch_assoc($request)) {
            $posters[] = $row['ID_MEMBER'];
        }
        mysql_free_result($request);
        // The board we're moving from counted posts, but not to.
        if (empty($pcounter_from)) {
            updateMemberData($posters, array('posts' => '-'));
        } else {
            updateMemberData($posters, array('posts' => '+'));
        }
    }
    // Do the move (includes statistics update needed for the redirect topic).
    moveTopics($topic, $_POST['toboard']);
    // Log that they moved this topic.
    if (!allowedTo('move_own') || $ID_MEMBER_STARTED != $ID_MEMBER) {
        logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $_POST['toboard']));
    }
    // Notify people that this topic has been moved?
    sendNotifications($topic, 'move');
    // Update the cache?
    if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] == 3) {
        cache_put_data('topic_board-' . $topic, null, 120);
    }
    // Why not go back to the original board in case they want to keep moving?
    if (!isset($_REQUEST['goback'])) {
        redirectexit('board=' . $board . '.0');
    } else {
        redirectexit('topic=' . $topic . '.0');
    }
}
Example #11
0
function QuickModeration()
{
    global $db_prefix, $sourcedir, $board, $ID_MEMBER, $modSettings, $sourcedir;
    // Check the session = get or post.
    checkSession('request');
    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('markread');
    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());
        $redirect_url = 'board=' . $board . '.' . $_REQUEST['start'];
    } else {
        // !!! Ugly.  There's no getting around this, is there?
        $boards_can = array('make_sticky' => boardsAllowedTo('make_sticky'), 'move_any' => boardsAllowedTo('move_any'), 'move_own' => boardsAllowedTo('move_own'), 'remove_any' => boardsAllowedTo('remove_any'), 'remove_own' => boardsAllowedTo('remove_own'), 'lock_any' => boardsAllowedTo('lock_any'), 'lock_own' => boardsAllowedTo('lock_own'), 'merge_any' => boardsAllowedTo('merge_any'));
        $redirect_url = isset($_POST['redirect_url']) ? $_POST['redirect_url'] : (isset($_SESSION['old_url']) ? $_SESSION['old_url'] : '');
    }
    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';
    }
    // 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 that *aren't* on this board.
        $request = db_query("\n\t\t\tSELECT ID_TOPIC, ID_MEMBER_STARTED, ID_BOARD, locked\n\t\t\tFROM {$db_prefix}topics\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', array_keys($_REQUEST['actions'])) . ")" . (!empty($board) ? "\n\t\t\t\tAND ID_BOARD != {$board}" : '') . "\n\t\t\tLIMIT " . count($_REQUEST['actions']), __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            if (!empty($board)) {
                unset($_REQUEST['actions'][$row['ID_TOPIC']]);
            } else {
                // Goodness, this is fun.  We need to validate the action.
                if ($_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'] != $ID_MEMBER || !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'] != $ID_MEMBER || !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'] != $ID_MEMBER || $locked == 1 || !in_array(0, $boards_can['lock_own']) && !in_array($row['ID_BOARD'], $boards_can['lock_own']))) {
                    unset($_REQUEST['actions'][$row['ID_TOPIC']]);
                }
            }
        }
        mysql_free_result($request);
    }
    $stickyCache = array();
    $moveCache = array(0 => array(), 1 => array());
    $removeCache = array();
    $lockCache = array();
    $markCache = 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') {
            // $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;
        }
    }
    if (empty($board)) {
        $affectedBoards = array();
    } else {
        $affectedBoards = array($board => array(0, 0));
    }
    // Do all the stickies...
    if (!empty($stickyCache)) {
        db_query("\n\t\t\tUPDATE {$db_prefix}topics\n\t\t\tSET isSticky = IF(isSticky = 1, 0, 1)\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $stickyCache) . ")\n\t\t\tLIMIT " . count($stickyCache), __FILE__, __LINE__);
    }
    // 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 = db_query("\n\t\t\tSELECT numReplies, ID_TOPIC, ID_BOARD\n\t\t\tFROM {$db_prefix}topics\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $moveCache[0]) . ")" . (!empty($board) && !allowedTo('move_any') ? "\n\t\t\t\tAND ID_MEMBER_STARTED = {$ID_MEMBER}" : '') . "\n\t\t\tLIMIT " . count($moveCache[0]), __FILE__, __LINE__);
        $moveCache2 = array();
        while ($row = mysql_fetch_assoc($request)) {
            $to = $moveCache[1][$row['ID_TOPIC']];
            $row['numReplies']++;
            if (empty($to)) {
                continue;
            }
            if (!isset($affectedBoards[$to])) {
                $affectedBoards[$to] = array(0, 0);
            }
            if (!isset($affectedBoards[$row['ID_BOARD']])) {
                $affectedBoards[$row['ID_BOARD']] = array(0, 0);
            }
            $affectedBoards[$row['ID_BOARD']][0]--;
            $affectedBoards[$row['ID_BOARD']][1] -= $row['numReplies'];
            $affectedBoards[$to][0]++;
            $affectedBoards[$to][1] += $row['numReplies'];
            // Move the actual topic.
            db_query("\n\t\t\t\tUPDATE {$db_prefix}topics\n\t\t\t\tSET ID_BOARD = {$to}\n\t\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            db_query("\n\t\t\t\tUPDATE {$db_prefix}messages\n\t\t\t\tSET ID_BOARD = {$to}\n\t\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}", __FILE__, __LINE__);
            db_query("\n\t\t\t\tUPDATE {$db_prefix}calendar\n\t\t\t\tSET ID_BOARD = {$to}\n\t\t\t\tWHERE ID_TOPIC = {$row['ID_TOPIC']}", __FILE__, __LINE__);
            $moveCache2[] = array($row['ID_TOPIC'], $row['ID_BOARD'], $to);
        }
        mysql_free_result($request);
        $moveCache = $moveCache2;
        foreach ($affectedBoards as $ID_BOARD => $topicsPosts) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}boards\n\t\t\t\tSET numPosts = numPosts + {$topicsPosts['1']}, numTopics = numTopics + {$topicsPosts['0']}\n\t\t\t\tWHERE ID_BOARD = {$ID_BOARD}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        }
    }
    // 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..)
        if (!empty($board) && !allowedTo('remove_any')) {
            $result = db_query("\n\t\t\t\tSELECT ID_TOPIC\n\t\t\t\tFROM {$db_prefix}topics\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $removeCache) . ")\n\t\t\t\t\tAND ID_MEMBER_STARTED = {$ID_MEMBER}\n\t\t\t\tLIMIT " . count($removeCache), __FILE__, __LINE__);
            $removeCache = array();
            while ($row = mysql_fetch_assoc($result)) {
                $removeCache[] = $row['ID_TOPIC'];
            }
            mysql_free_result($result);
        }
        // Maybe *none* were their own topics.
        if (!empty($removeCache)) {
            // Gotta send the notifications *first*!
            foreach ($removeCache as $topic) {
                logAction('remove', array('topic' => $topic));
                sendNotifications($topic, 'remove');
            }
            require_once $sourcedir . '/RemoveTopic.php';
            removeTopics($removeCache);
        }
    }
    // And 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 = db_query("\n\t\t\t\tSELECT ID_TOPIC, locked\n\t\t\t\tFROM {$db_prefix}topics\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $lockCache) . ")\n\t\t\t\t\tAND ID_MEMBER_STARTED = {$ID_MEMBER}\n\t\t\t\t\tAND locked IN (2, 0)\n\t\t\t\tLIMIT " . count($lockCache), __FILE__, __LINE__);
            $lockCache = array();
            while ($row = mysql_fetch_assoc($result)) {
                $lockCache[] = $row['ID_TOPIC'];
                $lockStatus[$row['ID_TOPIC']] = empty($row['locked']);
            }
            mysql_free_result($result);
        } else {
            $result = db_query("\n\t\t\t\tSELECT ID_TOPIC, locked\n\t\t\t\tFROM {$db_prefix}topics\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $lockCache) . ")\n\t\t\t\tLIMIT " . count($lockCache), __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($result)) {
                $lockStatus[$row['ID_TOPIC']] = empty($row['locked']);
            }
            mysql_free_result($result);
        }
        // It could just be that *none* were their own topics...
        if (!empty($lockCache)) {
            // Alternate the locked value.
            db_query("\n\t\t\t\tUPDATE {$db_prefix}topics\n\t\t\t\tSET locked = IF(locked = 0, " . (allowedTo('lock_any') ? '1' : '2') . ", 0)\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $lockCache) . ")\n\t\t\t\tLIMIT " . count($lockCache), __FILE__, __LINE__);
        }
    }
    if (!empty($markCache)) {
        $setString = '';
        foreach ($markCache as $topic) {
            $setString .= "\n\t\t\t\t({$modSettings['maxMsgID']}, {$ID_MEMBER}, {$topic}),";
        }
        db_query("\n\t\t\tREPLACE INTO {$db_prefix}log_topics\n\t\t\t\t(ID_MSG, ID_MEMBER, ID_TOPIC)\n\t\t\tVALUES" . substr($setString, 0, -1), __FILE__, __LINE__);
    }
    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('lock', array('topic' => $topic));
        sendNotifications($topic, $lockStatus ? 'lock' : 'unlock');
    }
    foreach ($stickyCache as $topic) {
        logAction('sticky', array('topic' => $topic));
        sendNotifications($topic, 'sticky');
    }
    updateStats('topic');
    updateStats('message');
    updateStats('calendar');
    if (!empty($affectedBoards)) {
        updateLastMessages(array_keys($affectedBoards));
    }
    redirectexit($redirect_url);
}
Example #12
0
/**
 * Create a new topic by email
 *
 * What it does:
 * - Called by pbe_topic to create a new topic or by pbe_main to create a new topic via a subject change
 * - checks posting permissions, but requires all email validation checks are complete
 * - Calls pbe_load_text to prepare text for the post
 * - Uses createPost to do the actual "posting"
 * - Calls sendNotifications to announce the new post
 * - Calls query_update_member_stats to show they did something
 * - Requires the pbe, email_message and board_info arrays to be populated.
 *
 * @package Maillist
 * @param mixed[] $pbe array of pbe 'user_info' values
 * @param Email_Parse $email_message
 * @param mixed[] $board_info
 */
function pbe_create_topic($pbe, $email_message, $board_info)
{
    global $txt, $modSettings;
    // It does not work like that
    if (empty($pbe) || empty($email_message)) {
        return false;
    }
    // We have the board info, and their permissions - do they have a right to start a new topic?
    $becomesApproved = true;
    if (!$pbe['user_info']['is_admin']) {
        if (!in_array('postby_email', $pbe['user_info']['permissions'])) {
            return pbe_emailError('error_permission', $email_message);
        } elseif ($modSettings['postmod_active'] && in_array('post_unapproved_topics', $pbe['user_info']['permissions']) && !in_array('post_new', $pbe['user_info']['permissions'])) {
            $becomesApproved = false;
        } elseif (!in_array('post_new', $pbe['user_info']['permissions'])) {
            return pbe_emailError('error_cant_start', $email_message);
        }
    }
    // Approving all new topics by email anyway, smart admin this one is ;)
    if (!empty($modSettings['maillist_newtopic_needsapproval'])) {
        $becomesApproved = false;
    }
    // First on the agenda the subject
    $subject = pbe_clean_email_subject($email_message->subject);
    $subject = strtr(Util::htmlspecialchars($subject), array("\r" => '', "\n" => '', "\t" => ''));
    // Not to long not to short
    if (Util::strlen($subject) > 100) {
        $subject = Util::substr($subject, 0, 100);
    } elseif ($subject == '') {
        return pbe_emailError('error_no_subject', $email_message);
    }
    // The message itself will need a bit of work
    $html = $email_message->html_found;
    $text = pbe_load_text($html, $email_message, $pbe);
    if (empty($text)) {
        return pbe_emailError('error_no_message', $email_message);
    }
    // Build the attachment array if needed
    if (!empty($email_message->attachments) && !empty($modSettings['maillist_allow_attachments']) && !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1) {
        if ($modSettings['postmod_active'] && in_array('post_unapproved_attachments', $pbe['user_info']['permissions']) || in_array('post_attachment', $pbe['user_info']['permissions'])) {
            $attachIDs = pbe_email_attachments($pbe, $email_message);
        } else {
            $text .= "\n\n" . $txt['error_no_attach'] . "\n";
        }
    }
    // If we get to this point ... then its time to play, lets start a topic !
    require_once SUBSDIR . '/Post.subs.php';
    // Setup the topic variables.
    $msgOptions = array('id' => 0, 'subject' => $subject, 'smileys_enabled' => true, 'body' => $text, 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved);
    $topicOptions = array('id' => 0, 'board' => $board_info['id_board'], 'mark_as_read' => false);
    $posterOptions = array('id' => $pbe['profile']['id_member'], 'name' => $pbe['profile']['real_name'], 'email' => $pbe['profile']['email_address'], 'update_post_count' => empty($board_info['count_posts']), 'ip' => isset($email_message->ip) ? $email_message->ip : $pbe['profile']['member_ip']);
    // Attempt to make the new topic.
    createPost($msgOptions, $topicOptions, $posterOptions);
    // The auto_notify setting
    $theme_settings = query_get_theme($pbe['profile']['id_member'], $pbe['profile']['id_theme'], $board_info);
    $auto_notify = isset($theme_settings['auto_notify']) ? $theme_settings['auto_notify'] : 0;
    // Notifications on or off
    query_notifications($pbe['profile']['id_member'], $board_info['id_board'], $topicOptions['id'], $auto_notify, $pbe['user_info']['permissions']);
    // Notify members who have notification turned on for this, (if it's approved)
    if ($becomesApproved) {
        require_once SUBSDIR . '/Notification.subs.php';
        sendNotifications($topicOptions['id'], 'reply', array(), array(), $pbe);
    }
    // Update this users info so the log shows them as active
    query_update_member_stats($pbe, $email_message, $topicOptions);
    return true;
}
Example #13
0
    /**
     * Posts or saves the message composed with Post().
     *
     * requires various permissions depending on the action.
     * handles attachment, post, and calendar saving.
     * sends off notifications, and allows for announcements and moderation.
     * accessed from ?action=post2.
     */
    public function action_post2()
    {
        global $board, $topic, $txt, $modSettings, $context, $user_settings;
        global $user_info, $board_info, $options, $ignore_temp;
        // Sneaking off, are we?
        if (empty($_POST) && empty($topic)) {
            if (empty($_SERVER['CONTENT_LENGTH'])) {
                redirectexit('action=post;board=' . $board . '.0');
            } else {
                fatal_lang_error('post_upload_error', false);
            }
        } elseif (empty($_POST) && !empty($topic)) {
            redirectexit('action=post;topic=' . $topic . '.0');
        }
        // No need!
        $context['robot_no_index'] = true;
        // We are now in post2 action
        $context['current_action'] = 'post2';
        require_once SOURCEDIR . '/AttachmentErrorContext.class.php';
        // No errors as yet.
        $post_errors = Error_Context::context('post', 1);
        $attach_errors = Attachment_Error_Context::context();
        // If the session has timed out, let the user re-submit their form.
        if (checkSession('post', '', false) != '') {
            $post_errors->addError('session_timeout');
            // Disable the preview so that any potentially malicious code is not executed
            $_REQUEST['preview'] = false;
            return $this->action_post();
        }
        // Wrong verification code?
        if (!$user_info['is_admin'] && !$user_info['is_mod'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1)) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions, true);
            if (is_array($context['require_verification'])) {
                foreach ($context['require_verification'] as $verification_error) {
                    $post_errors->addError($verification_error);
                }
            }
        }
        require_once SUBSDIR . '/Boards.subs.php';
        require_once SUBSDIR . '/Post.subs.php';
        loadLanguage('Post');
        // Drafts enabled and needed?
        if (!empty($modSettings['drafts_enabled']) && (isset($_POST['save_draft']) || isset($_POST['id_draft']))) {
            require_once SUBSDIR . '/Drafts.subs.php';
        }
        // First check to see if they are trying to delete any current attachments.
        if (isset($_POST['attach_del'])) {
            $keep_temp = array();
            $keep_ids = array();
            foreach ($_POST['attach_del'] as $dummy) {
                if (strpos($dummy, 'post_tmp_' . $user_info['id']) !== false) {
                    $keep_temp[] = $dummy;
                } else {
                    $keep_ids[] = (int) $dummy;
                }
            }
            if (isset($_SESSION['temp_attachments'])) {
                foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                    if (isset($_SESSION['temp_attachments']['post']['files'], $attachment['name']) && in_array($attachment['name'], $_SESSION['temp_attachments']['post']['files']) || in_array($attachID, $keep_temp) || strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                        continue;
                    }
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($attachment['tmp_name']);
                }
            }
            if (!empty($_REQUEST['msg'])) {
                require_once SUBSDIR . '/ManageAttachments.subs.php';
                $attachmentQuery = array('attachment_type' => 0, 'id_msg' => (int) $_REQUEST['msg'], 'not_id_attach' => $keep_ids);
                removeAttachments($attachmentQuery);
            }
        }
        // Then try to upload any attachments.
        $context['attachments']['can']['post'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'));
        if ($context['attachments']['can']['post'] && empty($_POST['from_qr'])) {
            require_once SUBSDIR . '/Attachments.subs.php';
            if (isset($_REQUEST['msg'])) {
                processAttachments((int) $_REQUEST['msg']);
            } else {
                processAttachments();
            }
        }
        // Previewing? Go back to start.
        if (isset($_REQUEST['preview'])) {
            return $this->action_post();
        }
        // Prevent double submission of this form.
        checkSubmitOnce('check');
        // If this isn't a new topic load the topic info that we need.
        if (!empty($topic)) {
            require_once SUBSDIR . '/Topic.subs.php';
            $topic_info = getTopicInfo($topic);
            // Though the topic should be there, it might have vanished.
            if (empty($topic_info)) {
                fatal_lang_error('topic_doesnt_exist');
            }
            // Did this topic suddenly move? Just checking...
            if ($topic_info['id_board'] != $board) {
                fatal_lang_error('not_a_topic');
            }
        }
        // Replying to a topic?
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            // Don't allow a post if it's locked.
            if ($topic_info['locked'] != 0 && !allowedTo('moderate_board')) {
                fatal_lang_error('topic_locked', false);
            }
            // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
            if (isset($_REQUEST['poll']) && $topic_info['id_poll'] > 0) {
                unset($_REQUEST['poll']);
            }
            // Do the permissions and approval stuff...
            $becomesApproved = true;
            if ($topic_info['id_member_started'] != $user_info['id']) {
                if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                    $becomesApproved = false;
                } else {
                    isAllowedTo('post_reply_any');
                }
            } elseif (!allowedTo('post_reply_any')) {
                if ($modSettings['postmod_active']) {
                    if (allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                        $becomesApproved = false;
                    } elseif ($user_info['is_guest'] && allowedTo('post_unapproved_replies_any')) {
                        $becomesApproved = false;
                    } else {
                        isAllowedTo('post_reply_own');
                    }
                }
            }
            if (isset($_POST['lock'])) {
                // Nothing is changed to the lock.
                if (empty($topic_info['locked']) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                    unset($_POST['lock']);
                } elseif (!allowedTo('lock_any')) {
                    // You cannot override a moderator lock.
                    if ($topic_info['locked'] == 1) {
                        unset($_POST['lock']);
                    } else {
                        $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                    }
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
                }
            }
            // So you wanna (un)sticky this...let's see.
            if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $topic_info['is_sticky'] || !allowedTo('make_sticky'))) {
                unset($_POST['sticky']);
            }
            // If drafts are enabled, then pass this off
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            // If the number of replies has changed, if the setting is enabled, go back to action_post() - which handles the error.
            if (empty($options['no_new_reply_warning']) && isset($_POST['last_msg']) && $topic_info['id_last_msg'] > $_POST['last_msg']) {
                addInlineJavascript('
					$(document).ready(function () {
						$("html,body").scrollTop($(\'.category_header:visible:first\').offset().top);
					});');
                return $this->action_post();
            }
            $posterIsGuest = $user_info['is_guest'];
        } elseif (empty($topic)) {
            // Now don't be silly, new topics will get their own id_msg soon enough.
            unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
            // Do like, the permissions, for safety and stuff...
            $becomesApproved = true;
            if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_new');
            }
            if (isset($_POST['lock'])) {
                // New topics are by default not locked.
                if (empty($_POST['lock'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
                }
            }
            if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
                unset($_POST['sticky']);
            }
            // Saving your new topic as a draft first?
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            $posterIsGuest = $user_info['is_guest'];
        } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
            $_REQUEST['msg'] = (int) $_REQUEST['msg'];
            require_once SUBSDIR . '/Messages.subs.php';
            $msgInfo = basicMessageInfo($_REQUEST['msg'], true);
            if (empty($msgInfo)) {
                fatal_lang_error('cant_find_messages', false);
            }
            if (!empty($topic_info['locked']) && !allowedTo('moderate_board')) {
                fatal_lang_error('topic_locked', false);
            }
            if (isset($_POST['lock'])) {
                // Nothing changes to the lock status.
                if (empty($_POST['lock']) && empty($topic_info['locked']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                    unset($_POST['lock']);
                } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                    unset($_POST['lock']);
                } elseif (!allowedTo('lock_any')) {
                    // You're not allowed to break a moderator's lock.
                    if ($topic_info['locked'] == 1) {
                        unset($_POST['lock']);
                    } else {
                        $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                    }
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
                }
            }
            // Change the sticky status of this topic?
            if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $topic_info['is_sticky'])) {
                unset($_POST['sticky']);
            }
            if ($msgInfo['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
                if ((!$modSettings['postmod_active'] || $msgInfo['approved']) && !empty($modSettings['edit_disable_time']) && $msgInfo['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) {
                    isAllowedTo('modify_replies');
                } else {
                    isAllowedTo('modify_own');
                }
            } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) {
                isAllowedTo('modify_replies');
                // If you're modifying a reply, I say it better be logged...
                $moderationAction = true;
            } else {
                isAllowedTo('modify_any');
                // Log it, assuming you're not modifying your own post.
                if ($msgInfo['id_member'] != $user_info['id']) {
                    $moderationAction = true;
                }
            }
            // If drafts are enabled, then lets send this off to save
            if (!empty($modSettings['drafts_enabled']) && isset($_POST['save_draft'])) {
                saveDraft();
                return $this->action_post();
            }
            $posterIsGuest = empty($msgInfo['id_member']);
            // Can they approve it?
            $can_approve = allowedTo('approve_posts');
            $becomesApproved = $modSettings['postmod_active'] ? $can_approve && !$msgInfo['approved'] ? !empty($_REQUEST['approve']) ? 1 : 0 : $msgInfo['approved'] : 1;
            $approve_has_changed = $msgInfo['approved'] != $becomesApproved;
            if (!allowedTo('moderate_forum') || !$posterIsGuest) {
                $_POST['guestname'] = $msgInfo['poster_name'];
                $_POST['email'] = $msgInfo['poster_email'];
            }
        }
        // In case we want to override
        if (allowedTo('approve_posts')) {
            $becomesApproved = !isset($_REQUEST['approve']) || !empty($_REQUEST['approve']) ? 1 : 0;
            $approve_has_changed = isset($msgInfo['approved']) ? $msgInfo['approved'] != $becomesApproved : false;
        }
        // If the poster is a guest evaluate the legality of name and email.
        if ($posterIsGuest) {
            $_POST['guestname'] = !isset($_POST['guestname']) ? '' : Util::htmlspecialchars(trim($_POST['guestname']));
            $_POST['email'] = !isset($_POST['email']) ? '' : Util::htmlspecialchars(trim($_POST['email']));
            if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
                $post_errors->addError('no_name');
            }
            if (Util::strlen($_POST['guestname']) > 25) {
                $post_errors->addError('long_name');
            }
            if (empty($modSettings['guest_post_no_email'])) {
                // Only check if they changed it!
                if (!isset($msgInfo) || $msgInfo['poster_email'] != $_POST['email']) {
                    require_once SUBSDIR . '/DataValidator.class.php';
                    if (!allowedTo('moderate_forum') && !Data_Validator::is_valid($_POST, array('email' => 'valid_email|required'), array('email' => 'trim'))) {
                        empty($_POST['email']) ? $post_errors->addError('no_email') : $post_errors->addError('bad_email');
                    }
                }
                // Now make sure this email address is not banned from posting.
                isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
            }
            // In case they are making multiple posts this visit, help them along by storing their name.
            if (!$post_errors->hasErrors()) {
                $_SESSION['guest_name'] = $_POST['guestname'];
                $_SESSION['guest_email'] = $_POST['email'];
            }
        }
        // Check the subject and message.
        if (!isset($_POST['subject']) || Util::htmltrim(Util::htmlspecialchars($_POST['subject'])) === '') {
            $post_errors->addError('no_subject');
        }
        if (!isset($_POST['message']) || Util::htmltrim(Util::htmlspecialchars($_POST['message'], ENT_QUOTES)) === '') {
            $post_errors->addError('no_message');
        } elseif (!empty($modSettings['max_messageLength']) && Util::strlen($_POST['message']) > $modSettings['max_messageLength']) {
            $post_errors->addError(array('long_message', array($modSettings['max_messageLength'])));
        } else {
            // Prepare the message a bit for some additional testing.
            $_POST['message'] = Util::htmlspecialchars($_POST['message'], ENT_QUOTES);
            // Preparse code. (Zef)
            if ($user_info['is_guest']) {
                $user_info['name'] = $_POST['guestname'];
            }
            preparsecode($_POST['message']);
            // Let's see if there's still some content left without the tags.
            if (Util::htmltrim(strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($_POST['message'], '[html]') === false)) {
                $post_errors->addError('no_message');
            }
        }
        if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && Util::htmltrim($_POST['evtitle']) === '') {
            $post_errors->addError('no_event');
        }
        // Validate the poll...
        if (isset($_REQUEST['poll']) && !empty($modSettings['pollMode'])) {
            if (!empty($topic) && !isset($_REQUEST['msg'])) {
                fatal_lang_error('no_access', false);
            }
            // This is a new topic... so it's a new poll.
            if (empty($topic)) {
                isAllowedTo('poll_post');
            } elseif ($user_info['id'] == $topic_info['id_member_started'] && !allowedTo('poll_add_any')) {
                isAllowedTo('poll_add_own');
            } else {
                isAllowedTo('poll_add_any');
            }
            if (!isset($_POST['question']) || trim($_POST['question']) == '') {
                $post_errors->addError('no_question');
            }
            $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
            // Get rid of empty ones.
            foreach ($_POST['options'] as $k => $option) {
                if ($option == '') {
                    unset($_POST['options'][$k], $_POST['options'][$k]);
                }
            }
            // What are you going to vote between with one choice?!?
            if (count($_POST['options']) < 2) {
                $post_errors->addError('poll_few');
            } elseif (count($_POST['options']) > 256) {
                $post_errors->addError('poll_many');
            }
        }
        if ($posterIsGuest) {
            // If user is a guest, make sure the chosen name isn't taken.
            require_once SUBSDIR . '/Members.subs.php';
            if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($msgInfo['poster_name']) || $_POST['guestname'] != $msgInfo['poster_name'])) {
                $post_errors->addError('bad_name');
            }
        } elseif (!isset($_REQUEST['msg'])) {
            $_POST['guestname'] = $user_info['username'];
            $_POST['email'] = $user_info['email'];
        }
        // Posting somewhere else? Are we sure you can?
        if (!empty($_REQUEST['post_in_board'])) {
            $new_board = (int) $_REQUEST['post_in_board'];
            if (!allowedTo('post_new', $new_board)) {
                $post_in_board = boardInfo($new_board);
                if (!empty($post_in_board)) {
                    $post_errors->addError(array('post_new_board', array($post_in_board['name'])));
                } else {
                    $post_errors->addError('post_new');
                }
            }
        }
        // Any mistakes?
        if ($post_errors->hasErrors() || $attach_errors->hasErrors()) {
            addInlineJavascript('
				$(document).ready(function () {
					$("html,body").scrollTop($(\'.category_header:visible:first\').offset().top);
				});');
            return $this->action_post();
        }
        // Make sure the user isn't spamming the board.
        if (!isset($_REQUEST['msg'])) {
            spamProtection('post');
        }
        // At about this point, we're posting and that's that.
        ignore_user_abort(true);
        @set_time_limit(300);
        // Add special html entities to the subject, name, and email.
        $_POST['subject'] = strtr(Util::htmlspecialchars($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
        $_POST['guestname'] = htmlspecialchars($_POST['guestname'], ENT_COMPAT, 'UTF-8');
        $_POST['email'] = htmlspecialchars($_POST['email'], ENT_COMPAT, 'UTF-8');
        // At this point, we want to make sure the subject isn't too long.
        if (Util::strlen($_POST['subject']) > 100) {
            $_POST['subject'] = Util::substr($_POST['subject'], 0, 100);
        }
        if (!empty($modSettings['mentions_enabled']) && !empty($_REQUEST['uid'])) {
            $query_params = array();
            $query_params['member_ids'] = array_unique(array_map('intval', $_REQUEST['uid']));
            require_once SUBSDIR . '/Members.subs.php';
            $mentioned_members = membersBy('member_ids', $query_params, true);
            $replacements = 0;
            $actually_mentioned = array();
            foreach ($mentioned_members as $member) {
                $_POST['message'] = str_replace('@' . $member['real_name'], '[member=' . $member['id_member'] . ']' . $member['real_name'] . '[/member]', $_POST['message'], $replacements);
                if ($replacements > 0) {
                    $actually_mentioned[] = $member['id_member'];
                }
            }
        }
        // Make the poll...
        if (isset($_REQUEST['poll'])) {
            // Make sure that the user has not entered a ridiculous number of options..
            if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
                $_POST['poll_max_votes'] = 1;
            } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
                $_POST['poll_max_votes'] = count($_POST['options']);
            } else {
                $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
            }
            $_POST['poll_expire'] = (int) $_POST['poll_expire'];
            $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
            // Just set it to zero if it's not there..
            if (!isset($_POST['poll_hide'])) {
                $_POST['poll_hide'] = 0;
            } else {
                $_POST['poll_hide'] = (int) $_POST['poll_hide'];
            }
            $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
            $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
            // Make sure guests are actually allowed to vote generally.
            if ($_POST['poll_guest_vote']) {
                require_once SUBSDIR . '/Members.subs.php';
                $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
                if (!in_array(-1, $allowedVoteGroups['allowed'])) {
                    $_POST['poll_guest_vote'] = 0;
                }
            }
            // If the user tries to set the poll too far in advance, don't let them.
            if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
                fatal_lang_error('poll_range_error', false);
            } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
                $_POST['poll_hide'] = 1;
            }
            // Clean up the question and answers.
            $_POST['question'] = htmlspecialchars($_POST['question'], ENT_COMPAT, 'UTF-8');
            $_POST['question'] = Util::substr($_POST['question'], 0, 255);
            $_POST['question'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', $_POST['question']);
            $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
            // Finally, make the poll.
            require_once SUBSDIR . '/Poll.subs.php';
            $id_poll = createPoll($_POST['question'], $user_info['id'], $_POST['guestname'], $_POST['poll_max_votes'], $_POST['poll_hide'], $_POST['poll_expire'], $_POST['poll_change_vote'], $_POST['poll_guest_vote'], $_POST['options']);
        } else {
            $id_poll = 0;
        }
        // ...or attach a new file...
        if (empty($ignore_temp) && $context['attachments']['can']['post'] && !empty($_SESSION['temp_attachments']) && empty($_POST['from_qr'])) {
            $attachIDs = array();
            foreach ($_SESSION['temp_attachments'] as $attachID => $attachment) {
                if ($attachID != 'initial_error' && strpos($attachID, 'post_tmp_' . $user_info['id']) === false) {
                    continue;
                }
                // If there was an initial error just show that message.
                if ($attachID == 'initial_error') {
                    unset($_SESSION['temp_attachments']);
                    break;
                }
                // No errors, then try to create the attachment
                if (empty($attachment['errors'])) {
                    // Load the attachmentOptions array with the data needed to create an attachment
                    $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $user_info['id'], 'name' => $attachment['name'], 'tmp_name' => $attachment['tmp_name'], 'size' => isset($attachment['size']) ? $attachment['size'] : 0, 'mime_type' => isset($attachment['type']) ? $attachment['type'] : '', 'id_folder' => isset($attachment['id_folder']) ? $attachment['id_folder'] : 0, 'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'), 'errors' => array());
                    if (createAttachment($attachmentOptions)) {
                        $attachIDs[] = $attachmentOptions['id'];
                        if (!empty($attachmentOptions['thumb'])) {
                            $attachIDs[] = $attachmentOptions['thumb'];
                        }
                    }
                } else {
                    @unlink($attachment['tmp_name']);
                }
            }
            unset($_SESSION['temp_attachments']);
        }
        // Creating a new topic?
        $newTopic = empty($_REQUEST['msg']) && empty($topic);
        $_POST['icon'] = !empty($attachIDs) && $_POST['icon'] == 'xx' ? 'clip' : $_POST['icon'];
        // Collect all parameters for the creation or modification of a post.
        $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved);
        $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $id_poll : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true, 'is_approved' => !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']));
        $posterOptions = array('id' => $user_info['id'], 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
        // This is an already existing message. Edit it.
        if (!empty($_REQUEST['msg'])) {
            // Have admins allowed people to hide their screwups?
            if (time() - $msgInfo['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $msgInfo['id_member']) {
                $msgOptions['modify_time'] = time();
                $msgOptions['modify_name'] = $user_info['name'];
            }
            // This will save some time...
            if (empty($approve_has_changed)) {
                unset($msgOptions['approved']);
            }
            modifyPost($msgOptions, $topicOptions, $posterOptions);
        } else {
            if (!empty($modSettings['enableFollowup']) && !empty($_REQUEST['followup'])) {
                $original_post = (int) $_REQUEST['followup'];
            }
            // We also have to fake the board:
            // if it's valid and it's not the current, let's forget about the "current" and load the new one
            if (!empty($new_board) && $board !== $new_board) {
                $board = $new_board;
                loadBoard();
                // Some details changed
                $topicOptions['board'] = $board;
                $topicOptions['is_approved'] = !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']);
                $posterOptions['update_post_count'] = !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count'];
            }
            createPost($msgOptions, $topicOptions, $posterOptions);
            if (isset($topicOptions['id'])) {
                $topic = $topicOptions['id'];
            }
            if (!empty($modSettings['enableFollowup'])) {
                require_once SUBSDIR . '/FollowUps.subs.php';
                require_once SUBSDIR . '/Messages.subs.php';
                // Time to update the original message with a pointer to the new one
                if (!empty($original_post) && canAccessMessage($original_post)) {
                    linkMessages($original_post, $topic);
                }
            }
        }
        // If we had a draft for this, its time to remove it since it was just posted
        if (!empty($modSettings['drafts_enabled']) && !empty($_POST['id_draft'])) {
            deleteDrafts($_POST['id_draft'], $user_info['id']);
        }
        // Editing or posting an event?
        if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
            require_once SUBSDIR . '/Calendar.subs.php';
            // Make sure they can link an event to this post.
            canLinkEvent();
            // Insert the event.
            $eventOptions = array('id_board' => $board, 'id_topic' => $topic, 'title' => $_POST['evtitle'], 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
            insertEvent($eventOptions);
        } elseif (isset($_POST['calendar'])) {
            $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
            // Validate the post...
            require_once SUBSDIR . '/Calendar.subs.php';
            validateEventPost();
            // If you're not allowed to edit any events, you have to be the poster.
            if (!allowedTo('calendar_edit_any')) {
                $event_poster = getEventPoster($_REQUEST['eventid']);
                // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
                isAllowedTo('calendar_edit_' . ($event_poster == $user_info['id'] ? 'own' : 'any'));
            }
            // Delete it?
            if (isset($_REQUEST['deleteevent'])) {
                removeEvent($_REQUEST['eventid']);
            } else {
                $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
                $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
                $eventOptions = array('start_date' => strftime('%Y-%m-%d', $start_time), 'end_date' => strftime('%Y-%m-%d', $start_time + $span * 86400), 'title' => $_REQUEST['evtitle']);
                modifyEvent($_REQUEST['eventid'], $eventOptions);
            }
        }
        // Marking boards as read.
        // (You just posted and they will be unread.)
        if (!$user_info['is_guest']) {
            $board_list = !empty($board_info['parent_boards']) ? array_keys($board_info['parent_boards']) : array();
            // Returning to the topic?
            if (!empty($_REQUEST['goback'])) {
                $board_list[] = $board;
            }
            if (!empty($board_list)) {
                markBoardsRead($board_list, false, false);
            }
        }
        // Turn notification on or off.
        if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) {
            setTopicNotification($user_info['id'], $topic, true);
        } elseif (!$newTopic) {
            setTopicNotification($user_info['id'], $topic, false);
        }
        // Log an act of moderation - modifying.
        if (!empty($moderationAction)) {
            logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $msgInfo['id_member'], 'board' => $board));
        }
        if (isset($_POST['lock']) && $_POST['lock'] != 2) {
            logAction(empty($_POST['lock']) ? 'unlock' : 'lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
        }
        if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
            logAction(empty($_POST['sticky']) ? 'unsticky' : 'sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
        }
        // Notify any members who have notification turned on for this topic/board - only do this if it's going to be approved(!)
        if ($becomesApproved) {
            require_once SUBSDIR . '/Notification.subs.php';
            if ($newTopic) {
                $notifyData = array('body' => $_POST['message'], 'subject' => $_POST['subject'], 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $board, 'topic' => $topic, 'signature' => isset($user_settings['signature']) ? $user_settings['signature'] : '');
                sendBoardNotifications($notifyData);
            } elseif (empty($_REQUEST['msg'])) {
                // Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it.
                if ($topic_info['approved']) {
                    sendNotifications($topic, 'reply');
                } else {
                    sendNotifications($topic, 'reply', array(), $topic_info['id_member_started']);
                }
            }
        }
        if (!empty($modSettings['mentions_enabled']) && !empty($actually_mentioned)) {
            require_once CONTROLLERDIR . '/Mentions.controller.php';
            $mentions = new Mentions_Controller();
            $mentions->setData(array('id_member' => $actually_mentioned, 'type' => 'men', 'id_msg' => $msgOptions['id'], 'status' => $becomesApproved ? 'new' : 'unapproved'));
            $mentions->action_add();
        }
        if ($board_info['num_topics'] == 0) {
            cache_put_data('board-' . $board, null, 120);
        }
        if (!empty($_POST['announce_topic'])) {
            redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
        }
        if (!empty($_POST['move']) && allowedTo('move_any')) {
            redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
        }
        // Return to post if the mod is on.
        if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
            redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], isBrowser('ie'));
        } elseif (!empty($_REQUEST['goback'])) {
            redirectexit('topic=' . $topic . '.new#new', isBrowser('ie'));
        } else {
            redirectexit('board=' . $board . '.0');
        }
    }
Example #14
0
    $notUpdatedForms = array_diff($formulize_allWrittenFids, $formsUpdatedInFramework);
    foreach ($notUpdatedForms as $thisFid) {
        $formObject = $form_handler->get($thisFid, true);
        // true causes all elements to be gathered, including ones that are not displayed to the users
        if (array_search("derived", $formObject->getVar('elementTypes'))) {
            foreach ($formulize_allWrittenEntryIds[$thisFid] as $thisEntry) {
                formulize_updateDerivedValues($thisEntry, $thisFid);
            }
        }
    }
}
// send notifications
foreach ($notEntriesList as $notEvent => $notDetails) {
    foreach ($notDetails as $notFid => $notEntries) {
        $notEntries = array_unique($notEntries);
        sendNotifications($notFid, $notEvent, $notEntries);
    }
}
$formulize_readElementsWasRun = true;
// flag that will prevent this from running again
// set the variables that need to be in global space, just in case this file was included from inside a function, which can happen in some cases
$GLOBALS['formulize_newEntryIds'] = $formulize_newEntryIds;
$GLOBALS['formulize_newEntryUsers'] = $formulize_newEntryUsers;
$GLOBALS['formulize_allWrittenEntryIds'] = $formulize_allWrittenEntryIds;
$GLOBALS['formulize_newSubformBlankElementIds'] = $formulize_newSubformBlankElementIds;
$GLOBALS['formulize_readElementsWasRun'] = $formulize_readElementsWasRun;
return $formulize_allWrittenEntryIds;
// this function handles triggering the after Saving Logic of custom elements after each entry is written to the database
// values are the element handle->data value pairs that were written to the database
// entry_id is the entry id that was just written to the database
function afterSavingLogic($values, $entry_id)
Example #15
0
/**
 * General function to split off a topic.
 * creates a new topic and moves the messages with the IDs in
 * array messagesToBeSplit to the new topic.
 * the subject of the newly created topic is set to 'newSubject'.
 * marks the newly created message as read for the user splitting it.
 * updates the statistics to reflect a newly created topic.
 * logs the action in the moderation log.
 * a notification is sent to all users monitoring this topic.
 *
 * @param int $split1_ID_TOPIC
 * @param int[] $splitMessages
 * @param string $new_subject
 * @return int the topic ID of the new split topic.
 */
function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
{
    global $txt;
    $db = database();
    // Nothing to split?
    if (empty($splitMessages)) {
        fatal_lang_error('no_posts_selected', false);
    }
    // Get some board info.
    $request = $db->query('', '
		SELECT id_board, approved
		FROM {db_prefix}topics
		WHERE id_topic = {int:id_topic}
		LIMIT 1', array('id_topic' => $split1_ID_TOPIC));
    list($id_board, $split1_approved) = $db->fetch_row($request);
    $db->free_result($request);
    // Find the new first and last not in the list. (old topic)
    $request = $db->query('', '
		SELECT
			MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg, COUNT(*) AS message_count, m.approved
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:id_topic})
		WHERE m.id_msg NOT IN ({array_int:no_msg_list})
			AND m.id_topic = {int:id_topic}
		GROUP BY m.approved
		ORDER BY m.approved DESC
		LIMIT 2', array('id_topic' => $split1_ID_TOPIC, 'no_msg_list' => $splitMessages));
    // You can't select ALL the messages!
    if ($db->num_rows($request) == 0) {
        fatal_lang_error('selected_all_posts', false);
    }
    $split1_first_msg = null;
    $split1_last_msg = null;
    while ($row = $db->fetch_assoc($request)) {
        // Get the right first and last message dependant on approved state...
        if (empty($split1_first_msg) || $row['myid_first_msg'] < $split1_first_msg) {
            $split1_first_msg = $row['myid_first_msg'];
        }
        if (empty($split1_last_msg) || $row['approved']) {
            $split1_last_msg = $row['myid_last_msg'];
        }
        // Get the counts correct...
        if ($row['approved']) {
            $split1_replies = $row['message_count'] - 1;
            $split1_unapprovedposts = 0;
        } else {
            if (!isset($split1_replies)) {
                $split1_replies = 0;
            } elseif (!$split1_approved) {
                $split1_replies++;
            }
            $split1_unapprovedposts = $row['message_count'];
        }
    }
    $db->free_result($request);
    $split1_firstMem = getMsgMemberID($split1_first_msg);
    $split1_lastMem = getMsgMemberID($split1_last_msg);
    // Find the first and last in the list. (new topic)
    $request = $db->query('', '
		SELECT MIN(id_msg) AS myid_first_msg, MAX(id_msg) AS myid_last_msg, COUNT(*) AS message_count, approved
		FROM {db_prefix}messages
		WHERE id_msg IN ({array_int:msg_list})
			AND id_topic = {int:id_topic}
		GROUP BY id_topic, approved
		ORDER BY approved DESC
		LIMIT 2', array('msg_list' => $splitMessages, 'id_topic' => $split1_ID_TOPIC));
    while ($row = $db->fetch_assoc($request)) {
        // As before get the right first and last message dependant on approved state...
        if (empty($split2_first_msg) || $row['myid_first_msg'] < $split2_first_msg) {
            $split2_first_msg = $row['myid_first_msg'];
        }
        if (empty($split2_last_msg) || $row['approved']) {
            $split2_last_msg = $row['myid_last_msg'];
        }
        // Then do the counts again...
        if ($row['approved']) {
            $split2_approved = true;
            $split2_replies = $row['message_count'] - 1;
            $split2_unapprovedposts = 0;
        } else {
            // Should this one be approved??
            if ($split2_first_msg == $row['myid_first_msg']) {
                $split2_approved = false;
            }
            if (!isset($split2_replies)) {
                $split2_replies = 0;
            } elseif (!$split2_approved) {
                $split2_replies++;
            }
            $split2_unapprovedposts = $row['message_count'];
        }
    }
    $db->free_result($request);
    $split2_firstMem = getMsgMemberID($split2_first_msg);
    $split2_lastMem = getMsgMemberID($split2_last_msg);
    // No database changes yet, so let's double check to see if everything makes at least a little sense.
    if ($split1_first_msg <= 0 || $split1_last_msg <= 0 || $split2_first_msg <= 0 || $split2_last_msg <= 0 || $split1_replies < 0 || $split2_replies < 0 || $split1_unapprovedposts < 0 || $split2_unapprovedposts < 0 || !isset($split1_approved) || !isset($split2_approved)) {
        fatal_lang_error('cant_find_messages');
    }
    // You cannot split off the first message of a topic.
    if ($split1_first_msg > $split2_first_msg) {
        fatal_lang_error('split_first_post', false);
    }
    // We're off to insert the new topic!  Use 0 for now to avoid UNIQUE errors.
    $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', 'num_replies' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'is_sticky' => 'int'), array((int) $id_board, $split2_firstMem, $split2_lastMem, 0, 0, $split2_replies, $split2_unapprovedposts, (int) $split2_approved, 0), array('id_topic'));
    $split2_ID_TOPIC = $db->insert_id('{db_prefix}topics', 'id_topic');
    if ($split2_ID_TOPIC <= 0) {
        fatal_lang_error('cant_insert_topic');
    }
    // Move the messages over to the other topic.
    $new_subject = strtr(Util::htmltrim(Util::htmlspecialchars($new_subject)), array("\r" => '', "\n" => '', "\t" => ''));
    // Check the subject length.
    if (Util::strlen($new_subject) > 100) {
        $new_subject = Util::substr($new_subject, 0, 100);
    }
    // Valid subject?
    if ($new_subject != '') {
        $db->query('', '
			UPDATE {db_prefix}messages
			SET
				id_topic = {int:id_topic},
				subject = CASE WHEN id_msg = {int:split_first_msg} THEN {string:new_subject} ELSE {string:new_subject_replies} END
			WHERE id_msg IN ({array_int:split_msgs})', array('split_msgs' => $splitMessages, 'id_topic' => $split2_ID_TOPIC, 'new_subject' => $new_subject, 'split_first_msg' => $split2_first_msg, 'new_subject_replies' => $txt['response_prefix'] . $new_subject));
        // Cache the new topics subject... we can do it now as all the subjects are the same!
        updateStats('subject', $split2_ID_TOPIC, $new_subject);
    }
    // Any associated reported posts better follow...
    require_once SUBSDIR . '/Topic.subs.php';
    updateSplitTopics(array('splitMessages' => $splitMessages, 'split2_ID_TOPIC' => $split2_ID_TOPIC, 'split1_replies' => $split1_replies, 'split1_first_msg' => $split1_first_msg, 'split1_last_msg' => $split1_last_msg, 'split1_firstMem' => $split1_firstMem, 'split1_lastMem' => $split1_lastMem, 'split1_unapprovedposts' => $split1_unapprovedposts, 'split1_ID_TOPIC' => $split1_ID_TOPIC, 'split2_first_msg' => $split2_first_msg, 'split2_last_msg' => $split2_last_msg, 'split2_ID_TOPIC' => $split2_ID_TOPIC, 'split2_approved' => $split2_approved), $id_board);
    require_once SUBSDIR . '/FollowUps.subs.php';
    // Let's see if we can create a stronger bridge between the two topics
    // @todo not sure what message from the oldest topic I should link to the new one, so I'll go with the first
    linkMessages($split1_first_msg, $split2_ID_TOPIC);
    // Copy log topic entries.
    // @todo This should really be chunked.
    $request = $db->query('', '
		SELECT id_member, id_msg, unwatched
		FROM {db_prefix}log_topics
		WHERE id_topic = {int:id_topic}', array('id_topic' => (int) $split1_ID_TOPIC));
    if ($db->num_rows($request) > 0) {
        $replaceEntries = array();
        while ($row = $db->fetch_assoc($request)) {
            $replaceEntries[] = array($row['id_member'], $split2_ID_TOPIC, $row['id_msg'], $row['unwatched']);
        }
        require_once SUBSDIR . '/Topic.subs.php';
        markTopicsRead($replaceEntries, false);
        unset($replaceEntries);
    }
    $db->free_result($request);
    // Housekeeping.
    updateTopicStats();
    updateLastMessages($id_board);
    logAction('split', array('topic' => $split1_ID_TOPIC, 'new_topic' => $split2_ID_TOPIC, 'board' => $id_board));
    // Notify people that this topic has been split?
    require_once SUBSDIR . '/Notification.subs.php';
    sendNotifications($split1_ID_TOPIC, 'split');
    // If there's a search index that needs updating, update it...
    require_once SUBSDIR . '/Search.subs.php';
    $searchAPI = findSearchAPI();
    if (is_callable(array($searchAPI, 'topicSplit'))) {
        $searchAPI->topicSplit($split2_ID_TOPIC, $splitMessages);
    }
    // Return the ID of the newly created topic.
    return $split2_ID_TOPIC;
}
Example #16
0
/**
 * set merge options and do the actual merge of two or more topics.
 *
 * the merge options screen:
 * * shows topics to be merged and allows to set some merge options.
 * * is accessed by ?action=mergetopics;sa=options.and can also internally be called by QuickModeration() (Subs-Boards.php).
 * * uses 'merge_extra_options' sub template of the SplitTopics template.
 *
 * the actual merge:
 * * is accessed with ?action=mergetopics;sa=execute.
 * * updates the statistics to reflect the merge.
 * * logs the action in the moderation log.
 * * sends a notification is sent to all users monitoring this topic.
 * * redirects to ?action=mergetopics;sa=done.
 * @param array $topics = array()
 */
function MergeExecute($topics = array())
{
    global $user_info, $txt, $context, $scripturl, $sourcedir;
    global $smcFunc, $language, $modSettings;
    // Check the session.
    checkSession('request');
    // Handle URLs from MergeIndex.
    if (!empty($_GET['from']) && !empty($_GET['to'])) {
        $topics = array((int) $_GET['from'], (int) $_GET['to']);
    }
    // If we came from a form, the topic IDs came by post.
    if (!empty($_POST['topics']) && is_array($_POST['topics'])) {
        $topics = $_POST['topics'];
    }
    // There's nothing to merge with just one topic...
    if (empty($topics) || !is_array($topics) || count($topics) == 1) {
        fatal_lang_error('merge_need_more_topics');
    }
    // Make sure every topic is numeric, or some nasty things could be done with the DB.
    foreach ($topics as $id => $topic) {
        $topics[$id] = (int) $topic;
    }
    // Joy of all joys, make sure they're not pi**ing about with unapproved topics they can't see :P
    if ($modSettings['postmod_active']) {
        $can_approve_boards = boardsAllowedTo('approve_posts');
    }
    // Get info about the topics and polls that will be merged.
    $request = $smcFunc['db_query']('', '
		SELECT
			t.id_topic, t.id_board, t.id_poll, t.num_views, t.is_sticky, t.approved, t.num_replies, t.unapproved_posts,
			m1.subject, m1.poster_time AS time_started, IFNULL(mem1.id_member, 0) AS id_member_started, IFNULL(mem1.real_name, m1.poster_name) AS name_started,
			m2.poster_time AS time_updated, IFNULL(mem2.id_member, 0) AS id_member_updated, IFNULL(mem2.real_name, m2.poster_name) AS name_updated
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg)
			LEFT JOIN {db_prefix}members AS mem1 ON (mem1.id_member = m1.id_member)
			LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
		WHERE t.id_topic IN ({array_int:topic_list})
		ORDER BY t.id_first_msg
		LIMIT ' . count($topics), array('topic_list' => $topics));
    if ($smcFunc['db_num_rows']($request) < 2) {
        fatal_lang_error('no_topic_id');
    }
    $num_views = 0;
    $is_sticky = 0;
    $boardTotals = array();
    $boards = array();
    $polls = array();
    $firstTopic = 0;
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // Make a note for the board counts...
        if (!isset($boardTotals[$row['id_board']])) {
            $boardTotals[$row['id_board']] = array('posts' => 0, 'topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
        }
        // We can't see unapproved topics here?
        if ($modSettings['postmod_active'] && !$row['approved'] && $can_approve_boards != array(0) && in_array($row['id_board'], $can_approve_boards)) {
            continue;
        } elseif (!$row['approved']) {
            $boardTotals[$row['id_board']]['unapproved_topics']++;
        } else {
            $boardTotals[$row['id_board']]['topics']++;
        }
        $boardTotals[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts'];
        $boardTotals[$row['id_board']]['posts'] += $row['num_replies'] + ($row['approved'] ? 1 : 0);
        $topic_data[$row['id_topic']] = array('id' => $row['id_topic'], 'board' => $row['id_board'], 'poll' => $row['id_poll'], 'num_views' => $row['num_views'], 'subject' => $row['subject'], 'started' => array('time' => timeformat($row['time_started']), 'timestamp' => forum_time(true, $row['time_started']), 'href' => empty($row['id_member_started']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_started'], 'link' => empty($row['id_member_started']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_started'] . '">' . $row['name_started'] . '</a>'), 'updated' => array('time' => timeformat($row['time_updated']), 'timestamp' => forum_time(true, $row['time_updated']), 'href' => empty($row['id_member_updated']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_updated'], 'link' => empty($row['id_member_updated']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_updated'] . '">' . $row['name_updated'] . '</a>'));
        $num_views += $row['num_views'];
        $boards[] = $row['id_board'];
        // If there's no poll, id_poll == 0...
        if ($row['id_poll'] > 0) {
            $polls[] = $row['id_poll'];
        }
        // Store the id_topic with the lowest id_first_msg.
        if (empty($firstTopic)) {
            $firstTopic = $row['id_topic'];
        }
        $is_sticky = max($is_sticky, $row['is_sticky']);
    }
    $smcFunc['db_free_result']($request);
    // If we didn't get any topics then they've been messing with unapproved stuff.
    if (empty($topic_data)) {
        fatal_lang_error('no_topic_id');
    }
    $boards = array_values(array_unique($boards));
    // The parameters of MergeExecute were set, so this must've been an internal call.
    if (!empty($topics)) {
        isAllowedTo('merge_any', $boards);
        loadTemplate('SplitTopics');
    }
    // Get the boards a user is allowed to merge in.
    $merge_boards = boardsAllowedTo('merge_any');
    if (empty($merge_boards)) {
        fatal_lang_error('cannot_merge_any', 'user');
    }
    // Make sure they can see all boards....
    $request = $smcFunc['db_query']('', '
		SELECT b.id_board
		FROM {db_prefix}boards AS b
		WHERE b.id_board IN ({array_int:boards})
			AND {query_see_board}' . (!in_array(0, $merge_boards) ? '
			AND b.id_board IN ({array_int:merge_boards})' : '') . '
		LIMIT ' . count($boards), array('boards' => $boards, 'merge_boards' => $merge_boards));
    // If the number of boards that's in the output isn't exactly the same as we've put in there, you're in trouble.
    if ($smcFunc['db_num_rows']($request) != count($boards)) {
        fatal_lang_error('no_board');
    }
    $smcFunc['db_free_result']($request);
    if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options') {
        if (count($polls) > 1) {
            $request = $smcFunc['db_query']('', '
				SELECT t.id_topic, t.id_poll, m.subject, p.question
				FROM {db_prefix}polls AS p
					INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll)
					INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
				WHERE p.id_poll IN ({array_int:polls})
				LIMIT ' . count($polls), array('polls' => $polls));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $context['polls'][] = array('id' => $row['id_poll'], 'topic' => array('id' => $row['id_topic'], 'subject' => $row['subject']), 'question' => $row['question'], 'selected' => $row['id_topic'] == $firstTopic);
            }
            $smcFunc['db_free_result']($request);
        }
        if (count($boards) > 1) {
            $request = $smcFunc['db_query']('', '
				SELECT id_board, name
				FROM {db_prefix}boards
				WHERE id_board IN ({array_int:boards})
				ORDER BY name
				LIMIT ' . count($boards), array('boards' => $boards));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $context['boards'][] = array('id' => $row['id_board'], 'name' => $row['name'], 'selected' => $row['id_board'] == $topic_data[$firstTopic]['board']);
            }
            $smcFunc['db_free_result']($request);
        }
        $context['topics'] = $topic_data;
        foreach ($topic_data as $id => $topic) {
            $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic;
        }
        $context['page_title'] = $txt['merge'];
        $context['sub_template'] = 'merge_extra_options';
        return;
    }
    // Determine target board.
    $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];
    if (!in_array($target_board, $boards)) {
        fatal_lang_error('no_board');
    }
    // Determine which poll will survive and which polls won't.
    $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0);
    if ($target_poll > 0 && !in_array($target_poll, $polls)) {
        fatal_lang_error('no_access', false);
    }
    $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll));
    // Determine the subject of the newly merged topic - was a custom subject specified?
    if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '') {
        $target_subject = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
        // Keep checking the length.
        if ($smcFunc['strlen']($target_subject) > 100) {
            $target_subject = $smcFunc['substr']($target_subject, 0, 100);
        }
        // Nothing left - odd but pick the first topics subject.
        if ($target_subject == '') {
            $target_subject = $topic_data[$firstTopic]['subject'];
        }
    } elseif (!empty($topic_data[(int) $_POST['subject']]['subject'])) {
        $target_subject = $topic_data[(int) $_POST['subject']]['subject'];
    } else {
        $target_subject = $topic_data[$firstTopic]['subject'];
    }
    // Get the first and last message and the number of messages....
    $request = $smcFunc['db_query']('', '
		SELECT approved, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg, COUNT(*) AS message_count
		FROM {db_prefix}messages
		WHERE id_topic IN ({array_int:topics})
		GROUP BY approved
		ORDER BY approved DESC', array('topics' => $topics));
    $topic_approved = 1;
    $first_msg = 0;
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // If this is approved, or is fully unapproved.
        if ($row['approved'] || !isset($first_msg)) {
            $first_msg = $row['first_msg'];
            $last_msg = $row['last_msg'];
            if ($row['approved']) {
                $num_replies = $row['message_count'] - 1;
                $num_unapproved = 0;
            } else {
                $topic_approved = 0;
                $num_replies = 0;
                $num_unapproved = $row['message_count'];
            }
        } else {
            // If this has a lower first_msg then the first post is not approved and hence the number of replies was wrong!
            if ($first_msg > $row['first_msg']) {
                $first_msg = $row['first_msg'];
                $num_replies++;
                $topic_approved = 0;
            }
            $num_unapproved = $row['message_count'];
        }
    }
    $smcFunc['db_free_result']($request);
    // Ensure we have a board stat for the target board.
    if (!isset($boardTotals[$target_board])) {
        $boardTotals[$target_board] = array('posts' => 0, 'topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0);
    }
    // Fix the topic count stuff depending on what the new one counts as.
    if ($topic_approved) {
        $boardTotals[$target_board]['topics']--;
    } else {
        $boardTotals[$target_board]['unapproved_topics']--;
    }
    $boardTotals[$target_board]['unapproved_posts'] -= $num_unapproved;
    $boardTotals[$target_board]['posts'] -= $topic_approved ? $num_replies + 1 : $num_replies;
    // Get the member ID of the first and last message.
    $request = $smcFunc['db_query']('', '
		SELECT id_member
		FROM {db_prefix}messages
		WHERE id_msg IN ({int:first_msg}, {int:last_msg})
		ORDER BY id_msg
		LIMIT 2', array('first_msg' => $first_msg, 'last_msg' => $last_msg));
    list($member_started) = $smcFunc['db_fetch_row']($request);
    list($member_updated) = $smcFunc['db_fetch_row']($request);
    // First and last message are the same, so only row was returned.
    if ($member_updated === NULL) {
        $member_updated = $member_started;
    }
    $smcFunc['db_free_result']($request);
    // Obtain all the message ids we are going to affect.
    $affected_msgs = array();
    $request = $smcFunc['db_query']('', '
		SELECT id_msg
		FROM {db_prefix}messages
		WHERE id_topic IN ({array_int:topic_list})', array('topic_list' => $topics));
    while ($row = $smcFunc['db_fetch_row']($request)) {
        $affected_msgs[] = $row[0];
    }
    $smcFunc['db_free_result']($request);
    // Assign the first topic ID to be the merged topic.
    $id_topic = min($topics);
    // Delete the remaining topics.
    $deleted_topics = array_diff($topics, array($id_topic));
    $smcFunc['db_query']('', '
		DELETE FROM {db_prefix}topics
		WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics));
    $smcFunc['db_query']('', '
		DELETE FROM {db_prefix}log_search_subjects
		WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics));
    // Asssign the properties of the newly merged topic.
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}topics
		SET
			id_board = {int:id_board},
			id_member_started = {int:id_member_started},
			id_member_updated = {int:id_member_updated},
			id_first_msg = {int:id_first_msg},
			id_last_msg = {int:id_last_msg},
			id_poll = {int:id_poll},
			num_replies = {int:num_replies},
			unapproved_posts = {int:unapproved_posts},
			num_views = {int:num_views},
			is_sticky = {int:is_sticky},
			approved = {int:approved}
		WHERE id_topic = {int:id_topic}', array('id_board' => $target_board, 'is_sticky' => $is_sticky, 'approved' => $topic_approved, 'id_topic' => $id_topic, 'id_member_started' => $member_started, 'id_member_updated' => $member_updated, 'id_first_msg' => $first_msg, 'id_last_msg' => $last_msg, 'id_poll' => $target_poll, 'num_replies' => $num_replies, 'unapproved_posts' => $num_unapproved, 'num_views' => $num_views));
    // Grab the response prefix (like 'Re: ') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // Change the topic IDs of all messages that will be merged.  Also adjust subjects if 'enforce subject' was checked.
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}messages
		SET
			id_topic = {int:id_topic},
			id_board = {int:target_board}' . (empty($_POST['enforce_subject']) ? '' : ',
			subject = {string:subject}') . '
		WHERE id_topic IN ({array_int:topic_list})', array('topic_list' => $topics, 'id_topic' => $id_topic, 'target_board' => $target_board, 'subject' => $context['response_prefix'] . $target_subject));
    // Any reported posts should reflect the new board.
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}log_reported
		SET
			id_topic = {int:id_topic},
			id_board = {int:target_board}
		WHERE id_topic IN ({array_int:topics_list})', array('topics_list' => $topics, 'id_topic' => $id_topic, 'target_board' => $target_board));
    // Change the subject of the first message...
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}messages
		SET subject = {string:target_subject}
		WHERE id_msg = {int:first_msg}', array('first_msg' => $first_msg, 'target_subject' => $target_subject));
    // Adjust all calendar events to point to the new topic.
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}calendar
		SET
			id_topic = {int:id_topic},
			id_board = {int:target_board}
		WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics, 'id_topic' => $id_topic, 'target_board' => $target_board));
    // Merge log topic entries.
    $request = $smcFunc['db_query']('', '
		SELECT id_member, MIN(id_msg) AS new_id_msg
		FROM {db_prefix}log_topics
		WHERE id_topic IN ({array_int:topics})
		GROUP BY id_member', array('topics' => $topics));
    if ($smcFunc['db_num_rows']($request) > 0) {
        $replaceEntries = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $replaceEntries[] = array($row['id_member'], $id_topic, $row['new_id_msg']);
        }
        $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), $replaceEntries, array('id_member', 'id_topic'));
        unset($replaceEntries);
        // Get rid of the old log entries.
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}log_topics
			WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics));
    }
    $smcFunc['db_free_result']($request);
    // Merge topic notifications.
    $notifications = isset($_POST['notifications']) && is_array($_POST['notifications']) ? array_intersect($topics, $_POST['notifications']) : array();
    if (!empty($notifications)) {
        $request = $smcFunc['db_query']('', '
			SELECT id_member, MAX(sent) AS sent
			FROM {db_prefix}log_notify
			WHERE id_topic IN ({array_int:topics_list})
			GROUP BY id_member', array('topics_list' => $notifications));
        if ($smcFunc['db_num_rows']($request) > 0) {
            $replaceEntries = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $replaceEntries[] = array($row['id_member'], $id_topic, 0, $row['sent']);
            }
            $smcFunc['db_insert']('replace', '{db_prefix}log_notify', array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int', 'sent' => 'int'), $replaceEntries, array('id_member', 'id_topic', 'id_board'));
            unset($replaceEntries);
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}log_topics
				WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics));
        }
        $smcFunc['db_free_result']($request);
    }
    // Get rid of the redundant polls.
    if (!empty($deleted_polls)) {
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}polls
			WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls));
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}poll_choices
			WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls));
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}log_polls
			WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls));
    }
    // Cycle through each board...
    foreach ($boardTotals as $id_board => $stats) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}boards
			SET
				num_topics = CASE WHEN {int:topics} > num_topics THEN 0 ELSE num_topics - {int:topics} END,
				unapproved_topics = CASE WHEN {int:unapproved_topics} > unapproved_topics THEN 0 ELSE unapproved_topics - {int:unapproved_topics} END,
				num_posts = CASE WHEN {int:posts} > num_posts THEN 0 ELSE num_posts - {int:posts} END,
				unapproved_posts = CASE WHEN {int:unapproved_posts} > unapproved_posts THEN 0 ELSE unapproved_posts - {int:unapproved_posts} END
			WHERE id_board = {int:id_board}', array('id_board' => $id_board, 'topics' => $stats['topics'], 'unapproved_topics' => $stats['unapproved_topics'], 'posts' => $stats['posts'], 'unapproved_posts' => $stats['unapproved_posts']));
    }
    // Determine the board the final topic resides in
    $request = $smcFunc['db_query']('', '
		SELECT id_board
		FROM {db_prefix}topics
		WHERE id_topic = {int:id_topic}
		LIMIT 1', array('id_topic' => $id_topic));
    list($id_board) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    require_once $sourcedir . '/Subs-Post.php';
    // Update all the statistics.
    updateStats('topic');
    updateStats('subject', $id_topic, $target_subject);
    updateLastMessages($boards);
    logAction('merge', array('topic' => $id_topic, 'board' => $id_board));
    // Notify people that these topics have been merged?
    sendNotifications($id_topic, 'merge');
    // If there's a search index that needs updating, update it...
    require_once $sourcedir . '/Search.php';
    $searchAPI = findSearchAPI();
    if (is_callable(array($searchAPI, 'topicMerge'))) {
        $searchAPI->topicMerge($id_topic, $topics, $affected_msgs, empty($_POST['enforce_subject']) ? null : array($context['response_prefix'], $target_subject));
    }
    // Send them to the all done page.
    redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board);
}
Example #17
0
function notificationEveryone()
{
    global $db;
    $subscriptionsQuery = "SELECT `subscriptionId` FROM `forum_subscriptions`";
    $subscriptionsResult = mysqli_query($db, $subscriptionsQuery);
    if (mysqli_num_rows($subscriptionsResult) == 0) {
        // Do nothing if no one's subscribed
        return;
    }
    $subscriptionIds = array();
    while ($row = $subscriptionsResult->fetch_assoc()) {
        $subscriptionIds[] = $row['subscriptionId'];
    }
    sendNotifications($subscriptionIds);
}
Example #18
0
function Post2()
{
    global $board, $topic, $txt, $db_prefix, $modSettings, $sourcedir, $context;
    global $ID_MEMBER, $user_info, $board_info, $options, $func;
    // Previewing? Go back to start.
    if (isset($_REQUEST['preview'])) {
        return Post();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // No errors as yet.
    $post_errors = array();
    // If the session has timed out, let the user re-submit their form.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    require_once $sourcedir . '/Subs-Post.php';
    loadLanguage('Post');
    // Replying to a topic?
    if (!empty($topic) && !isset($_REQUEST['msg'])) {
        $request = db_query("\n\t\t\tSELECT t.locked, t.isSticky, t.ID_POLL, t.numReplies, m.ID_MEMBER\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\tWHERE t.ID_TOPIC = {$topic}\n\t\t\t\tAND m.ID_MSG = t.ID_FIRST_MSG\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($tmplocked, $tmpstickied, $pollID, $numReplies, $ID_MEMBER_POSTER) = mysql_fetch_row($request);
        mysql_free_result($request);
        // Don't allow a post if it's locked.
        if ($tmplocked != 0 && !allowedTo('moderate_board')) {
            fatal_lang_error(90, false);
        }
        // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
        if (isset($_REQUEST['poll']) && $pollID > 0) {
            unset($_REQUEST['poll']);
        }
        if ($ID_MEMBER_POSTER != $ID_MEMBER) {
            isAllowedTo('post_reply_any');
        } elseif (!allowedTo('post_reply_any')) {
            isAllowedTo('post_reply_own');
        }
        if (isset($_POST['lock'])) {
            // Nothing is changed to the lock.
            if (empty($tmplocked) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($tmplocked)) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $ID_MEMBER != $ID_MEMBER_POSTER) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You cannot override a moderator lock.
                if ($tmplocked == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // So you wanna (un)sticky this...let's see.
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $tmpstickied || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        // If the number of replies has changed, if the setting is enabled, go back to Post() - which handles the error.
        $newReplies = isset($_POST['num_replies']) && $numReplies > $_POST['num_replies'] ? $numReplies - $_POST['num_replies'] : 0;
        if (empty($options['no_new_reply_warning']) && !empty($newReplies)) {
            $_REQUEST['preview'] = true;
            return Post();
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (empty($topic)) {
        if (!isset($_REQUEST['poll']) || $modSettings['pollMode'] != '1') {
            isAllowedTo('post_new');
        }
        if (isset($_POST['lock'])) {
            // New topics are by default not locked.
            if (empty($_POST['lock'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                unset($_POST['lock']);
            } else {
                $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
            }
        }
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tm.ID_MEMBER, m.posterName, m.posterEmail, m.posterTime, \n\t\t\t\tt.ID_FIRST_MSG, t.locked, t.isSticky, t.ID_MEMBER_STARTED AS ID_MEMBER_POSTER\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\tWHERE m.ID_MSG = {$_REQUEST['msg']}\n\t\t\t\tAND t.ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('smf272', false);
        }
        $row = mysql_fetch_assoc($request);
        mysql_free_result($request);
        if (!empty($row['locked']) && !allowedTo('moderate_board')) {
            fatal_lang_error(90, false);
        }
        if (isset($_POST['lock'])) {
            // Nothing changes to the lock status.
            if (empty($_POST['lock']) && empty($row['locked']) || !empty($_POST['lock']) && !empty($row['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $ID_MEMBER != $row['ID_MEMBER_POSTER']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You're not allowed to break a moderator's lock.
                if ($row['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // Change the sticky status of this topic?
        if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $row['isSticky'])) {
            unset($_POST['sticky']);
        }
        if ($row['ID_MEMBER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            if (!empty($modSettings['edit_disable_time']) && $row['posterTime'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
            // If you're modifying a reply, I say it better be logged...
            $moderationAction = true;
        } else {
            isAllowedTo('modify_any');
            // Log it, assuming you're not modifying your own post.
            if ($row['ID_MEMBER'] != $ID_MEMBER) {
                $moderationAction = true;
            }
        }
        $posterIsGuest = empty($row['ID_MEMBER']);
        if (!allowedTo('moderate_forum') || !$posterIsGuest) {
            $_POST['guestname'] = addslashes($row['posterName']);
            $_POST['email'] = addslashes($row['posterEmail']);
        }
    }
    // If the poster is a guest evaluate the legality of name and email.
    if ($posterIsGuest) {
        $_POST['guestname'] = !isset($_POST['guestname']) ? '' : trim($_POST['guestname']);
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
            $post_errors[] = 'no_name';
        }
        if ($func['strlen']($_POST['guestname']) > 25) {
            $post_errors[] = 'long_name';
        }
        if (empty($modSettings['guest_post_no_email'])) {
            // Only check if they changed it!
            if (!isset($row) || $row['posterEmail'] != $_POST['email']) {
                if (!allowedTo('moderate_forum') && (!isset($_POST['email']) || $_POST['email'] == '')) {
                    $post_errors[] = 'no_email';
                }
                if (!allowedTo('moderate_forum') && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['email'])) == 0) {
                    $post_errors[] = 'bad_email';
                }
            }
            // Now make sure this email address is not banned from posting.
            isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt[28]));
        }
    }
    // Check the subject and message.
    if (!isset($_POST['subject']) || $func['htmltrim']($_POST['subject']) === '') {
        $post_errors[] = 'no_subject';
    }
    if (!isset($_POST['message']) || $func['htmltrim']($_POST['message']) === '') {
        $post_errors[] = 'no_message';
    } elseif (!empty($modSettings['max_messageLength']) && $func['strlen']($_POST['message']) > $modSettings['max_messageLength']) {
        $post_errors[] = 'long_message';
    } else {
        // Prepare the message a bit for some additional testing.
        $_POST['message'] = $func['htmlspecialchars']($_POST['message'], ENT_QUOTES);
        // Preparse code. (Zef)
        if ($user_info['is_guest']) {
            $user_info['name'] = $_POST['guestname'];
        }
        preparsecode($_POST['message']);
        // Let's see if there's still some content left without the tags.
        if ($func['htmltrim'](strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '') {
            $post_errors[] = 'no_message';
        }
    }
    if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && $func['htmltrim']($_POST['evtitle']) === '') {
        $post_errors[] = 'no_event';
    }
    // You are not!
    if (isset($_POST['message']) && strtolower($_POST['message']) == 'i am the administrator.' && !$user_info['is_admin']) {
        fatal_error('Knave! Masquerader! Charlatan!', false);
    }
    // Validate the poll...
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            fatal_lang_error(1, false);
        }
        // This is a new topic... so it's a new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($ID_MEMBER == $row['ID_MEMBER_POSTER'] && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        if (!isset($_POST['question']) || trim($_POST['question']) == '') {
            $post_errors[] = 'no_question';
        }
        $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
        // Get rid of empty ones.
        foreach ($_POST['options'] as $k => $option) {
            if ($option == '') {
                unset($_POST['options'][$k], $_POST['options'][$k]);
            }
        }
        // What are you going to vote between with one choice?!?
        if (count($_POST['options']) < 2) {
            $post_errors[] = 'poll_few';
        }
    }
    if ($posterIsGuest) {
        // If user is a guest, make sure the chosen name isn't taken.
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($row['posterName']) || $_POST['guestname'] != $row['posterName'])) {
            $post_errors[] = 'bad_name';
        }
    } elseif (!isset($_REQUEST['msg'])) {
        $_POST['guestname'] = addslashes($user_info['username']);
        $_POST['email'] = addslashes($user_info['email']);
    }
    // Any mistakes?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_REQUEST['preview'] = true;
        $context['post_error'] = array('messages' => array());
        foreach ($post_errors as $post_error) {
            $context['post_error'][$post_error] = true;
            $context['post_error']['messages'][] = $txt['error_' . $post_error];
        }
        return Post();
    }
    // Make sure the user isn't spamming the board.
    if (!isset($_REQUEST['msg'])) {
        spamProtection('spam');
    }
    // At about this point, we're posting and that's that.
    ignore_user_abort(true);
    @set_time_limit(300);
    // Add special html entities to the subject, name, and email.
    $_POST['subject'] = strtr($func['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
    $_POST['guestname'] = htmlspecialchars($_POST['guestname']);
    $_POST['email'] = htmlspecialchars($_POST['email']);
    // At this point, we want to make sure the subject isn't too long.
    if ($func['strlen']($_POST['subject']) > 100) {
        $_POST['subject'] = addslashes($func['substr'](stripslashes($_POST['subject']), 0, 100));
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Make sure that the user has not entered a ridiculous number of options..
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
            $_POST['poll_max_votes'] = count($_POST['options']);
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
        // Just set it to zero if it's not there..
        if (!isset($_POST['poll_hide'])) {
            $_POST['poll_hide'] = 0;
        } else {
            $_POST['poll_hide'] = (int) $_POST['poll_hide'];
        }
        $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
        // If the user tries to set the poll too far in advance, don't let them.
        if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
            fatal_lang_error('poll_range_error', false);
        } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        }
        // Clean up the question and answers.
        $_POST['question'] = $func['htmlspecialchars']($_POST['question']);
        $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
    }
    // Check if they are trying to delete any current attachments....
    if (isset($_REQUEST['msg'], $_POST['attach_del']) && allowedTo('post_attachment')) {
        $del_temp = array();
        foreach ($_POST['attach_del'] as $i => $dummy) {
            $del_temp[$i] = (int) $dummy;
        }
        require_once $sourcedir . '/ManageAttachments.php';
        removeAttachments('a.attachmentType = 0 AND a.ID_MSG = ' . (int) $_REQUEST['msg'] . ' AND a.ID_ATTACH NOT IN (' . implode(', ', $del_temp) . ')');
    }
    // ...or attach a new file...
    if (isset($_FILES['attachment']['name']) || !empty($_SESSION['temp_attachments'])) {
        isAllowedTo('post_attachment');
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = db_query("\n\t\t\t\tSELECT COUNT(*), SUM(size)\n\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\tAND attachmentType = 0", __FILE__, __LINE__);
            list($quantity, $total_size) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                if (preg_match('~^post_tmp_' . $ID_MEMBER . '_\\d+$~', $attachID) == 0) {
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($modSettings['attachmentUploadDir'] . '/' . $attachID);
                    continue;
                }
                $_FILES['attachment']['tmp_name'][] = $attachID;
                $_FILES['attachment']['name'][] = addslashes($name);
                $_FILES['attachment']['size'][] = filesize($modSettings['attachmentUploadDir'] . '/' . $attachID);
                list($_FILES['attachment']['width'][], $_FILES['attachment']['height'][]) = @getimagesize($modSettings['attachmentUploadDir'] . '/' . $attachID);
                unset($_SESSION['temp_attachments'][$attachID]);
            }
        }
        if (!isset($_FILES['attachment']['name'])) {
            $_FILES['attachment']['tmp_name'] = array();
        }
        $attachIDs = array();
        foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
            if ($_FILES['attachment']['name'][$n] == '') {
                continue;
            }
            // Have we reached the maximum number of files we are allowed?
            $quantity++;
            if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
            }
            // Check the total upload size for this post...
            $total_size += $_FILES['attachment']['size'][$n];
            if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                fatal_lang_error('smf122', false, array($modSettings['attachmentPostLimit']));
            }
            $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $ID_MEMBER, 'name' => $_FILES['attachment']['name'][$n], 'tmp_name' => $_FILES['attachment']['tmp_name'][$n], 'size' => $_FILES['attachment']['size'][$n]);
            if (createAttachment($attachmentOptions)) {
                $attachIDs[] = $attachmentOptions['id'];
                if (!empty($attachmentOptions['thumb'])) {
                    $attachIDs[] = $attachmentOptions['thumb'];
                }
            } else {
                if (in_array('could_not_upload', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf124');
                }
                if (in_array('too_large', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf122', false, array($modSettings['attachmentSizeLimit']));
                }
                if (in_array('bad_extension', $attachmentOptions['errors'])) {
                    fatal_error($attachmentOptions['name'] . '.<br />' . $txt['smf123'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                }
                if (in_array('directory_full', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf126');
                }
                if (in_array('bad_filename', $attachmentOptions['errors'])) {
                    fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['smf130b'] . '.');
                }
                if (in_array('taken_filename', $attachmentOptions['errors'])) {
                    fatal_lang_error('smf125');
                }
            }
        }
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Create the poll.
        db_query("\n\t\t\tINSERT INTO {$db_prefix}polls\n\t\t\t\t(question, hideResults, maxVotes, expireTime, ID_MEMBER, posterName, changeVote)\n\t\t\tVALUES (SUBSTRING('{$_POST['question']}', 1, 255), {$_POST['poll_hide']}, {$_POST['poll_max_votes']},\n\t\t\t\t" . (empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24) . ", {$ID_MEMBER}, SUBSTRING('{$_POST['guestname']}', 1, 255), {$_POST['poll_change_vote']})", __FILE__, __LINE__);
        $ID_POLL = db_insert_id();
        // Create each answer choice.
        $i = 0;
        $setString = '';
        foreach ($_POST['options'] as $option) {
            $setString .= "\n\t\t\t\t\t({$ID_POLL}, {$i}, SUBSTRING('{$option}', 1, 255)),";
            $i++;
        }
        db_query("\n\t\t\tINSERT INTO {$db_prefix}poll_choices\n\t\t\t\t(ID_POLL, ID_CHOICE, label)\n\t\t\tVALUES" . substr($setString, 0, -1), __FILE__, __LINE__);
    } else {
        $ID_POLL = 0;
    }
    // Creating a new topic?
    $newTopic = empty($_REQUEST['msg']) && empty($topic);
    // Collect all parameters for the creation or modification of a post.
    $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*\':"<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs);
    $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $ID_POLL : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true);
    $posterOptions = array('id' => $ID_MEMBER, 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
    // This is an already existing message. Edit it.
    if (!empty($_REQUEST['msg'])) {
        // Have admins allowed people to hide their screwups?
        if (time() - $row['posterTime'] > $modSettings['edit_wait_time'] || $ID_MEMBER != $row['ID_MEMBER']) {
            $msgOptions['modify_time'] = time();
            $msgOptions['modify_name'] = addslashes($user_info['name']);
        }
        modifyPost($msgOptions, $topicOptions, $posterOptions);
    } else {
        createPost($msgOptions, $topicOptions, $posterOptions);
        if (isset($topicOptions['id'])) {
            $topic = $topicOptions['id'];
        }
    }
    // Editing or posting an event?
    if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
        require_once $sourcedir . '/Calendar.php';
        calendarCanLink();
        calendarInsertEvent($board, $topic, $_POST['evtitle'], $ID_MEMBER, $_POST['month'], $_POST['day'], $_POST['year'], isset($_POST['span']) ? $_POST['span'] : null);
    } elseif (isset($_POST['calendar'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
        // Validate the post...
        require_once $sourcedir . '/Subs-Post.php';
        calendarValidatePost();
        // If you're not allowed to edit any events, you have to be the poster.
        if (!allowedTo('calendar_edit_any')) {
            // Get the event's poster.
            $request = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}", __FILE__, __LINE__);
            $row2 = mysql_fetch_assoc($request);
            mysql_free_result($request);
            // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
            isAllowedTo('calendar_edit_' . ($row2['ID_MEMBER'] == $ID_MEMBER ? 'own' : 'any'));
        }
        // Delete it?
        if (isset($_REQUEST['deleteevent'])) {
            db_query("\n\t\t\t\tDELETE FROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        } else {
            $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
            $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
            db_query("\n\t\t\t\tUPDATE {$db_prefix}calendar\n\t\t\t\tSET endDate = '" . strftime('%Y-%m-%d', $start_time + $span * 86400) . "',\n\t\t\t\t\tstartDate = '" . strftime('%Y-%m-%d', $start_time) . "',\n\t\t\t\t\ttitle = '" . $func['htmlspecialchars']($_REQUEST['evtitle'], ENT_QUOTES) . "'\n\t\t\t\tWHERE ID_EVENT = {$_REQUEST['eventid']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        }
        updateStats('calendar');
    }
    // Marking read should be done even for editing messages....
    if (!$user_info['is_guest']) {
        // Mark all the parents read.  (since you just posted and they will be unread.)
        if (!empty($board_info['parent_boards'])) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}log_boards\n\t\t\t\tSET ID_MSG = {$modSettings['maxMsgID']}\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_BOARD IN (" . implode(',', array_keys($board_info['parent_boards'])) . ")", __FILE__, __LINE__);
        }
    }
    // Turn notification on or off.  (note this just blows smoke if it's already on or off.)
    if (!empty($_POST['notify'])) {
        if (allowedTo('mark_any_notify')) {
            db_query("\n\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_notify\n\t\t\t\t\t(ID_MEMBER, ID_TOPIC, ID_BOARD)\n\t\t\t\tVALUES ({$ID_MEMBER}, {$topic}, 0)", __FILE__, __LINE__);
        }
    } elseif (!$newTopic) {
        db_query("\n\t\t\tDELETE FROM {$db_prefix}log_notify\n\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
    }
    // Log an act of moderation - modifying.
    if (!empty($moderationAction)) {
        logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $row['ID_MEMBER']));
    }
    if (isset($_POST['lock']) && $_POST['lock'] != 2) {
        logAction('lock', array('topic' => $topicOptions['id']));
    }
    if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
        logAction('sticky', array('topic' => $topicOptions['id']));
    }
    // Notify any members who have notification turned on for this topic.
    if ($newTopic) {
        notifyMembersBoard();
    } elseif (empty($_REQUEST['msg'])) {
        sendNotifications($topic, 'reply');
    }
    // Returning to the topic?
    if (!empty($_REQUEST['goback'])) {
        // Mark the board as read.... because it might get confusing otherwise.
        db_query("\n\t\t\tUPDATE {$db_prefix}log_boards\n\t\t\tSET ID_MSG = {$modSettings['maxMsgID']}\n\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND ID_BOARD = {$board}", __FILE__, __LINE__);
    }
    if (!empty($_POST['announce_topic'])) {
        redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    if (!empty($_POST['move']) && allowedTo('move_any')) {
        redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    // Return to post if the mod is on.
    if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], $context['browser']['is_ie']);
    } elseif (!empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.new#new', $context['browser']['is_ie']);
    } else {
        redirectexit('board=' . $board . '.0');
    }
}
Example #19
0
     autoPassSuggestedJobs();
     break;
 case 'processPendingReviewsNotifications':
     Utils::validateAPIKey();
     processPendingReviewsNotifications();
     break;
 case 'getFavoriteUsers':
     getFavoriteUsers();
     break;
 case 'deployErrorNotification':
     Utils::validateAPIKey();
     deployErrorNotification();
     break;
 case 'sendNotifications':
     Utils::validateAPIKey();
     sendNotifications();
     break;
 case 'checkInactiveProjects':
     Utils::validateAPIKey();
     checkInactiveProjects();
     break;
 case 'checkRemovableProjects':
     Utils::validateAPIKey();
     checkRemovableProjects();
     break;
 case 'setFavorite':
     setFavorite();
     break;
 case 'getBonusHistory':
     getBonusHistory();
     break;
Example #20
0
function Post2()
{
    global $board, $topic, $txt, $modSettings, $sourcedir, $context;
    global $user_info, $board_info, $options, $smcFunc;
    // Sneaking off, are we?
    if (empty($_POST) && empty($topic)) {
        redirectexit('action=post;board=' . $board . '.0');
    } elseif (empty($_POST) && !empty($topic)) {
        redirectexit('action=post;topic=' . $topic . '.0');
    }
    // No need!
    $context['robot_no_index'] = true;
    // If we came from WYSIWYG then turn it back into BBC regardless.
    if (!empty($_REQUEST['message_mode']) && isset($_REQUEST['message'])) {
        require_once $sourcedir . '/Subs-Editor.php';
        $_REQUEST['message'] = html_to_bbc($_REQUEST['message']);
        // We need to unhtml it now as it gets done shortly.
        $_REQUEST['message'] = un_htmlspecialchars($_REQUEST['message']);
        // We need this for everything else.
        $_POST['message'] = $_REQUEST['message'];
    }
    // Previewing? Go back to start.
    if (isset($_REQUEST['preview'])) {
        return Post();
    }
    // Prevent double submission of this form.
    checkSubmitOnce('check');
    // No errors as yet.
    $post_errors = array();
    // If the session has timed out, let the user re-submit their form.
    if (checkSession('post', '', false) != '') {
        $post_errors[] = 'session_timeout';
    }
    // Wrong verification code?
    if (!$user_info['is_admin'] && !$user_info['is_mod'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1)) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions, true);
        if (is_array($context['require_verification'])) {
            $post_errors = array_merge($post_errors, $context['require_verification']);
        }
    }
    require_once $sourcedir . '/Subs-Post.php';
    loadLanguage('Post');
    // If this isn't a new topic load the topic info that we need.
    if (!empty($topic)) {
        $request = $smcFunc['db_query']('', '
			SELECT locked, is_sticky, id_poll, approved, id_first_msg, id_last_msg, id_member_started, id_board
			FROM {db_prefix}topics
			WHERE id_topic = {int:current_topic}
			LIMIT 1', array('current_topic' => $topic));
        $topic_info = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        // Though the topic should be there, it might have vanished.
        if (!is_array($topic_info)) {
            fatal_lang_error('topic_doesnt_exist');
        }
        // Did this topic suddenly move? Just checking...
        if ($topic_info['id_board'] != $board) {
            fatal_lang_error('not_a_topic');
        }
    }
    // Replying to a topic?
    if (!empty($topic) && !isset($_REQUEST['msg'])) {
        // Don't allow a post if it's locked.
        if ($topic_info['locked'] != 0 && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        // Sorry, multiple polls aren't allowed... yet.  You should stop giving me ideas :P.
        if (isset($_REQUEST['poll']) && $topic_info['id_poll'] > 0) {
            unset($_REQUEST['poll']);
        }
        // Do the permissions and approval stuff...
        $becomesApproved = true;
        if ($topic_info['id_member_started'] != $user_info['id']) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_any');
            }
        } elseif (!allowedTo('post_reply_any')) {
            if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) {
                $becomesApproved = false;
            } else {
                isAllowedTo('post_reply_own');
            }
        }
        if (isset($_POST['lock'])) {
            // Nothing is changed to the lock.
            if (empty($topic_info['locked']) && empty($_POST['lock']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You cannot override a moderator lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // So you wanna (un)sticky this...let's see.
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || $_POST['sticky'] == $topic_info['is_sticky'] || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        // If the number of replies has changed, if the setting is enabled, go back to Post() - which handles the error.
        if (empty($options['no_new_reply_warning']) && isset($_POST['last_msg']) && $topic_info['id_last_msg'] > $_POST['last_msg']) {
            $_REQUEST['preview'] = true;
            return Post();
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (empty($topic)) {
        // Now don't be silly, new topics will get their own id_msg soon enough.
        unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']);
        // Do like, the permissions, for safety and stuff...
        $becomesApproved = true;
        if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) {
            $becomesApproved = false;
        } else {
            isAllowedTo('post_new');
        }
        if (isset($_POST['lock'])) {
            // New topics are by default not locked.
            if (empty($_POST['lock'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own'))) {
                unset($_POST['lock']);
            } else {
                $_POST['lock'] = allowedTo('lock_any') ? 1 : 2;
            }
        }
        if (isset($_POST['sticky']) && (empty($modSettings['enableStickyTopics']) || empty($_POST['sticky']) || !allowedTo('make_sticky'))) {
            unset($_POST['sticky']);
        }
        $posterIsGuest = $user_info['is_guest'];
    } elseif (isset($_REQUEST['msg']) && !empty($topic)) {
        $_REQUEST['msg'] = (int) $_REQUEST['msg'];
        $request = $smcFunc['db_query']('', '
			SELECT id_member, poster_name, poster_email, poster_time, approved
			FROM {db_prefix}messages
			WHERE id_msg = {int:id_msg}
			LIMIT 1', array('id_msg' => $_REQUEST['msg']));
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('cant_find_messages', false);
        }
        $row = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        if (!empty($topic_info['locked']) && !allowedTo('moderate_board')) {
            fatal_lang_error('topic_locked', false);
        }
        if (isset($_POST['lock'])) {
            // Nothing changes to the lock status.
            if (empty($_POST['lock']) && empty($topic_info['locked']) || !empty($_POST['lock']) && !empty($topic_info['locked'])) {
                unset($_POST['lock']);
            } elseif (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $topic_info['id_member_started']) {
                unset($_POST['lock']);
            } elseif (!allowedTo('lock_any')) {
                // You're not allowed to break a moderator's lock.
                if ($topic_info['locked'] == 1) {
                    unset($_POST['lock']);
                } else {
                    $_POST['lock'] = empty($_POST['lock']) ? 0 : 2;
                }
            } else {
                $_POST['lock'] = empty($_POST['lock']) ? 0 : 1;
            }
        }
        // Change the sticky status of this topic?
        if (isset($_POST['sticky']) && (!allowedTo('make_sticky') || $_POST['sticky'] == $topic_info['is_sticky'])) {
            unset($_POST['sticky']);
        }
        if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) {
            if ((!$modSettings['postmod_active'] || $row['approved']) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) {
                isAllowedTo('modify_replies');
            } else {
                isAllowedTo('modify_own');
            }
        } elseif ($topic_info['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) {
            isAllowedTo('modify_replies');
            // If you're modifying a reply, I say it better be logged...
            $moderationAction = true;
        } else {
            isAllowedTo('modify_any');
            // Log it, assuming you're not modifying your own post.
            if ($row['id_member'] != $user_info['id']) {
                $moderationAction = true;
            }
        }
        $posterIsGuest = empty($row['id_member']);
        // Can they approve it?
        $can_approve = allowedTo('approve_posts');
        $becomesApproved = $modSettings['postmod_active'] ? $can_approve && !$row['approved'] ? !empty($_REQUEST['approve']) ? 1 : 0 : $row['approved'] : 1;
        $approve_has_changed = $row['approved'] != $becomesApproved;
        if (!allowedTo('moderate_forum') || !$posterIsGuest) {
            $_POST['guestname'] = $row['poster_name'];
            $_POST['email'] = $row['poster_email'];
        }
    }
    // If the poster is a guest evaluate the legality of name and email.
    if ($posterIsGuest) {
        $_POST['guestname'] = !isset($_POST['guestname']) ? '' : trim($_POST['guestname']);
        $_POST['email'] = !isset($_POST['email']) ? '' : trim($_POST['email']);
        if ($_POST['guestname'] == '' || $_POST['guestname'] == '_') {
            $post_errors[] = 'no_name';
        }
        if ($smcFunc['strlen']($_POST['guestname']) > 25) {
            $post_errors[] = 'long_name';
        }
        if (empty($modSettings['guest_post_no_email'])) {
            // Only check if they changed it!
            if (!isset($row) || $row['poster_email'] != $_POST['email']) {
                if (!allowedTo('moderate_forum') && (!isset($_POST['email']) || $_POST['email'] == '')) {
                    $post_errors[] = 'no_email';
                }
                if (!allowedTo('moderate_forum') && preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['email']) == 0) {
                    $post_errors[] = 'bad_email';
                }
            }
            // Now make sure this email address is not banned from posting.
            isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt['guest_title']));
        }
        // In case they are making multiple posts this visit, help them along by storing their name.
        if (empty($post_errors)) {
            $_SESSION['guest_name'] = $_POST['guestname'];
            $_SESSION['guest_email'] = $_POST['email'];
        }
    }
    // Check the subject and message.
    if (!isset($_POST['subject']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['subject'])) === '') {
        $post_errors[] = 'no_subject';
    }
    if (!isset($_POST['message']) || $smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['message']), ENT_QUOTES) === '') {
        $post_errors[] = 'no_message';
    } elseif (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_POST['message']) > $modSettings['max_messageLength']) {
        $post_errors[] = 'long_message';
    } else {
        // Prepare the message a bit for some additional testing.
        $_POST['message'] = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES);
        // Preparse code. (Zef)
        if ($user_info['is_guest']) {
            $user_info['name'] = $_POST['guestname'];
        }
        preparsecode($_POST['message']);
        // Let's see if there's still some content left without the tags.
        if ($smcFunc['htmltrim'](strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '' && (!allowedTo('admin_forum') || strpos($_POST['message'], '[html]') === false)) {
            $post_errors[] = 'no_message';
        }
    }
    if (isset($_POST['calendar']) && !isset($_REQUEST['deleteevent']) && $smcFunc['htmltrim']($_POST['evtitle']) === '') {
        $post_errors[] = 'no_event';
    }
    // You are not!
    if (isset($_POST['message']) && strtolower($_POST['message']) == 'i am the administrator.' && !$user_info['is_admin']) {
        fatal_error('Knave! Masquerader! Charlatan!', false);
    }
    // Validate the poll...
    if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') {
        if (!empty($topic) && !isset($_REQUEST['msg'])) {
            fatal_lang_error('no_access', false);
        }
        // This is a new topic... so it's a new poll.
        if (empty($topic)) {
            isAllowedTo('poll_post');
        } elseif ($user_info['id'] == $topic_info['id_member_started'] && !allowedTo('poll_add_any')) {
            isAllowedTo('poll_add_own');
        } else {
            isAllowedTo('poll_add_any');
        }
        if (!isset($_POST['question']) || trim($_POST['question']) == '') {
            $post_errors[] = 'no_question';
        }
        $_POST['options'] = empty($_POST['options']) ? array() : htmltrim__recursive($_POST['options']);
        // Get rid of empty ones.
        foreach ($_POST['options'] as $k => $option) {
            if ($option == '') {
                unset($_POST['options'][$k], $_POST['options'][$k]);
            }
        }
        // What are you going to vote between with one choice?!?
        if (count($_POST['options']) < 2) {
            $post_errors[] = 'poll_few';
        }
    }
    if ($posterIsGuest) {
        // If user is a guest, make sure the chosen name isn't taken.
        require_once $sourcedir . '/Subs-Members.php';
        if (isReservedName($_POST['guestname'], 0, true, false) && (!isset($row['poster_name']) || $_POST['guestname'] != $row['poster_name'])) {
            $post_errors[] = 'bad_name';
        }
    } elseif (!isset($_REQUEST['msg'])) {
        $_POST['guestname'] = $user_info['username'];
        $_POST['email'] = $user_info['email'];
    }
    // Any mistakes?
    if (!empty($post_errors)) {
        loadLanguage('Errors');
        // Previewing.
        $_REQUEST['preview'] = true;
        $context['post_error'] = array('messages' => array());
        foreach ($post_errors as $post_error) {
            $context['post_error'][$post_error] = true;
            if ($post_error == 'long_message') {
                $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']);
            }
            $context['post_error']['messages'][] = $txt['error_' . $post_error];
        }
        return Post();
    }
    // Make sure the user isn't spamming the board.
    if (!isset($_REQUEST['msg'])) {
        spamProtection('post');
    }
    // At about this point, we're posting and that's that.
    ignore_user_abort(true);
    @set_time_limit(300);
    // Add special html entities to the subject, name, and email.
    $_POST['subject'] = strtr($smcFunc['htmlspecialchars']($_POST['subject']), array("\r" => '', "\n" => '', "\t" => ''));
    $_POST['guestname'] = htmlspecialchars($_POST['guestname']);
    $_POST['email'] = htmlspecialchars($_POST['email']);
    // At this point, we want to make sure the subject isn't too long.
    if ($smcFunc['strlen']($_POST['subject']) > 100) {
        $_POST['subject'] = $smcFunc['substr']($_POST['subject'], 0, 100);
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Make sure that the user has not entered a ridiculous number of options..
        if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) {
            $_POST['poll_max_votes'] = 1;
        } elseif ($_POST['poll_max_votes'] > count($_POST['options'])) {
            $_POST['poll_max_votes'] = count($_POST['options']);
        } else {
            $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes'];
        }
        $_POST['poll_expire'] = (int) $_POST['poll_expire'];
        $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']);
        // Just set it to zero if it's not there..
        if (!isset($_POST['poll_hide'])) {
            $_POST['poll_hide'] = 0;
        } else {
            $_POST['poll_hide'] = (int) $_POST['poll_hide'];
        }
        $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0;
        $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0;
        // Make sure guests are actually allowed to vote generally.
        if ($_POST['poll_guest_vote']) {
            require_once $sourcedir . '/Subs-Members.php';
            $allowedVoteGroups = groupsAllowedTo('poll_vote', $board);
            if (!in_array(-1, $allowedVoteGroups['allowed'])) {
                $_POST['poll_guest_vote'] = 0;
            }
        }
        // If the user tries to set the poll too far in advance, don't let them.
        if (!empty($_POST['poll_expire']) && $_POST['poll_expire'] < 1) {
            fatal_lang_error('poll_range_error', false);
        } elseif (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) {
            $_POST['poll_hide'] = 1;
        }
        // Clean up the question and answers.
        $_POST['question'] = htmlspecialchars($_POST['question']);
        $_POST['question'] = $smcFunc['truncate']($_POST['question'], 255);
        $_POST['question'] = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', $_POST['question']);
        $_POST['options'] = htmlspecialchars__recursive($_POST['options']);
    }
    // Check if they are trying to delete any current attachments....
    if (isset($_REQUEST['msg'], $_POST['attach_del']) && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments'))) {
        $del_temp = array();
        foreach ($_POST['attach_del'] as $i => $dummy) {
            $del_temp[$i] = (int) $dummy;
        }
        require_once $sourcedir . '/ManageAttachments.php';
        $attachmentQuery = array('attachment_type' => 0, 'id_msg' => (int) $_REQUEST['msg'], 'not_id_attach' => $del_temp);
        removeAttachments($attachmentQuery);
    }
    // ...or attach a new file...
    if (isset($_FILES['attachment']['name']) || !empty($_SESSION['temp_attachments']) && empty($_POST['from_qr'])) {
        // Verify they can post them!
        if (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_attachments')) {
            isAllowedTo('post_attachment');
        }
        // Make sure we're uploading to the right place.
        if (!empty($modSettings['currentAttachmentUploadDir'])) {
            if (!is_array($modSettings['attachmentUploadDir'])) {
                $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']);
            }
            // The current directory, of course!
            $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']];
        } else {
            $current_attach_dir = $modSettings['attachmentUploadDir'];
        }
        // If this isn't a new post, check the current attachments.
        if (isset($_REQUEST['msg'])) {
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*), SUM(size)
				FROM {db_prefix}attachments
				WHERE id_msg = {int:id_msg}
					AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0));
            list($quantity, $total_size) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
        } else {
            $quantity = 0;
            $total_size = 0;
        }
        if (!empty($_SESSION['temp_attachments'])) {
            foreach ($_SESSION['temp_attachments'] as $attachID => $name) {
                if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) {
                    continue;
                }
                if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) {
                    unset($_SESSION['temp_attachments'][$attachID]);
                    @unlink($current_attach_dir . '/' . $attachID);
                    continue;
                }
                $_FILES['attachment']['tmp_name'][] = $attachID;
                $_FILES['attachment']['name'][] = $name;
                $_FILES['attachment']['size'][] = filesize($current_attach_dir . '/' . $attachID);
                list($_FILES['attachment']['width'][], $_FILES['attachment']['height'][]) = @getimagesize($current_attach_dir . '/' . $attachID);
                unset($_SESSION['temp_attachments'][$attachID]);
            }
        }
        if (!isset($_FILES['attachment']['name'])) {
            $_FILES['attachment']['tmp_name'] = array();
        }
        $attachIDs = array();
        foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) {
            if ($_FILES['attachment']['name'][$n] == '') {
                continue;
            }
            // Have we reached the maximum number of files we are allowed?
            $quantity++;
            if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) {
                checkSubmitOnce('free');
                fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit']));
            }
            // Check the total upload size for this post...
            $total_size += $_FILES['attachment']['size'][$n];
            if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) {
                checkSubmitOnce('free');
                fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit']));
            }
            $attachmentOptions = array('post' => isset($_REQUEST['msg']) ? $_REQUEST['msg'] : 0, 'poster' => $user_info['id'], 'name' => $_FILES['attachment']['name'][$n], 'tmp_name' => $_FILES['attachment']['tmp_name'][$n], 'size' => $_FILES['attachment']['size'][$n], 'approved' => !$modSettings['postmod_active'] || allowedTo('post_attachment'));
            if (createAttachment($attachmentOptions)) {
                $attachIDs[] = $attachmentOptions['id'];
                if (!empty($attachmentOptions['thumb'])) {
                    $attachIDs[] = $attachmentOptions['thumb'];
                }
            } else {
                if (in_array('could_not_upload', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('attach_timeout', 'critical');
                }
                if (in_array('too_large', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit']));
                }
                if (in_array('bad_extension', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error($attachmentOptions['name'] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false);
                }
                if (in_array('directory_full', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('ran_out_of_space', 'critical');
                }
                if (in_array('bad_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_error(basename($attachmentOptions['name']) . '.<br />' . $txt['restricted_filename'] . '.', 'critical');
                }
                if (in_array('taken_filename', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('filename_exists');
                }
                if (in_array('bad_attachment', $attachmentOptions['errors'])) {
                    checkSubmitOnce('free');
                    fatal_lang_error('bad_attachment');
                }
            }
        }
    }
    // Make the poll...
    if (isset($_REQUEST['poll'])) {
        // Create the poll.
        $smcFunc['db_insert']('', '{db_prefix}polls', array('question' => 'string-255', 'hide_results' => 'int', 'max_votes' => 'int', 'expire_time' => 'int', 'id_member' => 'int', 'poster_name' => 'string-255', 'change_vote' => 'int', 'guest_vote' => 'int'), array($_POST['question'], $_POST['poll_hide'], $_POST['poll_max_votes'], empty($_POST['poll_expire']) ? 0 : time() + $_POST['poll_expire'] * 3600 * 24, $user_info['id'], $_POST['guestname'], $_POST['poll_change_vote'], $_POST['poll_guest_vote']), array('id_poll'));
        $id_poll = $smcFunc['db_insert_id']('{db_prefix}polls', 'id_poll');
        // Create each answer choice.
        $i = 0;
        $pollOptions = array();
        foreach ($_POST['options'] as $option) {
            $pollOptions[] = array($id_poll, $i, $option);
            $i++;
        }
        $smcFunc['db_insert']('insert', '{db_prefix}poll_choices', array('id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255'), $pollOptions, array('id_poll', 'id_choice'));
    } else {
        $id_poll = 0;
    }
    // Creating a new topic?
    $newTopic = empty($_REQUEST['msg']) && empty($topic);
    $_POST['icon'] = !empty($attachIDs) && $_POST['icon'] == 'xx' ? 'clip' : $_POST['icon'];
    // Collect all parameters for the creation or modification of a post.
    $msgOptions = array('id' => empty($_REQUEST['msg']) ? 0 : (int) $_REQUEST['msg'], 'subject' => $_POST['subject'], 'body' => $_POST['message'], 'icon' => preg_replace('~[\\./\\\\*:"\'<>]~', '', $_POST['icon']), 'smileys_enabled' => !isset($_POST['ns']), 'attachments' => empty($attachIDs) ? array() : $attachIDs, 'approved' => $becomesApproved);
    $topicOptions = array('id' => empty($topic) ? 0 : $topic, 'board' => $board, 'poll' => isset($_REQUEST['poll']) ? $id_poll : null, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true, 'is_approved' => !$modSettings['postmod_active'] || empty($topic) || !empty($board_info['cur_topic_approved']));
    $posterOptions = array('id' => $user_info['id'], 'name' => $_POST['guestname'], 'email' => $_POST['email'], 'update_post_count' => !$user_info['is_guest'] && !isset($_REQUEST['msg']) && $board_info['posts_count']);
    // This is an already existing message. Edit it.
    if (!empty($_REQUEST['msg'])) {
        // Have admins allowed people to hide their screwups?
        if (time() - $row['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $row['id_member']) {
            $msgOptions['modify_time'] = time();
            $msgOptions['modify_name'] = $user_info['name'];
        }
        // This will save some time...
        if (empty($approve_has_changed)) {
            unset($msgOptions['approved']);
        }
        modifyPost($msgOptions, $topicOptions, $posterOptions);
    } else {
        createPost($msgOptions, $topicOptions, $posterOptions);
        if (isset($topicOptions['id'])) {
            $topic = $topicOptions['id'];
        }
    }
    // Editing or posting an event?
    if (isset($_POST['calendar']) && (!isset($_REQUEST['eventid']) || $_REQUEST['eventid'] == -1)) {
        require_once $sourcedir . '/Subs-Calendar.php';
        // Make sure they can link an event to this post.
        canLinkEvent();
        // Insert the event.
        $eventOptions = array('board' => $board, 'topic' => $topic, 'title' => $_POST['evtitle'], 'member' => $user_info['id'], 'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']), 'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0);
        insertEvent($eventOptions);
    } elseif (isset($_POST['calendar'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
        // Validate the post...
        require_once $sourcedir . '/Subs-Calendar.php';
        validateEventPost();
        // If you're not allowed to edit any events, you have to be the poster.
        if (!allowedTo('calendar_edit_any')) {
            // Get the event's poster.
            $request = $smcFunc['db_query']('', '
				SELECT id_member
				FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
            $row2 = $smcFunc['db_fetch_assoc']($request);
            $smcFunc['db_free_result']($request);
            // Silly hacker, Trix are for kids. ...probably trademarked somewhere, this is FAIR USE! (parody...)
            isAllowedTo('calendar_edit_' . ($row2['id_member'] == $user_info['id'] ? 'own' : 'any'));
        }
        // Delete it?
        if (isset($_REQUEST['deleteevent'])) {
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}calendar
				WHERE id_event = {int:id_event}', array('id_event' => $_REQUEST['eventid']));
        } else {
            $span = !empty($modSettings['cal_allowspan']) && !empty($_REQUEST['span']) ? min((int) $modSettings['cal_maxspan'], (int) $_REQUEST['span'] - 1) : 0;
            $start_time = mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year']);
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}calendar
				SET end_date = {date:end_date},
					start_date = {date:start_date},
					title = {string:title}
				WHERE id_event = {int:id_event}', array('end_date' => strftime('%Y-%m-%d', $start_time + $span * 86400), 'start_date' => strftime('%Y-%m-%d', $start_time), 'id_event' => $_REQUEST['eventid'], 'title' => $smcFunc['htmlspecialchars']($_REQUEST['evtitle'], ENT_QUOTES)));
        }
        updateSettings(array('calendar_updated' => time()));
    }
    // Marking read should be done even for editing messages....
    // Mark all the parents read.  (since you just posted and they will be unread.)
    if (!$user_info['is_guest'] && !empty($board_info['parent_boards'])) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:id_msg}
			WHERE id_member = {int:current_member}
				AND id_board IN ({array_int:board_list})', array('current_member' => $user_info['id'], 'board_list' => array_keys($board_info['parent_boards']), 'id_msg' => $modSettings['maxMsgID']));
    }
    // Turn notification on or off.  (note this just blows smoke if it's already on or off.)
    if (!empty($_POST['notify']) && allowedTo('mark_any_notify')) {
        $smcFunc['db_insert']('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int'), array($user_info['id'], $topic, 0), array('id_member', 'id_topic', 'id_board'));
    } elseif (!$newTopic) {
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}log_notify
			WHERE id_member = {int:current_member}
				AND id_topic = {int:current_topic}', array('current_member' => $user_info['id'], 'current_topic' => $topic));
    }
    // Log an act of moderation - modifying.
    if (!empty($moderationAction)) {
        logAction('modify', array('topic' => $topic, 'message' => (int) $_REQUEST['msg'], 'member' => $row['id_member'], 'board' => $board));
    }
    if (isset($_POST['lock']) && $_POST['lock'] != 2) {
        logAction('lock', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    if (isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics'])) {
        logAction('sticky', array('topic' => $topicOptions['id'], 'board' => $topicOptions['board']));
    }
    // Notify any members who have notification turned on for this topic - only do this if it's going to be approved(!)
    if ($becomesApproved) {
        if ($newTopic) {
            $notifyData = array('body' => $_POST['message'], 'subject' => $_POST['subject'], 'name' => $user_info['name'], 'poster' => $user_info['id'], 'msg' => $msgOptions['id'], 'board' => $board, 'topic' => $topic);
            notifyMembersBoard($notifyData);
        } elseif (empty($_REQUEST['msg'])) {
            // Only send it to everyone if the topic is approved, otherwise just to the topic starter if they want it.
            if ($topic_info['approved']) {
                sendNotifications($topic, 'reply');
            } else {
                sendNotifications($topic, 'reply', array(), $topic_info['id_member_started']);
            }
        }
    }
    // Returning to the topic?
    if (!empty($_REQUEST['goback'])) {
        // Mark the board as read.... because it might get confusing otherwise.
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}log_boards
			SET id_msg = {int:maxMsgID}
			WHERE id_member = {int:current_member}
				AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'], 'maxMsgID' => $modSettings['maxMsgID']));
    }
    if ($board_info['num_topics'] == 0) {
        cache_put_data('board-' . $board, null, 120);
    }
    if (!empty($_POST['announce_topic'])) {
        redirectexit('action=announce;sa=selectgroup;topic=' . $topic . (!empty($_POST['move']) && allowedTo('move_any') ? ';move' : '') . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    if (!empty($_POST['move']) && allowedTo('move_any')) {
        redirectexit('action=movetopic;topic=' . $topic . '.0' . (empty($_REQUEST['goback']) ? '' : ';goback'));
    }
    // Return to post if the mod is on.
    if (isset($_REQUEST['msg']) && !empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg'], $context['browser']['is_ie']);
    } elseif (!empty($_REQUEST['goback'])) {
        redirectexit('topic=' . $topic . '.new#new', $context['browser']['is_ie']);
    } else {
        redirectexit('board=' . $board . '.0');
    }
}
Example #21
0
 /**
  * Sticky a topic.
  * Can't be done by topic starters - that would be annoying!
  * What this does:
  *  - stickies a topic - toggles between sticky and normal.
  *  - requires the make_sticky permission.
  *  - adds an entry to the moderator log.
  *  - when done, sends the user back to the topic.
  *  - accessed via ?action=topic;sa=sticky.
  */
 public function action_sticky()
 {
     global $modSettings, $topic, $board;
     // Make sure the user can sticky it, and they are stickying *something*.
     isAllowedTo('make_sticky');
     // You shouldn't be able to (un)sticky a topic if the setting is disabled.
     if (empty($modSettings['enableStickyTopics'])) {
         fatal_lang_error('cannot_make_sticky', false);
     }
     // You can't sticky a board or something!
     if (empty($topic)) {
         fatal_lang_error('not_a_topic', false);
     }
     checkSession('get');
     // We need this for the sendNotifications() function.
     require_once SUBSDIR . '/Notification.subs.php';
     // And Topic subs for topic attributes.
     require_once SUBSDIR . '/Topic.subs.php';
     // Is this topic already stickied, or no?
     $is_sticky = topicAttribute($topic, 'sticky');
     // Toggle the sticky value.
     setTopicAttribute($topic, array('sticky' => empty($is_sticky) ? 1 : 0));
     // Log this sticky action - always a moderator thing.
     logAction(empty($is_sticky) ? 'sticky' : 'unsticky', array('topic' => $topic, 'board' => $board));
     // Notify people that this topic has been stickied?
     if (empty($is_sticky)) {
         sendNotifications($topic, 'sticky');
     }
     // Take them back to the now stickied topic.
     redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
 }
Example #22
0
function MergeExecute($topics = array())
{
    global $db_prefix, $user_info, $txt, $context, $scripturl, $sourcedir;
    global $func, $language, $modSettings;
    // The parameters of MergeExecute were set, so this must've been an internal call.
    if (!empty($topics)) {
        isAllowedTo('merge_any');
        loadTemplate('SplitTopics');
    }
    checkSession('request');
    // Handle URLs from MergeIndex.
    if (!empty($_GET['from']) && !empty($_GET['to'])) {
        $topics = array((int) $_GET['from'], (int) $_GET['to']);
    }
    // If we came from a form, the topic IDs came by post.
    if (!empty($_POST['topics']) && is_array($_POST['topics'])) {
        $topics = $_POST['topics'];
    }
    // There's nothing to merge with just one topic...
    if (empty($topics) || !is_array($topics) || count($topics) == 1) {
        fatal_lang_error('merge_need_more_topics');
    }
    // Make sure every topic is numeric, or some nasty things could be done with the DB.
    foreach ($topics as $id => $topic) {
        $topics[$id] = (int) $topic;
    }
    // Get info about the topics and polls that will be merged.
    $request = db_query("\n\t\tSELECT\n\t\t\tt.ID_TOPIC, t.ID_BOARD, t.ID_POLL, t.numViews, t.isSticky,\n\t\t\tm1.subject, m1.posterTime AS time_started, IFNULL(mem1.ID_MEMBER, 0) AS ID_MEMBER_STARTED, IFNULL(mem1.realName, m1.posterName) AS name_started,\n\t\t\tm2.posterTime AS time_updated, IFNULL(mem2.ID_MEMBER, 0) AS ID_MEMBER_UPDATED, IFNULL(mem2.realName, m2.posterName) AS name_updated\n\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m1, {$db_prefix}messages AS m2)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem1 ON (mem1.ID_MEMBER = m1.ID_MEMBER)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem2 ON (mem2.ID_MEMBER = m2.ID_MEMBER)\n\t\tWHERE t.ID_TOPIC IN (" . implode(', ', $topics) . ")\n\t\t\tAND m1.ID_MSG = t.ID_FIRST_MSG\n\t\t\tAND m2.ID_MSG = t.ID_LAST_MSG\n\t\tORDER BY t.ID_FIRST_MSG\n\t\tLIMIT " . count($topics), __FILE__, __LINE__);
    if (mysql_num_rows($request) < 2) {
        fatal_lang_error('smf263');
    }
    $num_views = 0;
    $isSticky = 0;
    $boards = array();
    $polls = array();
    while ($row = mysql_fetch_assoc($request)) {
        $topic_data[$row['ID_TOPIC']] = array('id' => $row['ID_TOPIC'], 'board' => $row['ID_BOARD'], 'poll' => $row['ID_POLL'], 'numViews' => $row['numViews'], 'subject' => $row['subject'], 'started' => array('time' => timeformat($row['time_started']), 'timestamp' => forum_time(true, $row['time_started']), 'href' => empty($row['ID_MEMBER_STARTED']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER_STARTED'], 'link' => empty($row['ID_MEMBER_STARTED']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER_STARTED'] . '">' . $row['name_started'] . '</a>'), 'updated' => array('time' => timeformat($row['time_updated']), 'timestamp' => forum_time(true, $row['time_updated']), 'href' => empty($row['ID_MEMBER_UPDATED']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER_UPDATED'], 'link' => empty($row['ID_MEMBER_UPDATED']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER_UPDATED'] . '">' . $row['name_updated'] . '</a>'));
        $num_views += $row['numViews'];
        $boards[] = $row['ID_BOARD'];
        // If there's no poll, ID_POLL == 0...
        if ($row['ID_POLL'] > 0) {
            $polls[] = $row['ID_POLL'];
        }
        // Store the ID_TOPIC with the lowest ID_FIRST_MSG.
        if (empty($firstTopic)) {
            $firstTopic = $row['ID_TOPIC'];
        }
        $isSticky = max($isSticky, $row['isSticky']);
    }
    mysql_free_result($request);
    $boards = array_values(array_unique($boards));
    // Get the boards a user is allowed to merge in.
    $merge_boards = boardsAllowedTo('merge_any');
    if (empty($merge_boards)) {
        fatal_lang_error('cannot_merge_any');
    }
    // Make sure they can see all boards....
    $request = db_query("\n\t\tSELECT b.ID_BOARD\n\t\tFROM {$db_prefix}boards AS b\n\t\tWHERE b.ID_BOARD IN (" . implode(', ', $boards) . ")\n\t\t\tAND {$user_info['query_see_board']}" . (!in_array(0, $merge_boards) ? "\n\t\t\tAND b.ID_BOARD IN (" . implode(', ', $merge_boards) . ")" : '') . "\n\t\tLIMIT " . count($boards), __FILE__, __LINE__);
    // If the number of boards that's in the output isn't exactly the same as we've put in there, you're in trouble.
    if (mysql_num_rows($request) != count($boards)) {
        fatal_lang_error('smf232');
    }
    mysql_free_result($request);
    if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options') {
        if (count($polls) > 1) {
            $request = db_query("\n\t\t\t\tSELECT t.ID_TOPIC, t.ID_POLL, m.subject, p.question\n\t\t\t\tFROM ({$db_prefix}polls AS p, {$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\t\tWHERE p.ID_POLL IN (" . implode(', ', $polls) . ")\n\t\t\t\t\tAND t.ID_POLL = p.ID_POLL\n\t\t\t\t\tAND m.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tLIMIT " . count($polls), __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($request)) {
                $context['polls'][] = array('id' => $row['ID_POLL'], 'topic' => array('id' => $row['ID_TOPIC'], 'subject' => $row['subject']), 'question' => $row['question'], 'selected' => $row['ID_TOPIC'] == $firstTopic);
            }
            mysql_free_result($request);
        }
        if (count($boards) > 1) {
            $request = db_query("\n\t\t\t\tSELECT ID_BOARD, name\n\t\t\t\tFROM {$db_prefix}boards\n\t\t\t\tWHERE ID_BOARD IN (" . implode(', ', $boards) . ")\n\t\t\t\tORDER BY name\n\t\t\t\tLIMIT " . count($boards), __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($request)) {
                $context['boards'][] = array('id' => $row['ID_BOARD'], 'name' => $row['name'], 'selected' => $row['ID_BOARD'] == $topic_data[$firstTopic]['board']);
            }
            mysql_free_result($request);
        }
        $context['topics'] = $topic_data;
        foreach ($topic_data as $id => $topic) {
            $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic;
        }
        $context['page_title'] = $txt['smf252'];
        $context['sub_template'] = 'merge_extra_options';
        return;
    }
    // Determine target board.
    $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0];
    if (!in_array($target_board, $boards)) {
        fatal_lang_error('smf232');
    }
    // Determine which poll will survive and which polls won't.
    $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0);
    if ($target_poll > 0 && !in_array($target_poll, $polls)) {
        fatal_lang_error(1, false);
    }
    $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll));
    // Determine the subject of the newly merged topic - was a custom subject specified?
    if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '') {
        $target_subject = $func['htmlspecialchars']($_POST['custom_subject']);
    } elseif (!empty($topic_data[(int) $_POST['subject']]['subject'])) {
        $target_subject = addslashes($topic_data[(int) $_POST['subject']]['subject']);
    } else {
        $target_subject = addslashes($topic_data[$firstTopic]['subject']);
    }
    // Get the first and last message and the number of messages....
    $request = db_query("\n\t\tSELECT MIN(ID_MSG), MAX(ID_MSG), COUNT(ID_MSG) - 1\n\t\tFROM {$db_prefix}messages\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $topics) . ")", __FILE__, __LINE__);
    list($first_msg, $last_msg, $num_replies) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Get the member ID of the first and last message.
    $request = db_query("\n\t\tSELECT ID_MEMBER\n\t\tFROM {$db_prefix}messages\n\t\tWHERE ID_MSG IN ({$first_msg}, {$last_msg})\n\t\tORDER BY ID_MSG\n\t\tLIMIT 2", __FILE__, __LINE__);
    list($member_started) = mysql_fetch_row($request);
    list($member_updated) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Assign the first topic ID to be the merged topic.
    $ID_TOPIC = min($topics);
    // Delete the remaining topics.
    $deleted_topics = array_diff($topics, array($ID_TOPIC));
    db_query("\n\t\tDELETE FROM {$db_prefix}topics\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $deleted_topics) . ")\n\t\tLIMIT " . count($deleted_topics), __FILE__, __LINE__);
    db_query("\n\t\tDELETE FROM {$db_prefix}log_search_subjects\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $deleted_topics) . ")", __FILE__, __LINE__);
    // Asssign the properties of the newly merged topic.
    db_query("\n\t\tUPDATE {$db_prefix}topics\n\t\tSET\n\t\t\tID_BOARD = {$target_board},\n\t\t\tID_MEMBER_STARTED = {$member_started},\n\t\t\tID_MEMBER_UPDATED = {$member_updated},\n\t\t\tID_FIRST_MSG = {$first_msg},\n\t\t\tID_LAST_MSG = {$last_msg},\n\t\t\tID_POLL = {$target_poll},\n\t\t\tnumReplies = {$num_replies},\n\t\t\tnumViews = {$num_views},\n\t\t\tisSticky = {$isSticky}\n\t\tWHERE ID_TOPIC = {$ID_TOPIC}\n\t\tLIMIT 1", __FILE__, __LINE__);
    // Grab the response prefix (like 'Re: ') in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
        if ($language === $user_info['language']) {
            $context['response_prefix'] = $txt['response_prefix'];
        } else {
            loadLanguage('index', $language, false);
            $context['response_prefix'] = $txt['response_prefix'];
            loadLanguage('index');
        }
        cache_put_data('response_prefix', $context['response_prefix'], 600);
    }
    // Change the topic IDs of all messages that will be merged.  Also adjust subjects if 'enforce subject' was checked.
    db_query("\n\t\tUPDATE {$db_prefix}messages\n\t\tSET\n\t\t\tID_TOPIC = {$ID_TOPIC},\n\t\t\tID_BOARD = {$target_board}" . (!empty($_POST['enforce_subject']) ? ",\n\t\t\tsubject = '{$context['response_prefix']}{$target_subject}'" : '') . "\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $topics) . ")", __FILE__, __LINE__);
    // Change the subject of the first message...
    db_query("\n\t\tUPDATE {$db_prefix}messages\n\t\tSET subject = '{$target_subject}'\n\t\tWHERE ID_MSG = {$first_msg}\n\t\tLIMIT 1", __FILE__, __LINE__);
    // Adjust all calendar events to point to the new topic.
    db_query("\n\t\tUPDATE {$db_prefix}calendar\n\t\tSET\n\t\t\tID_TOPIC = {$ID_TOPIC},\n\t\t\tID_BOARD = {$target_board}\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $deleted_topics) . ")", __FILE__, __LINE__);
    // Merge log topic entries.
    $request = db_query("\n\t\tSELECT ID_MEMBER, MIN(ID_MSG) AS new_ID_MSG\n\t\tFROM {$db_prefix}log_topics\n\t\tWHERE ID_TOPIC IN (" . implode(', ', $topics) . ")\n\t\tGROUP BY ID_MEMBER", __FILE__, __LINE__);
    if (mysql_num_rows($request) > 0) {
        $replaceEntries = array();
        while ($row = mysql_fetch_assoc($request)) {
            $replaceEntries[] = "({$row['ID_MEMBER']}, {$ID_TOPIC}, {$row['new_ID_MSG']})";
        }
        db_query("\n\t\t\tREPLACE INTO {$db_prefix}log_topics\n\t\t\t\t(ID_MEMBER, ID_TOPIC, ID_MSG)\n\t\t\tVALUES " . implode(', ', $replaceEntries), __FILE__, __LINE__);
        unset($replaceEntries);
        // Get rid of the old log entries.
        db_query("\n\t\t\tDELETE FROM {$db_prefix}log_topics\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $deleted_topics) . ")", __FILE__, __LINE__);
    }
    mysql_free_result($request);
    // Merge topic notifications.
    if (!empty($_POST['notifications']) && is_array($_POST['notifications'])) {
        // Check if the notification array contains valid topics.
        if (count(array_diff($_POST['notifications'], $topics)) > 0) {
            fatal_lang_error('smf232');
        }
        $request = db_query("\n\t\t\tSELECT ID_MEMBER, MAX(sent) AS sent\n\t\t\tFROM {$db_prefix}log_notify\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $_POST['notifications']) . ")\n\t\t\tGROUP BY ID_MEMBER", __FILE__, __LINE__);
        if (mysql_num_rows($request) > 0) {
            $replaceEntries = array();
            while ($row = mysql_fetch_assoc($request)) {
                $replaceEntries[] = "({$row['ID_MEMBER']}, {$ID_TOPIC}, 0, {$row['sent']})";
            }
            db_query("\n\t\t\t\tREPLACE INTO {$db_prefix}log_notify\n\t\t\t\t\t(ID_MEMBER, ID_TOPIC, ID_BOARD, sent)\n\t\t\t\tVALUES " . implode(', ', $replaceEntries), __FILE__, __LINE__);
            unset($replaceEntries);
            db_query("\n\t\t\t\tDELETE FROM {$db_prefix}log_topics\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $deleted_topics) . ")", __FILE__, __LINE__);
        }
        mysql_free_result($request);
    }
    // Get rid of the redundant polls.
    if (!empty($deleted_polls)) {
        db_query("\n\t\t\tDELETE FROM {$db_prefix}polls\n\t\t\tWHERE ID_POLL IN (" . implode(', ', $deleted_polls) . ")\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        db_query("\n\t\t\tDELETE FROM {$db_prefix}poll_choices\n\t\t\tWHERE ID_POLL IN (" . implode(', ', $deleted_polls) . ")", __FILE__, __LINE__);
        db_query("\n\t\t\tDELETE FROM {$db_prefix}log_polls\n\t\t\tWHERE ID_POLL IN (" . implode(', ', $deleted_polls) . ")", __FILE__, __LINE__);
    }
    // Fix the board totals.
    if (count($boards) > 1) {
        $request = db_query("\n\t\t\tSELECT ID_BOARD, COUNT(*) AS numTopics, SUM(numReplies) + COUNT(*) AS numPosts\n\t\t\tFROM {$db_prefix}topics\n\t\t\tWHERE ID_BOARD IN (" . implode(', ', $boards) . ")\n\t\t\tGROUP BY ID_BOARD\n\t\t\tLIMIT " . count($boards), __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            db_query("\n\t\t\t\tUPDATE {$db_prefix}boards\n\t\t\t\tSET\n\t\t\t\t\tnumPosts = {$row['numPosts']},\n\t\t\t\t\tnumTopics = {$row['numTopics']}\n\t\t\t\tWHERE ID_BOARD = {$row['ID_BOARD']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
        }
        mysql_free_result($request);
    } else {
        db_query("\n\t\t\tUPDATE {$db_prefix}boards\n\t\t\tSET numTopics = IF(" . (count($topics) - 1) . " > numTopics, 0, numTopics - " . (count($topics) - 1) . ")\n\t\t\tWHERE ID_BOARD = {$target_board}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
    }
    require_once $sourcedir . '/Subs-Post.php';
    // Update all the statistics.
    updateStats('topic');
    updateStats('subject', $ID_TOPIC, $target_subject);
    updateLastMessages($boards);
    logAction('merge', array('topic' => $ID_TOPIC));
    // Notify people that these topics have been merged?
    sendNotifications($ID_TOPIC, 'merge');
    // Send them to the all done page.
    redirectexit('action=mergetopics;sa=done;to=' . $ID_TOPIC . ';targetboard=' . $target_board);
}
Example #23
0
function Sticky()
{
    global $db_prefix, $modSettings, $topic, $sourcedir;
    // Make sure the user can sticky it, and they are stickying *something*.
    isAllowedTo('make_sticky');
    // You shouldn't be able to (un)sticky a topic if the setting is disabled.
    if (empty($modSettings['enableStickyTopics'])) {
        fatal_lang_error('cannot_make_sticky', false);
    }
    // You can't sticky a board or something!
    if (empty($topic)) {
        fatal_lang_error(472, false);
    }
    checkSession('get');
    // We need Subs-Post.php for the sendNotifications() function.
    require_once $sourcedir . '/Subs-Post.php';
    // Is this topic already stickied, or no?
    $request = db_query("\n\t\tSELECT isSticky\n\t\tFROM {$db_prefix}topics\n\t\tWHERE ID_TOPIC = {$topic}\n\t\tLIMIT 1", __FILE__, __LINE__);
    list($isSticky) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Toggle the sticky value.... pretty simple ;).
    db_query("\n\t\tUPDATE {$db_prefix}topics\n\t\tSET isSticky = " . (empty($isSticky) ? 1 : 0) . "\n\t\tWHERE ID_TOPIC = {$topic}\n\t\tLIMIT 1", __FILE__, __LINE__);
    // Log this sticky action - always a moderator thing.
    logAction('sticky', array('topic' => $topic));
    // Notify people that this topic has been stickied?
    if (empty($isSticky)) {
        sendNotifications($topic, 'sticky');
    }
    // Take them back to the now stickied topic.
    redirectexit('topic=' . $topic . '.' . $_REQUEST['start']);
}
Example #24
0
function MoveTopic2()
{
    global $txt, $board, $topic, $scripturl, $sourcedir, $modSettings, $context;
    global $board, $language, $user_info, $smcFunc;
    if (empty($topic)) {
        fatal_lang_error('no_access', false);
    }
    // You can't choose to have a redirection topic and use an empty reason.
    if (isset($_POST['postRedirect']) && (!isset($_POST['reason']) || trim($_POST['reason']) == '')) {
        fatal_lang_error('movetopic_no_reason', false);
    }
    // Make sure this form hasn't been submitted before.
    checkSubmitOnce('check');
    $request = $smcFunc['db_query']('', '
		SELECT id_member_started, id_first_msg, approved
		FROM {db_prefix}topics
		WHERE id_topic = {int:current_topic}
		LIMIT 1', array('current_topic' => $topic));
    list($id_member_started, $id_first_msg, $context['is_approved']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Can they see it?
    if (!$context['is_approved']) {
        isAllowedTo('approve_posts');
    }
    // Can they move topics on this board?
    if (!allowedTo('move_any')) {
        if ($id_member_started == $user_info['id']) {
            isAllowedTo('move_own');
            $boards = array_merge(boardsAllowedTo('move_own'), boardsAllowedTo('move_any'));
        } else {
            isAllowedTo('move_any');
        }
    } else {
        $boards = boardsAllowedTo('move_any');
    }
    // If this topic isn't approved don't let them move it if they can't approve it!
    if ($modSettings['postmod_active'] && !$context['is_approved'] && !allowedTo('approve_posts')) {
        // Only allow them to move it to other boards they can't approve it in.
        $can_approve = boardsAllowedTo('approve_posts');
        $boards = array_intersect($boards, $can_approve);
    }
    checkSession();
    require_once $sourcedir . '/Subs-Post.php';
    // The destination board must be numeric.
    $_POST['toboard'] = (int) $_POST['toboard'];
    // Make sure they can see the board they are trying to move to (and get whether posts count in the target board).
    $request = $smcFunc['db_query']('', '
		SELECT b.count_posts, b.name, m.subject
		FROM {db_prefix}boards AS b
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
		WHERE {query_see_board}
			AND b.id_board = {int:to_board}
			AND b.redirect = {string:blank_redirect}
		LIMIT 1', array('current_topic' => $topic, 'to_board' => $_POST['toboard'], 'blank_redirect' => ''));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('no_board');
    }
    list($pcounter, $board_name, $subject) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Remember this for later.
    $_SESSION['move_to_topic'] = $_POST['toboard'];
    // Rename the topic...
    if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '') {
        $_POST['custom_subject'] = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
        // Keep checking the length.
        if ($smcFunc['strlen']($_POST['custom_subject']) > 100) {
            $_POST['custom_subject'] = $smcFunc['substr']($_POST['custom_subject'], 0, 100);
        }
        // If it's still valid move onwards and upwards.
        if ($_POST['custom_subject'] != '') {
            if (isset($_POST['enforce_subject'])) {
                // Get a response prefix, but in the forum's default language.
                if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) {
                    if ($language === $user_info['language']) {
                        $context['response_prefix'] = $txt['response_prefix'];
                    } else {
                        loadLanguage('index', $language, false);
                        $context['response_prefix'] = $txt['response_prefix'];
                        loadLanguage('index');
                    }
                    cache_put_data('response_prefix', $context['response_prefix'], 600);
                }
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}messages
					SET subject = {string:subject}
					WHERE id_topic = {int:current_topic}', array('current_topic' => $topic, 'subject' => $context['response_prefix'] . $_POST['custom_subject']));
            }
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}messages
				SET subject = {string:custom_subject}
				WHERE id_msg = {int:id_first_msg}', array('id_first_msg' => $id_first_msg, 'custom_subject' => $_POST['custom_subject']));
            // Fix the subject cache.
            updateStats('subject', $topic, $_POST['custom_subject']);
        }
    }
    // Create a link to this in the old board.
    //!!! Does this make sense if the topic was unapproved before? I'd just about say so.
    if (isset($_POST['postRedirect'])) {
        // Should be in the boardwide language.
        if ($user_info['language'] != $language) {
            loadLanguage('index', $language);
        }
        $_POST['reason'] = $smcFunc['htmlspecialchars']($_POST['reason'], ENT_QUOTES);
        preparsecode($_POST['reason']);
        // Add a URL onto the message.
        $_POST['reason'] = strtr($_POST['reason'], array($txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]', $txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'));
        $msgOptions = array('subject' => $txt['moved'] . ': ' . $subject, 'body' => $_POST['reason'], 'icon' => 'moved', 'smileys_enabled' => 1);
        $topicOptions = array('board' => $board, 'lock_mode' => 1, 'mark_as_read' => true);
        $posterOptions = array('id' => $user_info['id'], 'update_post_count' => empty($pcounter));
        createPost($msgOptions, $topicOptions, $posterOptions);
    }
    $request = $smcFunc['db_query']('', '
		SELECT count_posts
		FROM {db_prefix}boards
		WHERE id_board = {int:current_board}
		LIMIT 1', array('current_board' => $board));
    list($pcounter_from) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    if ($pcounter_from != $pcounter) {
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND approved = {int:is_approved}', array('current_topic' => $topic, 'is_approved' => 1));
        $posters = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (!isset($posters[$row['id_member']])) {
                $posters[$row['id_member']] = 0;
            }
            $posters[$row['id_member']]++;
        }
        $smcFunc['db_free_result']($request);
        foreach ($posters as $id_member => $posts) {
            // The board we're moving from counted posts, but not to.
            if (empty($pcounter_from)) {
                updateMemberData($id_member, array('posts' => 'posts - ' . $posts));
            } else {
                updateMemberData($id_member, array('posts' => 'posts + ' . $posts));
            }
        }
    }
    // Do the move (includes statistics update needed for the redirect topic).
    moveTopics($topic, $_POST['toboard']);
    // Log that they moved this topic.
    if (!allowedTo('move_own') || $id_member_started != $user_info['id']) {
        logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $_POST['toboard']));
    }
    // Notify people that this topic has been moved?
    sendNotifications($topic, 'move');
    // Why not go back to the original board in case they want to keep moving?
    if (!isset($_REQUEST['goback'])) {
        redirectexit('board=' . $board . '.0');
    } else {
        redirectexit('topic=' . $topic . '.0');
    }
}
Example #25
0
function writeElementValue($formframe = "", $ele, $entry, $value, $append, $prevValue = null, $lvoverride = false, $linkedTargetHint = "")
{
    if (get_magic_quotes_gpc()) {
        $value = stripslashes($value);
    }
    global $xoopsUser, $formulize_mgr, $xoopsDB, $myts;
    if (!is_object($myts)) {
        $myts =& MyTextSanitizer::getInstance();
    }
    if (!$formulize_mgr) {
        $formulize_mgr =& xoops_getmodulehandler('elements', 'formulize');
    }
    $uid = $xoopsUser ? $xoopsUser->getVar('uid') : 0;
    $date = date("Y-m-d");
    if (is_numeric($ele)) {
        $element =& $formulize_mgr->get($ele);
        $element_id = $ele;
    } else {
        $framework_handler = xoops_getmodulehandler('frameworks', 'formulize');
        $frameworkObject = $framework_handler->get($formframe);
        if (is_object($frameworkObject)) {
            $frameworkElementIds = $frameworkObject->getVar('element_ids');
            if (isset($frameworkElementIds[$ele])) {
                $element_id = $frameworkElementIds[$ele];
                $element =& $formulize_mgr->get($element_id);
            }
        }
        if (!is_object($element)) {
            // then check the element data handles instead
            $element =& $formulize_mgr->get($ele);
        }
    }
    if (!is_object($element)) {
        print "<b>Error: could not save the value for element: " . $ele . ". Please notify your webmaster, or <a href=\"mailto:formulize@freeformsolutions.ca\">Freeform Solutions</a> about this error.</b>";
        return;
    }
    $ele_value = $element->getVar('ele_value');
    if (!is_array($value)) {
        // value can be an array of multiple values -- initially that only worked for linked selectboxes
        if ($element->getVar('ele_type') == "yn") {
            $value = strtoupper($value) == strtoupper(_formulize_TEMP_QYES) ? 1 : $value;
            $value = strtoupper($value) == strtoupper(_formulize_TEMP_QNO) ? 2 : $value;
        } else {
            $value = $myts->htmlSpecialChars($value);
        }
    } else {
        foreach ($value as $id => $thisValue) {
            if ($element->getVar('ele_type') == "yn") {
                $value[$id] = strtoupper($value[$id]) == strtoupper(_formulize_TEMP_QYES) ? 1 : $value[$id];
                $value[$id] = strtoupper($value[$id]) == strtoupper(_formulize_TEMP_QNO) ? 2 : $value[$id];
            } else {
                $value[$id] = $myts->htmlSpecialChars($value[$id]);
            }
        }
    }
    $form_handler = xoops_getmodulehandler('forms', 'formulize');
    if ($foundit = strstr($ele_value[2], "#*=:*") and !$lvoverride) {
        // completely rejig things for a linked selectbox
        $boxproperties = explode("#*=:*", $ele_value[2]);
        // NOTE:
        // boxproperties[0] is fid, 1 is the handle
        if (!is_array($value)) {
            // convert $value to an array if it's not already. arrays are only valid for linked selectboxes for now
            $temp_value = $value;
            unset($value);
            $value = array(0 => $temp_value);
        }
        static $cachedEntryIds = array();
        $foundEntryIds = array();
        $searchForValues = array();
        foreach ($value as $thisValue) {
            if (isset($cachedEntryIds[$boxproperties[0]][$boxproperties[1]][$thisValue])) {
                $foundEntryIds[] = $cachedEntryIds[$boxproperties[0]][$boxproperties[1]][$thisValue];
            } else {
                $searchForValues[] = formulize_db_escape(html_entity_decode($thisValue));
            }
        }
        // need to check for link to a link, and change target if that's what we're dealing with
        $element_handler = xoops_getmodulehandler('elements', 'formulize');
        $sourceElement = $element_handler->get($boxproperties[1]);
        if (is_object($sourceElement)) {
            $sourceEleValue = $sourceElement->getVar('ele_value');
            if (strstr($sourceEleValue[2], "#*=:*")) {
                $sourceParts = explode("#*=:*", $sourceEleValue[2]);
                $sourceFormObject = $form_handler->get($sourceParts[0]);
                $linkQueryResult = q("SELECT `entry_id` FROM " . $xoopsDB->prefix("formulize_" . $sourceFormObject->getVar('form_handle')) . " WHERE `" . $sourceParts[1] . "` = '" . implode("' OR `" . $sourceParts[1] . "` = '", $searchForValues) . "'");
                unset($searchForValues);
                foreach ($linkQueryResult as $linkedEntryId) {
                    $searchForValues[] = $linkedEntryId['entry_id'];
                }
                if ($linkedTargetHint) {
                    $linkedTargetHint = " AND `entry_id` = {$linkedTargetHint}";
                }
            }
        }
        if (count($searchForValues) > 0) {
            $boxFormObject = $form_handler->get($boxproperties[0]);
            $entry_id_q = q("SELECT `entry_id`, `" . $boxproperties[1] . "` FROM " . $xoopsDB->prefix("formulize_" . $boxFormObject->getVar('form_handle')) . " WHERE `" . $boxproperties[1] . "` = '" . implode("' OR `" . $boxproperties[1] . "` = '", $searchForValues) . "' {$linkedTargetHint}");
            foreach ($entry_id_q as $thisEntryId) {
                $cachedEntryIds[$boxproperties[0]][$boxproperties[1]][$thisEntryId[$boxproperties[1]]] = $thisEntryId['entry_id'];
                $foundEntryIds[] = $thisEntryId['entry_id'];
            }
        }
        if (count($foundEntryIds) > 1) {
            $foundEntryIdString = "," . implode(",", $foundEntryIds) . ",";
        } elseif (count($foundEntryIds) == 1) {
            $foundEntryIdString = $foundEntryIds[0];
        } else {
            $foundEntryIdString = "";
        }
        unset($value);
        $value = $foundEntryIdString;
        $append = "replace";
    }
    $elementFormObject = $form_handler->get($element->getVar('id_form'));
    $lockIsOn = false;
    if ($value == "{ID}" and $entry == "new" or $value == "{SEQUENCE}") {
        $lockIsOn = true;
        // need to lock table since there are multiple operations required on it for this one write transaction
        $xoopsDB->query("LOCK TABLES " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle')) . " WRITE");
        $fromField = $value == "{ID}" ? "entry_id" : $element->getVar('ele_handle');
        $maxValueSQL = "SELECT MAX(`{$fromField}`) FROM " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle'));
        if ($maxValueRes = $xoopsDB->query($maxValueSQL)) {
            $maxValueArray = $xoopsDB->fetchArray($maxValueRes);
            $value = $maxValueArray["MAX(`{$fromfield}`)"] + 1;
        } else {
            exit("Error: could not determine max value to use for {$value}.  SQL:<br>{$maxValueSQL}<br>");
        }
    } elseif ($value == "{ID}" and $entry != "new") {
        $value = $entry;
    }
    $needToSetOwner = false;
    if ($entry == "new") {
        // making a new entry
        $owner = is_numeric($append) ? $append : $uid;
        // for new entries, a numeric "action" indicates an owner for the entry that is different from the current user, ie: this is a proxy entry
        // no handling as yet for an array of values, which would be required for replacing the selections in a checkbox series or selectbox series.
        // radio buttons would also need to be massaged?
        $sql = "INSERT INTO " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle')) . " (creation_datetime, mod_datetime, creation_uid, mod_uid, `" . $element->getVar('ele_handle') . "`) VALUES (NOW(), NOW(), \"{$owner}\", \"{$uid}\", '" . formulize_db_escape($value) . "')";
        $needToSetOwner = true;
    } else {
        // not new entry, so update the existing entry
        if ($append == "remove") {
            $prevValue = q("SELECT `" . $element->getVar('ele_handle') . "` FROM " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle')) . " WHERE entry_id=" . intval($entry));
            if (strstr($prevValue[0]['ele_value'], "*=+*:")) {
                $valueToWrite = str_replace("*=+*:" . $value, "", $prevValue[0]['ele_value']);
            } else {
                $valueToWrite = str_replace($value, "", $prevValue[0]['ele_value']);
            }
        } elseif ($append == "append") {
            $prevValue = q("SELECT `" . $element->getVar('ele_handle') . "` FROM " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle')) . " WHERE entry_id=" . intval($entry));
            switch ($element->getVar('ele_type')) {
                case "checkbox":
                    $valueToWrite = $prevValue[0]['ele_value'] . "*=+*:" . $value;
                    break;
                case "select":
                    if ($ele_value[1]) {
                        // multiple selections possible
                        $valueToWrite = $prevValue[0]['ele_value'] . "*=+*:" . $value;
                    } else {
                        // cannot append to dropdowns
                        $valueToWrite = $value;
                    }
                    break;
                case "yn":
                    // cannot append to yn
                // cannot append to yn
                case "date":
                    // cannot append to date
                // cannot append to date
                case "radio":
                    // cannot append to radios
                    $valueToWrite = $value;
                    break;
                case "text":
                case "textarea":
                    $valueToWrite = $prevValue[0]['ele_value'] . $value;
                    break;
                default:
                    exit("Error: unknown type of element used in a call to displayButton");
            }
        } else {
            // append == "replace" or all other settings for append
            $valueToWrite = $value;
        }
        $sql = "UPDATE " . $xoopsDB->prefix("formulize_" . $elementFormObject->getVar('form_handle')) . " SET `" . $element->getVar('ele_handle') . "` = '" . formulize_db_escape($valueToWrite) . "' WHERE entry_id=" . intval($entry);
    }
    if ($sql) {
        if (!($res = $xoopsDB->queryF($sql))) {
            exit("Error: unable to execute a \"displayButton\" or writeElementValue call, using the following SQL:<br>{$sql}<br>" . $xoopsDB->error);
        }
        $GLOBALS['formulize_writeElementValueWasRun'] = true;
    }
    if ($lockIsOn) {
        $xoopsDB->query("UNLOCK TABLES");
    }
    if ($entry == "new") {
        $insertedId = $xoopsDB->getInsertId();
    }
    if ($needToSetOwner) {
        include_once XOOPS_ROOT_PATH . "/modules/formulize/class/data.php";
        $data_handler = new formulizeDataHandler($element->getVar('id_form'));
        if (!($groupResult = $data_handler->setEntryOwnerGroups($owner, $insertedId))) {
            print "ERROR: failed to write the entry ownership information to the database.<br>";
        }
    }
    // handle notifications
    // get the form ID of the form based on the element id
    switch ($entry) {
        case "new":
            sendNotifications($element->getVar('id_form'), "new_entry", array(0 => $insertedId));
            break;
        default:
            sendNotifications($element->getVar('id_form'), "update_entry", array(0 => $entry));
            break;
    }
    unset($element);
    return $entry == "new" ? $insertedId : $entry;
}