コード例 #1
0
function loadRelated($topic)
{
    global $modSettings, $context, $smcFunc;
    $context['can_approve_posts_boards'] = boardsAllowedTo('approve_posts', false);
    // Otherwise use customized fulltext index
    $request = $smcFunc['db_query']('', '
		SELECT IF(rt.id_topic_first = {int:topic}, rt.id_topic_second, rt.id_topic_first) AS id_topic
		FROM {db_prefix}related_topics AS rt
			JOIN {db_prefix}topics AS t ON (t.id_topic = IF(rt.id_topic_first = {int:topic}, rt.id_topic_second, rt.id_topic_first))
			JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
		WHERE (id_topic_first = {int:topic} OR id_topic_second = {int:topic})
			AND {query_see_board}
		ORDER BY rt.score DESC
		LIMIT {int:limit}', array('topic' => $topic, 'limit' => $modSettings['relatedTopicsCount']));
    if ($smcFunc['db_num_rows']($request) == 0) {
        $smcFunc['db_free_result']($request);
        return false;
    }
    $topics_ids = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $topics_ids[] = $row['id_topic'];
    }
    $smcFunc['db_free_result']($request);
    return prepareTopicArray($topics_ids);
}
コード例 #2
0
 /**
  * Called from a mouse click,
  * works out what we want to do with attachments and actions it.
  * Accessed by ?action=attachapprove
  */
 public function action_attachapprove()
 {
     global $user_info;
     // Security is our primary concern...
     checkSession('get');
     // If it approve or delete?
     $is_approve = !isset($_GET['sa']) || $_GET['sa'] != 'reject' ? true : false;
     $attachments = array();
     require_once SUBSDIR . '/ManageAttachments.subs.php';
     // If we are approving all ID's in a message , get the ID's.
     if ($_GET['sa'] == 'all' && !empty($_GET['mid'])) {
         $id_msg = (int) $_GET['mid'];
         $attachments = attachmentsOfMessage($id_msg);
     } elseif (!empty($_GET['aid'])) {
         $attachments[] = (int) $_GET['aid'];
     }
     if (empty($attachments)) {
         fatal_lang_error('no_access', false);
     }
     // @todo nb: this requires permission to approve posts, not manage attachments
     // Now we have some ID's cleaned and ready to approve, but first - let's check we have permission!
     $allowed_boards = !empty($user_info['mod_cache']['ap']) ? $user_info['mod_cache']['ap'] : boardsAllowedTo('approve_posts');
     if ($allowed_boards == array(0)) {
         $approve_query = '';
     } elseif (!empty($allowed_boards)) {
         $approve_query = ' AND m.id_board IN (' . implode(',', $allowed_boards) . ')';
     } else {
         $approve_query = ' AND 0';
     }
     // Validate the attachments exist and have the right approval state.
     $attachments = validateAttachments($attachments, $approve_query);
     // Set up a return link based off one of the attachments for this message
     $attach_home = attachmentBelongsTo($attachments[0]);
     $redirect = 'topic=' . $attach_home['id_topic'] . '.msg' . $attach_home['id_msg'] . '#msg' . $attach_home['id_msg'];
     if (empty($attachments)) {
         fatal_lang_error('no_access', false);
     }
     // Finally, we are there. Follow through!
     if ($is_approve) {
         // Checked and deemed worthy.
         approveAttachments($attachments);
     } else {
         removeAttachments(array('id_attach' => $attachments, 'do_logging' => true));
     }
     // We approved or removed, either way we reset those numbers
     cache_put_data('num_menu_errors', null, 900);
     // Return to the topic....
     redirectexit($redirect);
 }
コード例 #3
0
ファイル: Ratings.php プロジェクト: norv/EosAlpha
/**
 * @param $memID 		int id_member
 *
 * fetch all likes received by the given user and display them
 * part of the profile -> show content area.
 */
function LikesByUser($memID)
{
    global $context, $user_info, $scripturl, $memberContext, $txt, $modSettings, $options;
    if ($memID != $user_info['id']) {
        isAllowedTo('can_view_ratings');
    }
    // let us use the same value as for topics per page here.
    $perpage = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    $out = $_GET['sa'] === 'likesout';
    // display likes *given* instead of received ones
    $is_owner = $user_info['id'] == $memID;
    // we are the owner of this profile, this is important for proper formatting (you/yours etc.)
    $boards_like_see = boardsAllowedTo('like_see');
    // respect permissions
    $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    if (!($user_info['is_admin'] || allowedTo('moderate_forum'))) {
        // admins and global mods can see everything
        $bq = ' AND b.id_board IN({array_int:boards})';
    } else {
        $bq = '';
    }
    $q = $out ? 'l.id_user = {int:id_user}' : 'l.id_receiver = {int:id_user}';
    $request = smf_db_query('SELECT count(l.id_msg) FROM {db_prefix}likes AS l
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = l.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE ' . $q . ' AND {query_see_board}' . $bq, array('id_user' => $memID, 'boards' => $boards_like_see));
    list($context['total_likes']) = mysql_fetch_row($request);
    mysql_free_result($request);
    $request = smf_db_query('SELECT m.subject, m.id_topic, l.id_user, l.id_receiver, l.updated, l.id_msg, l.rtype, mfirst.subject AS first_subject, SUBSTRING(m.body, 1, 150) AS body FROM {db_prefix}likes AS l
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = l.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}messages AS mfirst ON (mfirst.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE ' . $q . ' AND {query_see_board} ' . $bq . ' ORDER BY l.id_like DESC LIMIT {int:startwith}, {int:perpage}', array('id_user' => $memID, 'startwith' => $start, 'perpage' => $perpage, 'boards' => $boards_like_see));
    $context['results_count'] = 0;
    $context['likes'] = array();
    $context['displaymode'] = $out ? true : false;
    $context['pages'] = '';
    if ($context['total_likes'] > $perpage) {
        $context['pages'] = constructPageIndex($scripturl . '?action=profile;area=showposts;sa=' . $_GET['sa'] . ';u=' . trim($memID), $start, $context['total_likes'], $perpage);
    }
    $users = array();
    while ($row = mysql_fetch_assoc($request)) {
        $context['results_count']++;
        $thref = URL::topic($row['id_topic'], $row['first_subject'], 0);
        $phref = URL::topic($row['id_topic'], $row['subject'], 0, false, '.msg' . $row['id_msg'], '#msg' . $row['id_msg']);
        $users[] = $out ? $row['id_receiver'] : $row['id_user'];
        $context['likes'][] = array('id_user' => $out ? $row['id_receiver'] : $row['id_user'], 'time' => timeformat($row['updated']), 'topic' => array('href' => $thref, 'link' => '<a href="' . $thref . '">' . $row['first_subject'] . '</a>', 'subject' => $row['first_subject']), 'post' => array('href' => $phref, 'link' => '<a href="' . $phref . '">' . $row['subject'] . '</a>', 'subject' => $row['subject'], 'id' => $row['id_msg']), 'rtype' => $row['rtype'], 'teaser' => strip_tags(preg_replace('~[[\\/\\!]*?[^\\[\\]]*?]~si', '', $row['body'])) . '...', 'morelink' => URL::parse('?msg=' . $row['id_msg'] . ';perma'));
    }
    loadMemberData(array_unique($users));
    foreach ($context['likes'] as &$like) {
        loadMemberContext($like['id_user']);
        $like['member'] =& $memberContext[$like['id_user']];
        $like['text'] = $out ? $is_owner ? sprintf($txt['liked_a_post'], $is_owner ? $txt['you_liker'] : $memberContext[$memID]['name'], $memberContext[$like['id_user']]['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : sprintf($txt['liked_a_post'], $is_owner ? $txt['you_liker'] : $memberContext[$memID]['name'], $memberContext[$like['id_user']]['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : ($is_owner ? sprintf($txt['liked_your_post'], $like['id_user'] == $user_info['id'] ? $txt['you_liker'] : $like['member']['link'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']) : sprintf($txt['liked_a_post'], $like['id_user'] == $user_info['id'] ? $txt['you_liker'] : $like['member']['link'], $memberContext[$memID]['name'], $like['post']['href'], $like['topic']['link'], $modSettings['ratings'][$like['rtype']]['text']));
    }
    mysql_free_result($request);
    EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'ratings/profile_display');
}
コード例 #4
0
ファイル: MoveTopic.php プロジェクト: Kheros/MMOver
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');
    }
}
コード例 #5
0
ファイル: Subs-Auth.php プロジェクト: albertlast/SMF2.1
/**
 * Quickly find out what moderation authority this user has
 * - builds the moderator, group and board level querys for the user
 * - stores the information on the current users moderation powers in $user_info['mod_cache'] and $_SESSION['mc']
 */
function rebuildModCache()
{
    global $user_info, $smcFunc;
    // What groups can they moderate?
    $group_query = allowedTo('manage_membergroups') ? '1=1' : '0=1';
    if ($group_query == '0=1') {
        $request = $smcFunc['db_query']('', '
			SELECT id_group
			FROM {db_prefix}group_moderators
			WHERE id_member = {int:current_member}', array('current_member' => $user_info['id']));
        $groups = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $groups[] = $row['id_group'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($groups)) {
            $group_query = '0=1';
        } else {
            $group_query = 'id_group IN (' . implode(',', $groups) . ')';
        }
    }
    // Then, same again, just the boards this time!
    $board_query = allowedTo('moderate_forum') ? '1=1' : '0=1';
    if ($board_query == '0=1') {
        $boards = boardsAllowedTo('moderate_board', true);
        if (empty($boards)) {
            $board_query = '0=1';
        } else {
            $board_query = 'id_board IN (' . implode(',', $boards) . ')';
        }
    }
    // What boards are they the moderator of?
    $boards_mod = array();
    if (!$user_info['is_guest']) {
        $request = $smcFunc['db_query']('', '
			SELECT id_board
			FROM {db_prefix}moderators
			WHERE id_member = {int:current_member}', array('current_member' => $user_info['id']));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards_mod[] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
    }
    $mod_query = empty($boards_mod) ? '0=1' : 'b.id_board IN (' . implode(',', $boards_mod) . ')';
    $_SESSION['mc'] = array('time' => time(), 'id' => $user_info['id'] && $user_info['name'] ? $user_info['id'] : 0, 'gq' => $group_query, 'bq' => $board_query, 'ap' => boardsAllowedTo('approve_posts'), 'mb' => $boards_mod, 'mq' => $mod_query);
    call_integration_hook('integrate_mod_cache');
    $user_info['mod_cache'] = $_SESSION['mc'];
    // Might as well clean up some tokens while we are at it.
    cleanTokens();
}
コード例 #6
0
function ViewWatchedUsers()
{
    global $smcFunc, $modSettings, $context, $txt, $scripturl, $user_info, $sourcedir;
    // Some important context!
    $context['page_title'] = $txt['mc_watched_users_title'];
    $context['view_posts'] = isset($_GET['sa']) && $_GET['sa'] == 'post';
    $context['start'] = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    loadTemplate('ModerationCenter');
    // Get some key settings!
    $modSettings['warning_watch'] = empty($modSettings['warning_watch']) ? 1 : $modSettings['warning_watch'];
    // Put some pretty tabs on cause we're gonna be doing hot stuff here...
    $context[$context['moderation_menu_name']]['tab_data'] = array('title' => $txt['mc_watched_users_title'], 'help' => '', 'description' => $txt['mc_watched_users_desc']);
    // First off - are we deleting?
    if (!empty($_REQUEST['delete'])) {
        checkSession(!is_array($_REQUEST['delete']) ? 'get' : 'post');
        $toDelete = array();
        if (!is_array($_REQUEST['delete'])) {
            $toDelete[] = (int) $_REQUEST['delete'];
        } else {
            foreach ($_REQUEST['delete'] as $did) {
                $toDelete[] = (int) $did;
            }
        }
        if (!empty($toDelete)) {
            require_once $sourcedir . '/RemoveTopic.php';
            // If they don't have permission we'll let it error - either way no chance of a security slip here!
            foreach ($toDelete as $did) {
                removeMessage($did);
            }
        }
    }
    // Start preparing the list by grabbing relevant permissions.
    if (!$context['view_posts']) {
        $approve_query = '';
        $delete_boards = array();
    } else {
        // Still obey permissions!
        $approve_boards = boardsAllowedTo('approve_posts');
        $delete_boards = boardsAllowedTo('delete_any');
        if ($approve_boards == array(0)) {
            $approve_query = '';
        } elseif (!empty($approve_boards)) {
            $approve_query = ' AND m.id_board IN (' . implode(',', $approve_boards) . ')';
        } else {
            $approve_query = ' AND 0';
        }
    }
    require_once $sourcedir . '/Subs-List.php';
    // This is all the information required for a watched user listing.
    $listOptions = array('id' => 'watch_user_list', 'title' => $txt['mc_watched_users_title'] . ' - ' . ($context['view_posts'] ? $txt['mc_watched_users_post'] : $txt['mc_watched_users_member']), 'width' => '100%', 'items_per_page' => $modSettings['defaultMaxMessages'], 'no_items_label' => $context['view_posts'] ? $txt['mc_watched_users_no_posts'] : $txt['mc_watched_users_none'], 'base_href' => $scripturl . '?action=moderate;area=userwatch;sa=' . ($context['view_posts'] ? 'post' : 'member'), 'default_sort_col' => $context['view_posts'] ? '' : 'member', 'get_items' => array('function' => $context['view_posts'] ? 'list_getWatchedUserPosts' : 'list_getWatchedUsers', 'params' => array($approve_query, $delete_boards)), 'get_count' => array('function' => $context['view_posts'] ? 'list_getWatchedUserPostsCount' : 'list_getWatchedUserCount', 'params' => array($approve_query)), 'columns' => array('member' => array('header' => array('value' => $txt['mc_watched_users_member']), 'data' => array('sprintf' => array('format' => '<a href="' . $scripturl . '?action=profile;u=%1$d">%2$s</a>', 'params' => array('id' => false, 'name' => false))), 'sort' => array('default' => 'real_name', 'reverse' => 'real_name DESC')), 'warning' => array('header' => array('value' => $txt['mc_watched_users_warning']), 'data' => array('function' => create_function('$member', '
						global $scripturl;

						return allowedTo(\'issue_warning\') ? \'<a href="\' . $scripturl . \'?action=profile;area=issuewarning;u=\' . $member[\'id\'] . \'">\' . $member[\'warning\'] . \'%</a>\' : $member[\'warning\'] . \'%\';
					')), 'sort' => array('default' => 'warning', 'reverse' => 'warning DESC')), 'posts' => array('header' => array('value' => $txt['posts']), 'data' => array('sprintf' => array('format' => '<a href="' . $scripturl . '?action=profile;u=%1$d;area=showposts;sa=messages">%2$s</a>', 'params' => array('id' => false, 'posts' => false))), 'sort' => array('default' => 'posts', 'reverse' => 'posts DESC')), 'last_login' => array('header' => array('value' => $txt['mc_watched_users_last_login']), 'data' => array('db' => 'last_login'), 'sort' => array('default' => 'last_login', 'reverse' => 'last_login DESC')), 'last_post' => array('header' => array('value' => $txt['mc_watched_users_last_post']), 'data' => array('function' => create_function('$member', '
						global $scripturl;

						if ($member[\'last_post_id\'])
							return \'<a href="\' . $scripturl . \'?msg=\' . $member[\'last_post_id\'] . \'">\' . $member[\'last_post\'] . \'</a>\';
						else
							return $member[\'last_post\'];
					')))), 'form' => array('href' => $scripturl . '?action=moderate;area=userwatch;sa=post', 'include_sort' => true, 'include_start' => true, 'hidden_fields' => array($context['session_var'] => $context['session_id'])), 'additional_rows' => array($context['view_posts'] ? array('position' => 'bottom_of_list', 'value' => '
					<input type="submit" name="delete_selected" value="' . $txt['quickmod_delete_selected'] . '" class="button_submit" />', 'align' => 'right') : array()));
    // If this is being viewed by posts we actually change the columns to call a template each time.
    if ($context['view_posts']) {
        $listOptions['columns'] = array('posts' => array('data' => array('function' => create_function('$post', '
						return template_user_watch_post_callback($post);
					'))));
    }
    // Create the watched user list.
    createList($listOptions);
    $context['sub_template'] = 'show_list';
    $context['default_list'] = 'watch_user_list';
}
コード例 #7
0
ファイル: Calendar.php プロジェクト: valek0972/hackits
function CalendarPost()
{
    global $context, $txt, $user_info, $sourcedir, $scripturl;
    global $modSettings, $topic, $smcFunc;
    // Well - can they?
    isAllowedTo('calendar_post');
    // We need this for all kinds of useful functions.
    require_once $sourcedir . '/Subs-Calendar.php';
    // Cast this for safety...
    if (isset($_REQUEST['eventid'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
    }
    // Submitting?
    if (isset($_POST[$context['session_var']], $_REQUEST['eventid'])) {
        checkSession();
        // Validate the post...
        if (!isset($_POST['link_to_board'])) {
            validateEventPost();
        }
        // If you're not allowed to edit any events, you have to be the poster.
        if ($_REQUEST['eventid'] > 0 && !allowedTo('calendar_edit_any')) {
            isAllowedTo('calendar_edit_' . (!empty($user_info['id']) && getEventPoster($_REQUEST['eventid']) == $user_info['id'] ? 'own' : 'any'));
        }
        // New - and directing?
        if ($_REQUEST['eventid'] == -1 && isset($_POST['link_to_board'])) {
            $_REQUEST['calendar'] = 1;
            require_once $sourcedir . '/Post.php';
            return Post();
        } elseif ($_REQUEST['eventid'] == -1) {
            $eventOptions = array('board' => 0, 'topic' => 0, 'title' => substr($_REQUEST['evtitle'], 0, 60), '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($_REQUEST['deleteevent'])) {
            removeEvent($_REQUEST['eventid']);
        } else {
            $eventOptions = array('title' => substr($_REQUEST['evtitle'], 0, 60), 'span' => empty($modSettings['cal_allowspan']) || empty($_POST['span']) || $_POST['span'] == 1 || empty($modSettings['cal_maxspan']) || $_POST['span'] > $modSettings['cal_maxspan'] ? 0 : min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1), 'start_date' => strftime('%Y-%m-%d', mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year'])));
            modifyEvent($_REQUEST['eventid'], $eventOptions);
        }
        updateSettings(array('calendar_updated' => time()));
        // No point hanging around here now...
        redirectexit($scripturl . '?action=calendar;month=' . $_POST['month'] . ';year=' . $_POST['year']);
    }
    // If we are not enabled... we are not enabled.
    if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid'])) {
        $_REQUEST['calendar'] = 1;
        require_once $sourcedir . '/Post.php';
        return Post();
    }
    // New?
    if (!isset($_REQUEST['eventid'])) {
        $today = getdate();
        $context['event'] = array('boards' => array(), 'board' => 0, 'new' => 1, 'eventid' => -1, 'year' => isset($_REQUEST['year']) ? $_REQUEST['year'] : $today['year'], 'month' => isset($_REQUEST['month']) ? $_REQUEST['month'] : $today['mon'], 'day' => isset($_REQUEST['day']) ? $_REQUEST['day'] : $today['mday'], 'title' => '', 'span' => 1);
        $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
        // Get list of boards that can be posted in.
        $boards = boardsAllowedTo('post_new');
        if (empty($boards)) {
            fatal_lang_error('cannot_post_new', 'permission');
        }
        // Load the list of boards and categories in the context.
        require_once $sourcedir . '/Subs-MessageIndex.php';
        $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => $modSettings['cal_defaultboard']);
        $context['event']['categories'] = getBoardList($boardListOptions);
    } else {
        $context['event'] = getEventProperties($_REQUEST['eventid']);
        if ($context['event'] === false) {
            fatal_lang_error('no_access', false);
        }
        // If it has a board, then they should be editing it within the topic.
        if (!empty($context['event']['topic']['id']) && !empty($context['event']['topic']['first_msg'])) {
            // We load the board up, for a check on the board access rights...
            $topic = $context['event']['topic']['id'];
            loadBoard();
        }
        // Make sure the user is allowed to edit this event.
        if ($context['event']['member'] != $user_info['id']) {
            isAllowedTo('calendar_edit_any');
        } elseif (!allowedTo('calendar_edit_any')) {
            isAllowedTo('calendar_edit_own');
        }
    }
    // Template, sub template, etc.
    loadTemplate('Calendar');
    $context['sub_template'] = 'event_post';
    $context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar_edit'] : $txt['calendar_post_event'];
    $context['linktree'][] = array('name' => $context['page_title']);
}
コード例 #8
0
ファイル: SSI.php プロジェクト: scripple/Elkarte
/**
 * We want to show the recent attachments outside of the forum.
 *
 * @param int $num_attachments = 10
 * @param string[] $attachment_ext = array()
 * @param string $output_method = 'echo'
 */
function ssi_recentAttachments($num_attachments = 10, $attachment_ext = array(), $output_method = 'echo')
{
    global $modSettings, $scripturl, $txt, $settings;
    // We want to make sure that we only get attachments for boards that we can see *if* any.
    $attachments_boards = boardsAllowedTo('view_attachments');
    // No boards?  Adios amigo.
    if (empty($attachments_boards)) {
        return array();
    }
    $db = database();
    // Is it an array?
    if (!is_array($attachment_ext)) {
        $attachment_ext = array($attachment_ext);
    }
    // Lets build the query.
    $request = $db->query('', '
		SELECT
			att.id_attach, att.id_msg, att.filename, IFNULL(att.size, 0) AS filesize, att.downloads, mem.id_member,
			IFNULL(mem.real_name, m.poster_name) AS poster_name, m.id_topic, m.subject, t.id_board, m.poster_time,
			att.width, att.height' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : ', IFNULL(thumb.id_attach, 0) AS id_thumb, thumb.width AS thumb_width, thumb.height AS thumb_height') . '
		FROM {db_prefix}attachments AS att
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = att.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
			LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = att.id_thumb)') . '
		WHERE att.attachment_type = 0' . ($attachments_boards === array(0) ? '' : '
			AND m.id_board IN ({array_int:boards_can_see})') . (!empty($attachment_ext) ? '
			AND att.fileext IN ({array_string:attachment_ext})' : '') . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
			AND t.approved = {int:is_approved}
			AND m.approved = {int:is_approved}
			AND att.approved = {int:is_approved}') . '
		ORDER BY att.id_attach DESC
		LIMIT {int:num_attachments}', array('boards_can_see' => $attachments_boards, 'attachment_ext' => $attachment_ext, 'num_attachments' => $num_attachments, 'is_approved' => 1));
    // We have something.
    $attachments = array();
    while ($row = $db->fetch_assoc($request)) {
        $filename = preg_replace('~&amp;#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($row['filename'], ENT_COMPAT, 'UTF-8'));
        // Is it an image?
        $attachments[$row['id_attach']] = array('member' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'), 'file' => array('filename' => $filename, 'filesize' => round($row['filesize'] / 1024, 2) . $txt['kilobyte'], 'downloads' => $row['downloads'], 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'], 'link' => '<img src="' . $settings['images_url'] . '/icons/clip.png" alt="" /> <a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . '">' . $filename . '</a>', 'is_image' => !empty($row['width']) && !empty($row['height']) && !empty($modSettings['attachmentShowImages'])), 'topic' => array('id' => $row['id_topic'], 'subject' => $row['subject'], 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '">' . $row['subject'] . '</a>', 'time' => standardTime($row['poster_time']), 'html_time' => htmlTime($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time'])));
        // Images.
        if ($attachments[$row['id_attach']]['file']['is_image']) {
            $id_thumb = empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb'];
            $attachments[$row['id_attach']]['file']['image'] = array('id' => $id_thumb, 'width' => $row['width'], 'height' => $row['height'], 'img' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image" alt="' . $filename . '" />', 'thumb' => '<img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" />', 'href' => $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image', 'link' => '<a href="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $row['id_attach'] . ';image"><img src="' . $scripturl . '?action=dlattach;topic=' . $row['id_topic'] . '.0;attach=' . $id_thumb . ';image" alt="' . $filename . '" /></a>');
        }
    }
    $db->free_result($request);
    // So you just want an array?  Here you can have it.
    if ($output_method == 'array' || empty($attachments)) {
        return $attachments;
    }
    // Give them the default.
    echo '
		<table class="ssi_downloads" cellpadding="2">
			<tr>
				<th align="left">', $txt['file'], '</th>
				<th align="left">', $txt['posted_by'], '</th>
				<th align="left">', $txt['downloads'], '</th>
				<th align="left">', $txt['filesize'], '</th>
			</tr>';
    foreach ($attachments as $attach) {
        echo '
			<tr>
				<td>', $attach['file']['link'], '</td>
				<td>', $attach['member']['link'], '</td>
				<td align="center">', $attach['file']['downloads'], '</td>
				<td>', $attach['file']['filesize'], '</td>
			</tr>';
    }
    echo '
		</table>';
}
コード例 #9
0
ファイル: PostModeration.php プロジェクト: Kheros/MMOver
function UnapprovedAttachments()
{
    global $txt, $scripturl, $context, $user_info, $sourcedir, $smcFunc;
    $context['page_title'] = $txt['mc_unapproved_attachments'];
    // Once again, permissions are king!
    $approve_boards = boardsAllowedTo('approve_posts');
    if ($approve_boards == array(0)) {
        $approve_query = '';
    } elseif (!empty($approve_boards)) {
        $approve_query = ' AND m.id_board IN (' . implode(',', $approve_boards) . ')';
    } else {
        $approve_query = ' AND 0';
    }
    // Get together the array of things to act on, if any.
    $attachments = array();
    if (isset($_GET['approve'])) {
        $attachments[] = (int) $_GET['approve'];
    } elseif (isset($_GET['delete'])) {
        $attachments[] = (int) $_GET['delete'];
    } elseif (isset($_POST['item'])) {
        foreach ($_POST['item'] as $item) {
            $attachments[] = (int) $item;
        }
    }
    // Are we approving or deleting?
    if (isset($_GET['approve']) || isset($_POST['do']) && $_POST['do'] == 'approve') {
        $curAction = 'approve';
    } elseif (isset($_GET['delete']) || isset($_POST['do']) && $_POST['do'] == 'delete') {
        $curAction = 'delete';
    }
    // Something to do, let's do it!
    if (!empty($attachments) && isset($curAction)) {
        checkSession('request');
        // This will be handy.
        require_once $sourcedir . '/ManageAttachments.php';
        // Confirm the attachments are eligible for changing!
        $request = $smcFunc['db_query']('', '
			SELECT a.id_attach
			FROM {db_prefix}attachments AS a
				INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
				LEFT JOIN {db_prefix}boards AS b ON (m.id_board = b.id_board)
			WHERE a.id_attach IN ({array_int:attachments})
				AND a.approved = {int:not_approved}
				AND a.attachment_type = {int:attachment_type}
				AND {query_see_board}
				' . $approve_query, array('attachments' => $attachments, 'not_approved' => 0, 'attachment_type' => 0));
        $attachments = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $attachments[] = $row['id_attach'];
        }
        $smcFunc['db_free_result']($request);
        // Assuming it wasn't all like, proper illegal, we can do the approving.
        if (!empty($attachments)) {
            if ($curAction == 'approve') {
                ApproveAttachments($attachments);
            } else {
                removeAttachments(array('id_attach' => $attachments));
            }
        }
    }
    // How many unapproved attachments in total?
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}attachments AS a
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
		WHERE a.approved = {int:not_approved}
			AND a.attachment_type = {int:attachment_type}
			AND {query_see_board}
			' . $approve_query, array('not_approved' => 0, 'attachment_type' => 0));
    list($context['total_unapproved_attachments']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=attachmod;sa=attachments', $_GET['start'], $context['total_unapproved_attachments'], 10);
    $context['start'] = $_GET['start'];
    // Get all unapproved attachments.
    $request = $smcFunc['db_query']('', '
		SELECT a.id_attach, a.filename, a.size, m.id_msg, m.id_topic, m.id_board, m.subject, m.body, m.id_member,
			IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time,
			t.id_member_started, t.id_first_msg, b.name AS board_name, c.id_cat, c.name AS cat_name
		FROM {db_prefix}attachments AS a
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
			LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
		WHERE a.approved = {int:not_approved}
			AND a.attachment_type = {int:attachment_type}
			AND {query_see_board}
			' . $approve_query . '
		LIMIT ' . $context['start'] . ', 10', array('not_approved' => 0, 'attachment_type' => 0));
    $context['unapproved_items'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $context['unapproved_items'][] = array('id' => $row['id_attach'], 'filename' => $row['filename'], 'size' => round($row['size'] / 1024, 2), 'time' => timeformat($row['poster_time']), 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member']), 'message' => array('id' => $row['id_msg'], 'subject' => $row['subject'], 'body' => parse_bbc($row['body']), 'time' => timeformat($row['poster_time']), 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg']), 'topic' => array('id' => $row['id_topic']), 'board' => array('id' => $row['id_board'], 'name' => $row['board_name']), 'category' => array('id' => $row['id_cat'], 'name' => $row['cat_name']));
    }
    $smcFunc['db_free_result']($request);
    $context['sub_template'] = 'unapproved_attachments';
}
コード例 #10
0
    /**
     * fetch_data.
     * Fetch Boards, Topics, Messages and Attaches.
     */
    function fetch_data()
    {
        global $context, $smcFunc, $modSettings, $boardurl, $txt;
        $this->boards = null;
        $this->attaches = null;
        $this->imgName = '';
        if (isset($this->cfg['config']['settings']['board']) && !empty($this->cfg['config']['settings']['board'])) {
            $this->posts = ssi_boardNews($this->cfg['config']['settings']['board'], $this->cfg['config']['settings']['total'], null, null, '');
            if (!empty($this->posts)) {
                $topics = null;
                $msgids = null;
                foreach ($this->posts as $id => $post) {
                    $topics[] = $post['id'];
                    $msgids[] = $post['message_id'];
                    // Rescale inline Images ?
                    if (!empty($this->cfg['config']['settings']['rescale']) || empty($this->cfg['config']['settings']['rescale']) && !is_numeric($this->cfg['config']['settings']['rescale'])) {
                        // find all images
                        if (preg_match_all('~<img[^>]*>~iS', $this->posts[$id]['body'], $matches) > 0) {
                            // remove smileys
                            foreach ($matches[0] as $i => $data) {
                                if (strpos($data, $modSettings['smileys_url']) !== false) {
                                    unset($matches[0][$i]);
                                }
                            }
                            // images found?
                            if (count($matches[0]) > 0) {
                                $this->imgName = $this->cfg['blocktype'] . '-' . $this->cfg['id'];
                                if (empty($this->cfg['config']['settings']['rescale'])) {
                                    $fnd = array('~ class?=?"[^"]*"~', '~ alt?=?"[^"]*"~', '~ title?=?"[^"]*"~');
                                } else {
                                    $fnd = array('~ width?=?"\\d+"~', '~ height?=?"\\d+"~', '~ class?=?"[^"]*"~', '~ alt?=?"[^"]*"~', '~ title?=?"[^"]*"~');
                                }
                                // modify the images for highslide
                                foreach ($matches[0] as $i => $data) {
                                    $datlen = strlen($data);
                                    preg_match('~src?=?"([^\\"]*\\")~i', $data, $src);
                                    $alt = substr(strrchr($src[1], '/'), 1);
                                    $alt = str_replace(array('_', '-'), ' ', strtoupper(substr($alt, 0, strrpos($alt, '.'))));
                                    $tmp = str_replace($src[0], ' class="' . $this->imgName . '" alt="' . $alt . '" ' . $src[0], preg_replace($fnd, '', $data));
                                    // highslide disabled?
                                    if (!empty($context['pmx']['settings']['disableHS']) || !empty($context['pmx']['settings']['disableHSonfront'])) {
                                        $this->posts[$id]['body'] = substr_replace($this->posts[$id]['body'], $tmp, strpos($this->posts[$id]['body'], $data), $datlen);
                                    } elseif (empty($this->cfg['config']['settings']['disableHSimg']) && empty($context['pmx']['settings']['disableHSonfront'])) {
                                        $this->posts[$id]['body'] = substr_replace($this->posts[$id]['body'], '<a href="' . $boardurl . '" class="' . $this->imgName . ' highslide" title="' . $txt['pmx_hs_expand'] . '" onclick="return hs.expand(this, {src: \'' . str_replace('"', '', $src[1]) . '\', align: \'center\', headingEval: \'this.thumb.alt\'})">' . $tmp . '</a>', strpos($this->posts[$id]['body'], $data), $datlen);
                                    } else {
                                        $this->posts[$id]['body'] = substr_replace($this->posts[$id]['body'], $tmp, strpos($this->posts[$id]['body'], $data), $datlen);
                                    }
                                }
                            }
                        }
                    } elseif (is_numeric($this->cfg['config']['settings']['rescale'])) {
                        $this->posts[$id]['body'] = PortaMx_revoveLinks($this->posts[$id]['body'], false, true);
                    }
                    // teaser enabled ?
                    if (!empty($this->cfg['config']['settings']['teaser'])) {
                        $this->posts[$id]['body'] = PortaMx_Tease_posts($this->posts[$id]['body'], $this->cfg['config']['settings']['teaser']);
                    }
                }
                // get attachments if show thumnails set
                $allow_boards = boardsAllowedTo('view_attachments');
                if (!empty($this->cfg['config']['settings']['thumbs']) && !empty($allow_boards)) {
                    $request = $smcFunc['db_query']('', '
						SELECT a.id_msg, a.id_attach, a.id_thumb, a.filename, m.id_topic
						FROM {db_prefix}attachments AS a
						LEFT JOIN {db_prefix}messages AS m ON (a.id_msg = m.id_msg)
						WHERE a.id_msg IN({array_int:messages}) AND a.mime_type LIKE {string:like}' . ($allow_boards === array(0) ? '' : (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' AND m.approved = 1 AND a.approved = 1') . ' AND m.id_board IN ({array_int:boards})') . '
						ORDER BY a.id_msg DESC, a.id_attach ASC', array('messages' => $msgids, 'like' => 'IMAGE%', 'boards' => $allow_boards));
                    $thumbs = array();
                    $msgcnt = array();
                    $saved = !empty($this->cfg['config']['settings']['thumbcnt']) ? $this->cfg['config']['settings']['thumbcnt'] : 0;
                    while ($row = $smcFunc['db_fetch_assoc']($request)) {
                        if (!in_array($row['id_attach'], $thumbs)) {
                            if (!empty($this->cfg['config']['settings']['thumbcnt'])) {
                                if (!in_array($row['id_msg'], $msgcnt)) {
                                    $saved = $this->cfg['config']['settings']['thumbcnt'];
                                } elseif (in_array($row['id_msg'], $msgcnt) && empty($saved)) {
                                    continue;
                                }
                            }
                            $saved--;
                            $msgcnt[] = $row['id_msg'];
                            $thumbs[] = $row['id_thumb'];
                            $this->attaches[$row['id_msg']][] = array('topic' => $row['id_topic'], 'image' => $row['id_attach'], 'thumb' => empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb'], 'fname' => str_replace('_thumb', '', $row['filename']));
                        }
                    }
                    $smcFunc['db_free_result']($request);
                }
                // get boards and views
                $request = $smcFunc['db_query']('', '
					SELECT b.id_board, b.name, t.id_topic, t.num_views
						FROM {db_prefix}boards b
						LEFT JOIN {db_prefix}topics t ON (t.id_board = b.id_board)
					WHERE t.id_topic IN ({array_int:topics})
						AND t.approved = 1', array('topics' => $topics));
                $this->boards = null;
                while ($row = $smcFunc['db_fetch_assoc']($request)) {
                    $this->boards[$row['id_topic']] = array('id_board' => $row['id_board'], 'boardname' => $row['name'], 'views' => $row['num_views']);
                }
                $smcFunc['db_free_result']($request);
            }
        }
    }
コード例 #11
0
ファイル: konusal-com.php プロジェクト: snrj/konusal-m-theme
function boardnewslide($start = null, $length = null, $output_method = 'echo')
{
    global $txt, $scripturl, $user_info, $context, $modSettings, $sourcedir, $board, $smcFunc, $settings;
    if (isset($_REQUEST['start']) && $_REQUEST['start'] > 95) {
        $_REQUEST['start'] = 95;
    }
    $query_parameters = array();
    if (!empty($_REQUEST['c']) && empty($board)) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        if (count($_REQUEST['c']) == 1) {
            $request = $smcFunc['db_query']('', '
				SELECT name
				FROM {db_prefix}categories
				WHERE id_cat = {int:id_cat}
				LIMIT 1', array('id_cat' => $_REQUEST['c'][0]));
            list($name) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            if (empty($name)) {
                fatal_lang_error('no_access', false);
            }
            $context['linktree'][] = array('url' => $scripturl . '#c' . (int) $_REQUEST['c'], 'name' => $name);
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board, b.num_topics
			FROM {db_prefix}boards AS b
			WHERE b.id_cat IN ({array_int:category_list})
				AND {query_see_board}', array('category_list' => $_REQUEST['c']));
        $total_cat_posts = 0;
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
            $total_cat_posts += $row['num_posts'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'b.id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        // If this category has a significant number of posts in it...
        if ($total_cat_posts > 100 && $total_cat_posts > $modSettings['totalMessages'] / 15) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 400 - $_REQUEST['start'] * 7);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?' . implode(',', $_REQUEST['c']), $_REQUEST['start'], min(100, $total_cat_posts), 5, false);
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board, b.num_topics
			FROM {db_prefix}boards AS b
			WHERE b.id_board IN ({array_int:board_list})
				AND {query_see_board}
			LIMIT {int:limit}', array('board_list' => $_REQUEST['boards'], 'limit' => count($_REQUEST['boards'])));
        $total_posts = 0;
        $boards = array();
        $say = 5;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
            $total_posts += $row['num_posts'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'b.id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        // If these boards have a significant number of posts in them...
        if ($total_posts > 100 && $total_posts > $modSettings['totalMessages'] / 12) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 500 - $_REQUEST['start'] * 9);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?boards=' . implode(',', $_REQUEST['boards']), $_REQUEST['start'], min(100, $total_posts), 5, false);
    } elseif (!empty($board)) {
        $request = $smcFunc['db_query']('', '
			SELECT num_topics
			FROM {db_prefix}boards
			WHERE id_board = {int:current_board}
			LIMIT 1', array('current_board' => $board));
        list($total_posts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $query_this_board = 'b.id_board = {int:board}';
        $query_parameters['board'] = $board;
        // If this board has a significant number of posts in it...
        if ($total_posts > 80 && $total_posts > $modSettings['totalMessages'] / 5) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 600 - $_REQUEST['start'] * 5);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], min(100, $total_posts), 5, true);
    } else {
        $query_this_board = '{query_wanna_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
					AND b.id_board != {int:recycle_board}' : '') . '
					AND m.id_msg >= {int:max_id_msg}';
        $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 100 - $_REQUEST['start'] * 6);
        $query_parameters['recycle_board'] = $modSettings['recycle_board'];
        $settings['adet'] = !empty($settings['adet']) ? (int) $settings['adet'] : 10;
        // !!! This isn't accurate because we ignore the recycle bin.
        $context['page_index'] = constructPageIndex($scripturl . '?', $_REQUEST['start'], min(100, $modSettings['totalTopics']), $settings['adet'], false);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=recent' . (empty($board) ? empty($_REQUEST['c']) ? '' : ';c=' . (int) $_REQUEST['c'] : ';board=' . $board . '.0'));
    $key = 'recent-' . $user_info['id'] . '-' . md5(serialize(array_diff_key($query_parameters, array('max_id_msg' => 0)))) . '-' . (int) $_REQUEST['start'];
    if (empty($modSettings['cache_enable']) || ($messages = cache_get_data($key, 120)) == null) {
        $done = false;
        while (!$done) {
            // Find the 10 most recent messages they can *view*.
            // !!!SLOW This query is really slow still, probably?
            $request = $smcFunc['db_query']('', '
				SELECT m.id_msg
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
					INNER JOIN {db_prefix}topics AS t ON (t.' . (!empty($modSettings['RecentTopicsOnRecentPostsPage_mode']) && $modSettings['RecentTopicsOnRecentPostsPage_mode'] == 'updated' ? 'id_last_msg' : 'id_first_msg') . ' = m.id_msg)
				WHERE ' . $query_this_board . '
					AND m.approved = {int:is_approved}
				ORDER BY m.id_msg DESC
				LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('is_approved' => 1, 'offset' => $_REQUEST['start'], 'limit' => 5)));
            // If we don't have 10 results, try again with an unoptimized version covering all rows, and cache the result.
            if (isset($query_parameters['max_id_msg']) && $smcFunc['db_num_rows']($request) < 5) {
                $smcFunc['db_free_result']($request);
                $query_this_board = str_replace('AND m.id_msg >= {int:max_id_msg}', '', $query_this_board);
                $cache_results = true;
                unset($query_parameters['max_id_msg']);
            } else {
                $done = true;
            }
        }
        $messages = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $messages[] = $row['id_msg'];
        }
        $smcFunc['db_free_result']($request);
        if (!empty($cache_results)) {
            cache_put_data($key, $messages, 120);
        }
    }
    // Nothing here... Or at least, nothing you can see...
    if (empty($messages)) {
        $context['posts'] = array();
        return;
    }
    // Get all the most recent posts.
    $request = $smcFunc['db_query']('', '
		SELECT
			m.id_msg, m.subject, m.smileys_enabled, m.poster_time, m.body, m.id_topic, t.id_board, b.id_cat,
			b.name AS bname, c.name AS cname, t.num_replies, m.id_member, m2.id_member AS id_first_member,
			IFNULL(mem2.real_name, m2.poster_name) AS first_poster_name, t.id_first_msg,
			IFNULL(mem.real_name, m.poster_name) AS poster_name, t.id_last_msg
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			INNER JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
			INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_first_msg)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
			LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
		WHERE m.id_msg IN ({array_int:message_list})
		ORDER BY m.id_msg DESC
		LIMIT ' . count($messages), array('message_list' => $messages));
    $counter = $_REQUEST['start'] + 1;
    $context['posts'] = array();
    $board_ids = array('own' => array(), 'any' => array());
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // If we want to limit the length of the post.
        if (!empty($length) && $smcFunc['strlen']($row['body']) > $length) {
            $row['body'] = $smcFunc['substr']($row['body'], 0, $length);
            $cutoff = false;
            $last_space = strrpos($row['body'], ' ');
            $last_open = strrpos($row['body'], '<');
            $last_close = strrpos($row['body'], '>');
            if (empty($last_space) || $last_space == $last_open + 3 && (empty($last_close) || !empty($last_close) && $last_close < $last_open) || $last_space < $last_open || $last_open == $length - 6) {
                $cutoff = $last_open;
            } elseif (empty($last_close) || $last_close < $last_open) {
                $cutoff = $last_space;
            }
            if ($cutoff !== false) {
                $row['body'] = $smcFunc['substr']($row['body'], 0, $cutoff);
            }
            $row['body'] .= '...';
        }
        $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
        if (!empty($recycle_board) && $row['id_board'] == $recycle_board) {
            $row['icon'] = 'recycled';
        }
        // Check that this message icon is there...
        if (!empty($modSettings['messageIconChecks_enable']) && !isset($icon_sources[$row['icon']])) {
            $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url';
        }
        // Censor everything.
        censorText($row['body']);
        censorText($row['subject']);
        // BBC-atize the message.
        $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
        $secimyap = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $row['body'], $sonuc);
        // src="" içindekini al.
        if (!empty($sonuc[0]) && !empty($sonuc[1])) {
            $ilkresim = $sonuc[1][0];
        } else {
            // Resim bulunmazsa default resim ekle
            $ilkresim = $settings['theme_url'] . '/images/konusaldefault.png';
        }
        // And build the array.
        $context['posts'][$row['id_msg']] = array('id' => $row['id_msg'], 'counter' => $counter++, 'alternate' => $counter % 2, 'category' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'href' => $scripturl . '#c' . $row['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $row['id_cat'] . '">' . $row['cname'] . '</a>'), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['bname'] . '</a>'), 'topic' => $row['id_topic'], 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>', 'start' => $row['num_replies'], 'subject' => $row['subject'], 'resim' => $ilkresim, 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'first_poster' => array('id' => $row['id_first_member'], 'name' => $row['first_poster_name'], 'href' => empty($row['id_first_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_first_member'], 'link' => empty($row['id_first_member']) ? $row['first_poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_first_member'] . '">' . $row['first_poster_name'] . '</a>'), 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'), 'message' => $row['body'], 'can_reply' => false, 'can_mark_notify' => false, 'can_delete' => false, 'delete_possible' => ($row['id_first_msg'] != $row['id_msg'] || $row['id_last_msg'] == $row['id_msg']) && (empty($modSettings['edit_disable_time']) || $row['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()));
        if ($user_info['id'] == $row['id_first_member']) {
            $board_ids['own'][$row['id_board']][] = $row['id_msg'];
        }
        $board_ids['any'][$row['id_board']][] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    // There might be - and are - different permissions between any and own.
    $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify', 'delete_any' => 'can_delete'));
    // Now go through all the permissions, looking for boards they can do it on.
    foreach ($permissions as $type => $list) {
        foreach ($list as $permission => $allowed) {
            // They can do it on these boards...
            $boards = boardsAllowedTo($permission);
            // If 0 is the only thing in the array, they can do it everywhere!
            if (!empty($boards) && $boards[0] == 0) {
                $boards = array_keys($board_ids[$type]);
            }
            // Go through the boards, and look for posts they can do this on.
            foreach ($boards as $board_id) {
                // Hmm, they have permission, but there are no topics from that board on this page.
                if (!isset($board_ids[$type][$board_id])) {
                    continue;
                }
                // Okay, looks like they can do it for these posts.
                foreach ($board_ids[$type][$board_id] as $counter) {
                    if ($type == 'any' || $context['posts'][$counter]['poster']['id'] == $user_info['id']) {
                        $context['posts'][$counter][$allowed] = true;
                    }
                }
            }
        }
    }
    $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    foreach ($context['posts'] as $counter => $dummy) {
        // Some posts - the first posts - can't just be deleted.
        $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
        // And some cannot be quoted...
        $context['posts'][$counter]['can_quote'] = $context['posts'][$counter]['can_reply'] && $quote_enabled;
    }
    global $context, $settings, $options, $txt, $scripturl;
    echo '<script type="text/javascript" src="', $settings['theme_url'], '/scripts/modernizr.custom.28468.js"></script>
		<div id="da-slider" class="da-slider">';
    foreach ($context['posts'] as $post) {
        echo '
				<div class="da-slide">
				<h2><a href="', $post['href'], '">', $post['subject'], '</a></h2>
				<p>', temizle($post['message']), ' </p>
				<a href="', $post['href'], '" class="da-link">', $txt['Read'], '</a>
				<div class="da-img"><a href="', $post['href'], '"> <img width="120px" src="', $post['resim'], '" alt="', $post['subject'], '" class="haber_resmi" /></a></div>
				</div>';
    }
    echo '
			</div>
		<script type="text/javascript" src="', $settings['theme_url'], '/scripts/jquery.cslider.js"></script>
		<script type="text/javascript">
			$(function() {
			
				$(\'#da-slider\').cslider({
					autoplay	: true,
					bgincrement	: 450
				});
			
			});
		</script>';
}
コード例 #12
0
function char_posts()
{
    global $txt, $user_info, $scripturl, $modSettings;
    global $context, $user_profile, $sourcedir, $smcFunc, $board;
    // Some initial context.
    $context['start'] = (int) $_REQUEST['start'];
    $context['sub_template'] = 'char_posts';
    // Create the tabs for the template.
    $context[$context['profile_menu_name']]['tab_data'] = array('title' => $txt['showPosts'], 'description' => $txt['showPosts_help_char'], 'icon' => 'profile_hd.png', 'tabs' => array('posts' => array(), 'topics' => array()));
    // Shortcut used to determine which $txt['show*'] string to use for the title, based on the SA
    $title = array('posts' => 'Posts', 'topics' => 'Topics');
    // Set the page title
    if (isset($_GET['sa']) && array_key_exists($_GET['sa'], $title)) {
        $context['linktree'][] = array('name' => $txt['show' . $title[$_GET['sa']] . '_char'], 'url' => $scripturl . '?action=profile;area=characters;char=' . $context['character']['id_character'] . ';sa=' . $_GET['sa'] . ';u=' . $context['id_member']);
        $context['page_title'] = $txt['show' . $title[$_GET['sa']]];
    } else {
        $context['linktree'][] = array('name' => $txt['showPosts_char'], 'url' => $scripturl . '?action=profile;area=characters;char=' . $context['character']['id_character'] . ';sa=posts;u=' . $context['id_member']);
        $context['page_title'] = $txt['showPosts'];
    }
    $context['page_title'] .= ' - ' . $context['character']['character_name'];
    // Is the load average too high to allow searching just now?
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_show_posts']) && $context['load_average'] >= $modSettings['loadavg_show_posts']) {
        fatal_lang_error('loadavg_show_posts_disabled', false);
    }
    // Are we just viewing topics?
    $context['is_topics'] = isset($_GET['sa']) && $_GET['sa'] == 'topics' ? true : false;
    // Default to 10.
    if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount'])) {
        $_REQUEST['viewscount'] = '10';
    }
    if ($context['is_topics']) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(*)
			FROM {db_prefix}topics AS t' . ($user_info['query_see_board'] == '1=1' ? '' : '
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board AND {query_see_board})') . '
				INNER JOIN {db_prefix}messages AS m ON (t.id_first_msg = m.id_msg)
			WHERE m.id_character = {int:current_member}' . (!empty($board) ? '
				AND t.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
				AND t.approved = {int:is_approved}'), array('current_member' => $context['character']['id_character'], 'is_approved' => 1, 'board' => $board));
    } else {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(*)
			FROM {db_prefix}messages AS m' . ($user_info['query_see_board'] == '1=1' ? '' : '
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})') . '
			WHERE m.id_character = {int:current_member}' . (!empty($board) ? '
				AND m.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
				AND m.approved = {int:is_approved}'), array('current_member' => $context['character']['id_character'], 'is_approved' => 1, 'board' => $board));
    }
    list($msgCount) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $request = $smcFunc['db_query']('', '
		SELECT MIN(id_msg), MAX(id_msg)
		FROM {db_prefix}messages AS m
		WHERE m.id_character = {int:current_member}' . (!empty($board) ? '
			AND m.id_board = {int:board}' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
			AND m.approved = {int:is_approved}'), array('current_member' => $context['character']['id_character'], 'is_approved' => 1, 'board' => $board));
    list($min_msg_member, $max_msg_member) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $reverse = false;
    $range_limit = '';
    if ($context['is_topics']) {
        $maxPerPage = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
    } else {
        $maxPerPage = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    }
    $maxIndex = $maxPerPage;
    // Make sure the starting place makes sense and construct our friend the page index.
    $context['page_index'] = constructPageIndex($scripturl . '?action=profile;area=characters;char=' . $context['character']['id_character'] . ';u=' . $context['id_member'] . ($context['is_topics'] ? ';sa=topics' : ';sa=posts') . (!empty($board) ? ';board=' . $board : ''), $context['start'], $msgCount, $maxIndex);
    $context['current_page'] = $context['start'] / $maxIndex;
    // Reverse the query if we're past 50% of the pages for better performance.
    $start = $context['start'];
    $reverse = $_REQUEST['start'] > $msgCount / 2;
    if ($reverse) {
        $maxIndex = $msgCount < $context['start'] + $maxPerPage + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : $maxPerPage;
        $start = $msgCount < $context['start'] + $maxPerPage + 1 || $msgCount < $context['start'] + $maxPerPage ? 0 : $msgCount - $context['start'] - $maxPerPage;
    }
    // Guess the range of messages to be shown.
    if ($msgCount > 1000) {
        $margin = floor(($max_msg_member - $min_msg_member) * (($start + $maxPerPage) / $msgCount) + 0.1 * ($max_msg_member - $min_msg_member));
        // Make a bigger margin for topics only.
        if ($context['is_topics']) {
            $margin *= 5;
            $range_limit = $reverse ? 't.id_first_msg < ' . ($min_msg_member + $margin) : 't.id_first_msg > ' . ($max_msg_member - $margin);
        } else {
            $range_limit = $reverse ? 'm.id_msg < ' . ($min_msg_member + $margin) : 'm.id_msg > ' . ($max_msg_member - $margin);
        }
    }
    // Find this user's posts.  The left join on categories somehow makes this faster, weird as it looks.
    $looped = false;
    while (true) {
        if ($context['is_topics']) {
            $request = $smcFunc['db_query']('', '
				SELECT
					b.id_board, b.name AS bname, c.id_cat, c.name AS cname, t.id_member_started, t.id_first_msg, t.id_last_msg,
					t.approved, m.body, m.smileys_enabled, m.subject, m.poster_time, m.id_topic, m.id_msg
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
					LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
					INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
				WHERE m.id_character = {int:current_member}' . (!empty($board) ? '
					AND t.id_board = {int:board}' : '') . (empty($range_limit) ? '' : '
					AND ' . $range_limit) . '
					AND {query_see_board}' . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
					AND t.approved = {int:is_approved} AND m.approved = {int:is_approved}') . '
				ORDER BY t.id_first_msg ' . ($reverse ? 'ASC' : 'DESC') . '
				LIMIT ' . $start . ', ' . $maxIndex, array('current_member' => $context['character']['id_character'], 'is_approved' => 1, 'board' => $board));
        } else {
            $request = $smcFunc['db_query']('', '
				SELECT
					b.id_board, b.name AS bname, c.id_cat, c.name AS cname, m.id_topic, m.id_msg,
					t.id_member_started, t.id_first_msg, t.id_last_msg, m.body, m.smileys_enabled,
					m.subject, m.poster_time, m.approved
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
					LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				WHERE m.id_character = {int:current_member}' . (!empty($board) ? '
					AND b.id_board = {int:board}' : '') . (empty($range_limit) ? '' : '
					AND ' . $range_limit) . '
					AND {query_see_board}' . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
					AND t.approved = {int:is_approved} AND m.approved = {int:is_approved}') . '
				ORDER BY m.id_msg ' . ($reverse ? 'ASC' : 'DESC') . '
				LIMIT ' . $start . ', ' . $maxIndex, array('current_member' => $context['character']['id_character'], 'is_approved' => 1, 'board' => $board));
        }
        // Make sure we quit this loop.
        if ($smcFunc['db_num_rows']($request) === $maxIndex || $looped) {
            break;
        }
        $looped = true;
        $range_limit = '';
    }
    // Start counting at the number of the first message displayed.
    $counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start'];
    $context['posts'] = [];
    $board_ids = array('own' => [], 'any' => []);
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // Censor....
        censorText($row['body']);
        censorText($row['subject']);
        // Do the code.
        $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
        // And the array...
        $context['posts'][$counter += $reverse ? -1 : 1] = array('body' => $row['body'], 'counter' => $counter, 'category' => array('name' => $row['cname'], 'id' => $row['id_cat']), 'board' => array('name' => $row['bname'], 'id' => $row['id_board']), 'topic' => $row['id_topic'], 'subject' => $row['subject'], 'start' => 'msg' . $row['id_msg'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'id' => $row['id_msg'], 'can_reply' => false, 'can_mark_notify' => !$context['user']['is_guest'], 'can_delete' => false, 'delete_possible' => ($row['id_first_msg'] != $row['id_msg'] || $row['id_last_msg'] == $row['id_msg']) && (empty($modSettings['edit_disable_time']) || $row['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()), 'approved' => $row['approved'], 'css_class' => $row['approved'] ? 'windowbg' : 'approvebg');
        if ($user_info['id'] == $row['id_member_started']) {
            $board_ids['own'][$row['id_board']][] = $counter;
        }
        $board_ids['any'][$row['id_board']][] = $counter;
    }
    $smcFunc['db_free_result']($request);
    // All posts were retrieved in reverse order, get them right again.
    if ($reverse) {
        $context['posts'] = array_reverse($context['posts'], true);
    }
    // These are all the permissions that are different from board to board..
    if ($context['is_topics']) {
        $permissions = array('own' => array('post_reply_own' => 'can_reply'), 'any' => array('post_reply_any' => 'can_reply'));
    } else {
        $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'delete_any' => 'can_delete'));
    }
    // For every permission in the own/any lists...
    foreach ($permissions as $type => $list) {
        foreach ($list as $permission => $allowed) {
            // Get the boards they can do this on...
            $boards = boardsAllowedTo($permission);
            // Hmm, they can do it on all boards, can they?
            if (!empty($boards) && $boards[0] == 0) {
                $boards = array_keys($board_ids[$type]);
            }
            // Now go through each board they can do the permission on.
            foreach ($boards as $board_id) {
                // There aren't any posts displayed from this board.
                if (!isset($board_ids[$type][$board_id])) {
                    continue;
                }
                // Set the permission to true ;).
                foreach ($board_ids[$type][$board_id] as $counter) {
                    $context['posts'][$counter][$allowed] = true;
                }
            }
        }
    }
    // Clean up after posts that cannot be deleted and quoted.
    $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    foreach ($context['posts'] as $counter => $dummy) {
        $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
        $context['posts'][$counter]['can_quote'] = $context['posts'][$counter]['can_reply'] && $quote_enabled;
    }
    // Allow last minute changes.
    call_integration_hook('integrate_profile_showPosts');
}
コード例 #13
0
function action_m_rename_topic()
{
    global $smcFunc, $context, $user_info, $topic, $modSettings, $txt;
    if (empty($topic)) {
        fatal_lang_error('no_access', false);
    }
    $_POST['custom_subject'] = mobiquo_encode($_POST['custom_subject']);
    $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();
    if (isset($_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']);
            return;
        }
    }
    get_error($txt['error_no_subject']);
}
コード例 #14
0
ファイル: Search.php プロジェクト: chenhao6593/smf
function PlushSearch2()
{
    global $scripturl, $modSettings, $sourcedir, $txt, $db_connection;
    global $user_info, $context, $options, $messages_request, $boards_can;
    global $excludedWords, $participants, $smcFunc, $search_versions, $searchAPI;
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) {
        fatal_lang_error('loadavg_search_disabled', false);
    }
    // No, no, no... this is a bit hard on the server, so don't you go prefetching it!
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Forbidden');
        die;
    }
    $weight_factors = array('frequency', 'age', 'length', 'subject', 'first_message', 'sticky');
    $weight = array();
    $weight_total = 0;
    foreach ($weight_factors as $weight_factor) {
        $weight[$weight_factor] = empty($modSettings['search_weight_' . $weight_factor]) ? 0 : (int) $modSettings['search_weight_' . $weight_factor];
        $weight_total += $weight[$weight_factor];
    }
    // Zero weight.  Weightless :P.
    if (empty($weight_total)) {
        fatal_lang_error('search_invalid_weights');
    }
    // These vars don't require an interface, they're just here for tweaking.
    $recentPercentage = 0.3;
    $humungousTopicPosts = 200;
    $maxMembersToSearch = 500;
    $maxMessageResults = empty($modSettings['search_max_results']) ? 0 : $modSettings['search_max_results'] * 5;
    // Start with no errors.
    $context['search_errors'] = array();
    // Number of pages hard maximum - normally not set at all.
    $modSettings['search_max_results'] = empty($modSettings['search_max_results']) ? 200 * $modSettings['search_results_per_page'] : (int) $modSettings['search_max_results'];
    // Maximum length of the string.
    $context['search_string_limit'] = 100;
    loadLanguage('Search');
    if (!isset($_REQUEST['xml'])) {
        loadTemplate('Search');
    } else {
        $context['sub_template'] = 'results';
    }
    // Are you allowed?
    isAllowedTo('search_posts');
    require_once $sourcedir . '/Display.php';
    require_once $sourcedir . '/Subs-Package.php';
    // Search has a special database set.
    db_extend('search');
    // Load up the search API we are going to use.
    $modSettings['search_index'] = empty($modSettings['search_index']) ? 'standard' : $modSettings['search_index'];
    if (!file_exists($sourcedir . '/SearchAPI-' . ucwords($modSettings['search_index']) . '.php')) {
        fatal_lang_error('search_api_missing');
    }
    loadClassFile('SearchAPI-' . ucwords($modSettings['search_index']) . '.php');
    // Create an instance of the search API and check it is valid for this version of SMF.
    $search_class_name = $modSettings['search_index'] . '_search';
    $searchAPI = new $search_class_name();
    if (!$searchAPI || $searchAPI->supportsMethod('isValid') && !$searchAPI->isValid() || !matchPackageVersion($search_versions['forum_version'], $searchAPI->min_smf_version . '-' . $searchAPI->version_compatible)) {
        // Log the error.
        loadLanguage('Errors');
        log_error(sprintf($txt['search_api_not_compatible'], 'SearchAPI-' . ucwords($modSettings['search_index']) . '.php'), 'critical');
        loadClassFile('SearchAPI-Standard.php');
        $searchAPI = new standard_search();
    }
    // $search_params will carry all settings that differ from the default search parameters.
    // That way, the URLs involved in a search page will be kept as short as possible.
    $search_params = array();
    if (isset($_REQUEST['params'])) {
        // Due to IE's 2083 character limit, we have to compress long search strings
        $temp_params = base64_decode(str_replace(array('-', '_', '.'), array('+', '/', '='), $_REQUEST['params']));
        // Test for gzuncompress failing
        $temp_params2 = @gzuncompress($temp_params);
        $temp_params = explode('|"|', !empty($temp_params2) ? $temp_params2 : $temp_params);
        foreach ($temp_params as $i => $data) {
            @(list($k, $v) = explode('|\'|', $data));
            $search_params[$k] = $v;
        }
        if (isset($search_params['brd'])) {
            $search_params['brd'] = empty($search_params['brd']) ? array() : explode(',', $search_params['brd']);
        }
    }
    // Store whether simple search was used (needed if the user wants to do another query).
    if (!isset($search_params['advanced'])) {
        $search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1;
    }
    // 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'.
    if (!empty($search_params['searchtype']) || !empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2) {
        $search_params['searchtype'] = 2;
    }
    // Minimum age of messages. Default to zero (don't set param in that case).
    if (!empty($search_params['minage']) || !empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0) {
        $search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage'];
    }
    // Maximum age of messages. Default to infinite (9999 days: param not set).
    if (!empty($search_params['maxage']) || !empty($_REQUEST['maxage']) && $_REQUEST['maxage'] < 9999) {
        $search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage'];
    }
    // Searching a specific topic?
    if (!empty($_REQUEST['topic'])) {
        $search_params['topic'] = (int) $_REQUEST['topic'];
        $search_params['show_complete'] = true;
    } elseif (!empty($search_params['topic'])) {
        $search_params['topic'] = (int) $search_params['topic'];
    }
    if (!empty($search_params['minage']) || !empty($search_params['maxage'])) {
        $request = $smcFunc['db_query']('', '
			SELECT ' . (empty($search_params['maxage']) ? '0, ' : 'IFNULL(MIN(id_msg), -1), ') . (empty($search_params['minage']) ? '0' : 'IFNULL(MAX(id_msg), -1)') . '
			FROM {db_prefix}messages
			WHERE 1=1' . ($modSettings['postmod_active'] ? '
				AND approved = {int:is_approved_true}' : '') . (empty($search_params['minage']) ? '' : '
				AND poster_time <= {int:timestamp_minimum_age}') . (empty($search_params['maxage']) ? '' : '
				AND poster_time >= {int:timestamp_maximum_age}'), array('timestamp_minimum_age' => empty($search_params['minage']) ? 0 : time() - 86400 * $search_params['minage'], 'timestamp_maximum_age' => empty($search_params['maxage']) ? 0 : time() - 86400 * $search_params['maxage'], 'is_approved_true' => 1));
        list($minMsgID, $maxMsgID) = $smcFunc['db_fetch_row']($request);
        if ($minMsgID < 0 || $maxMsgID < 0) {
            $context['search_errors']['no_messages_in_time_frame'] = true;
        }
        $smcFunc['db_free_result']($request);
    }
    // Default the user name to a wildcard matching every user (*).
    if (!empty($search_params['userspec']) || !empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*') {
        $search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec'];
    }
    // If there's no specific user, then don't mention it in the main query.
    if (empty($search_params['userspec'])) {
        $userQuery = '';
    } else {
        $userString = strtr($smcFunc['htmlspecialchars']($search_params['userspec'], ENT_QUOTES), array('&quot;' => '"'));
        $userString = strtr($userString, array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_'));
        preg_match_all('~"([^"]+)"~', $userString, $matches);
        $possible_users = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $userString)));
        for ($k = 0, $n = count($possible_users); $k < $n; $k++) {
            $possible_users[$k] = trim($possible_users[$k]);
            if (strlen($possible_users[$k]) == 0) {
                unset($possible_users[$k]);
            }
        }
        // Create a list of database-escaped search names.
        $realNameMatches = array();
        foreach ($possible_users as $possible_user) {
            $realNameMatches[] = $smcFunc['db_quote']('{string:possible_user}', array('possible_user' => $possible_user));
        }
        // Retrieve a list of possible members.
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}members
			WHERE {raw:match_possible_users}', array('match_possible_users' => 'real_name LIKE ' . implode(' OR real_name LIKE ', $realNameMatches)));
        // Simply do nothing if there're too many members matching the criteria.
        if ($smcFunc['db_num_rows']($request) > $maxMembersToSearch) {
            $userQuery = '';
        } elseif ($smcFunc['db_num_rows']($request) == 0) {
            $userQuery = $smcFunc['db_quote']('m.id_member = {int:id_member_guest} AND ({raw:match_possible_guest_names})', array('id_member_guest' => 0, 'match_possible_guest_names' => 'm.poster_name LIKE ' . implode(' OR m.poster_name LIKE ', $realNameMatches)));
        } else {
            $memberlist = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $memberlist[] = $row['id_member'];
            }
            $userQuery = $smcFunc['db_quote']('(m.id_member IN ({array_int:matched_members}) OR (m.id_member = {int:id_member_guest} AND ({raw:match_possible_guest_names})))', array('matched_members' => $memberlist, 'id_member_guest' => 0, 'match_possible_guest_names' => 'm.poster_name LIKE ' . implode(' OR m.poster_name LIKE ', $realNameMatches)));
        }
        $smcFunc['db_free_result']($request);
    }
    // If the boards were passed by URL (params=), temporarily put them back in $_REQUEST.
    if (!empty($search_params['brd']) && is_array($search_params['brd'])) {
        $_REQUEST['brd'] = $search_params['brd'];
    }
    // Ensure that brd is an array.
    if (!empty($_REQUEST['brd']) && !is_array($_REQUEST['brd'])) {
        $_REQUEST['brd'] = strpos($_REQUEST['brd'], ',') !== false ? explode(',', $_REQUEST['brd']) : array($_REQUEST['brd']);
    }
    // Make sure all boards are integers.
    if (!empty($_REQUEST['brd'])) {
        foreach ($_REQUEST['brd'] as $id => $brd) {
            $_REQUEST['brd'][$id] = (int) $brd;
        }
    }
    // Special case for boards: searching just one topic?
    if (!empty($search_params['topic'])) {
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE t.id_topic = {int:search_topic_id}
				AND {query_see_board}' . ($modSettings['postmod_active'] ? '
				AND t.approved = {int:is_approved_true}' : '') . '
			LIMIT 1', array('search_topic_id' => $search_params['topic'], 'is_approved_true' => 1));
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('topic_gone', false);
        }
        $search_params['brd'] = array();
        list($search_params['brd'][0]) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
    } elseif ($user_info['is_admin'] && (!empty($search_params['advanced']) || !empty($_REQUEST['brd']))) {
        $search_params['brd'] = empty($_REQUEST['brd']) ? array() : $_REQUEST['brd'];
    } else {
        $see_board = empty($search_params['advanced']) ? 'query_wanna_see_board' : 'query_see_board';
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board
			FROM {db_prefix}boards AS b
			WHERE {raw:boards_allowed_to_see}
				AND redirect = {string:empty_string}' . (empty($_REQUEST['brd']) ? !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
				AND b.id_board != {int:recycle_board_id}' : '' : '
				AND b.id_board IN ({array_int:selected_search_boards})'), array('boards_allowed_to_see' => $user_info[$see_board], 'empty_string' => '', 'selected_search_boards' => empty($_REQUEST['brd']) ? array() : $_REQUEST['brd'], 'recycle_board_id' => $modSettings['recycle_board']));
        $search_params['brd'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $search_params['brd'][] = $row['id_board'];
        }
        $smcFunc['db_free_result']($request);
        // This error should pro'bly only happen for hackers.
        if (empty($search_params['brd'])) {
            $context['search_errors']['no_boards_selected'] = true;
        }
    }
    if (count($search_params['brd']) != 0) {
        foreach ($search_params['brd'] as $k => $v) {
            $search_params['brd'][$k] = (int) $v;
        }
        // If we've selected all boards, this parameter can be left empty.
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(*)
			FROM {db_prefix}boards
			WHERE redirect = {string:empty_string}', array('empty_string' => ''));
        list($num_boards) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        if (count($search_params['brd']) == $num_boards) {
            $boardQuery = '';
        } elseif (count($search_params['brd']) == $num_boards - 1 && !empty($modSettings['recycle_board']) && !in_array($modSettings['recycle_board'], $search_params['brd'])) {
            $boardQuery = '!= ' . $modSettings['recycle_board'];
        } else {
            $boardQuery = 'IN (' . implode(', ', $search_params['brd']) . ')';
        }
    } else {
        $boardQuery = '';
    }
    $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']);
    $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']);
    $context['compact'] = !$search_params['show_complete'];
    // Get the sorting parameters right. Default to sort by relevance descending.
    $sort_columns = array('relevance', 'num_replies', 'id_msg');
    if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) {
        list($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, '');
    }
    $search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'relevance';
    if (!empty($search_params['topic']) && $search_params['sort'] === 'num_replies') {
        $search_params['sort'] = 'id_msg';
    }
    // Sorting direction: descending unless stated otherwise.
    $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc';
    // Determine some values needed to calculate the relevance.
    $minMsg = (int) ((1 - $recentPercentage) * $modSettings['maxMsgID']);
    $recentMsg = $modSettings['maxMsgID'] - $minMsg;
    // *** Parse the search query
    // Unfortunately, searching for words like this is going to be slow, so we're blacklisting them.
    // !!! Setting to add more here?
    // !!! Maybe only blacklist if they are the only word, or "any" is used?
    $blacklisted_words = array('img', 'url', 'quote', 'www', 'http', 'the', 'is', 'it', 'are', 'if');
    // What are we searching for?
    if (empty($search_params['search'])) {
        if (isset($_GET['search'])) {
            $search_params['search'] = un_htmlspecialchars($_GET['search']);
        } elseif (isset($_POST['search'])) {
            $search_params['search'] = $_POST['search'];
        } else {
            $search_params['search'] = '';
        }
    }
    // Nothing??
    if (!isset($search_params['search']) || $search_params['search'] == '') {
        $context['search_errors']['invalid_search_string'] = true;
    } elseif ($smcFunc['strlen']($search_params['search']) > $context['search_string_limit']) {
        $context['search_errors']['string_too_long'] = true;
        $txt['error_string_too_long'] = sprintf($txt['error_string_too_long'], $context['search_string_limit']);
    }
    // Change non-word characters into spaces.
    $stripped_query = preg_replace('~(?:[\\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}' : " " : '\\xA0') . '\\t\\r\\s\\n(){}\\[\\]<>!@$%^*.,:+=`\\~\\?/\\\\]+|&(?:amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']);
    // Make the query lower case. It's gonna be case insensitive anyway.
    $stripped_query = un_htmlspecialchars($smcFunc['strtolower']($stripped_query));
    // This (hidden) setting will do fulltext searching in the most basic way.
    if (!empty($modSettings['search_simple_fulltext'])) {
        $stripped_query = strtr($stripped_query, array('"' => ''));
    }
    $no_regexp = preg_match('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', $stripped_query) === 1;
    // Extract phrase parts first (e.g. some words "this is a phrase" some more words.)
    preg_match_all('/(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)/', $stripped_query, $matches, PREG_PATTERN_ORDER);
    $phraseArray = $matches[2];
    // Remove the phrase parts and extract the words.
    $wordArray = explode(' ', preg_replace('~(?:^|\\s)(?:[-]?)"(?:[^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']));
    // A minus sign in front of a word excludes the word.... so...
    $excludedWords = array();
    $excludedIndexWords = array();
    $excludedSubjectWords = array();
    $excludedPhrases = array();
    // .. first, we check for things like -"some words", but not "-some words".
    foreach ($matches[1] as $index => $word) {
        if ($word === '-') {
            if (($word = trim($phraseArray[$index], '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) {
                $excludedWords[] = $word;
            }
            unset($phraseArray[$index]);
        }
    }
    // Now we look for -test, etc.... normaller.
    foreach ($wordArray as $index => $word) {
        if (strpos(trim($word), '-') === 0) {
            if (($word = trim($word, '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) {
                $excludedWords[] = $word;
            }
            unset($wordArray[$index]);
        }
    }
    // The remaining words and phrases are all included.
    $searchArray = array_merge($phraseArray, $wordArray);
    // Trim everything and make sure there are no words that are the same.
    foreach ($searchArray as $index => $value) {
        // Skip anything practically empty.
        if (($searchArray[$index] = trim($value, '-_\' ')) === '') {
            unset($searchArray[$index]);
        } elseif (in_array($searchArray[$index], $blacklisted_words)) {
            $foundBlackListedWords = true;
            unset($searchArray[$index]);
        } elseif ($smcFunc['strlen']($value) < 2) {
            $context['search_errors']['search_string_small_words'] = true;
            unset($searchArray[$index]);
        } else {
            $searchArray[$index] = $searchArray[$index];
        }
    }
    $searchArray = array_slice(array_unique($searchArray), 0, 10);
    // Create an array of replacements for highlighting.
    $context['mark'] = array();
    foreach ($searchArray as $word) {
        $context['mark'][$word] = '<strong class="highlight">' . $word . '</strong>';
    }
    // Initialize two arrays storing the words that have to be searched for.
    $orParts = array();
    $searchWords = array();
    // Make sure at least one word is being searched for.
    if (empty($searchArray)) {
        $context['search_errors']['invalid_search_string' . (!empty($foundBlackListedWords) ? '_blacklist' : '')] = true;
    } elseif (empty($search_params['searchtype'])) {
        $orParts[0] = $searchArray;
    } else {
        foreach ($searchArray as $index => $value) {
            $orParts[$index] = array($value);
        }
    }
    // Don't allow duplicate error messages if one string is too short.
    if (isset($context['search_errors']['search_string_small_words'], $context['search_errors']['invalid_search_string'])) {
        unset($context['search_errors']['invalid_search_string']);
    }
    // Make sure the excluded words are in all or-branches.
    foreach ($orParts as $orIndex => $andParts) {
        foreach ($excludedWords as $word) {
            $orParts[$orIndex][] = $word;
        }
    }
    // Determine the or-branches and the fulltext search words.
    foreach ($orParts as $orIndex => $andParts) {
        $searchWords[$orIndex] = array('indexed_words' => array(), 'words' => array(), 'subject_words' => array(), 'all_words' => array());
        // Sort the indexed words (large words -> small words -> excluded words).
        if ($searchAPI->supportsMethod('searchSort')) {
            usort($orParts[$orIndex], 'searchSort');
        }
        foreach ($orParts[$orIndex] as $word) {
            $is_excluded = in_array($word, $excludedWords);
            $searchWords[$orIndex]['all_words'][] = $word;
            $subjectWords = text2words($word);
            if (!$is_excluded || count($subjectWords) === 1) {
                $searchWords[$orIndex]['subject_words'] = array_merge($searchWords[$orIndex]['subject_words'], $subjectWords);
                if ($is_excluded) {
                    $excludedSubjectWords = array_merge($excludedSubjectWords, $subjectWords);
                }
            } else {
                $excludedPhrases[] = $word;
            }
            // Have we got indexes to prepare?
            if ($searchAPI->supportsMethod('prepareIndexes')) {
                $searchAPI->prepareIndexes($word, $searchWords[$orIndex], $excludedIndexWords, $is_excluded);
            }
        }
        // Search_force_index requires all AND parts to have at least one fulltext word.
        if (!empty($modSettings['search_force_index']) && empty($searchWords[$orIndex]['indexed_words'])) {
            $context['search_errors']['query_not_specific_enough'] = true;
            break;
        } elseif ($search_params['subject_only'] && empty($searchWords[$orIndex]['subject_words']) && empty($excludedSubjectWords)) {
            $context['search_errors']['query_not_specific_enough'] = true;
            break;
        } else {
            $searchWords[$orIndex]['indexed_words'] = array_slice($searchWords[$orIndex]['indexed_words'], 0, 7);
            $searchWords[$orIndex]['subject_words'] = array_slice($searchWords[$orIndex]['subject_words'], 0, 7);
        }
    }
    // *** Spell checking
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    if ($context['show_spellchecking']) {
        // Windows fix.
        ob_start();
        $old = error_reporting(0);
        pspell_new('en');
        $pspell_link = pspell_new($txt['lang_dictionary'], $txt['lang_spelling'], '', strtr($txt['lang_character_set'], array('iso-' => 'iso', 'ISO-' => 'iso')), PSPELL_FAST | PSPELL_RUN_TOGETHER);
        if (!$pspell_link) {
            $pspell_link = pspell_new('en', '', '', '', PSPELL_FAST | PSPELL_RUN_TOGETHER);
        }
        error_reporting($old);
        ob_end_clean();
        $did_you_mean = array('search' => array(), 'display' => array());
        $found_misspelling = false;
        foreach ($searchArray as $word) {
            if (empty($pspell_link)) {
                continue;
            }
            $word = $word;
            // Don't check phrases.
            if (preg_match('~^\\w+$~', $word) === 0) {
                $did_you_mean['search'][] = '"' . $word . '"';
                $did_you_mean['display'][] = '&quot;' . $smcFunc['htmlspecialchars']($word) . '&quot;';
                continue;
            } elseif (preg_match('~\\d~', $word) === 1) {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $smcFunc['htmlspecialchars']($word);
                continue;
            } elseif (pspell_check($pspell_link, $word)) {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $smcFunc['htmlspecialchars']($word);
                continue;
            }
            $suggestions = pspell_suggest($pspell_link, $word);
            foreach ($suggestions as $i => $s) {
                // Search is case insensitive.
                if ($smcFunc['strtolower']($s) == $smcFunc['strtolower']($word)) {
                    unset($suggestions[$i]);
                } elseif ($suggestions[$i] != censorText($s)) {
                    unset($suggestions[$i]);
                }
            }
            // Anything found?  If so, correct it!
            if (!empty($suggestions)) {
                $suggestions = array_values($suggestions);
                $did_you_mean['search'][] = $suggestions[0];
                $did_you_mean['display'][] = '<em><strong>' . $smcFunc['htmlspecialchars']($suggestions[0]) . '</strong></em>';
                $found_misspelling = true;
            } else {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $smcFunc['htmlspecialchars']($word);
            }
        }
        if ($found_misspelling) {
            // Don't spell check excluded words, but add them still...
            $temp_excluded = array('search' => array(), 'display' => array());
            foreach ($excludedWords as $word) {
                $word = $word;
                if (preg_match('~^\\w+$~', $word) == 0) {
                    $temp_excluded['search'][] = '-"' . $word . '"';
                    $temp_excluded['display'][] = '-&quot;' . $smcFunc['htmlspecialchars']($word) . '&quot;';
                } else {
                    $temp_excluded['search'][] = '-' . $word;
                    $temp_excluded['display'][] = '-' . $smcFunc['htmlspecialchars']($word);
                }
            }
            $did_you_mean['search'] = array_merge($did_you_mean['search'], $temp_excluded['search']);
            $did_you_mean['display'] = array_merge($did_you_mean['display'], $temp_excluded['display']);
            $temp_params = $search_params;
            $temp_params['search'] = implode(' ', $did_you_mean['search']);
            if (isset($temp_params['brd'])) {
                $temp_params['brd'] = implode(',', $temp_params['brd']);
            }
            $context['params'] = array();
            foreach ($temp_params as $k => $v) {
                $context['did_you_mean_params'][] = $k . '|\'|' . $v;
            }
            $context['did_you_mean_params'] = base64_encode(implode('|"|', $context['did_you_mean_params']));
            $context['did_you_mean'] = implode(' ', $did_you_mean['display']);
        }
    }
    // Let the user adjust the search query, should they wish?
    $context['search_params'] = $search_params;
    if (isset($context['search_params']['search'])) {
        $context['search_params']['search'] = $smcFunc['htmlspecialchars']($context['search_params']['search']);
    }
    if (isset($context['search_params']['userspec'])) {
        $context['search_params']['userspec'] = $smcFunc['htmlspecialchars']($context['search_params']['userspec']);
    }
    // Do we have captcha enabled?
    if ($user_info['is_guest'] && !empty($modSettings['search_enable_captcha']) && empty($_SESSION['ss_vv_passed']) && (empty($_SESSION['last_ss']) || $_SESSION['last_ss'] != $search_params['search'])) {
        // If we come from another search box tone down the error...
        if (!isset($_REQUEST['search_vv'])) {
            $context['search_errors']['need_verification_code'] = true;
        } else {
            require_once $sourcedir . '/Subs-Editor.php';
            $verificationOptions = array('id' => 'search');
            $context['require_verification'] = create_control_verification($verificationOptions, true);
            if (is_array($context['require_verification'])) {
                foreach ($context['require_verification'] as $error) {
                    $context['search_errors'][$error] = true;
                }
            } else {
                $_SESSION['ss_vv_passed'] = true;
            }
        }
    }
    // *** Encode all search params
    // All search params have been checked, let's compile them to a single string... made less simple by PHP 4.3.9 and below.
    $temp_params = $search_params;
    if (isset($temp_params['brd'])) {
        $temp_params['brd'] = implode(',', $temp_params['brd']);
    }
    $context['params'] = array();
    foreach ($temp_params as $k => $v) {
        $context['params'][] = $k . '|\'|' . $v;
    }
    if (!empty($context['params'])) {
        // Due to old IE's 2083 character limit, we have to compress long search strings
        $params = @gzcompress(implode('|"|', $context['params']));
        // Gzcompress failed, use try non-gz
        if (empty($params)) {
            $params = implode('|"|', $context['params']);
        }
        // Base64 encode, then replace +/= with uri safe ones that can be reverted
        $context['params'] = str_replace(array('+', '/', '='), array('-', '_', '.'), base64_encode($params));
    }
    // ... and add the links to the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?action=search;params=' . $context['params'], 'name' => $txt['search']);
    $context['linktree'][] = array('url' => $scripturl . '?action=search2;params=' . $context['params'], 'name' => $txt['search_results']);
    // *** A last error check
    // One or more search errors? Go back to the first search screen.
    if (!empty($context['search_errors'])) {
        $_REQUEST['params'] = $context['params'];
        return PlushSearch1();
    }
    // Spam me not, Spam-a-lot?
    if (empty($_SESSION['last_ss']) || $_SESSION['last_ss'] != $search_params['search']) {
        spamProtection('search');
    }
    // Store the last search string to allow pages of results to be browsed.
    $_SESSION['last_ss'] = $search_params['search'];
    // *** Reserve an ID for caching the search results.
    $query_params = array_merge($search_params, array('min_msg_id' => isset($minMsgID) ? (int) $minMsgID : 0, 'max_msg_id' => isset($maxMsgID) ? (int) $maxMsgID : 0, 'memberlist' => !empty($memberlist) ? $memberlist : array()));
    // Can this search rely on the API given the parameters?
    if ($searchAPI->supportsMethod('searchQuery', $query_params)) {
        $participants = array();
        $searchArray = array();
        $num_results = $searchAPI->searchQuery($query_params, $searchWords, $excludedIndexWords, $participants, $searchArray);
    } else {
        $update_cache = empty($_SESSION['search_cache']) || $_SESSION['search_cache']['params'] != $context['params'];
        if ($update_cache) {
            // Increase the pointer...
            $modSettings['search_pointer'] = empty($modSettings['search_pointer']) ? 0 : (int) $modSettings['search_pointer'];
            // ...and store it right off.
            updateSettings(array('search_pointer' => $modSettings['search_pointer'] >= 255 ? 0 : $modSettings['search_pointer'] + 1));
            // As long as you don't change the parameters, the cache result is yours.
            $_SESSION['search_cache'] = array('id_search' => $modSettings['search_pointer'], 'num_results' => -1, 'params' => $context['params']);
            // Clear the previous cache of the final results cache.
            $smcFunc['db_search_query']('delete_log_search_results', '
				DELETE FROM {db_prefix}log_search_results
				WHERE id_search = {int:search_id}', array('search_id' => $_SESSION['search_cache']['id_search']));
            if ($search_params['subject_only']) {
                // We do this to try and avoid duplicate keys on databases not supporting INSERT IGNORE.
                $inserts = array();
                foreach ($searchWords as $orIndex => $words) {
                    $subject_query_params = array();
                    $subject_query = array('from' => '{db_prefix}topics AS t', 'inner_join' => array(), 'left_join' => array(), 'where' => array());
                    if ($modSettings['postmod_active']) {
                        $subject_query['where'][] = 't.approved = {int:is_approved}';
                    }
                    $numTables = 0;
                    $prev_join = 0;
                    $numSubjectResults = 0;
                    foreach ($words['subject_words'] as $subjectWord) {
                        $numTables++;
                        if (in_array($subjectWord, $excludedSubjectWords)) {
                            $subject_query['left_join'][] = '{db_prefix}log_search_subjects AS subj' . $numTables . ' ON (subj' . $numTables . '.word ' . (empty($modSettings['search_match_words']) ? 'LIKE {string:subject_words_' . $numTables . '_wild}' : '= {string:subject_words_' . $numTables . '}') . ' AND subj' . $numTables . '.id_topic = t.id_topic)';
                            $subject_query['where'][] = '(subj' . $numTables . '.word IS NULL)';
                        } else {
                            $subject_query['inner_join'][] = '{db_prefix}log_search_subjects AS subj' . $numTables . ' ON (subj' . $numTables . '.id_topic = ' . ($prev_join === 0 ? 't' : 'subj' . $prev_join) . '.id_topic)';
                            $subject_query['where'][] = 'subj' . $numTables . '.word ' . (empty($modSettings['search_match_words']) ? 'LIKE {string:subject_words_' . $numTables . '_wild}' : '= {string:subject_words_' . $numTables . '}');
                            $prev_join = $numTables;
                        }
                        $subject_query_params['subject_words_' . $numTables] = $subjectWord;
                        $subject_query_params['subject_words_' . $numTables . '_wild'] = '%' . $subjectWord . '%';
                    }
                    if (!empty($userQuery)) {
                        if ($subject_query['from'] != '{db_prefix}messages AS m') {
                            $subject_query['inner_join'][] = '{db_prefix}messages AS m ON (m.id_topic = t.id_topic)';
                        }
                        $subject_query['where'][] = $userQuery;
                    }
                    if (!empty($search_params['topic'])) {
                        $subject_query['where'][] = 't.id_topic = ' . $search_params['topic'];
                    }
                    if (!empty($minMsgID)) {
                        $subject_query['where'][] = 't.id_first_msg >= ' . $minMsgID;
                    }
                    if (!empty($maxMsgID)) {
                        $subject_query['where'][] = 't.id_last_msg <= ' . $maxMsgID;
                    }
                    if (!empty($boardQuery)) {
                        $subject_query['where'][] = 't.id_board ' . $boardQuery;
                    }
                    if (!empty($excludedPhrases)) {
                        if ($subject_query['from'] != '{db_prefix}messages AS m') {
                            $subject_query['inner_join'][] = '{db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)';
                        }
                        $count = 0;
                        foreach ($excludedPhrases as $phrase) {
                            $subject_query['where'][] = 'm.subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:excluded_phrases_' . $count . '}';
                            $subject_query_params['excluded_phrases_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . '[[:>:]]';
                        }
                    }
                    $ignoreRequest = $smcFunc['db_search_query']('insert_log_search_results_subject', ($smcFunc['db_support_ignore'] ? '
						INSERT IGNORE INTO {db_prefix}log_search_results
							(id_search, id_topic, relevance, id_msg, num_matches)' : '') . '
						SELECT
							{int:id_search},
							t.id_topic,
							1000 * (
								{int:weight_frequency} / (t.num_replies + 1) +
								{int:weight_age} * CASE WHEN t.id_first_msg < {int:min_msg} THEN 0 ELSE (t.id_first_msg - {int:min_msg}) / {int:recent_message} END +
								{int:weight_length} * CASE WHEN t.num_replies < {int:huge_topic_posts} THEN t.num_replies / {int:huge_topic_posts} ELSE 1 END +
								{int:weight_subject} +
								{int:weight_sticky} * t.is_sticky
							) / {int:weight_total} AS relevance,
							' . (empty($userQuery) ? 't.id_first_msg' : 'm.id_msg') . ',
							1
						FROM ' . $subject_query['from'] . (empty($subject_query['inner_join']) ? '' : '
							INNER JOIN ' . implode('
							INNER JOIN ', $subject_query['inner_join'])) . (empty($subject_query['left_join']) ? '' : '
							LEFT JOIN ' . implode('
							LEFT JOIN ', $subject_query['left_join'])) . '
						WHERE ' . implode('
							AND ', $subject_query['where']) . (empty($modSettings['search_max_results']) ? '' : '
						LIMIT ' . ($modSettings['search_max_results'] - $numSubjectResults)), array_merge($subject_query_params, array('id_search' => $_SESSION['search_cache']['id_search'], 'weight_age' => $weight['age'], 'weight_frequency' => $weight['frequency'], 'weight_length' => $weight['length'], 'weight_sticky' => $weight['sticky'], 'weight_subject' => $weight['subject'], 'weight_total' => $weight_total, 'min_msg' => $minMsg, 'recent_message' => $recentMsg, 'huge_topic_posts' => $humungousTopicPosts, 'is_approved' => 1)));
                    // If the database doesn't support IGNORE to make this fast we need to do some tracking.
                    if (!$smcFunc['db_support_ignore']) {
                        while ($row = $smcFunc['db_fetch_row']($ignoreRequest)) {
                            // No duplicates!
                            if (isset($inserts[$row[1]])) {
                                continue;
                            }
                            foreach ($row as $key => $value) {
                                $inserts[$row[1]][] = (int) $row[$key];
                            }
                        }
                        $smcFunc['db_free_result']($ignoreRequest);
                        $numSubjectResults = count($inserts);
                    } else {
                        $numSubjectResults += $smcFunc['db_affected_rows']();
                    }
                    if (!empty($modSettings['search_max_results']) && $numSubjectResults >= $modSettings['search_max_results']) {
                        break;
                    }
                }
                // If there's data to be inserted for non-IGNORE databases do it here!
                if (!empty($inserts)) {
                    $smcFunc['db_insert']('', '{db_prefix}log_search_results', array('id_search' => 'int', 'id_topic' => 'int', 'relevance' => 'int', 'id_msg' => 'int', 'num_matches' => 'int'), $inserts, array('id_search', 'id_topic'));
                }
                $_SESSION['search_cache']['num_results'] = $numSubjectResults;
            } else {
                $main_query = array('select' => array('id_search' => $_SESSION['search_cache']['id_search'], 'relevance' => '0'), 'weights' => array(), 'from' => '{db_prefix}topics AS t', 'inner_join' => array('{db_prefix}messages AS m ON (m.id_topic = t.id_topic)'), 'left_join' => array(), 'where' => array(), 'group_by' => array(), 'parameters' => array('min_msg' => $minMsg, 'recent_message' => $recentMsg, 'huge_topic_posts' => $humungousTopicPosts, 'is_approved' => 1));
                if (empty($search_params['topic']) && empty($search_params['show_complete'])) {
                    $main_query['select']['id_topic'] = 't.id_topic';
                    $main_query['select']['id_msg'] = 'MAX(m.id_msg) AS id_msg';
                    $main_query['select']['num_matches'] = 'COUNT(*) AS num_matches';
                    $main_query['weights'] = array('frequency' => 'COUNT(*) / (MAX(t.num_replies) + 1)', 'age' => 'CASE WHEN MAX(m.id_msg) < {int:min_msg} THEN 0 ELSE (MAX(m.id_msg) - {int:min_msg}) / {int:recent_message} END', 'length' => 'CASE WHEN MAX(t.num_replies) < {int:huge_topic_posts} THEN MAX(t.num_replies) / {int:huge_topic_posts} ELSE 1 END', 'subject' => '0', 'first_message' => 'CASE WHEN MIN(m.id_msg) = MAX(t.id_first_msg) THEN 1 ELSE 0 END', 'sticky' => 'MAX(t.is_sticky)');
                    $main_query['group_by'][] = 't.id_topic';
                } else {
                    // This is outrageous!
                    $main_query['select']['id_topic'] = 'm.id_msg AS id_topic';
                    $main_query['select']['id_msg'] = 'm.id_msg';
                    $main_query['select']['num_matches'] = '1 AS num_matches';
                    $main_query['weights'] = array('age' => '((m.id_msg - t.id_first_msg) / CASE WHEN t.id_last_msg = t.id_first_msg THEN 1 ELSE t.id_last_msg - t.id_first_msg END)', 'first_message' => 'CASE WHEN m.id_msg = t.id_first_msg THEN 1 ELSE 0 END');
                    if (!empty($search_params['topic'])) {
                        $main_query['where'][] = 't.id_topic = {int:topic}';
                        $main_query['parameters']['topic'] = $search_params['topic'];
                    }
                    if (!empty($search_params['show_complete'])) {
                        $main_query['group_by'][] = 'm.id_msg, t.id_first_msg, t.id_last_msg';
                    }
                }
                // *** Get the subject results.
                $numSubjectResults = 0;
                if (empty($search_params['topic'])) {
                    $inserts = array();
                    // Create a temporary table to store some preliminary results in.
                    $smcFunc['db_search_query']('drop_tmp_log_search_topics', '
						DROP TABLE IF EXISTS {db_prefix}tmp_log_search_topics', array('db_error_skip' => true));
                    $createTemporary = $smcFunc['db_search_query']('create_tmp_log_search_topics', '
						CREATE TEMPORARY TABLE {db_prefix}tmp_log_search_topics (
							id_topic mediumint(8) unsigned NOT NULL default {string:string_zero},
							PRIMARY KEY (id_topic)
						) ENGINE=MEMORY', array('string_zero' => '0', 'db_error_skip' => true)) !== false;
                    // Clean up some previous cache.
                    if (!$createTemporary) {
                        $smcFunc['db_search_query']('delete_log_search_topics', '
							DELETE FROM {db_prefix}log_search_topics
							WHERE id_search = {int:search_id}', array('search_id' => $_SESSION['search_cache']['id_search']));
                    }
                    foreach ($searchWords as $orIndex => $words) {
                        $subject_query = array('from' => '{db_prefix}topics AS t', 'inner_join' => array(), 'left_join' => array(), 'where' => array(), 'params' => array());
                        $numTables = 0;
                        $prev_join = 0;
                        $count = 0;
                        foreach ($words['subject_words'] as $subjectWord) {
                            $numTables++;
                            if (in_array($subjectWord, $excludedSubjectWords)) {
                                if ($subject_query['from'] != '{db_prefix}messages AS m') {
                                    $subject_query['inner_join'][] = '{db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)';
                                }
                                $subject_query['left_join'][] = '{db_prefix}log_search_subjects AS subj' . $numTables . ' ON (subj' . $numTables . '.word ' . (empty($modSettings['search_match_words']) ? 'LIKE {string:subject_not_' . $count . '}' : '= {string:subject_not_' . $count . '}') . ' AND subj' . $numTables . '.id_topic = t.id_topic)';
                                $subject_query['params']['subject_not_' . $count] = empty($modSettings['search_match_words']) ? '%' . $subjectWord . '%' : $subjectWord;
                                $subject_query['where'][] = '(subj' . $numTables . '.word IS NULL)';
                                $subject_query['where'][] = 'm.body NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:body_not_' . $count . '}';
                                $subject_query['params']['body_not_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($subjectWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $subjectWord), '\\\'') . '[[:>:]]';
                            } else {
                                $subject_query['inner_join'][] = '{db_prefix}log_search_subjects AS subj' . $numTables . ' ON (subj' . $numTables . '.id_topic = ' . ($prev_join === 0 ? 't' : 'subj' . $prev_join) . '.id_topic)';
                                $subject_query['where'][] = 'subj' . $numTables . '.word LIKE {string:subject_like_' . $count . '}';
                                $subject_query['params']['subject_like_' . $count++] = empty($modSettings['search_match_words']) ? '%' . $subjectWord . '%' : $subjectWord;
                                $prev_join = $numTables;
                            }
                        }
                        if (!empty($userQuery)) {
                            if ($subject_query['from'] != '{db_prefix}messages AS m') {
                                $subject_query['inner_join'][] = '{db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)';
                            }
                            $subject_query['where'][] = '{raw:user_query}';
                            $subject_query['params']['user_query'] = $userQuery;
                        }
                        if (!empty($search_params['topic'])) {
                            $subject_query['where'][] = 't.id_topic = {int:topic}';
                            $subject_query['params']['topic'] = $search_params['topic'];
                        }
                        if (!empty($minMsgID)) {
                            $subject_query['where'][] = 't.id_first_msg >= {int:min_msg_id}';
                            $subject_query['params']['min_msg_id'] = $minMsgID;
                        }
                        if (!empty($maxMsgID)) {
                            $subject_query['where'][] = 't.id_last_msg <= {int:max_msg_id}';
                            $subject_query['params']['max_msg_id'] = $maxMsgID;
                        }
                        if (!empty($boardQuery)) {
                            $subject_query['where'][] = 't.id_board {raw:board_query}';
                            $subject_query['params']['board_query'] = $boardQuery;
                        }
                        if (!empty($excludedPhrases)) {
                            if ($subject_query['from'] != '{db_prefix}messages AS m') {
                                $subject_query['inner_join'][] = '{db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)';
                            }
                            $count = 0;
                            foreach ($excludedPhrases as $phrase) {
                                $subject_query['where'][] = 'm.subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:exclude_phrase_' . $count . '}';
                                $subject_query['where'][] = 'm.body NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:exclude_phrase_' . $count . '}';
                                $subject_query['params']['exclude_phrase_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . '[[:>:]]';
                            }
                        }
                        // Nothing to search for?
                        if (empty($subject_query['where'])) {
                            continue;
                        }
                        $ignoreRequest = $smcFunc['db_search_query']('insert_log_search_topics', ($smcFunc['db_support_ignore'] ? '
							INSERT IGNORE INTO {db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_topics
								(' . ($createTemporary ? '' : 'id_search, ') . 'id_topic)' : '') . '
							SELECT ' . ($createTemporary ? '' : $_SESSION['search_cache']['id_search'] . ', ') . 't.id_topic
							FROM ' . $subject_query['from'] . (empty($subject_query['inner_join']) ? '' : '
								INNER JOIN ' . implode('
								INNER JOIN ', $subject_query['inner_join'])) . (empty($subject_query['left_join']) ? '' : '
								LEFT JOIN ' . implode('
								LEFT JOIN ', $subject_query['left_join'])) . '
							WHERE ' . implode('
								AND ', $subject_query['where']) . (empty($modSettings['search_max_results']) ? '' : '
							LIMIT ' . ($modSettings['search_max_results'] - $numSubjectResults)), $subject_query['params']);
                        // Don't do INSERT IGNORE? Manually fix this up!
                        if (!$smcFunc['db_support_ignore']) {
                            while ($row = $smcFunc['db_fetch_row']($ignoreRequest)) {
                                $ind = $createTemporary ? 0 : 1;
                                // No duplicates!
                                if (isset($inserts[$row[$ind]])) {
                                    continue;
                                }
                                $inserts[$row[$ind]] = $row;
                            }
                            $smcFunc['db_free_result']($ignoreRequest);
                            $numSubjectResults = count($inserts);
                        } else {
                            $numSubjectResults += $smcFunc['db_affected_rows']();
                        }
                        if (!empty($modSettings['search_max_results']) && $numSubjectResults >= $modSettings['search_max_results']) {
                            break;
                        }
                    }
                    // Got some non-MySQL data to plonk in?
                    if (!empty($inserts)) {
                        $smcFunc['db_insert']('', '{db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_topics', $createTemporary ? array('id_topic' => 'int') : array('id_search' => 'int', 'id_topic' => 'int'), $inserts, $createTemporary ? array('id_topic') : array('id_search', 'id_topic'));
                    }
                    if ($numSubjectResults !== 0) {
                        $main_query['weights']['subject'] = 'CASE WHEN MAX(lst.id_topic) IS NULL THEN 0 ELSE 1 END';
                        $main_query['left_join'][] = '{db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_topics AS lst ON (' . ($createTemporary ? '' : 'lst.id_search = {int:id_search} AND ') . 'lst.id_topic = t.id_topic)';
                        if (!$createTemporary) {
                            $main_query['parameters']['id_search'] = $_SESSION['search_cache']['id_search'];
                        }
                    }
                }
                $indexedResults = 0;
                // We building an index?
                if ($searchAPI->supportsMethod('indexedWordQuery', $query_params)) {
                    $inserts = array();
                    $smcFunc['db_search_query']('drop_tmp_log_search_messages', '
						DROP TABLE IF EXISTS {db_prefix}tmp_log_search_messages', array('db_error_skip' => true));
                    $createTemporary = $smcFunc['db_search_query']('create_tmp_log_search_messages', '
						CREATE TEMPORARY TABLE {db_prefix}tmp_log_search_messages (
							id_msg int(10) unsigned NOT NULL default {string:string_zero},
							PRIMARY KEY (id_msg)
						) ENGINE=MEMORY', array('string_zero' => '0', 'db_error_skip' => true)) !== false;
                    // Clear, all clear!
                    if (!$createTemporary) {
                        $smcFunc['db_search_query']('delete_log_search_messages', '
							DELETE FROM {db_prefix}log_search_messages
							WHERE id_search = {int:id_search}', array('id_search' => $_SESSION['search_cache']['id_search']));
                    }
                    foreach ($searchWords as $orIndex => $words) {
                        // Search for this word, assuming we have some words!
                        if (!empty($words['indexed_words'])) {
                            // Variables required for the search.
                            $search_data = array('insert_into' => ($createTemporary ? 'tmp_' : '') . 'log_search_messages', 'no_regexp' => $no_regexp, 'max_results' => $maxMessageResults, 'indexed_results' => $indexedResults, 'params' => array('id_search' => !$createTemporary ? $_SESSION['search_cache']['id_search'] : 0, 'excluded_words' => $excludedWords, 'user_query' => !empty($userQuery) ? $userQuery : '', 'board_query' => !empty($boardQuery) ? $boardQuery : '', 'topic' => !empty($search_params['topic']) ? $search_params['topic'] : 0, 'min_msg_id' => !empty($minMsgID) ? $minMsgID : 0, 'max_msg_id' => !empty($maxMsgID) ? $maxMsgID : 0, 'excluded_phrases' => !empty($excludedPhrases) ? $excludedPhrases : array(), 'excluded_index_words' => !empty($excludedIndexWords) ? $excludedIndexWords : array(), 'excluded_subject_words' => !empty($excludedSubjectWords) ? $excludedSubjectWords : array()));
                            $ignoreRequest = $searchAPI->indexedWordQuery($words, $search_data);
                            if (!$smcFunc['db_support_ignore']) {
                                while ($row = $smcFunc['db_fetch_row']($ignoreRequest)) {
                                    // No duplicates!
                                    if (isset($inserts[$row[0]])) {
                                        continue;
                                    }
                                    $inserts[$row[0]] = $row;
                                }
                                $smcFunc['db_free_result']($ignoreRequest);
                                $indexedResults = count($inserts);
                            } else {
                                $indexedResults += $smcFunc['db_affected_rows']();
                            }
                            if (!empty($maxMessageResults) && $indexedResults >= $maxMessageResults) {
                                break;
                            }
                        }
                    }
                    // More non-MySQL stuff needed?
                    if (!empty($inserts)) {
                        $smcFunc['db_insert']('', '{db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_messages', $createTemporary ? array('id_msg' => 'int') : array('id_msg' => 'int', 'id_search' => 'int'), $inserts, $createTemporary ? array('id_msg') : array('id_msg', 'id_search'));
                    }
                    if (empty($indexedResults) && empty($numSubjectResults) && !empty($modSettings['search_force_index'])) {
                        $context['search_errors']['query_not_specific_enough'] = true;
                        $_REQUEST['params'] = $context['params'];
                        return PlushSearch1();
                    } elseif (!empty($indexedResults)) {
                        $main_query['inner_join'][] = '{db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_messages AS lsm ON (lsm.id_msg = m.id_msg)';
                        if (!$createTemporary) {
                            $main_query['where'][] = 'lsm.id_search = {int:id_search}';
                            $main_query['parameters']['id_search'] = $_SESSION['search_cache']['id_search'];
                        }
                    }
                } else {
                    $orWhere = array();
                    $count = 0;
                    foreach ($searchWords as $orIndex => $words) {
                        $where = array();
                        foreach ($words['all_words'] as $regularWord) {
                            $where[] = 'm.body' . (in_array($regularWord, $excludedWords) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:all_word_body_' . $count . '}';
                            if (in_array($regularWord, $excludedWords)) {
                                $where[] = 'm.subject NOT' . (empty($modSettings['search_match_words']) || $no_regexp ? ' LIKE ' : ' RLIKE ') . '{string:all_word_body_' . $count . '}';
                            }
                            $main_query['parameters']['all_word_body_' . $count++] = empty($modSettings['search_match_words']) || $no_regexp ? '%' . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . '%' : '[[:<:]]' . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . '[[:>:]]';
                        }
                        if (!empty($where)) {
                            $orWhere[] = count($where) > 1 ? '(' . implode(' AND ', $where) . ')' : $where[0];
                        }
                    }
                    if (!empty($orWhere)) {
                        $main_query['where'][] = count($orWhere) > 1 ? '(' . implode(' OR ', $orWhere) . ')' : $orWhere[0];
                    }
                    if (!empty($userQuery)) {
                        $main_query['where'][] = '{raw:user_query}';
                        $main_query['parameters']['user_query'] = $userQuery;
                    }
                    if (!empty($search_params['topic'])) {
                        $main_query['where'][] = 'm.id_topic = {int:topic}';
                        $main_query['parameters']['topic'] = $search_params['topic'];
                    }
                    if (!empty($minMsgID)) {
                        $main_query['where'][] = 'm.id_msg >= {int:min_msg_id}';
                        $main_query['parameters']['min_msg_id'] = $minMsgID;
                    }
                    if (!empty($maxMsgID)) {
                        $main_query['where'][] = 'm.id_msg <= {int:max_msg_id}';
                        $main_query['parameters']['max_msg_id'] = $maxMsgID;
                    }
                    if (!empty($boardQuery)) {
                        $main_query['where'][] = 'm.id_board {raw:board_query}';
                        $main_query['parameters']['board_query'] = $boardQuery;
                    }
                }
                // Did we either get some indexed results, or otherwise did not do an indexed query?
                if (!empty($indexedResults) || !$searchAPI->supportsMethod('indexedWordQuery', $query_params)) {
                    $relevance = '1000 * (';
                    $new_weight_total = 0;
                    foreach ($main_query['weights'] as $type => $value) {
                        $relevance .= $weight[$type] . ' * ' . $value . ' + ';
                        $new_weight_total += $weight[$type];
                    }
                    $main_query['select']['relevance'] = substr($relevance, 0, -3) . ') / ' . $new_weight_total . ' AS relevance';
                    $ignoreRequest = $smcFunc['db_search_query']('insert_log_search_results_no_index', ($smcFunc['db_support_ignore'] ? '
						INSERT IGNORE INTO ' . '{db_prefix}log_search_results
							(' . implode(', ', array_keys($main_query['select'])) . ')' : '') . '
						SELECT
							' . implode(',
							', $main_query['select']) . '
						FROM ' . $main_query['from'] . (empty($main_query['inner_join']) ? '' : '
							INNER JOIN ' . implode('
							INNER JOIN ', $main_query['inner_join'])) . (empty($main_query['left_join']) ? '' : '
							LEFT JOIN ' . implode('
							LEFT JOIN ', $main_query['left_join'])) . (!empty($main_query['where']) ? '
						WHERE ' : '') . implode('
							AND ', $main_query['where']) . (empty($main_query['group_by']) ? '' : '
						GROUP BY ' . implode(', ', $main_query['group_by'])) . (empty($modSettings['search_max_results']) ? '' : '
						LIMIT ' . $modSettings['search_max_results']), $main_query['parameters']);
                    // We love to handle non-good databases that don't support our ignore!
                    if (!$smcFunc['db_support_ignore']) {
                        $inserts = array();
                        while ($row = $smcFunc['db_fetch_row']($ignoreRequest)) {
                            // No duplicates!
                            if (isset($inserts[$row[2]])) {
                                continue;
                            }
                            foreach ($row as $key => $value) {
                                $inserts[$row[2]][] = (int) $row[$key];
                            }
                        }
                        $smcFunc['db_free_result']($ignoreRequest);
                        // Now put them in!
                        if (!empty($inserts)) {
                            $query_columns = array();
                            foreach ($main_query['select'] as $k => $v) {
                                $query_columns[$k] = 'int';
                            }
                            $smcFunc['db_insert']('', '{db_prefix}log_search_results', $query_columns, $inserts, array('id_search', 'id_topic'));
                        }
                        $_SESSION['search_cache']['num_results'] += count($inserts);
                    } else {
                        $_SESSION['search_cache']['num_results'] = $smcFunc['db_affected_rows']();
                    }
                }
                // Insert subject-only matches.
                if ($_SESSION['search_cache']['num_results'] < $modSettings['search_max_results'] && $numSubjectResults !== 0) {
                    $usedIDs = array_flip(empty($inserts) ? array() : array_keys($inserts));
                    $ignoreRequest = $smcFunc['db_search_query']('insert_log_search_results_sub_only', ($smcFunc['db_support_ignore'] ? '
						INSERT IGNORE INTO {db_prefix}log_search_results
							(id_search, id_topic, relevance, id_msg, num_matches)' : '') . '
						SELECT
							{int:id_search},
							t.id_topic,
							1000 * (
								{int:weight_frequency} / (t.num_replies + 1) +
								{int:weight_age} * CASE WHEN t.id_first_msg < {int:min_msg} THEN 0 ELSE (t.id_first_msg - {int:min_msg}) / {int:recent_message} END +
								{int:weight_length} * CASE WHEN t.num_replies < {int:huge_topic_posts} THEN t.num_replies / {int:huge_topic_posts} ELSE 1 END +
								{int:weight_subject} +
								{int:weight_sticky} * t.is_sticky
							) / {int:weight_total} AS relevance,
							t.id_first_msg,
							1
						FROM {db_prefix}topics AS t
							INNER JOIN {db_prefix}' . ($createTemporary ? 'tmp_' : '') . 'log_search_topics AS lst ON (lst.id_topic = t.id_topic)' . ($createTemporary ? '' : 'WHERE lst.id_search = {int:id_search}') . (empty($modSettings['search_max_results']) ? '' : '
						LIMIT ' . ($modSettings['search_max_results'] - $_SESSION['search_cache']['num_results'])), array('id_search' => $_SESSION['search_cache']['id_search'], 'weight_age' => $weight['age'], 'weight_frequency' => $weight['frequency'], 'weight_length' => $weight['frequency'], 'weight_sticky' => $weight['frequency'], 'weight_subject' => $weight['frequency'], 'weight_total' => $weight_total, 'min_msg' => $minMsg, 'recent_message' => $recentMsg, 'huge_topic_posts' => $humungousTopicPosts));
                    // Once again need to do the inserts if the database don't support ignore!
                    if (!$smcFunc['db_support_ignore']) {
                        $inserts = array();
                        while ($row = $smcFunc['db_fetch_row']($ignoreRequest)) {
                            // No duplicates!
                            if (isset($usedIDs[$row[1]])) {
                                continue;
                            }
                            $usedIDs[$row[1]] = true;
                            $inserts[] = $row;
                        }
                        $smcFunc['db_free_result']($ignoreRequest);
                        // Now put them in!
                        if (!empty($inserts)) {
                            $smcFunc['db_insert']('', '{db_prefix}log_search_results', array('id_search' => 'int', 'id_topic' => 'int', 'relevance' => 'float', 'id_msg' => 'int', 'num_matches' => 'int'), $inserts, array('id_search', 'id_topic'));
                        }
                        $_SESSION['search_cache']['num_results'] += count($inserts);
                    } else {
                        $_SESSION['search_cache']['num_results'] += $smcFunc['db_affected_rows']();
                    }
                } else {
                    $_SESSION['search_cache']['num_results'] = 0;
                }
            }
        }
        // *** Retrieve the results to be shown on the page
        $participants = array();
        $request = $smcFunc['db_search_query']('', '
			SELECT ' . (empty($search_params['topic']) ? 'lsr.id_topic' : $search_params['topic'] . ' AS id_topic') . ', lsr.id_msg, lsr.relevance, lsr.num_matches
			FROM {db_prefix}log_search_results AS lsr' . ($search_params['sort'] == 'num_replies' ? '
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = lsr.id_topic)' : '') . '
			WHERE lsr.id_search = {int:id_search}
			ORDER BY ' . $search_params['sort'] . ' ' . $search_params['sort_dir'] . '
			LIMIT ' . (int) $_REQUEST['start'] . ', ' . $modSettings['search_results_per_page'], array('id_search' => $_SESSION['search_cache']['id_search']));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $context['topics'][$row['id_msg']] = array('relevance' => round($row['relevance'] / 10, 1) . '%', 'num_matches' => $row['num_matches'], 'matches' => array());
            // By default they didn't participate in the topic!
            $participants[$row['id_topic']] = false;
        }
        $smcFunc['db_free_result']($request);
        $num_results = $_SESSION['search_cache']['num_results'];
    }
    if (!empty($context['topics'])) {
        // Create an array for the permissions.
        $boards_can = array('post_reply_own' => boardsAllowedTo('post_reply_own'), 'post_reply_any' => boardsAllowedTo('post_reply_any'), 'mark_any_notify' => boardsAllowedTo('mark_any_notify'));
        // How's about some quick moderation?
        if (!empty($options['display_quick_mod'])) {
            $boards_can['lock_any'] = boardsAllowedTo('lock_any');
            $boards_can['lock_own'] = boardsAllowedTo('lock_own');
            $boards_can['make_sticky'] = boardsAllowedTo('make_sticky');
            $boards_can['move_any'] = boardsAllowedTo('move_any');
            $boards_can['move_own'] = boardsAllowedTo('move_own');
            $boards_can['remove_any'] = boardsAllowedTo('remove_any');
            $boards_can['remove_own'] = boardsAllowedTo('remove_own');
            $boards_can['merge_any'] = boardsAllowedTo('merge_any');
            $context['can_lock'] = in_array(0, $boards_can['lock_any']);
            $context['can_sticky'] = in_array(0, $boards_can['make_sticky']) && !empty($modSettings['enableStickyTopics']);
            $context['can_move'] = in_array(0, $boards_can['move_any']);
            $context['can_remove'] = in_array(0, $boards_can['remove_any']);
            $context['can_merge'] = in_array(0, $boards_can['merge_any']);
        }
        // What messages are we using?
        $msg_list = array_keys($context['topics']);
        // Load the posters...
        $request = $smcFunc['db_query']('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_member != {int:no_member}
				AND id_msg IN ({array_int:message_list})
			LIMIT ' . count($context['topics']), array('message_list' => $msg_list, 'no_member' => 0));
        $posters = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $posters[] = $row['id_member'];
        }
        $smcFunc['db_free_result']($request);
        if (!empty($posters)) {
            loadMemberData(array_unique($posters));
        }
        // Get the messages out for the callback - select enough that it can be made to look just like Display.
        $messages_request = $smcFunc['db_query']('', '
			SELECT
				m.id_msg, m.subject, m.poster_name, m.poster_email, m.poster_time, m.id_member,
				m.icon, m.poster_ip, m.body, m.smileys_enabled, m.modified_time, m.modified_name,
				first_m.id_msg AS first_msg, first_m.subject AS first_subject, first_m.icon AS first_icon, first_m.poster_time AS first_poster_time,
				first_mem.id_member AS first_member_id, IFNULL(first_mem.real_name, first_m.poster_name) AS first_member_name,
				last_m.id_msg AS last_msg, last_m.poster_time AS last_poster_time, last_mem.id_member AS last_member_id,
				IFNULL(last_mem.real_name, last_m.poster_name) AS last_member_name, last_m.icon AS last_icon, last_m.subject AS last_subject,
				t.id_topic, t.is_sticky, t.locked, t.id_poll, t.num_replies, t.num_views,
				b.id_board, b.name AS board_name, c.id_cat, c.name AS cat_name
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
				INNER JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
				INNER JOIN {db_prefix}messages AS first_m ON (first_m.id_msg = t.id_first_msg)
				INNER JOIN {db_prefix}messages AS last_m ON (last_m.id_msg = t.id_last_msg)
				LEFT JOIN {db_prefix}members AS first_mem ON (first_mem.id_member = first_m.id_member)
				LEFT JOIN {db_prefix}members AS last_mem ON (last_mem.id_member = first_m.id_member)
			WHERE m.id_msg IN ({array_int:message_list})' . ($modSettings['postmod_active'] ? '
				AND m.approved = {int:is_approved}' : '') . '
			ORDER BY FIND_IN_SET(m.id_msg, {string:message_list_in_set})
			LIMIT {int:limit}', array('message_list' => $msg_list, 'is_approved' => 1, 'message_list_in_set' => implode(',', $msg_list), 'limit' => count($context['topics'])));
        // If there are no results that means the things in the cache got deleted, so pretend we have no topics anymore.
        if ($smcFunc['db_num_rows']($messages_request) == 0) {
            $context['topics'] = array();
        }
        // If we want to know who participated in what then load this now.
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest']) {
            $result = $smcFunc['db_query']('', '
				SELECT id_topic
				FROM {db_prefix}messages
				WHERE id_topic IN ({array_int:topic_list})
					AND id_member = {int:current_member}
				GROUP BY id_topic
				LIMIT ' . count($participants), array('current_member' => $user_info['id'], 'topic_list' => array_keys($participants)));
            while ($row = $smcFunc['db_fetch_assoc']($result)) {
                $participants[$row['id_topic']] = true;
            }
            $smcFunc['db_free_result']($result);
        }
    }
    // Now that we know how many results to expect we can start calculating the page numbers.
    $context['page_index'] = constructPageIndex($scripturl . '?action=search2;params=' . $context['params'], $_REQUEST['start'], $num_results, $modSettings['search_results_per_page'], false);
    // Consider the search complete!
    if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
        cache_put_data('search_start:' . ($user_info['is_guest'] ? $user_info['ip'] : $user_info['id']), null, 90);
    }
    $context['key_words'] =& $searchArray;
    // Setup the default topic icons... for checking they exist and the like!
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless', 'clip');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $context['sub_template'] = 'results';
    $context['page_title'] = $txt['search_results'];
    $context['get_topics'] = 'prepareSearchContext';
    $context['can_send_pm'] = allowedTo('pm_send');
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => addslashes(un_htmlspecialchars($txt['select_destination'])));
}
コード例 #15
0
function sp_showPoll($parameters, $id, $return_parameters = false)
{
    global $smcFunc, $context, $scripturl, $modSettings, $boardurl, $txt;
    $block_parameters = array('topic' => 'int', 'type' => 'select');
    if ($return_parameters) {
        return $block_parameters;
    }
    $topic = !empty($parameters['topic']) ? $parameters['topic'] : null;
    $type = !empty($parameters['type']) ? (int) $parameters['type'] : 0;
    $boardsAllowed = boardsAllowedTo('poll_view');
    if (empty($boardsAllowed)) {
        loadLanguage('Errors');
        echo '
								', $txt['cannot_poll_view'];
        return;
    }
    if (!empty($type)) {
        $request = $smcFunc['db_query']('', '
			SELECT t.id_topic
			FROM {db_prefix}polls AS p
				INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ')
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			WHERE {query_wanna_see_board}
				AND p.voting_locked = {int:not_locked}' . (!in_array(0, $boardsAllowed) ? '
				AND b.id_board IN ({array_int:boards_allowed_list})' : '') . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
				AND b.id_board != {int:recycle_enable}' : '') . '
			ORDER BY {raw:type}
			LIMIT 1', array('boards_allowed_list' => $boardsAllowed, 'not_locked' => 0, 'is_approved' => 1, 'recycle_enable' => $modSettings['recycle_board'], 'type' => $type == 1 ? 'p.id_poll DESC' : 'RAND()'));
        list($topic) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
    }
    if (empty($topic) || $topic < 0) {
        loadLanguage('Errors');
        echo '
								', $txt['topic_doesnt_exist'];
        return;
    }
    $poll = ssi_showPoll($topic, 'array');
    if ($poll['allow_vote']) {
        echo '
								<form action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '">
									<ul class="sp_list">
										<li><strong>', $poll['question'], '</strong></li>
										<li>', $poll['allowed_warning'], '</li>';
        foreach ($poll['options'] as $option) {
            echo '
										<li><label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label></li>';
        }
        echo '
										<li class="sp_center"><input type="submit" value="', $txt['poll_vote'], '" class="button_submit" /></li>
										<li class="sp_center"><a href="', $scripturl, '?topic=', $poll['topic'], '.0">', $txt['sp-pollViewTopic'], '</a></li>
									</ul>
									<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
									<input type="hidden" name="poll" value="', $poll['id'], '" />
								</form>';
    } elseif ($poll['allow_view_results']) {
        echo '
								<ul class="sp_list">
									<li><strong>', $poll['question'], '</strong></li>';
        foreach ($poll['options'] as $option) {
            echo '
									<li>', sp_embed_image('dot'), ' ', $option['option'], '</li>
									<li class="sp_list_indent"><strong>', $option['votes'], '</strong> (', $option['percent'], '%)</li>';
        }
        echo '
									<li><strong>', $txt['poll_total_voters'], ': ', $poll['total_votes'], '</strong></li>
									<li class="sp_center"><a href="', $scripturl, '?topic=', $poll['topic'], '.0">', $txt['sp-pollViewTopic'], '</a></li>
								</ul>';
    } else {
        echo '
								', $txt['poll_cannot_see'];
    }
}
コード例 #16
0
ファイル: Profile-View.php プロジェクト: chenhao6593/smf
function showAttachments($memID)
{
    global $txt, $user_info, $scripturl, $modSettings, $board;
    global $context, $user_profile, $sourcedir, $smcFunc;
    // OBEY permissions!
    $boardsAllowed = boardsAllowedTo('view_attachments');
    // Make sure we can't actually see anything...
    if (empty($boardsAllowed)) {
        $boardsAllowed = array(-1);
    }
    // Get the total number of attachments they have posted.
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}attachments AS a
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
		WHERE a.attachment_type = {int:attachment_type}
			AND a.id_msg != {int:no_message}
			AND m.id_member = {int:current_member}' . (!empty($board) ? '
			AND b.id_board = {int:board}' : '') . (!in_array(0, $boardsAllowed) ? '
			AND b.id_board IN ({array_int:boards_list})' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
			AND m.approved = {int:is_approved}'), array('boards_list' => $boardsAllowed, 'attachment_type' => 0, 'no_message' => 0, 'current_member' => $memID, 'is_approved' => 1, 'board' => $board));
    list($attachCount) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $maxIndex = (int) $modSettings['defaultMaxMessages'];
    // What about ordering?
    $sortTypes = array('filename' => 'a.filename', 'downloads' => 'a.downloads', 'subject' => 'm.subject', 'posted' => 'm.poster_time');
    $context['sort_order'] = isset($_GET['sort']) && isset($sortTypes[$_GET['sort']]) ? $_GET['sort'] : 'posted';
    $context['sort_direction'] = isset($_GET['asc']) ? 'up' : 'down';
    $sort = $sortTypes[$context['sort_order']];
    // Let's get ourselves a lovely page index.
    $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';area=showposts;sa=attach;sort=' . $context['sort_order'] . ($context['sort_direction'] == 'up' ? ';asc' : ''), $context['start'], $attachCount, $maxIndex);
    // Retrieve some attachments.
    $request = $smcFunc['db_query']('', '
		SELECT a.id_attach, a.id_msg, a.filename, a.downloads, a.approved, m.id_msg, m.id_topic,
			m.id_board, m.poster_time, m.subject, b.name
		FROM {db_prefix}attachments AS a
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
		WHERE a.attachment_type = {int:attachment_type}
			AND a.id_msg != {int:no_message}
			AND m.id_member = {int:current_member}' . (!empty($board) ? '
			AND b.id_board = {int:board}' : '') . (!in_array(0, $boardsAllowed) ? '
			AND b.id_board IN ({array_int:boards_list})' : '') . (!$modSettings['postmod_active'] || $context['user']['is_owner'] ? '' : '
			AND m.approved = {int:is_approved}') . '
		ORDER BY {raw:sort}
		LIMIT {int:offset}, {int:limit}', array('boards_list' => $boardsAllowed, 'attachment_type' => 0, 'no_message' => 0, 'current_member' => $memID, 'is_approved' => 1, 'board' => $board, 'sort' => $sort . ' ' . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC'), 'offset' => $context['start'], 'limit' => $maxIndex));
    $context['attachments'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $row['subject'] = censorText($row['subject']);
        $context['attachments'][] = array('id' => $row['id_attach'], 'filename' => $row['filename'], 'downloads' => $row['downloads'], 'subject' => $row['subject'], 'posted' => timeformat($row['poster_time']), 'msg' => $row['id_msg'], 'topic' => $row['id_topic'], 'board' => $row['id_board'], 'board_name' => $row['name'], 'approved' => $row['approved']);
    }
    $smcFunc['db_free_result']($request);
}
コード例 #17
0
ファイル: Post.php プロジェクト: alencarmo/OCF
function QuoteFast()
{
    global $db_prefix, $modSettings, $user_info, $txt, $settings, $context;
    global $sourcedir, $func;
    loadLanguage('Post');
    if (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
    checkSession('get');
    include_once $sourcedir . '/Subs-Post.php';
    $moderate_boards = boardsAllowedTo('moderate_board');
    $request = db_query("\n\t\tSELECT IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime, m.body, m.ID_TOPIC, m.subject, t.locked\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b, {$db_prefix}topics AS t)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)\n\t\tWHERE m.ID_MSG = " . (int) $_REQUEST['quote'] . "\n\t\t\tAND b.ID_BOARD = m.ID_BOARD\n\t\t\tAND t.ID_TOPIC = m.ID_TOPIC\n\t\t\tAND {$user_info['query_see_board']}" . (!isset($_REQUEST['modify']) || !empty($moderate_boards) && $moderate_boards[0] == 0 ? '' : '
 			AND (t.locked = 0' . (empty($moderate_boards) ? '' : ' OR b.ID_BOARD IN (' . implode(', ', $moderate_boards) . ')') . ')') . "\n\t\tLIMIT 1", __FILE__, __LINE__);
    $context['close_window'] = mysql_num_rows($request) == 0;
    $context['sub_template'] = 'quotefast';
    if (mysql_num_rows($request) != 0) {
        $row = mysql_fetch_assoc($request);
        mysql_free_result($request);
        // Remove special formatting we don't want anymore.
        $row['body'] = un_preparsecode($row['body']);
        // Censor the message!
        censorText($row['body']);
        $row['body'] = preg_replace('~<br(?: /)?' . '>~i', "\n", $row['body']);
        // Want to modify a single message by double clicking it?
        if (isset($_REQUEST['modify'])) {
            censorText($row['subject']);
            $context['sub_template'] = 'modifyfast';
            $context['message'] = array('id' => $_REQUEST['quote'], 'body' => $row['body'], 'subject' => addcslashes($row['subject'], '"'));
            return;
        }
        // Remove any nested quotes.
        if (!empty($modSettings['removeNestedQuotes'])) {
            $row['body'] = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $row['body']);
        }
        // Add a quote string on the front and end.
        $context['quote']['xml'] = '[quote author=' . $row['posterName'] . ' link=topic=' . $row['ID_TOPIC'] . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $row['posterTime'] . ']' . "\n" . $row['body'] . "\n" . '[/quote]';
        $context['quote']['text'] = strtr(un_htmlspecialchars($context['quote']['xml']), array('\'' => '\\\'', '\\' => '\\\\', "\n" => '\\n', '</script>' => '</\' + \'script>'));
        $context['quote']['xml'] = strtr($context['quote']['xml'], array('&nbsp;' => '&#160;', '<' => '&lt;', '>' => '&gt;'));
        $context['quote']['mozilla'] = strtr($func['htmlspecialchars']($context['quote']['text']), array('&quot;' => '"'));
    } elseif (isset($_REQUEST['modify'])) {
        $context['sub_template'] = 'modifyfast';
        $context['message'] = array('id' => 0, 'body' => '', 'subject' => '');
    } else {
        $context['quote'] = array('xml' => '', 'mozilla' => '', 'text' => '');
    }
}
コード例 #18
0
ファイル: Profile.php プロジェクト: alencarmo/OCF
function showPosts($memID)
{
    global $txt, $user_info, $scripturl, $modSettings, $db_prefix;
    global $context, $user_profile, $ID_MEMBER, $sourcedir;
    // If just deleting a message, do it and then redirect back.
    if (isset($_GET['delete'])) {
        checkSession('get');
        // We can be lazy, since removeMessage() will check the permissions for us.
        require_once $sourcedir . '/RemoveTopic.php';
        removeMessage((int) $_GET['delete']);
        // Back to... where we are now ;).
        redirectexit('action=profile;u=' . $memID . ';sa=showPosts;start=' . $_GET['start']);
    }
    // Is the load average too high to allow searching just now?
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_show_posts']) && $context['load_average'] >= $modSettings['loadavg_show_posts']) {
        fatal_lang_error('loadavg_show_posts_disabled', false);
    }
    // Default to 10.
    if (empty($_REQUEST['viewscount']) || !is_numeric($_REQUEST['viewscount'])) {
        $_REQUEST['viewscount'] = '10';
    }
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b)\n\t\tWHERE m.ID_MEMBER = {$memID}\n\t\t\tAND b.ID_BOARD = m.ID_BOARD\n\t\t\tAND {$user_info['query_see_board']}", __FILE__, __LINE__);
    list($msgCount) = mysql_fetch_row($request);
    mysql_free_result($request);
    $request = db_query("\n\t\tSELECT MIN(ID_MSG), MAX(ID_MSG)\n\t\tFROM {$db_prefix}messages AS m\n\t\tWHERE m.ID_MEMBER = {$memID}", __FILE__, __LINE__);
    list($min_msg_member, $max_msg_member) = mysql_fetch_row($request);
    mysql_free_result($request);
    $reverse = false;
    $range_limit = '';
    $maxIndex = (int) $modSettings['defaultMaxMessages'];
    // Make sure the starting place makes sense and construct our friend the page index.
    $context['start'] = (int) $_REQUEST['start'];
    $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';sa=showPosts', $context['start'], $msgCount, $maxIndex);
    $context['current_page'] = $context['start'] / $maxIndex;
    $context['current_member'] = $memID;
    // Reverse the query if we're past 50% of the pages for better performance.
    $start = $context['start'];
    $reverse = $_REQUEST['start'] > $msgCount / 2;
    if ($reverse) {
        $maxIndex = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 && $msgCount > $context['start'] ? $msgCount - $context['start'] : (int) $modSettings['defaultMaxMessages'];
        $start = $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] + 1 || $msgCount < $context['start'] + $modSettings['defaultMaxMessages'] ? 0 : $msgCount - $context['start'] - $modSettings['defaultMaxMessages'];
    }
    // Guess the range of messages to be shown.
    if ($msgCount > 1000) {
        $margin = floor(($max_msg_member - $min_msg_member) * (($start + $modSettings['defaultMaxMessages']) / $msgCount) + 0.1 * ($max_msg_member - $min_msg_member));
        $range_limit = $reverse ? 'ID_MSG < ' . ($min_msg_member + $margin) : 'ID_MSG > ' . ($max_msg_member - $margin);
    }
    $context['page_title'] = $txt[458] . ' ' . $user_profile[$memID]['realName'];
    // Find this user's posts.  The left join on categories somehow makes this faster, weird as it looks.
    $looped = false;
    while (true) {
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tb.ID_BOARD, b.name AS bname, c.ID_CAT, c.name AS cname, m.ID_TOPIC, m.ID_MSG,\n\t\t\t\tt.ID_MEMBER_STARTED, t.ID_FIRST_MSG, t.ID_LAST_MSG, m.body, m.smileysEnabled,\n\t\t\t\tm.subject, m.posterTime\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\tWHERE m.ID_MEMBER = {$memID}\n\t\t\t\tAND m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\tAND t.ID_BOARD = b.ID_BOARD" . (empty($range_limit) ? '' : "\n\t\t\t\tAND {$range_limit}") . "\n\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\tORDER BY m.ID_MSG " . ($reverse ? 'ASC' : 'DESC') . "\n\t\t\tLIMIT {$start}, {$maxIndex}", __FILE__, __LINE__);
        // Make sure we quit this loop.
        if (mysql_num_rows($request) === $maxIndex || $looped) {
            break;
        }
        $looped = true;
        $range_limit = '';
    }
    // Start counting at the number of the first message displayed.
    $counter = $reverse ? $context['start'] + $maxIndex + 1 : $context['start'];
    $context['posts'] = array();
    $board_ids = array('own' => array(), 'any' => array());
    while ($row = mysql_fetch_assoc($request)) {
        // Censor....
        censorText($row['body']);
        censorText($row['subject']);
        // Do the code.
        $row['body'] = parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']);
        // And the array...
        $context['posts'][$counter += $reverse ? -1 : 1] = array('body' => $row['body'], 'counter' => $counter, 'category' => array('name' => $row['cname'], 'id' => $row['ID_CAT']), 'board' => array('name' => $row['bname'], 'id' => $row['ID_BOARD']), 'topic' => $row['ID_TOPIC'], 'subject' => $row['subject'], 'start' => 'msg' . $row['ID_MSG'], 'time' => timeformat($row['posterTime']), 'timestamp' => forum_time(true, $row['posterTime']), 'id' => $row['ID_MSG'], 'can_reply' => false, 'can_mark_notify' => false, 'can_delete' => false, 'delete_possible' => ($row['ID_FIRST_MSG'] != $row['ID_MSG'] || $row['ID_LAST_MSG'] == $row['ID_MSG']) && (empty($modSettings['edit_disable_time']) || $row['posterTime'] + $modSettings['edit_disable_time'] * 60 >= time()));
        if ($ID_MEMBER == $row['ID_MEMBER_STARTED']) {
            $board_ids['own'][$row['ID_BOARD']][] = $counter;
        }
        $board_ids['any'][$row['ID_BOARD']][] = $counter;
    }
    mysql_free_result($request);
    // All posts were retrieved in reverse order, get them right again.
    if ($reverse) {
        $context['posts'] = array_reverse($context['posts'], true);
    }
    // These are all the permissions that are different from board to board..
    $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify', 'delete_any' => 'can_delete'));
    // For every permission in the own/any lists...
    foreach ($permissions as $type => $list) {
        foreach ($list as $permission => $allowed) {
            // Get the boards they can do this on...
            $boards = boardsAllowedTo($permission);
            // Hmm, they can do it on all boards, can they?
            if (!empty($boards) && $boards[0] == 0) {
                $boards = array_keys($board_ids[$type]);
            }
            // Now go through each board they can do the permission on.
            foreach ($boards as $board_id) {
                // There aren't any posts displayed from this board.
                if (!isset($board_ids[$type][$board_id])) {
                    continue;
                }
                // Set the permission to true ;).
                foreach ($board_ids[$type][$board_id] as $counter) {
                    $context['posts'][$counter][$allowed] = true;
                }
            }
        }
    }
    // Clean up after posts that cannot be deleted.
    foreach ($context['posts'] as $counter => $dummy) {
        $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
    }
}
コード例 #19
0
ファイル: Post.php プロジェクト: valek0972/hackits
function QuoteFast()
{
    global $modSettings, $user_info, $txt, $settings, $context;
    global $sourcedir, $smcFunc;
    loadLanguage('Post');
    if (!isset($_REQUEST['xml'])) {
        loadTemplate('Post');
    }
    include_once $sourcedir . '/Subs-Post.php';
    $moderate_boards = boardsAllowedTo('moderate_board');
    // Where we going if we need to?
    $context['post_box_name'] = isset($_GET['pb']) ? $_GET['pb'] : '';
    $request = $smcFunc['db_query']('', '
		SELECT IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body, m.id_topic, m.subject,
			m.id_board, m.id_member, m.approved
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board})
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
		WHERE m.id_msg = {int:id_msg}' . (isset($_REQUEST['modify']) || !empty($moderate_boards) && $moderate_boards[0] == 0 ? '' : '
			AND (t.locked = {int:not_locked}' . (empty($moderate_boards) ? '' : ' OR b.id_board IN ({array_int:moderation_board_list})') . ')') . '
		LIMIT 1', array('current_member' => $user_info['id'], 'moderation_board_list' => $moderate_boards, 'id_msg' => (int) $_REQUEST['quote'], 'not_locked' => 0));
    $context['close_window'] = $smcFunc['db_num_rows']($request) == 0;
    $row = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    $context['sub_template'] = 'quotefast';
    if (!empty($row)) {
        $can_view_post = $row['approved'] || $row['id_member'] != 0 && $row['id_member'] == $user_info['id'] || allowedTo('approve_posts', $row['id_board']);
    }
    if (!empty($can_view_post)) {
        // Remove special formatting we don't want anymore.
        $row['body'] = un_preparsecode($row['body']);
        // Censor the message!
        censorText($row['body']);
        $row['body'] = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']);
        // Want to modify a single message by double clicking it?
        if (isset($_REQUEST['modify'])) {
            censorText($row['subject']);
            $context['sub_template'] = 'modifyfast';
            $context['message'] = array('id' => $_REQUEST['quote'], 'body' => $row['body'], 'subject' => addcslashes($row['subject'], '"'));
            return;
        }
        // Remove any nested quotes.
        if (!empty($modSettings['removeNestedQuotes'])) {
            $row['body'] = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $row['body']);
        }
        // Make the body HTML if need be.
        if (!empty($_REQUEST['mode'])) {
            require_once $sourcedir . '/Subs-Editor.php';
            $row['body'] = strtr($row['body'], array('&lt;' => '#smlt#', '&gt;' => '#smgt#', '&amp;' => '#smamp#'));
            $row['body'] = bbc_to_html($row['body']);
            $lb = '<br />';
        } else {
            $lb = "\n";
        }
        // Add a quote string on the front and end.
        $context['quote']['xml'] = '[quote author=' . $row['poster_name'] . ' link=topic=' . $row['id_topic'] . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $row['poster_time'] . ']' . $lb . $row['body'] . $lb . '[/quote]';
        $context['quote']['text'] = strtr(un_htmlspecialchars($context['quote']['xml']), array('\'' => '\\\'', '\\' => '\\\\', "\n" => '\\n', '</script>' => '</\' + \'script>'));
        $context['quote']['xml'] = strtr($context['quote']['xml'], array('&nbsp;' => '&#160;', '<' => '&lt;', '>' => '&gt;'));
        $context['quote']['mozilla'] = strtr($smcFunc['htmlspecialchars']($context['quote']['text']), array('&quot;' => '"'));
    } elseif (isset($_REQUEST['modify'])) {
        $context['sub_template'] = 'modifyfast';
        $context['message'] = array('id' => 0, 'body' => '', 'subject' => '');
    } else {
        $context['quote'] = array('xml' => '', 'mozilla' => '', 'text' => '');
    }
}
コード例 #20
0
function ApproveAttach()
{
    global $smcFunc;
    // Security is our primary concern...
    checkSession('get');
    // If it approve or delete?
    $is_approve = !isset($_GET['sa']) || $_GET['sa'] != 'reject' ? true : false;
    $attachments = array();
    // If we are approving all ID's in a message , get the ID's.
    if ($_GET['sa'] == 'all' && !empty($_GET['mid'])) {
        $id_msg = (int) $_GET['mid'];
        $request = $smcFunc['db_query']('', '
			SELECT id_attach
			FROM {db_prefix}attachments
			WHERE id_msg = {int:id_msg}
				AND approved = {int:is_approved}
				AND attachment_type = {int:attachment_type}', array('id_msg' => $id_msg, 'is_approved' => 0, 'attachment_type' => 0));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $attachments[] = $row['id_attach'];
        }
        $smcFunc['db_free_result']($request);
    } elseif (!empty($_GET['aid'])) {
        $attachments[] = (int) $_GET['aid'];
    }
    if (empty($attachments)) {
        fatal_lang_error('no_access', false);
    }
    // Now we have some ID's cleaned and ready to approve, but first - let's check we have permission!
    $allowed_boards = boardsAllowedTo('approve_posts');
    // Validate the attachments exist and are the right approval state.
    $request = $smcFunc['db_query']('', '
		SELECT a.id_attach, m.id_board, m.id_msg, m.id_topic
		FROM {db_prefix}attachments AS a
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg)
		WHERE a.id_attach IN ({array_int:attachments})
			AND a.attachment_type = {int:attachment_type}
			AND a.approved = {int:is_approved}', array('attachments' => $attachments, 'attachment_type' => 0, 'is_approved' => 0));
    $attachments = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // We can only add it if we can approve in this board!
        if ($allowed_boards = array(0) || in_array($row['id_board'], $allowed_boards)) {
            $attachments[] = $row['id_attach'];
            // Also come up witht he redirection URL.
            $redirect = 'topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'];
        }
    }
    $smcFunc['db_free_result']($request);
    if (empty($attachments)) {
        fatal_lang_error('no_access', false);
    }
    // Finally, we are there. Follow through!
    if ($is_approve) {
        ApproveAttachments($attachments);
    } else {
        removeAttachments(array('id_attach' => $attachments));
    }
    // Return to the topic....
    redirectexit($redirect);
}
コード例 #21
0
ファイル: SplitTopics.php プロジェクト: VBGAMER45/SMFMods
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);
}
コード例 #22
0
ファイル: Search.php プロジェクト: VBGAMER45/SMFMods
function PlushSearch2()
{
    global $scripturl, $modSettings, $sourcedir, $txt, $db_prefix, $db_connection;
    global $user_info, $ID_MEMBER, $context, $options, $messages_request, $boards_can;
    global $excludedWords, $participants, $func;
    // !!! Add spam protection.
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) {
        fatal_lang_error('loadavg_search_disabled', false);
    }
    // No, no, no... this is a bit hard on the server, so don't you go prefetching it!
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Forbidden');
        die;
    }
    $weight_factors = array('frequency', 'age', 'length', 'subject', 'first_message', 'sticky');
    $weight = array();
    $weight_total = 0;
    foreach ($weight_factors as $weight_factor) {
        $weight[$weight_factor] = empty($modSettings['search_weight_' . $weight_factor]) ? 0 : (int) $modSettings['search_weight_' . $weight_factor];
        $weight_total += $weight[$weight_factor];
    }
    // Zero weight.  Weightless :P.
    if (empty($weight_total)) {
        fatal_lang_error('search_invalid_weights');
    }
    // These vars don't require an interface, the're just here for tweaking.
    $recentPercentage = 0.3;
    $humungousTopicPosts = 200;
    $maxMembersToSearch = 500;
    $maxMessageResults = empty($modSettings['search_max_results']) ? 0 : $modSettings['search_max_results'] * 5;
    // Start with no errors.
    $context['search_errors'] = array();
    // Number of pages hard maximum - normally not set at all.
    $modSettings['search_max_results'] = empty($modSettings['search_max_results']) ? 200 * $modSettings['search_results_per_page'] : (int) $modSettings['search_max_results'];
    loadLanguage('Search');
    loadTemplate('Search');
    // Are you allowed?
    isAllowedTo('search_posts');
    require_once $sourcedir . '/Display.php';
    if (!empty($modSettings['search_index']) && $modSettings['search_index'] == 'fulltext') {
        // Try to determine the minimum number of letters for a fulltext search.
        $request = db_query("\n\t\t\tSHOW VARIABLES\n\t\t\tLIKE 'ft_min_word_len'", false, false);
        if ($request !== false && mysql_num_rows($request) == 1) {
            list(, $min_word_length) = mysql_fetch_row($request);
            mysql_free_result($request);
        } else {
            $min_word_length = '4';
        }
        // Some MySQL versions are superior to others :P.
        $canDoBooleanSearch = version_compare(mysql_get_server_info($db_connection), '4.0.1', '>=') == 1;
        // Get a list of banned fulltext words.
        $banned_words = empty($modSettings['search_banned_words']) ? array() : explode(',', addslashes($modSettings['search_banned_words']));
    } elseif (!empty($modSettings['search_index']) && $modSettings['search_index'] == 'custom' && !empty($modSettings['search_custom_index_config'])) {
        $customIndexSettings = unserialize($modSettings['search_custom_index_config']);
        $min_word_length = $customIndexSettings['bytes_per_word'];
        $banned_words = empty($modSettings['search_stopwords']) ? array() : explode(',', addslashes($modSettings['search_stopwords']));
    } else {
        $modSettings['search_index'] = '';
    }
    // $search_params will carry all settings that differ from the default search parameters.
    // That way, the URLs involved in a search page will be kept as short as possible.
    $search_params = array();
    if (isset($_REQUEST['params'])) {
        $temp_params = explode('|"|', base64_decode(strtr($_REQUEST['params'], array(' ' => '+'))));
        foreach ($temp_params as $i => $data) {
            @(list($k, $v) = explode('|\'|', $data));
            $search_params[$k] = stripslashes($v);
        }
        if (isset($search_params['brd'])) {
            $search_params['brd'] = empty($search_params['brd']) ? array() : explode(',', $search_params['brd']);
        }
    }
    // Store whether simple search was used (needed if the user wants to do another query).
    if (!isset($search_params['advanced'])) {
        $search_params['advanced'] = empty($_REQUEST['advanced']) ? 0 : 1;
    }
    // 1 => 'allwords' (default, don't set as param) / 2 => 'anywords'.
    if (!empty($search_params['searchtype']) || !empty($_REQUEST['searchtype']) && $_REQUEST['searchtype'] == 2) {
        $search_params['searchtype'] = 2;
    }
    // Minimum age of messages. Default to zero (don't set param in that case).
    if (!empty($search_params['minage']) || !empty($_REQUEST['minage']) && $_REQUEST['minage'] > 0) {
        $search_params['minage'] = !empty($search_params['minage']) ? (int) $search_params['minage'] : (int) $_REQUEST['minage'];
    }
    // Maximum age of messages. Default to infinite (9999 days: param not set).
    if (!empty($search_params['maxage']) || !empty($_REQUEST['maxage']) && $_REQUEST['maxage'] != 9999) {
        $search_params['maxage'] = !empty($search_params['maxage']) ? (int) $search_params['maxage'] : (int) $_REQUEST['maxage'];
    }
    // Searching a specific topic?
    if (!empty($_REQUEST['topic'])) {
        $search_params['topic'] = (int) $_REQUEST['topic'];
        $search_params['show_complete'] = true;
    } elseif (!empty($search_params['topic'])) {
        $search_params['topic'] = (int) $search_params['topic'];
    }
    if (!empty($search_params['minage']) || !empty($search_params['maxage'])) {
        $request = db_query("\n\t\t\tSELECT " . (empty($search_params['maxage']) ? '0, ' : 'IFNULL(MIN(ID_MSG), -1), ') . (empty($search_params['minage']) ? '0' : 'IFNULL(MAX(ID_MSG), -1)') . "\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE " . (empty($search_params['minage']) ? '1' : 'posterTime <= ' . (time() - 86400 * $search_params['minage'])) . (empty($search_params['maxage']) ? '' : "\n\t\t\t\tAND posterTime >= " . (time() - 86400 * $search_params['maxage'])), __FILE__, __LINE__);
        list($minMsgID, $maxMsgID) = mysql_fetch_row($request);
        if ($minMsgID < 0 || $maxMsgID < 0) {
            $context['search_errors']['no_messages_in_time_frame'] = true;
        }
        mysql_free_result($request);
    }
    // Default the user name to a wildcard matching every user (*).
    if (!empty($search_params['userspec']) || !empty($_REQUEST['userspec']) && $_REQUEST['userspec'] != '*') {
        $search_params['userspec'] = isset($search_params['userspec']) ? $search_params['userspec'] : $_REQUEST['userspec'];
    }
    // If there's no specific user, then don't mention it in the main query.
    if (empty($search_params['userspec'])) {
        $userQuery = '';
    } else {
        $userString = strtr(addslashes($func['htmlspecialchars'](stripslashes($search_params['userspec']), ENT_QUOTES)), array('&quot;' => '"'));
        $userString = strtr($userString, array('%' => '\\%', '_' => '\\_', '*' => '%', '?' => '_'));
        preg_match_all('~"([^"]+)"~', $userString, $matches);
        $possible_users = array_merge($matches[1], explode(',', preg_replace('~"([^"]+)"~', '', $userString)));
        for ($k = 0, $n = count($possible_users); $k < $n; $k++) {
            $possible_users[$k] = trim($possible_users[$k]);
            if (strlen($possible_users[$k]) == 0) {
                unset($possible_users[$k]);
            }
        }
        // Retrieve a list of possible members.
        $request = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}members\n\t\t\tWHERE realName LIKE '" . implode("' OR realName LIKE '", $possible_users) . "'", __FILE__, __LINE__);
        // Simply do nothing if there're too many members matching the criteria.
        if (mysql_num_rows($request) > $maxMembersToSearch) {
            $userQuery = '';
        } elseif (mysql_num_rows($request) == 0) {
            $userQuery = "m.ID_MEMBER = 0 AND (m.posterName LIKE '" . implode("' OR m.posterName LIKE '", $possible_users) . "')";
        } else {
            $memberlist = array();
            while ($row = mysql_fetch_assoc($request)) {
                $memberlist[] = $row['ID_MEMBER'];
            }
            $userQuery = "(m.ID_MEMBER IN (" . implode(', ', $memberlist) . ") OR (m.ID_MEMBER = 0 AND (m.posterName LIKE '" . implode("' OR m.posterName LIKE '", $possible_users) . "')))";
        }
        mysql_free_result($request);
    }
    // If the boards were passed by URL (params=), temporarily put them back in $_REQUEST.
    if (!empty($search_params['brd']) && is_array($search_params['brd'])) {
        $_REQUEST['brd'] = $search_params['brd'];
    }
    // Ensure that brd is an array.
    if (!empty($_REQUEST['brd']) && !is_array($_REQUEST['brd'])) {
        $_REQUEST['brd'] = strpos($_REQUEST['brd'], ',') !== false ? explode(',', $_REQUEST['brd']) : array($_REQUEST['brd']);
    }
    // Make sure all boards are integers.
    if (!empty($_REQUEST['brd'])) {
        foreach ($_REQUEST['brd'] as $id => $brd) {
            $_REQUEST['brd'][$id] = (int) $brd;
        }
    }
    // Special case for boards: searching just one topic?
    if (!empty($search_params['topic'])) {
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\tWHERE b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND t.ID_TOPIC = " . $search_params['topic'] . "\n\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error('topic_gone', false);
        }
        $search_params['brd'] = array();
        list($search_params['brd'][0]) = mysql_fetch_row($request);
        mysql_free_result($request);
    } elseif ($user_info['is_admin'] && (!empty($search_params['advanced']) || !empty($_REQUEST['brd']))) {
        $search_params['brd'] = empty($_REQUEST['brd']) ? array() : $_REQUEST['brd'];
    } else {
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}" . (empty($_REQUEST['brd']) ? !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "\n\t\t\t\tAND b.ID_BOARD != {$modSettings['recycle_board']}" : '' : "\n\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $_REQUEST['brd']) . ")"), __FILE__, __LINE__);
        $search_params['brd'] = array();
        while ($row = mysql_fetch_assoc($request)) {
            $search_params['brd'][] = $row['ID_BOARD'];
        }
        mysql_free_result($request);
        // This error should pro'bly only happen for hackers.
        if (empty($search_params['brd'])) {
            $context['search_errors']['no_boards_selected'] = true;
        }
    }
    if (count($search_params['brd']) != 0) {
        // If we've selected all boards, this parameter can be left empty.
        $request = db_query("\n\t\t\tSELECT COUNT(*)\n\t\t\tFROM {$db_prefix}boards", __FILE__, __LINE__);
        list($num_boards) = mysql_fetch_row($request);
        mysql_free_result($request);
        if (count($search_params['brd']) == $num_boards) {
            $boardQuery = '';
        } elseif (count($search_params['brd']) == $num_boards - 1 && !empty($modSettings['recycle_board']) && !in_array($modSettings['recycle_board'], $search_params['brd'])) {
            $boardQuery = '!= ' . $modSettings['recycle_board'];
        } else {
            $boardQuery = 'IN (' . implode(', ', $search_params['brd']) . ')';
        }
    } else {
        $boardQuery = '';
    }
    $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']);
    $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']);
    $context['compact'] = !$search_params['show_complete'];
    // Get the sorting parameters right. Default to sort by relevance descending.
    $sort_columns = array('relevance', 'numReplies', 'ID_MSG');
    if (empty($search_params['sort']) && !empty($_REQUEST['sort'])) {
        list($search_params['sort'], $search_params['sort_dir']) = array_pad(explode('|', $_REQUEST['sort']), 2, '');
    }
    $search_params['sort'] = !empty($search_params['sort']) && in_array($search_params['sort'], $sort_columns) ? $search_params['sort'] : 'relevance';
    if (!empty($search_params['topic']) && $search_params['sort'] === 'numReplies') {
        $search_params['sort'] = 'ID_MSG';
    }
    // Sorting direction: descending unless stated otherwise.
    $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc';
    // Determine some values needed to calculate the relevance.
    $minMsg = (int) ((1 - $recentPercentage) * $modSettings['maxMsgID']);
    $recentMsg = $modSettings['maxMsgID'] - $minMsg;
    // *** Parse the search query
    // Unfortunately, searching for words like this is going to be slow, so we're blacklisting them.
    // !!! Setting to add more here?
    // !!! Maybe only blacklist if they are the only word, or "any" is used?
    $blacklisted_words = array('img', 'url', 'quote', 'www', 'http', 'the', 'is', 'it', 'are', 'if');
    // What are we searching for?
    if (empty($search_params['search'])) {
        if (isset($_GET['search'])) {
            $search_params['search'] = un_htmlspecialchars($_GET['search']);
        } elseif (isset($_POST['search'])) {
            $search_params['search'] = stripslashes($_POST['search']);
        } else {
            $search_params['search'] = '';
        }
    }
    // Nothing??
    if (!isset($search_params['search']) || $search_params['search'] == '') {
        $context['search_errors']['invalid_search_string'] = true;
    }
    // Change non-word characters into spaces.
    $stripped_query = preg_replace('~([\\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}' : pack('C*', 0xc2, 0xa0) : '\\xA0') . '\\t\\r\\s\\n(){}\\[\\]<>!@$%^*.,:+=`\\~\\?/\\\\]|&(amp|lt|gt|quot);)+~' . ($context['utf8'] ? 'u' : ''), ' ', $search_params['search']);
    // Make the query lower case. It's gonna be case insensitive anyway.
    $stripped_query = un_htmlspecialchars($func['strtolower']($stripped_query));
    // This (hidden) setting will do fulltext searching in the most basic way.
    if (!empty($modSettings['search_simple_fulltext'])) {
        $stripped_query = strtr($stripped_query, array('"' => ''));
    }
    $no_regexp = preg_match('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', $stripped_query) === 1;
    // Extract phrase parts first (e.g. some words "this is a phrase" some more words.)
    preg_match_all('/(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)/', $stripped_query, $matches, PREG_PATTERN_ORDER);
    $phraseArray = $matches[2];
    // Remove the phrase parts and extract the words.
    $wordArray = explode(' ', preg_replace('~(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), ' ', $stripped_query));
    // A minus sign in front of a word excludes the word.... so...
    $excludedWords = array();
    $excludedIndexWords = array();
    $excludedSubjectWords = array();
    $excludedPhrases = array();
    // .. first, we check for things like -"some words", but not "-some words".
    foreach ($matches[1] as $index => $word) {
        if ($word === '-') {
            if (($word = trim($phraseArray[$index], '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) {
                $excludedWords[] = addslashes($word);
            }
            unset($phraseArray[$index]);
        }
    }
    // Now we look for -test, etc.... normaller.
    foreach ($wordArray as $index => $word) {
        if (strpos(trim($word), '-') === 0) {
            if (($word = trim($word, '-_\' ')) !== '' && !in_array($word, $blacklisted_words)) {
                $excludedWords[] = addslashes($word);
            }
            unset($wordArray[$index]);
        }
    }
    // The remaining words and phrases are all included.
    $searchArray = array_merge($phraseArray, $wordArray);
    // Trim everything and make sure there are no words that are the same.
    foreach ($searchArray as $index => $value) {
        if (($searchArray[$index] = trim($value, '-_\' ')) === '' || in_array($searchArray[$index], $blacklisted_words)) {
            unset($searchArray[$index]);
        } else {
            $searchArray[$index] = addslashes($searchArray[$index]);
        }
    }
    $searchArray = array_slice(array_unique($searchArray), 0, 10);
    // Create an array of replacements for highlighting.
    $context['mark'] = array();
    foreach ($searchArray as $word) {
        $context['mark'][$word] = '<b class="highlight">' . $word . '</b>';
    }
    // Initialize two arrays storing the words that have to be searched for.
    $orParts = array();
    $searchWords = array();
    // Make sure at least one word is being searched for.
    if (empty($searchArray)) {
        $context['search_errors']['invalid_search_string'] = true;
    } elseif (empty($search_params['searchtype'])) {
        $orParts[0] = $searchArray;
    } else {
        foreach ($searchArray as $index => $value) {
            $orParts[$index] = array($value);
        }
    }
    // Make sure the excluded words are in all or-branches.
    foreach ($orParts as $orIndex => $andParts) {
        foreach ($excludedWords as $word) {
            $orParts[$orIndex][] = $word;
        }
    }
    // Determine the or-branches and the fulltext search words.
    foreach ($orParts as $orIndex => $andParts) {
        $searchWords[$orIndex] = array('indexed_words' => array(), 'words' => array(), 'subject_words' => array(), 'all_words' => array());
        // Sort the indexed words (large words -> small words -> excluded words).
        if (!empty($modSettings['search_index'])) {
            usort($orParts[$orIndex], 'searchSort');
        }
        foreach ($orParts[$orIndex] as $word) {
            $is_excluded = in_array($word, $excludedWords);
            $searchWords[$orIndex]['all_words'][] = $word;
            $subjectWords = text2words(stripslashes($word));
            if (!$is_excluded || count($subjectWords) === 1) {
                $searchWords[$orIndex]['subject_words'] = array_merge($searchWords[$orIndex]['subject_words'], $subjectWords);
                if ($is_excluded) {
                    $excludedSubjectWords = array_merge($excludedSubjectWords, $subjectWords);
                }
            } else {
                $excludedPhrases[] = $word;
            }
            if (!empty($modSettings['search_index'])) {
                $subwords = text2words(stripslashes($word), $modSettings['search_index'] === 'fulltext' ? null : $min_word_length, $modSettings['search_index'] === 'custom');
                if (($modSettings['search_index'] === 'custom' || $modSettings['search_index'] === 'fulltext' && !$canDoBooleanSearch && count($subwords) > 1) && empty($modSettings['search_force_index'])) {
                    $searchWords[$orIndex]['words'][] = $word;
                }
                if ($modSettings['search_index'] === 'fulltext' && $canDoBooleanSearch) {
                    $fulltextWord = count($subwords) === 1 ? $word : '"' . $word . '"';
                    $searchWords[$orIndex]['indexed_words'][] = $fulltextWord;
                    if ($is_excluded) {
                        $excludedIndexWords[] = $fulltextWord;
                    }
                } elseif (count($subwords) > 1 && $is_excluded) {
                    continue;
                } else {
                    $relyOnIndex = true;
                    foreach ($subwords as $subword) {
                        if (($modSettings['search_index'] === 'custom' || strlen(stripslashes($subword)) >= $min_word_length) && !in_array($subword, $banned_words)) {
                            $searchWords[$orIndex]['indexed_words'][] = $subword;
                            if ($is_excluded) {
                                $excludedIndexWords[] = $subword;
                            }
                        } elseif (!in_array($subword, $banned_words)) {
                            $relyOnIndex = false;
                        }
                    }
                    if ($modSettings['search_index'] === 'fulltext' && $canDoBooleanSearch && !$relyOnIndex && empty($modSettings['search_force_index'])) {
                        $searchWords[$orIndex]['words'][] = $word;
                    }
                }
            }
        }
        // Search_force_index requires all AND parts to have at least one fulltext word.
        if (!empty($modSettings['search_force_index']) && empty($searchWords[$orIndex]['indexed_words'])) {
            $context['search_errors']['query_not_specific_enough'] = true;
            break;
        } else {
            $searchWords[$orIndex]['indexed_words'] = array_slice($searchWords[$orIndex]['indexed_words'], 0, 7);
            $searchWords[$orIndex]['subject_words'] = array_slice($searchWords[$orIndex]['subject_words'], 0, 7);
        }
    }
    // *** Spell checking
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    if ($context['show_spellchecking']) {
        // Windows fix.
        ob_start();
        $old = error_reporting(0);
        pspell_new('en');
        $pspell_link = pspell_new($txt['lang_dictionary'], $txt['lang_spelling'], '', strtr($txt['lang_character_set'], array('iso-' => 'iso', 'ISO-' => 'iso')), PSPELL_FAST | PSPELL_RUN_TOGETHER);
        error_reporting($old);
        if (!$pspell_link) {
            $pspell_link = pspell_new('en', '', '', '', PSPELL_FAST | PSPELL_RUN_TOGETHER);
        }
        ob_end_clean();
        $did_you_mean = array('search' => array(), 'display' => array());
        $found_misspelling = false;
        foreach ($searchArray as $word) {
            if (empty($pspell_link)) {
                continue;
            }
            $word = stripslashes($word);
            // Don't check phrases.
            if (preg_match('~^\\w+$~', $word) === 0) {
                $did_you_mean['search'][] = '"' . $word . '"';
                $did_you_mean['display'][] = '&quot;' . $func['htmlspecialchars']($word) . '&quot;';
                continue;
            } elseif (preg_match('~\\d~', $word) === 1) {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $func['htmlspecialchars']($word);
                continue;
            } elseif (pspell_check($pspell_link, $word)) {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $func['htmlspecialchars']($word);
                continue;
            }
            $suggestions = pspell_suggest($pspell_link, $word);
            foreach ($suggestions as $i => $s) {
                // Search is case insensitive.
                if ($func['strtolower']($s) == $func['strtolower']($word)) {
                    unset($suggestions[$i]);
                }
            }
            // Anything found?  If so, correct it!
            if (!empty($suggestions)) {
                $suggestions = array_values($suggestions);
                $did_you_mean['search'][] = $suggestions[0];
                $did_you_mean['display'][] = '<em><b>' . $func['htmlspecialchars']($suggestions[0]) . '</b></em>';
                $found_misspelling = true;
            } else {
                $did_you_mean['search'][] = $word;
                $did_you_mean['display'][] = $func['htmlspecialchars']($word);
            }
        }
        if ($found_misspelling) {
            // Don't spell check excluded words, but add them still...
            $temp_excluded = array('search' => array(), 'display' => array());
            foreach ($excludedWords as $word) {
                $word = stripslashes($word);
                if (preg_match('~^\\w+$~', $word) == 0) {
                    $temp_excluded['search'][] = '-"' . $word . '"';
                    $temp_excluded['display'][] = '-&quot;' . $func['htmlspecialchars']($word) . '&quot;';
                } else {
                    $temp_excluded['search'][] = '-' . $word;
                    $temp_excluded['display'][] = '-' . $func['htmlspecialchars']($word);
                }
            }
            $did_you_mean['search'] = array_merge($did_you_mean['search'], $temp_excluded['search']);
            $did_you_mean['display'] = array_merge($did_you_mean['display'], $temp_excluded['display']);
            $temp_params = $search_params;
            $temp_params['search'] = implode(' ', $did_you_mean['search']);
            if (isset($temp_params['brd'])) {
                $temp_params['brd'] = implode(',', $temp_params['brd']);
            }
            $context['params'] = array();
            foreach ($temp_params as $k => $v) {
                $context['did_you_mean_params'][] = $k . '|\'|' . addslashes($v);
            }
            $context['did_you_mean_params'] = base64_encode(implode('|"|', $context['did_you_mean_params']));
            $context['did_you_mean'] = implode(' ', $did_you_mean['display']);
        }
    }
    // Let the user adjust the search query, should they wish?
    $context['search_params'] = $search_params;
    if (isset($context['search_params']['search'])) {
        $context['search_params']['search'] = $func['htmlspecialchars']($context['search_params']['search']);
    }
    if (isset($context['search_params']['userspec'])) {
        $context['search_params']['userspec'] = $func['htmlspecialchars']($context['search_params']['userspec']);
    }
    // *** Encode all search params
    // All search params have been checked, let's compile them to a single string... made less simple by PHP 4.3.9 and below.
    $temp_params = $search_params;
    if (isset($temp_params['brd'])) {
        $temp_params['brd'] = implode(',', $temp_params['brd']);
    }
    $context['params'] = array();
    foreach ($temp_params as $k => $v) {
        $context['params'][] = $k . '|\'|' . addslashes($v);
    }
    $context['params'] = base64_encode(implode('|"|', $context['params']));
    // ... and add the links to the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?action=search;params=' . $context['params'], 'name' => $txt[182]);
    $context['linktree'][] = array('url' => $scripturl . '?action=search2;params=' . $context['params'], 'name' => $txt['search_results']);
    // *** A last error check
    // One or more search errors? Go back to the first search screen.
    if (!empty($context['search_errors'])) {
        $_REQUEST['params'] = $context['params'];
        return PlushSearch1();
    }
    /*	// !!! This doesn't seem too urgent anymore. Can we remove it?
    	if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2)
    	{
    		// !!! Change error message...
    		if (cache_get_data('search_start:' . ($user_info['is_guest'] ? $user_info['ip'] : $ID_MEMBER), 90) == 1)
    			fatal_lang_error('loadavg_search_disabled', false);
    		cache_put_data('search_start:' . ($user_info['is_guest'] ? $user_info['ip'] : $ID_MEMBER), 1, 90);
    	}*/
    // *** Reserve an ID for caching the search results.
    // Update the cache if the current search term is not yet cached.
    if (empty($_SESSION['search_cache']) || $_SESSION['search_cache']['params'] != $context['params']) {
        // Increase the pointer...
        $modSettings['search_pointer'] = empty($modSettings['search_pointer']) ? 0 : (int) $modSettings['search_pointer'];
        // ...and store it right off.
        updateSettings(array('search_pointer' => $modSettings['search_pointer'] >= 255 ? 0 : $modSettings['search_pointer'] + 1));
        // As long as you don't change the parameters, the cache result is yours.
        $_SESSION['search_cache'] = array('ID_SEARCH' => $modSettings['search_pointer'], 'num_results' => -1, 'params' => $context['params']);
        // Clear the previous cache of the final results cache.
        db_query("\n\t\t\tDELETE FROM {$db_prefix}log_search_results\n\t\t\tWHERE ID_SEARCH = " . $_SESSION['search_cache']['ID_SEARCH'], __FILE__, __LINE__);
        if ($search_params['subject_only']) {
            foreach ($searchWords as $orIndex => $words) {
                $subject_query = array('from' => array("{$db_prefix}topics AS t"), 'left_join' => array(), 'where' => array());
                $numTables = 0;
                $prev_join = 0;
                $numSubjectResults = 0;
                foreach ($words['subject_words'] as $subjectWord) {
                    $numTables++;
                    if (in_array($subjectWord, $excludedSubjectWords)) {
                        $subject_query['left_join'][] = "{$db_prefix}log_search_subjects AS subj{$numTables} ON (subj{$numTables}.word " . (empty($modSettings['search_match_words']) ? "LIKE '%{$subjectWord}%'" : "= '{$subjectWord}'") . " AND subj{$numTables}.ID_TOPIC = t.ID_TOPIC)";
                        $subject_query['where'][] = "(subj{$numTables}.word IS NULL)";
                    } else {
                        $subject_query['from'][] = "{$db_prefix}log_search_subjects AS subj{$numTables}";
                        $subject_query['where'][] = "subj{$numTables}.word " . (empty($modSettings['search_match_words']) ? "LIKE '%{$subjectWord}%'" : "= '{$subjectWord}'");
                        $subject_query['where'][] = "subj{$numTables}.ID_TOPIC = " . ($prev_join === 0 ? 't' : 'subj' . $prev_join) . '.ID_TOPIC';
                        $prev_join = $numTables;
                    }
                }
                if (!empty($userQuery)) {
                    if (!in_array("{$db_prefix}messages AS m", $subject_query['from'])) {
                        $subject_query['from'][] = "{$db_prefix}messages AS m";
                        $subject_query['where'][] = 'm.ID_TOPIC = t.ID_TOPIC';
                    }
                    $subject_query['where'][] = $userQuery;
                }
                if (!empty($search_params['topic'])) {
                    $subject_query['where'][] = 't.ID_TOPIC = ' . $search_params['topic'];
                }
                if (!empty($minMsgID)) {
                    $subject_query['where'][] = 't.ID_FIRST_MSG >= ' . $minMsgID;
                }
                if (!empty($maxMsgID)) {
                    $subject_query['where'][] = 't.ID_LAST_MSG <= ' . $maxMsgID;
                }
                if (!empty($boardQuery)) {
                    $subject_query['where'][] = 't.ID_BOARD ' . $boardQuery;
                }
                if (!empty($excludedPhrases)) {
                    if (!in_array("{$db_prefix}messages AS m", $subject_query['from'])) {
                        $subject_query['from'][] = "{$db_prefix}messages AS m";
                        $subject_query['where'][] = 'm.ID_MSG = t.ID_FIRST_MSG';
                    }
                    foreach ($excludedPhrases as $phrase) {
                        $subject_query['where'][] = 'm.subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . "[[:>:]]'");
                    }
                }
                db_query("\n\t\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_search_results\n\t\t\t\t\t\t(ID_SEARCH, ID_TOPIC, relevance, ID_MSG, num_matches)\n\t\t\t\t\tSELECT \n\t\t\t\t\t\t" . $_SESSION['search_cache']['ID_SEARCH'] . ",\n\t\t\t\t\t\tt.ID_TOPIC,\n\t\t\t\t\t\t1000 * (\n\t\t\t\t\t\t\t{$weight['frequency']} / (t.numReplies + 1) +\n\t\t\t\t\t\t\t{$weight['age']} * IF(t.ID_FIRST_MSG < {$minMsg}, 0, (t.ID_FIRST_MSG - {$minMsg}) / {$recentMsg}) +\n\t\t\t\t\t\t\t{$weight['length']} * IF(t.numReplies < {$humungousTopicPosts}, t.numReplies / {$humungousTopicPosts}, 1) +\n\t\t\t\t\t\t\t{$weight['subject']} +\n\t\t\t\t\t\t\t{$weight['sticky']} * t.isSticky\n\t\t\t\t\t\t) / {$weight_total} AS relevance,\n\t\t\t\t\t\t" . (empty($userQuery) ? 't.ID_FIRST_MSG' : 'm.ID_MSG') . ",\n\t\t\t\t\t\t1\n\t\t\t\t\tFROM (" . implode(', ', $subject_query['from']) . ')' . (empty($subject_query['left_join']) ? '' : "\n\t\t\t\t\t\tLEFT JOIN " . implode("\n\t\t\t\t\t\tLEFT JOIN ", $subject_query['left_join'])) . "\n\t\t\t\t\tWHERE " . implode("\n\t\t\t\t\t\tAND ", $subject_query['where']) . (empty($modSettings['search_max_results']) ? '' : "\n\t\t\t\t\tLIMIT " . ($modSettings['search_max_results'] - $numSubjectResults)), __FILE__, __LINE__);
                $numSubjectResults += db_affected_rows();
                if (!empty($modSettings['search_max_results']) && $numSubjectResults >= $modSettings['search_max_results']) {
                    break;
                }
            }
            $_SESSION['search_cache']['num_results'] = $numSubjectResults;
        } else {
            $main_query = array('select' => array('ID_SEARCH' => $_SESSION['search_cache']['ID_SEARCH'], 'relevance' => '0'), 'weights' => array(), 'from' => array("{$db_prefix}topics AS t", "{$db_prefix}messages AS m"), 'left_join' => array(), 'where' => array('t.ID_TOPIC = m.ID_TOPIC'), 'group_by' => array());
            if (empty($search_params['topic'])) {
                $main_query['select']['ID_TOPIC'] = 't.ID_TOPIC';
                $main_query['select']['ID_MSG'] = 'MAX(m.ID_MSG) AS ID_MSG';
                $main_query['select']['num_matches'] = 'COUNT(*) AS num_matches';
                $main_query['weights'] = array('frequency' => 'COUNT(*) / (t.numReplies + 1)', 'age' => "IF(MAX(m.ID_MSG) < {$minMsg}, 0, (MAX(m.ID_MSG) - {$minMsg}) / {$recentMsg})", 'length' => "IF(t.numReplies < {$humungousTopicPosts}, t.numReplies / {$humungousTopicPosts}, 1)", 'subject' => '0', 'first_message' => "IF(MIN(m.ID_MSG) = t.ID_FIRST_MSG, 1, 0)", 'sticky' => 't.isSticky');
                $main_query['group_by'][] = 't.ID_TOPIC';
            } else {
                // This is outrageous!
                $main_query['select']['ID_TOPIC'] = 'm.ID_MSG AS ID_TOPIC';
                $main_query['select']['ID_MSG'] = 'm.ID_MSG';
                $main_query['select']['num_matches'] = '1 AS num_matches';
                $main_query['weights'] = array('age' => "((m.ID_MSG - t.ID_FIRST_MSG) / IF(t.ID_LAST_MSG = t.ID_FIRST_MSG, 1, t.ID_LAST_MSG - t.ID_FIRST_MSG))", 'first_message' => "IF(m.ID_MSG = t.ID_FIRST_MSG, 1, 0)");
                $main_query['where'][] = 't.ID_TOPIC = ' . $search_params['topic'];
            }
            // *** Get the subject results.
            $numSubjectResults = 0;
            if (empty($search_params['topic'])) {
                // Create a temporary table to store some preliminary results in.
                db_query("\n\t\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}tmp_log_search_topics", __FILE__, __LINE__);
                $createTemporary = db_query("\n\t\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}tmp_log_search_topics (\n\t\t\t\t\t\tID_TOPIC mediumint(8) unsigned NOT NULL default '0',\n\t\t\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t\t\t) TYPE=HEAP", false, false) !== false;
                // Clean up some previous cache.
                if (!$createTemporary) {
                    db_query("\n\t\t\t\t\t\tDELETE FROM {$db_prefix}log_search_topics\n\t\t\t\t\t\tWHERE ID_SEARCH = " . $_SESSION['search_cache']['ID_SEARCH'], __FILE__, __LINE__);
                }
                foreach ($searchWords as $orIndex => $words) {
                    $subject_query = array('from' => array("{$db_prefix}topics AS t"), 'left_join' => array(), 'where' => array());
                    $numTables = 0;
                    $prev_join = 0;
                    foreach ($words['subject_words'] as $subjectWord) {
                        $numTables++;
                        if (in_array($subjectWord, $excludedSubjectWords)) {
                            if (!in_array("{$db_prefix}messages AS m", $subject_query['from'])) {
                                $subject_query['from'][] = "{$db_prefix}messages AS m";
                                $subject_query['where'][] = 'm.ID_MSG = t.ID_FIRST_MSG';
                            }
                            $subject_query['left_join'][] = "{$db_prefix}log_search_subjects AS subj{$numTables} ON (subj{$numTables}.word " . (empty($modSettings['search_match_words']) ? "LIKE '%{$subjectWord}%'" : "= '{$subjectWord}'") . " AND subj{$numTables}.ID_TOPIC = t.ID_TOPIC)";
                            $subject_query['where'][] = "(subj{$numTables}.word IS NULL)";
                            $subject_query['where'][] = 'm.body NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($subjectWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $subjectWord), '\\\'') . "[[:>:]]'");
                        } else {
                            $subject_query['from'][] = "{$db_prefix}log_search_subjects AS subj{$numTables}";
                            $subject_query['where'][] = "subj{$numTables}.word " . (empty($modSettings['search_match_words']) ? "LIKE '%{$subjectWord}%'" : "= '{$subjectWord}'");
                            $subject_query['where'][] = "subj{$numTables}.ID_TOPIC = " . ($prev_join === 0 ? 't' : 'subj' . $prev_join) . '.ID_TOPIC';
                            $prev_join = $numTables;
                        }
                    }
                    if (!empty($userQuery)) {
                        if (!in_array("{$db_prefix}messages AS m", $subject_query['from'])) {
                            $subject_query['from'][] = "{$db_prefix}messages AS m";
                            $subject_query['where'][] = 'm.ID_MSG = t.ID_FIRST_MSG';
                        }
                        $subject_query['where'][] = $userQuery;
                    }
                    if (!empty($search_params['topic'])) {
                        $subject_query['where'][] = 't.ID_TOPIC = ' . $search_params['topic'];
                    }
                    if (!empty($minMsgID)) {
                        $subject_query['where'][] = 't.ID_FIRST_MSG >= ' . $minMsgID;
                    }
                    if (!empty($maxMsgID)) {
                        $subject_query['where'][] = 't.ID_LAST_MSG <= ' . $maxMsgID;
                    }
                    if (!empty($boardQuery)) {
                        $subject_query['where'][] = 't.ID_BOARD ' . $boardQuery;
                    }
                    if (!empty($excludedPhrases)) {
                        if (!in_array("{$db_prefix}messages AS m", $subject_query['from'])) {
                            $subject_query['from'][] = "{$db_prefix}messages AS m";
                            $subject_query['where'][] = 'm.ID_MSG = t.ID_FIRST_MSG';
                        }
                        foreach ($excludedPhrases as $phrase) {
                            $subject_query['where'][] = 'm.subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . "[[:>:]]'");
                            $subject_query['where'][] = 'm.body NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . "[[:>:]]'");
                        }
                    }
                    db_query("\n\t\t\t\t\t\tINSERT IGNORE INTO {$db_prefix}" . ($createTemporary ? 'tmp_' : '') . "log_search_topics\n\t\t\t\t\t\t\t(" . ($createTemporary ? '' : 'ID_SEARCH, ') . "ID_TOPIC)\n\t\t\t\t\t\tSELECT " . ($createTemporary ? '' : $_SESSION['search_cache']['ID_SEARCH'] . ', ') . "t.ID_TOPIC\n\t\t\t\t\t\tFROM (" . implode(', ', $subject_query['from']) . ')' . (empty($subject_query['left_join']) ? '' : "\n\t\t\t\t\t\t\tLEFT JOIN " . implode("\n\t\t\t\t\t\t\tLEFT JOIN ", $subject_query['left_join'])) . "\n\t\t\t\t\t\tWHERE " . implode("\n\t\t\t\t\t\t\tAND ", $subject_query['where']) . (empty($modSettings['search_max_results']) ? '' : "\n\t\t\t\t\t\tLIMIT " . ($modSettings['search_max_results'] - $numSubjectResults)), __FILE__, __LINE__);
                    $numSubjectResults += db_affected_rows();
                    if (!empty($modSettings['search_max_results']) && $numSubjectResults >= $modSettings['search_max_results']) {
                        break;
                    }
                }
                if ($numSubjectResults !== 0) {
                    $main_query['weights']['subject'] = 'IF(lst.ID_TOPIC IS NULL, 0, 1)';
                    $main_query['left_join'][] = "{$db_prefix}" . ($createTemporary ? 'tmp_' : '') . "log_search_topics AS lst ON (" . ($createTemporary ? '' : 'lst.ID_SEARCH = ' . $_SESSION['search_cache']['ID_SEARCH'] . ' AND ') . "lst.ID_TOPIC = t.ID_TOPIC)";
                }
            }
            $indexedResults = 0;
            if (!empty($modSettings['search_index'])) {
                db_query("\n\t\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}tmp_log_search_messages", __FILE__, __LINE__);
                $createTemporary = db_query("\n\t\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}tmp_log_search_messages (\n\t\t\t\t\t\tID_MSG int(10) unsigned NOT NULL default '0',\n\t\t\t\t\t\tPRIMARY KEY (ID_MSG)\n\t\t\t\t\t) TYPE=HEAP", false, false) !== false;
                if (!$createTemporary) {
                    db_query("\n\t\t\t\t\t\tDELETE FROM {$db_prefix}log_search_messages\n\t\t\t\t\t\tWHERE ID_SEARCH = " . $_SESSION['search_cache']['ID_SEARCH'], __FILE__, __LINE__);
                }
                foreach ($searchWords as $orIndex => $words) {
                    // *** Do the fulltext search.
                    if (!empty($words['indexed_words']) && $modSettings['search_index'] == 'fulltext') {
                        $fulltext_query = array('insert_into' => $db_prefix . ($createTemporary ? 'tmp_' : '') . 'log_search_messages', 'select' => array('ID_MSG' => 'ID_MSG'), 'where' => array());
                        if (!$createTemporary) {
                            $fulltext_query['select']['ID_SEARCH'] = $_SESSION['search_cache']['ID_SEARCH'];
                        }
                        if (empty($modSettings['search_simple_fulltext'])) {
                            foreach ($words['words'] as $regularWord) {
                                $fulltext_query['where'][] = 'body' . (in_array($regularWord, $excludedWords) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . "[[:>:]]'");
                            }
                        }
                        if (!empty($userQuery)) {
                            $fulltext_query['where'][] = strtr($userQuery, array('m.' => ''));
                        }
                        if (!empty($search_params['topic'])) {
                            $fulltext_query['where'][] = 'ID_TOPIC = ' . $search_params['topic'];
                        }
                        if (!empty($minMsgID)) {
                            $fulltext_query['where'][] = 'ID_MSG >= ' . $minMsgID;
                        }
                        if (!empty($maxMsgID)) {
                            $fulltext_query['where'][] = 'ID_MSG <= ' . $maxMsgID;
                        }
                        if (!empty($boardQuery)) {
                            $fulltext_query['where'][] = 'ID_BOARD ' . $boardQuery;
                        }
                        if (!empty($excludedPhrases) && empty($modSettings['search_force_index'])) {
                            foreach ($excludedPhrases as $phrase) {
                                $fulltext_query['where'][] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . "[[:>:]]'");
                            }
                        }
                        if (!empty($excludedSubjectWords) && empty($modSettings['search_force_index'])) {
                            foreach ($excludedSubjectWords as $excludedWord) {
                                $fulltext_query['where'][] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($excludedWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $excludedWord), '\\\'') . "[[:>:]]'");
                            }
                        }
                        if (!empty($modSettings['search_simple_fulltext'])) {
                            $fulltext_query['where'][] = "MATCH (body) AGAINST ('" . implode(' ', array_diff($words['indexed_words'], $excludedIndexWords)) . "')";
                        } elseif ($canDoBooleanSearch) {
                            $where = "MATCH (body) AGAINST ('";
                            foreach ($words['indexed_words'] as $fulltextWord) {
                                $where .= (in_array($fulltextWord, $excludedIndexWords) ? '-' : '+') . $fulltextWord . ' ';
                            }
                            $fulltext_query['where'][] = substr($where, 0, -1) . "' IN BOOLEAN MODE)";
                        } else {
                            foreach ($words['indexed_words'] as $fulltextWord) {
                                $fulltext_query['where'][] = (in_array($fulltextWord, $excludedIndexWords) ? 'NOT ' : '') . "MATCH (body) AGAINST ('{$fulltextWord}')";
                            }
                        }
                        db_query("\n\t\t\t\t\t\t\tINSERT IGNORE INTO {$fulltext_query['insert_into']}\n\t\t\t\t\t\t\t\t(" . implode(', ', array_keys($fulltext_query['select'])) . ")\n\t\t\t\t\t\t\tSELECT " . implode(', ', $fulltext_query['select']) . "\n\t\t\t\t\t\t\tFROM {$db_prefix}messages\n\t\t\t\t\t\t\tWHERE " . implode("\n\t\t\t\t\t\t\t\tAND ", $fulltext_query['where']) . (empty($maxMessageResults) ? '' : "\n\t\t\t\t\t\t\tLIMIT " . ($maxMessageResults - $indexedResults)), __FILE__, __LINE__);
                        $indexedResults += db_affected_rows();
                        if (!empty($maxMessageResults) && $indexedResults >= $maxMessageResults) {
                            break;
                        }
                    } elseif (!empty($words['indexed_words']) && $modSettings['search_index'] == 'custom') {
                        $custom_query = array('insert_into' => $db_prefix . ($createTemporary ? 'tmp_' : '') . 'log_search_messages', 'select' => array('ID_MSG' => 'm.ID_MSG'), 'from' => array("{$db_prefix}messages AS m"), 'left_join' => array(), 'where' => array());
                        if (!$createTemporary) {
                            $custom_query['select']['ID_SEARCH'] = $_SESSION['search_cache']['ID_SEARCH'];
                        }
                        foreach ($words['words'] as $regularWord) {
                            $custom_query['where'][] = 'm.body' . (in_array($regularWord, $excludedWords) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . "[[:>:]]'");
                        }
                        if (!empty($userQuery)) {
                            $custom_query['where'][] = $userQuery;
                        }
                        if (!empty($search_params['topic'])) {
                            $custom_query['where'][] = 'm.ID_TOPIC = ' . $search_params['topic'];
                        }
                        if (!empty($minMsgID)) {
                            $custom_query['where'][] = 'm.ID_MSG >= ' . $minMsgID;
                        }
                        if (!empty($maxMsgID)) {
                            $custom_query['where'][] = 'm.ID_MSG <= ' . $maxMsgID;
                        }
                        if (!empty($boardQuery)) {
                            $custom_query['where'][] = 'm.ID_BOARD ' . $boardQuery;
                        }
                        if (!empty($excludedPhrases) && empty($modSettings['search_force_index'])) {
                            foreach ($excludedPhrases as $phrase) {
                                $fulltext_query['where'][] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($phrase, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $phrase), '\\\'') . "[[:>:]]'");
                            }
                        }
                        if (!empty($excludedSubjectWords) && empty($modSettings['search_force_index'])) {
                            foreach ($excludedSubjectWords as $excludedWord) {
                                $fulltext_query['where'][] = 'subject NOT ' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($excludedWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $excludedWord), '\\\'') . "[[:>:]]'");
                            }
                        }
                        $numTables = 0;
                        $prev_join = 0;
                        foreach ($words['indexed_words'] as $indexedWord) {
                            $numTables++;
                            if (in_array($indexedWord, $excludedIndexWords)) {
                                $custom_query['left_join'][] = "{$db_prefix}log_search_words AS lsw{$numTables} ON (lsw{$numTables}.ID_WORD = {$indexedWord} AND lsw{$numTables}.ID_MSG = m.ID_MSG)";
                                $custom_query['where'][] = "(lsw{$numTables}.ID_WORD IS NULL)";
                            } else {
                                $custom_query['from'][] = "{$db_prefix}log_search_words AS lsw{$numTables}";
                                $custom_query['where'][] = "lsw{$numTables}.ID_WORD = {$indexedWord}";
                                $custom_query['where'][] = "lsw{$numTables}.ID_MSG = " . ($prev_join === 0 ? 'm' : 'lsw' . $prev_join) . '.ID_MSG';
                                $prev_join = $numTables;
                            }
                        }
                        db_query("\n\t\t\t\t\t\t\tINSERT IGNORE INTO {$custom_query['insert_into']}\n\t\t\t\t\t\t\t\t(" . implode(', ', array_keys($custom_query['select'])) . ")\n\t\t\t\t\t\t\tSELECT " . implode(', ', $custom_query['select']) . "\n\t\t\t\t\t\t\tFROM (" . implode(', ', $custom_query['from']) . ')' . (empty($custom_query['left_join']) ? '' : "\n\t\t\t\t\t\t\t\tLEFT JOIN " . implode("\n\t\t\t\t\t\t\t\tLEFT JOIN ", $custom_query['left_join'])) . "\n\t\t\t\t\t\t\tWHERE " . implode("\n\t\t\t\t\t\t\t\tAND ", $custom_query['where']) . (empty($maxMessageResults) ? '' : "\n\t\t\t\t\t\t\tLIMIT " . ($maxMessageResults - $indexedResults)), __FILE__, __LINE__);
                        $indexedResults += db_affected_rows();
                        if (!empty($maxMessageResults) && $indexedResults >= $maxMessageResults) {
                            break;
                        }
                    }
                }
                if (empty($indexedResults) && empty($numSubjectResults) && !empty($modSettings['search_force_index'])) {
                    $context['search_errors']['query_not_specific_enough'] = true;
                    $_REQUEST['params'] = $context['params'];
                    return PlushSearch1();
                } elseif (!empty($indexedResults)) {
                    $main_query['from'][] = $db_prefix . ($createTemporary ? 'tmp_' : '') . 'log_search_messages AS lsm';
                    $main_query['where'][] = 'lsm.ID_MSG = m.ID_MSG';
                    if (!$createTemporary) {
                        $main_query['where'][] = 'lsm.ID_SEARCH = ' . $_SESSION['search_cache']['ID_SEARCH'];
                    }
                }
            } else {
                $orWhere = array();
                foreach ($searchWords as $orIndex => $words) {
                    $where = array();
                    foreach ($words['all_words'] as $regularWord) {
                        $where[] = 'm.body' . (in_array($regularWord, $excludedWords) ? ' NOT' : '') . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . "[[:>:]]'");
                        if (in_array($regularWord, $excludedWords)) {
                            $where[] = 'm.subject NOT' . (empty($modSettings['search_match_words']) || $no_regexp ? " LIKE '%" . strtr($regularWord, array('_' => '\\_', '%' => '\\%')) . "%'" : " RLIKE '[[:<:]]" . addcslashes(preg_replace(array('/([\\[\\]$.+*?|{}()])/'), array('[$1]'), $regularWord), '\\\'') . "[[:>:]]'");
                        }
                    }
                    if (!empty($where)) {
                        $orWhere[] = count($where) > 1 ? '(' . implode(' AND ', $where) . ')' : $where[0];
                    }
                }
                if (!empty($orWhere)) {
                    $main_query['where'][] = count($orWhere) > 1 ? '(' . implode(' OR ', $orWhere) . ')' : $orWhere[0];
                }
                if (!empty($userQuery)) {
                    $main_query['where'][] = $userQuery;
                }
                if (!empty($search_params['topic'])) {
                    $main_query['where'][] = 'm.ID_TOPIC = ' . $search_params['topic'];
                }
                if (!empty($minMsgID)) {
                    $main_query['where'][] = 'm.ID_MSG >= ' . $minMsgID;
                }
                if (!empty($maxMsgID)) {
                    $main_query['where'][] = 'm.ID_MSG <= ' . $maxMsgID;
                }
                if (!empty($boardQuery)) {
                    $main_query['where'][] = 'm.ID_BOARD ' . $boardQuery;
                }
            }
            if (!empty($indexedResults) || empty($modSettings['search_index'])) {
                $relevance = '1000 * (';
                $new_weight_total = 0;
                foreach ($main_query['weights'] as $type => $value) {
                    $relevance .= $weight[$type] . ' * ' . $value . ' + ';
                    $new_weight_total += $weight[$type];
                }
                $main_query['select']['relevance'] = substr($relevance, 0, -3) . ") / {$new_weight_total} AS relevance";
                db_query("\n\t\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_search_results\n\t\t\t\t\t\t(" . implode(', ', array_keys($main_query['select'])) . ")\n\t\t\t\t\tSELECT\n\t\t\t\t\t\t" . implode(',
						', $main_query['select']) . "\n\t\t\t\t\tFROM (" . implode(', ', $main_query['from']) . ')' . (empty($main_query['left_join']) ? '' : "\n\t\t\t\t\t\tLEFT JOIN " . implode("\n\t\t\t\t\t\tLEFT JOIN ", $main_query['left_join'])) . "\n\t\t\t\t\tWHERE " . implode("\n\t\t\t\t\t\tAND ", $main_query['where']) . (empty($main_query['group_by']) ? '' : "\n\t\t\t\t\tGROUP BY " . implode(', ', $main_query['group_by'])) . (empty($modSettings['search_max_results']) ? '' : "\n\t\t\t\t\tLIMIT {$modSettings['search_max_results']}"), __FILE__, __LINE__);
                $_SESSION['search_cache']['num_results'] = db_affected_rows();
            }
            // Insert subject-only matches.
            if ($_SESSION['search_cache']['num_results'] < $modSettings['search_max_results'] && $numSubjectResults !== 0) {
                db_query("\n\t\t\t\t\tINSERT IGNORE INTO {$db_prefix}log_search_results\n\t\t\t\t\t\t(ID_SEARCH, ID_TOPIC, relevance, ID_MSG, num_matches)\n\t\t\t\t\tSELECT\n\t\t\t\t\t\t" . $_SESSION['search_cache']['ID_SEARCH'] . ",\n\t\t\t\t\t\tt.ID_TOPIC,\n\t\t\t\t\t\t1000 * (\n\t\t\t\t\t\t\t{$weight['frequency']} / (t.numReplies + 1) +\n\t\t\t\t\t\t\t{$weight['age']} * IF(t.ID_FIRST_MSG < {$minMsg}, 0, (t.ID_FIRST_MSG - {$minMsg}) / {$recentMsg}) +\n\t\t\t\t\t\t\t{$weight['length']} * IF(t.numReplies < {$humungousTopicPosts}, t.numReplies / {$humungousTopicPosts}, 1) +\n\t\t\t\t\t\t\t{$weight['subject']} +\n\t\t\t\t\t\t\t{$weight['sticky']} * t.isSticky\n\t\t\t\t\t\t) / {$weight_total} AS relevance,\n\t\t\t\t\t\tt.ID_FIRST_MSG,\n\t\t\t\t\t\t1\n\t\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}" . ($createTemporary ? 'tmp_' : '') . "log_search_topics AS lst)\n\t\t\t\t\tWHERE lst.ID_TOPIC = t.ID_TOPIC" . (empty($modSettings['search_max_results']) ? '' : "\n\t\t\t\t\tLIMIT " . ($modSettings['search_max_results'] - $_SESSION['search_cache']['num_results'])), __FILE__, __LINE__);
                $_SESSION['search_cache']['num_results'] += db_affected_rows();
            } elseif ($_SESSION['search_cache']['num_results'] == -1) {
                $_SESSION['search_cache']['num_results'] = 0;
            }
        }
    }
    // *** Retrieve the results to be shown on the page
    $participants = array();
    $request = db_query("\n\t\tSELECT " . (empty($search_params['topic']) ? 'lsr.ID_TOPIC' : $search_params['topic'] . ' AS ID_TOPIC') . ", lsr.ID_MSG, lsr.relevance, lsr.num_matches\n\t\tFROM ({$db_prefix}log_search_results AS lsr" . ($search_params['sort'] == 'numReplies' ? ", {$db_prefix}topics AS t" : '') . ")\n\t\tWHERE ID_SEARCH = " . $_SESSION['search_cache']['ID_SEARCH'] . ($search_params['sort'] == 'numReplies' ? "\n\t\t\tAND t.ID_TOPIC = lsr.ID_TOPIC" : '') . "\n\t\tORDER BY {$search_params['sort']} {$search_params['sort_dir']}\n\t\tLIMIT " . (int) $_REQUEST['start'] . ", {$modSettings['search_results_per_page']}", __FILE__, __LINE__);
    while ($row = mysql_fetch_assoc($request)) {
        $context['topics'][$row['ID_MSG']] = array('id' => $row['ID_TOPIC'], 'relevance' => round($row['relevance'] / 10, 1) . '%', 'num_matches' => $row['num_matches'], 'matches' => array());
        // By default they didn't participate in the topic!
        $participants[$row['ID_TOPIC']] = false;
    }
    mysql_free_result($request);
    // Now that we know how many results to expect we can start calculating the page numbers.
    $context['page_index'] = constructPageIndex($scripturl . '?action=search2;params=' . $context['params'], $_REQUEST['start'], $_SESSION['search_cache']['num_results'], $modSettings['search_results_per_page'], false);
    if (!empty($context['topics'])) {
        // Create an array for the permissions.
        $boards_can = array('post_reply_own' => boardsAllowedTo('post_reply_own'), 'post_reply_any' => boardsAllowedTo('post_reply_any'), 'mark_any_notify' => boardsAllowedTo('mark_any_notify'));
        // How's about some quick moderation?
        if (!empty($options['display_quick_mod']) && !empty($context['topics'])) {
            $boards_can['lock_any'] = boardsAllowedTo('lock_any');
            $boards_can['lock_own'] = boardsAllowedTo('lock_own');
            $boards_can['make_sticky'] = boardsAllowedTo('make_sticky');
            $boards_can['move_any'] = boardsAllowedTo('move_any');
            $boards_can['move_own'] = boardsAllowedTo('move_own');
            $boards_can['remove_any'] = boardsAllowedTo('remove_any');
            $boards_can['remove_own'] = boardsAllowedTo('remove_own');
            $boards_can['merge_any'] = boardsAllowedTo('merge_any');
            $context['can_lock'] = in_array(0, $boards_can['lock_any']);
            $context['can_sticky'] = in_array(0, $boards_can['make_sticky']) && !empty($modSettings['enableStickyTopics']);
            $context['can_move'] = in_array(0, $boards_can['move_any']);
            $context['can_remove'] = in_array(0, $boards_can['remove_any']);
            $context['can_merge'] = in_array(0, $boards_can['merge_any']);
        }
        // Load the posters...
        $request = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_MEMBER != 0\n\t\t\t\tAND ID_MSG IN (" . implode(', ', array_keys($context['topics'])) . ")\n\t\t\tLIMIT " . count($context['topics']), __FILE__, __LINE__);
        $posters = array();
        while ($row = mysql_fetch_assoc($request)) {
            $posters[] = $row['ID_MEMBER'];
        }
        mysql_free_result($request);
        if (!empty($posters)) {
            loadMemberData(array_unique($posters));
        }
        // Get the messages out for the callback - select enough that it can be made to look just like Display.
        $messages_request = db_query("\n\t\t\tSELECT\n\t\t\t\tm.ID_MSG, m.subject, m.posterName, m.posterEmail, m.posterTime, m.ID_MEMBER,\n\t\t\t\tm.icon, m.posterIP, m.body, m.smileysEnabled, m.modifiedTime, m.modifiedName,\n\t\t\t\tfirst_m.ID_MSG AS first_msg, first_m.subject AS first_subject, first_m.icon AS firstIcon, first_m.posterTime AS first_posterTime,\n\t\t\t\tfirst_mem.ID_MEMBER AS first_member_id, IFNULL(first_mem.realName, first_m.posterName) AS first_member_name,\n\t\t\t\tlast_m.ID_MSG AS last_msg, last_m.posterTime AS last_posterTime, last_mem.ID_MEMBER AS last_member_id,\n\t\t\t\tIFNULL(last_mem.realName, last_m.posterName) AS last_member_name, last_m.icon AS lastIcon, last_m.subject AS last_subject,\n\t\t\t\tt.ID_TOPIC, t.isSticky, t.locked, t.ID_POLL, t.numReplies, t.numViews,\n\t\t\t\tb.ID_BOARD, b.name AS bName, c.ID_CAT, c.name AS cName\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t, {$db_prefix}boards AS b, {$db_prefix}categories AS c, {$db_prefix}messages AS first_m, {$db_prefix}messages AS last_m)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS first_mem ON (first_mem.ID_MEMBER = first_m.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS last_mem ON (last_mem.ID_MEMBER = first_m.ID_MEMBER)\n\t\t\tWHERE m.ID_MSG IN (" . implode(', ', array_keys($context['topics'])) . ")\n\t\t\t\tAND t.ID_TOPIC = m.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND c.ID_CAT = b.ID_CAT\n\t\t\t\tAND first_m.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND last_m.ID_MSG = t.ID_LAST_MSG\n\t\t\tORDER BY FIND_IN_SET(m.ID_MSG, '" . implode(',', array_keys($context['topics'])) . "')\n\t\t\tLIMIT " . count($context['topics']), __FILE__, __LINE__);
        // Note that the reg-exp slows things alot, but makes things make a lot more sense.
        // If we want to know who participated in what then load this now.
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest']) {
            $result = db_query("\n\t\t\t\tSELECT ID_TOPIC\n\t\t\t\tFROM {$db_prefix}messages\n\t\t\t\tWHERE ID_TOPIC IN (" . implode(', ', array_keys($participants)) . ")\n\t\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tGROUP BY ID_TOPIC\n\t\t\t\tLIMIT " . count($participants), __FILE__, __LINE__);
            while ($row = mysql_fetch_assoc($result)) {
                $participants[$row['ID_TOPIC']] = true;
            }
            mysql_free_result($result);
        }
    }
    // Consider the search complete!
    if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 2) {
        cache_put_data('search_start:' . ($user_info['is_guest'] ? $user_info['ip'] : $ID_MEMBER), null, 90);
    }
    $context['key_words'] =& $searchArray;
    // Set the basic stuff for the template.
    $context['allow_hide_email'] = !empty($modSettings['allow_hideEmail']);
    // Setup the default topic icons... for checking they exist and the like!
    $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
    $context['icon_sources'] = array();
    foreach ($stable_icons as $icon) {
        $context['icon_sources'][$icon] = 'images_url';
    }
    $context['sub_template'] = 'results';
    $context['page_title'] = $txt[166];
    $context['get_topics'] = 'prepareSearchContext';
    $context['can_send_pm'] = allowedTo('pm_send');
    loadJumpTo();
    if (!empty($options['display_quick_mod']) && !empty($_SESSION['move_to_topic'])) {
        foreach ($context['jump_to'] as $id => $cat) {
            if (isset($context['jump_to'][$id]['boards'][$_SESSION['move_to_topic']])) {
                $context['jump_to'][$id]['boards'][$_SESSION['move_to_topic']]['selected'] = true;
            }
        }
    }
}
コード例 #23
0
ファイル: Recent.php プロジェクト: VBGAMER45/SMFMods
function RecentPosts()
{
    global $txt, $scripturl, $db_prefix, $user_info, $context, $ID_MEMBER, $modSettings, $sourcedir, $board;
    loadTemplate('Recent');
    $context['page_title'] = $txt[214];
    if (isset($_REQUEST['start']) && $_REQUEST['start'] > 95) {
        $_REQUEST['start'] = 95;
    }
    if (!empty($_REQUEST['c']) && empty($board)) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        if (count($_REQUEST['c']) == 1) {
            $request = db_query("\n\t\t\t\tSELECT name\n\t\t\t\tFROM {$db_prefix}categories\n\t\t\t\tWHERE ID_CAT = " . $_REQUEST['c'][0] . "\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            list($name) = mysql_fetch_row($request);
            mysql_free_result($request);
            if (empty($name)) {
                fatal_lang_error(1, false);
            }
            $context['linktree'][] = array('url' => $scripturl . '#' . (int) $_REQUEST['c'], 'name' => $name);
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD, b.numPosts\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE b.ID_CAT IN (" . implode(', ', $_REQUEST['c']) . ")\n\t\t\t\tAND {$user_info['query_see_board']}", __FILE__, __LINE__);
        $total_cat_posts = 0;
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
            $total_cat_posts += $row['numPosts'];
        }
        mysql_free_result($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected', false);
        }
        $query_this_board = 'b.ID_BOARD IN (' . implode(', ', $boards) . ')';
        // If this category has a significant number of posts in it...
        if ($total_cat_posts > 100 && $total_cat_posts > $modSettings['totalMessages'] / 15) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 400 - $_REQUEST['start'] * 7);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;c=' . implode(',', $_REQUEST['c']), $_REQUEST['start'], min(100, $total_cat_posts), 10, false);
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = db_query("\n\t\t\tSELECT b.ID_BOARD, b.numPosts\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE b.ID_BOARD IN (" . implode(', ', $_REQUEST['boards']) . ")\n\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\tLIMIT " . count($_REQUEST['boards']), __FILE__, __LINE__);
        $total_posts = 0;
        $boards = array();
        while ($row = mysql_fetch_assoc($request)) {
            $boards[] = $row['ID_BOARD'];
            $total_posts += $row['numPosts'];
        }
        mysql_free_result($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected', false);
        }
        $query_this_board = 'b.ID_BOARD IN (' . implode(', ', $boards) . ')';
        // If these boards have a significant number of posts in them...
        if ($total_posts > 100 && $total_posts > $modSettings['totalMessages'] / 12) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 500 - $_REQUEST['start'] * 9);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;boards=' . implode(',', $_REQUEST['boards']), $_REQUEST['start'], min(100, $total_posts), 10, false);
    } elseif (!empty($board)) {
        $request = db_query("\n\t\t\tSELECT numPosts\n\t\t\tFROM {$db_prefix}boards\n\t\t\tWHERE ID_BOARD = {$board}\n\t\t\tLIMIT 1", __FILE__, __LINE__);
        list($total_posts) = mysql_fetch_row($request);
        mysql_free_result($request);
        $query_this_board = 'b.ID_BOARD = ' . $board;
        // If this board has a significant number of posts in it...
        if ($total_posts > 80 && $total_posts > $modSettings['totalMessages'] / 10) {
            $query_this_board .= '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 600 - $_REQUEST['start'] * 10);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;board=' . $board . '.%d', $_REQUEST['start'], min(100, $total_posts), 10, true);
    } else {
        $query_this_board = $user_info['query_see_board'] . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "\n\t\t\tAND b.ID_BOARD != {$modSettings['recycle_board']}" : '') . '
			AND m.ID_MSG >= ' . max(0, $modSettings['maxMsgID'] - 100 - $_REQUEST['start'] * 6);
        // !!! This isn't accurate because we ignore the recycle bin.
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent', $_REQUEST['start'], min(100, $modSettings['totalMessages']), 10, false);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=recent' . (empty($board) ? empty($_REQUEST['c']) ? '' : ';c=' . (int) $_REQUEST['c'] : ';board=' . $board . '.0'), 'name' => $context['page_title']);
    // Find the 10 most recent messages they can *view*.
    // !!!SLOW This query is really slow still, probably?
    $request = db_query("\n\t\tSELECT m.ID_MSG\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b)\n\t\tWHERE b.ID_BOARD = m.ID_BOARD\n\t\t\tAND {$query_this_board}\n\t\tORDER BY m.ID_MSG DESC\n\t\tLIMIT {$_REQUEST['start']}, 10", __FILE__, __LINE__);
    $messages = array();
    while ($row = mysql_fetch_assoc($request)) {
        $messages[] = $row['ID_MSG'];
    }
    mysql_free_result($request);
    // Looks like nothin's happen here... or, at least, nothin' you can see...
    if (empty($messages)) {
        $context['posts'] = array();
        return;
    }
    // Get all the most recent posts.
    $request = db_query("\n\t\tSELECT\n\t\t\tm.ID_MSG, m.subject, m.smileysEnabled, m.posterTime, m.body, m.ID_TOPIC, t.ID_BOARD, b.ID_CAT,\n\t\t\tb.name AS bname, c.name AS cname, t.numReplies, m.ID_MEMBER, m2.ID_MEMBER AS ID_FIRST_MEMBER,\n\t\t\tIFNULL(mem2.realName, m2.posterName) AS firstPosterName, t.ID_FIRST_MSG,\n\t\t\tIFNULL(mem.realName, m.posterName) AS posterName, t.ID_LAST_MSG\n\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}messages AS m2, {$db_prefix}topics AS t, {$db_prefix}boards AS b, {$db_prefix}categories AS c)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)\n\t\t\tLEFT JOIN {$db_prefix}members AS mem2 ON (mem2.ID_MEMBER = m2.ID_MEMBER)\n\t\tWHERE m2.ID_MSG = t.ID_FIRST_MSG\n\t\t\tAND t.ID_TOPIC = m.ID_TOPIC\n\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\tAND c.ID_CAT = b.ID_CAT\n\t\t\tAND m.ID_MSG IN (" . implode(', ', $messages) . ")\n\t\tORDER BY m.ID_MSG DESC\n\t\tLIMIT " . count($messages), __FILE__, __LINE__);
    $counter = $_REQUEST['start'] + 1;
    $context['posts'] = array();
    $board_ids = array('own' => array(), 'any' => array());
    while ($row = mysql_fetch_assoc($request)) {
        // Censor everything.
        censorText($row['body']);
        censorText($row['subject']);
        // BBC-atize the message.
        $row['body'] = parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']);
        // And build the array.
        $context['posts'][$row['ID_MSG']] = array('id' => $row['ID_MSG'], 'counter' => $counter++, 'category' => array('id' => $row['ID_CAT'], 'name' => $row['cname'], 'href' => $scripturl . '#' . $row['ID_CAT'], 'link' => '<a href="' . $scripturl . '#' . $row['ID_CAT'] . '">' . $row['cname'] . '</a>'), 'board' => array('id' => $row['ID_BOARD'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bname'] . '</a>'), 'topic' => $row['ID_TOPIC'], 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'] . '">' . $row['subject'] . '</a>', 'start' => $row['numReplies'], 'subject' => $row['subject'], 'time' => timeformat($row['posterTime']), 'timestamp' => forum_time(true, $row['posterTime']), 'first_poster' => array('id' => $row['ID_FIRST_MEMBER'], 'name' => $row['firstPosterName'], 'href' => empty($row['ID_FIRST_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'], 'link' => empty($row['ID_FIRST_MEMBER']) ? $row['firstPosterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'] . '">' . $row['firstPosterName'] . '</a>'), 'poster' => array('id' => $row['ID_MEMBER'], 'name' => $row['posterName'], 'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>'), 'message' => $row['body'], 'can_reply' => false, 'can_mark_notify' => false, 'can_delete' => false, 'delete_possible' => ($row['ID_FIRST_MSG'] != $row['ID_MSG'] || $row['ID_LAST_MSG'] == $row['ID_MSG']) && (empty($modSettings['edit_disable_time']) || $row['posterTime'] + $modSettings['edit_disable_time'] * 60 >= time()));
        if ($ID_MEMBER == $row['ID_FIRST_MEMBER']) {
            $board_ids['own'][$row['ID_BOARD']][] = $row['ID_MSG'];
        }
        $board_ids['any'][$row['ID_BOARD']][] = $row['ID_MSG'];
    }
    mysql_free_result($request);
    // There might be - and are - different permissions between any and own.
    $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify', 'delete_any' => 'can_delete'));
    // Now go through all the permissions, looking for boards they can do it on.
    foreach ($permissions as $type => $list) {
        foreach ($list as $permission => $allowed) {
            // They can do it on these boards...
            $boards = boardsAllowedTo($permission);
            // If 0 is the only thing in the array, they can do it everywhere!
            if (!empty($boards) && $boards[0] == 0) {
                $boards = array_keys($board_ids[$type]);
            }
            // Go through the boards, and look for posts they can do this on.
            foreach ($boards as $board_id) {
                // Hmm, they have permission, but there are no topics from that board on this page.
                if (!isset($board_ids[$type][$board_id])) {
                    continue;
                }
                // Okay, looks like they can do it for these posts.
                foreach ($board_ids[$type][$board_id] as $counter) {
                    if ($type == 'any' || $context['posts'][$counter]['poster']['id'] == $ID_MEMBER) {
                        $context['posts'][$counter][$allowed] = true;
                    }
                }
            }
        }
    }
    // Some posts - the first posts - can't just be deleted.
    foreach ($context['posts'] as $counter => $dummy) {
        $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
    }
}
コード例 #24
0
ファイル: Poll.subs.php プロジェクト: KeiroD/Elkarte
/**
 * Get all poll information you wanted to know.
 * Only returns info on the poll, not its options.
 *
 * @param int $id_poll
 * @param bool $ignore_permissions if true permissions are not checked.
 *             If false, {query_see_board} boardsAllowedTo('poll_view') and
 *             $modSettings['postmod_active'] will be considered in the query.
 *             This param is currently used only in SSI, it may be useful in any
 *             kind of integration
 * @return array|false array of poll information, or false if no poll is found
 */
function pollInfo($id_poll, $ignore_permissions = true)
{
    global $modSettings;
    $db = database();
    $boardsAllowed = array();
    if ($ignore_permissions === false) {
        $boardsAllowed = boardsAllowedTo('poll_view');
        if (empty($boardsAllowed)) {
            return false;
        }
    }
    // Read info from the db
    $request = $db->query('', '
		SELECT
			p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote,
			p.guest_vote, p.id_member, IFNULL(mem.real_name, p.poster_name) AS poster_name,
			p.num_guest_voters, p.reset_poll' . ($ignore_permissions ? '' : ',
			b.id_board') . '
		FROM {db_prefix}polls AS p
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)' . ($ignore_permissions ? '' : '
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)') . '
		WHERE p.id_poll = {int:id_poll}' . ($ignore_permissions ? '' : (in_array(0, $boardsAllowed) ? '' : '
			AND b.id_board IN ({array_int:boards_allowed_see})') . (!$modSettings['postmod_active'] ? '' : '
			AND t.approved = {int:is_approved}')) . '
		LIMIT 1', array('id_poll' => $id_poll, 'boards_allowed_see' => $boardsAllowed, 'is_approved' => 1));
    $poll_info = $db->fetch_assoc($request);
    $db->free_result($request);
    if (empty($poll_info)) {
        return false;
    }
    $request = $db->query('', '
		SELECT COUNT(DISTINCT id_member) AS total
		FROM {db_prefix}log_polls
		WHERE id_poll = {int:id_poll}
			AND id_member != {int:not_guest}', array('id_poll' => $id_poll, 'not_guest' => 0));
    list($poll_info['total']) = $db->fetch_row($request);
    $db->free_result($request);
    // Total voters needs to include guest voters
    $poll_info['total'] += $poll_info['num_guest_voters'];
    return $poll_info;
}
コード例 #25
0
ファイル: MessageIndex.php プロジェクト: Glyph13/SMF2.1
/**
 * 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);
}
コード例 #26
0
ファイル: SplitTopics.php プロジェクト: Glyph13/SMF2.1
/**
 * 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);
}
コード例 #27
0
    /**
     * fetch_data.
     * Fetch Boards, Topics, Messages and Attaches.
     */
    function fetch_data()
    {
        global $context, $smcFunc, $modSettings, $settings, $boardurl, $scripturl, $txt;
        $boards = !empty($this->cfg['config']['settings']['board']) ? $this->cfg['config']['settings']['board'] : array();
        $this->cfg['config']['settings']['total'] = empty($this->cfg['config']['settings']['total']) ? 1 : $this->cfg['config']['settings']['total'];
        $this->posts = null;
        $this->attaches = null;
        $this->imgName = '';
        if (!empty($boards)) {
            // Load the message icons
            $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled');
            $icon_sources = array();
            foreach ($stable_icons as $icon) {
                $icon_sources[$icon] = 'images_url';
            }
            // find the n post from each board
            $this->cfg['config']['settings']['total'] = empty($this->cfg['config']['settings']['total']) ? 1 : $this->cfg['config']['settings']['total'];
            $msgids = array();
            $curboard = 0;
            $request = $smcFunc['db_query']('', '
				SELECT b.id_board, b.name, t.id_topic, t.num_replies, t.num_views, m.*
				FROM {db_prefix}topics as t
				LEFT JOIN {db_prefix}boards as b ON (t.id_board = b.id_board)
				LEFT JOIN {db_prefix}messages as m ON (t.id_first_msg = m.id_msg)
				WHERE b.id_board IN ({array_int:boards}) AND {query_wanna_see_board}
					' . ($modSettings['postmod_active'] ? ' AND m.approved = {int:approv}' : '') . '
					AND t.id_last_msg >= {int:min_msg}
				ORDER BY b.id_board ASC, t.id_topic DESC', array('boards' => $boards, 'min_msg' => $modSettings['maxMsgID'] - 100 * $this->cfg['config']['settings']['total'], 'approv' => 1));
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if ($row['id_board'] != $curboard) {
                    $curboard = $row['id_board'];
                    $max = $this->cfg['config']['settings']['total'];
                }
                if (!empty($max)) {
                    $msgids[$row['id_topic']] = $row['id_msg'];
                    $max--;
                    $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
                    // Check that this message icon is there...
                    if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']])) {
                        $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url';
                    }
                    censorText($row['subject']);
                    censorText($row['body']);
                    // Rescale inline Images ?
                    if (!empty($this->cfg['config']['settings']['rescale']) || empty($this->cfg['config']['settings']['rescale']) && !is_numeric($this->cfg['config']['settings']['rescale'])) {
                        // find all images
                        if (preg_match_all('~<img[^>]*>~iS', $row['body'], $matches) > 0) {
                            // remove smileys
                            foreach ($matches[0] as $i => $data) {
                                if (strpos($data, $modSettings['smileys_url']) !== false) {
                                    unset($matches[0][$i]);
                                }
                            }
                            // images found?
                            if (count($matches[0]) > 0) {
                                $this->imgName = $this->cfg['blocktype'] . '-' . $this->cfg['id'];
                                if (empty($this->cfg['config']['settings']['rescale'])) {
                                    $fnd = array('~ class?=?"[^"]*"~', '~ alt?=?"[^"]*"~', '~ title?=?"[^"]*"~');
                                } else {
                                    $fnd = array('~ width?=?"\\d+"~', '~ height?=?"\\d+"~', '~ class?=?"[^"]*"~', '~ alt?=?"[^"]*"~', '~ title?=?"[^"]*"~');
                                }
                                // modify the images for highslide
                                foreach ($matches[0] as $i => $data) {
                                    $datlen = strlen($data);
                                    preg_match('~src?=?"([^\\"]*\\")~i', $data, $src);
                                    $alt = substr(strrchr($src[1], '/'), 1);
                                    $alt = str_replace(array('_', '-'), ' ', strtoupper(substr($alt, 0, strrpos($alt, '.'))));
                                    $tmp = str_replace($src[0], ' class="' . $this->imgName . '" alt="' . $alt . '" ' . $src[0], preg_replace($fnd, '', $data));
                                    // highslide disabled?
                                    if (!empty($context['pmx']['settings']['disableHS']) || !empty($context['pmx']['settings']['disableHSonfront'])) {
                                        $row['body'] = substr_replace($row['body'], $tmp, strpos($row['body'], $data), $datlen);
                                    } elseif (empty($this->cfg['config']['settings']['disableHSimg']) && empty($context['pmx']['settings']['disableHSonfront'])) {
                                        $row['body'] = substr_replace($row['body'], '<a href="' . $boardurl . '" class="' . $this->imgName . ' highslide" title="' . $txt['pmx_hs_expand'] . '" onclick="return hs.expand(this, {src: \'' . str_replace('"', '', $src[1]) . '\', align: \'center\', headingEval: \'this.thumb.alt\'})">' . $tmp . '</a>', strpos($row['body'], $data), $datlen);
                                    } else {
                                        $row['body'] = substr_replace($row['body'], $tmp, strpos($row['body'], $data), $datlen);
                                    }
                                }
                            }
                        }
                    } elseif (is_numeric($this->cfg['config']['settings']['rescale'])) {
                        $row['body'] = PortaMx_revoveLinks($row['body'], false, true);
                    }
                    // teaser enabled ?
                    if (!empty($this->cfg['config']['settings']['teaser'])) {
                        $row['body'] = PortaMx_Tease_posts($row['body'], $this->cfg['config']['settings']['teaser'], '', false, false);
                    }
                    $this->posts[] = array('id_board' => $row['id_board'], 'board_name' => $row['name'], 'id' => $row['id_topic'], 'message_id' => $row['id_msg'], 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" alt="' . $row['icon'] . '" />', 'subject' => $row['subject'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'body' => $row['body'], 'replies' => $row['num_replies'], 'views' => $row['num_views'], 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '', 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name']), 'locked' => !empty($row['locked']));
                }
            }
            $smcFunc['db_free_result']($request);
            // any post found?
            if (!is_null($this->posts)) {
                // get attachments if show thumnails set
                $allow_boards = boardsAllowedTo('view_attachments');
                if (!empty($this->cfg['config']['settings']['thumbs']) && !empty($allow_boards)) {
                    $request = $smcFunc['db_query']('', '
						SELECT a.id_msg, a.id_attach, a.id_thumb, a.filename, m.id_topic
						FROM {db_prefix}attachments AS a
						LEFT JOIN {db_prefix}messages AS m ON (a.id_msg = m.id_msg)
						WHERE a.id_msg IN({array_int:messages}) AND a.mime_type LIKE {string:like}' . ($allow_boards === array(0) ? '' : (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' AND m.approved = 1 AND a.approved = 1') . ' AND m.id_board IN ({array_int:boards})') . '
						ORDER BY m.id_msg DESC, a.id_attach ASC', array('messages' => $msgids, 'like' => 'IMAGE%', 'boards' => $allow_boards));
                    $thumbs = array();
                    $msgcnt = array();
                    $saved = !empty($this->cfg['config']['settings']['thumbcnt']) ? $this->cfg['config']['settings']['thumbcnt'] : 0;
                    while ($row = $smcFunc['db_fetch_assoc']($request)) {
                        if (!in_array($row['id_attach'], $thumbs)) {
                            if (!empty($this->cfg['config']['settings']['thumbcnt'])) {
                                if (!in_array($row['id_msg'], $msgcnt)) {
                                    $saved = $this->cfg['config']['settings']['thumbcnt'];
                                } elseif (in_array($row['id_msg'], $msgcnt) && empty($saved)) {
                                    continue;
                                }
                            }
                            $saved--;
                            $msgcnt[] = $row['id_msg'];
                            $thumbs[] = $row['id_thumb'];
                            $this->attaches[$row['id_msg']][] = array('topic' => $row['id_topic'], 'image' => $row['id_attach'], 'thumb' => empty($row['id_thumb']) ? $row['id_attach'] : $row['id_thumb'], 'fname' => str_replace('_thumb', '', $row['filename']));
                        }
                    }
                    $smcFunc['db_free_result']($request);
                }
            }
        }
    }
コード例 #28
0
ファイル: RemoveTopic.php プロジェクト: Glyph13/SMF2.1
/**
 * Remove a specific message (including permission checks).
 * - normally, local and global should be the localCookies and globalCookies settings, respectively.
 * - uses boardurl to determine these two things.
 *
 * @param int $message The message id
 * @param bool $decreasePostCount if true users' post count will be reduced
 * @return array an array to set the cookie on with domain and path in it, in that order
 */
function removeMessage($message, $decreasePostCount = true)
{
    global $board, $sourcedir, $modSettings, $user_info, $smcFunc, $context;
    if (empty($message) || !is_numeric($message)) {
        return false;
    }
    $request = $smcFunc['db_query']('', '
		SELECT
			m.id_member, m.icon, m.poster_time, m.subject,' . (empty($modSettings['search_custom_index_config']) ? '' : ' m.body,') . '
			m.approved, t.id_topic, t.id_first_msg, t.id_last_msg, t.num_replies, t.id_board,
			t.id_member_started AS id_member_poster,
			b.count_posts
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
		WHERE m.id_msg = {int:id_msg}
		LIMIT 1', array('id_msg' => $message));
    if ($smcFunc['db_num_rows']($request) == 0) {
        return false;
    }
    $row = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    if (empty($board) || $row['id_board'] != $board) {
        $delete_any = boardsAllowedTo('delete_any');
        if (!in_array(0, $delete_any) && !in_array($row['id_board'], $delete_any)) {
            $delete_own = boardsAllowedTo('delete_own');
            $delete_own = in_array(0, $delete_own) || in_array($row['id_board'], $delete_own);
            $delete_replies = boardsAllowedTo('delete_replies');
            $delete_replies = in_array(0, $delete_replies) || in_array($row['id_board'], $delete_replies);
            if ($row['id_member'] == $user_info['id']) {
                if (!$delete_own) {
                    if ($row['id_member_poster'] == $user_info['id']) {
                        if (!$delete_replies) {
                            fatal_lang_error('cannot_delete_replies', 'permission');
                        }
                    } else {
                        fatal_lang_error('cannot_delete_own', 'permission');
                    }
                } elseif (($row['id_member_poster'] != $user_info['id'] || !$delete_replies) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) {
                    fatal_lang_error('modify_post_time_passed', false);
                }
            } elseif ($row['id_member_poster'] == $user_info['id']) {
                if (!$delete_replies) {
                    fatal_lang_error('cannot_delete_replies', 'permission');
                }
            } else {
                fatal_lang_error('cannot_delete_any', 'permission');
            }
        }
        // Can't delete an unapproved message, if you can't see it!
        if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !(in_array(0, $delete_any) || in_array($row['id_board'], $delete_any))) {
            $approve_posts = boardsAllowedTo('approve_posts');
            if (!in_array(0, $approve_posts) && !in_array($row['id_board'], $approve_posts)) {
                return false;
            }
        }
    } else {
        // Check permissions to delete this message.
        if ($row['id_member'] == $user_info['id']) {
            if (!allowedTo('delete_own')) {
                if ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) {
                    isAllowedTo('delete_replies');
                } elseif (!allowedTo('delete_any')) {
                    isAllowedTo('delete_own');
                }
            } elseif (!allowedTo('delete_any') && ($row['id_member_poster'] != $user_info['id'] || !allowedTo('delete_replies')) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + $modSettings['edit_disable_time'] * 60 < time()) {
                fatal_lang_error('modify_post_time_passed', false);
            }
        } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('delete_any')) {
            isAllowedTo('delete_replies');
        } else {
            isAllowedTo('delete_any');
        }
        if ($modSettings['postmod_active'] && !$row['approved'] && $row['id_member'] != $user_info['id'] && !allowedTo('delete_own')) {
            isAllowedTo('approve_posts');
        }
    }
    // Close any moderation reports for this message.
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}log_reported
		SET closed = {int:is_closed}
		WHERE id_msg = {int:id_msg}', array('is_closed' => 1, 'id_msg' => $message));
    if ($smcFunc['db_affected_rows']() != 0) {
        require_once $sourcedir . '/ModerationCenter.php';
        updateSettings(array('last_mod_report_action' => time()));
        recountOpenReports();
    }
    // Delete the *whole* topic, but only if the topic consists of one message.
    if ($row['id_first_msg'] == $message) {
        if (empty($board) || $row['id_board'] != $board) {
            $remove_any = boardsAllowedTo('remove_any');
            $remove_any = in_array(0, $remove_any) || in_array($row['id_board'], $remove_any);
            if (!$remove_any) {
                $remove_own = boardsAllowedTo('remove_own');
                $remove_own = in_array(0, $remove_own) || in_array($row['id_board'], $remove_own);
            }
            if ($row['id_member'] != $user_info['id'] && !$remove_any) {
                fatal_lang_error('cannot_remove_any', 'permission');
            } elseif (!$remove_any && !$remove_own) {
                fatal_lang_error('cannot_remove_own', 'permission');
            }
        } else {
            // Check permissions to delete a whole topic.
            if ($row['id_member'] != $user_info['id']) {
                isAllowedTo('remove_any');
            } elseif (!allowedTo('remove_any')) {
                isAllowedTo('remove_own');
            }
        }
        // ...if there is only one post.
        if (!empty($row['num_replies'])) {
            fatal_lang_error('delFirstPost', false);
        }
        removeTopics($row['id_topic']);
        return true;
    }
    // Deleting a recycled message can not lower anyone's post count.
    if ($row['icon'] == 'recycled') {
        $decreasePostCount = false;
    }
    // This is the last post, update the last post on the board.
    if ($row['id_last_msg'] == $message) {
        // Find the last message, set it, and decrease the post count.
        $request = $smcFunc['db_query']('', '
			SELECT id_msg, id_member
			FROM {db_prefix}messages
			WHERE id_topic = {int:id_topic}
				AND id_msg != {int:id_msg}
			ORDER BY ' . ($modSettings['postmod_active'] ? 'approved DESC, ' : '') . 'id_msg DESC
			LIMIT 1', array('id_topic' => $row['id_topic'], 'id_msg' => $message));
        $row2 = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET
				id_last_msg = {int:id_last_msg},
				id_member_updated = {int:id_member_updated}' . (!$modSettings['postmod_active'] || $row['approved'] ? ',
				num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : ',
				unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
			WHERE id_topic = {int:id_topic}', array('id_last_msg' => $row2['id_msg'], 'id_member_updated' => $row2['id_member'], 'no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic']));
    } else {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET ' . ($row['approved'] ? '
				num_replies = CASE WHEN num_replies = {int:no_replies} THEN 0 ELSE num_replies - 1 END' : '
				unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
			WHERE id_topic = {int:id_topic}', array('no_replies' => 0, 'no_unapproved' => 0, 'id_topic' => $row['id_topic']));
    }
    // Default recycle to false.
    $recycle = false;
    // If recycle topics has been set, make a copy of this message in the recycle board.
    // Make sure we're not recycling messages that are already on the recycle board.
    if (!empty($modSettings['recycle_enable']) && $row['id_board'] != $modSettings['recycle_board'] && $row['icon'] != 'recycled') {
        // Check if the recycle board exists and if so get the read status.
        $request = $smcFunc['db_query']('', '
			SELECT (IFNULL(lb.id_msg, 0) >= b.id_msg_updated) AS is_seen, id_last_msg
			FROM {db_prefix}boards AS b
				LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})
			WHERE b.id_board = {int:recycle_board}', array('current_member' => $user_info['id'], 'recycle_board' => $modSettings['recycle_board']));
        if ($smcFunc['db_num_rows']($request) == 0) {
            fatal_lang_error('recycle_no_valid_board');
        }
        list($isRead, $last_board_msg) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Is there an existing topic in the recycle board to group this post with?
        $request = $smcFunc['db_query']('', '
			SELECT id_topic, id_first_msg, id_last_msg
			FROM {db_prefix}topics
			WHERE id_previous_topic = {int:id_previous_topic}
				AND id_board = {int:recycle_board}', array('id_previous_topic' => $row['id_topic'], 'recycle_board' => $modSettings['recycle_board']));
        list($id_recycle_topic, $first_topic_msg, $last_topic_msg) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Insert a new topic in the recycle board if $id_recycle_topic is empty.
        if (empty($id_recycle_topic)) {
            $smcFunc['db_insert']('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'id_previous_topic' => 'int'), array($modSettings['recycle_board'], $row['id_member'], $row['id_member'], $message, $message, 0, 1, $row['id_topic']), array('id_topic'));
        }
        // Capture the ID of the new topic...
        $topicID = empty($id_recycle_topic) ? $smcFunc['db_insert_id']('{db_prefix}topics', 'id_topic') : $id_recycle_topic;
        // If the topic creation went successful, move the message.
        if ($topicID > 0) {
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}messages
				SET
					id_topic = {int:id_topic},
					id_board = {int:recycle_board},
					icon = {string:recycled},
					approved = {int:is_approved}
				WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message, 'recycled' => 'recycled', 'is_approved' => 1));
            // Take any reported posts with us...
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}log_reported
				SET
					id_topic = {int:id_topic},
					id_board = {int:recycle_board}
				WHERE id_msg = {int:id_msg}', array('id_topic' => $topicID, 'recycle_board' => $modSettings['recycle_board'], 'id_msg' => $message));
            // Mark recycled topic as read.
            if (!$user_info['is_guest']) {
                $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($topicID, $user_info['id'], $modSettings['maxMsgID']), array('id_topic', 'id_member'));
            }
            // Mark recycle board as seen, if it was marked as seen before.
            if (!empty($isRead) && !$user_info['is_guest']) {
                $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_board' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($modSettings['recycle_board'], $user_info['id'], $modSettings['maxMsgID']), array('id_board', 'id_member'));
            }
            // Add one topic and post to the recycle bin board.
            $smcFunc['db_query']('', '
				UPDATE {db_prefix}boards
				SET
					num_topics = num_topics + {int:num_topics_inc},
					num_posts = num_posts + 1' . ($message > $last_board_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . '
				WHERE id_board = {int:recycle_board}', array('num_topics_inc' => empty($id_recycle_topic) ? 1 : 0, 'recycle_board' => $modSettings['recycle_board'], 'id_merged_msg' => $message));
            // Lets increase the num_replies, and the first/last message ID as appropriate.
            if (!empty($id_recycle_topic)) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}topics
					SET num_replies = num_replies + 1' . ($message > $last_topic_msg ? ', id_last_msg = {int:id_merged_msg}' : '') . ($message < $first_topic_msg ? ', id_first_msg = {int:id_merged_msg}' : '') . '
					WHERE id_topic = {int:id_recycle_topic}', array('id_recycle_topic' => $id_recycle_topic, 'id_merged_msg' => $message));
            }
            // Make sure this message isn't getting deleted later on.
            $recycle = true;
            // Make sure we update the search subject index.
            updateStats('subject', $topicID, $row['subject']);
        }
        // If it wasn't approved don't keep it in the queue.
        if (!$row['approved']) {
            $smcFunc['db_query']('', '
				DELETE FROM {db_prefix}approval_queue
				WHERE id_msg = {int:id_msg}
					AND id_attach = {int:id_attach}', array('id_msg' => $message, 'id_attach' => 0));
        }
    }
    $smcFunc['db_query']('', '
		UPDATE {db_prefix}boards
		SET ' . ($row['approved'] ? '
			num_posts = CASE WHEN num_posts = {int:no_posts} THEN 0 ELSE num_posts - 1 END' : '
			unapproved_posts = CASE WHEN unapproved_posts = {int:no_unapproved} THEN 0 ELSE unapproved_posts - 1 END') . '
		WHERE id_board = {int:id_board}', array('no_posts' => 0, 'no_unapproved' => 0, 'id_board' => $row['id_board']));
    // If the poster was registered and the board this message was on incremented
    // the member's posts when it was posted, decrease his or her post count.
    if (!empty($row['id_member']) && $decreasePostCount && empty($row['count_posts']) && $row['approved']) {
        updateMemberData($row['id_member'], array('posts' => '-'));
    }
    // Only remove posts if they're not recycled.
    if (!$recycle) {
        // Remove the message!
        $smcFunc['db_query']('', '
			DELETE FROM {db_prefix}messages
			WHERE id_msg = {int:id_msg}', array('id_msg' => $message));
        if (!empty($modSettings['search_custom_index_config'])) {
            $customIndexSettings = unserialize($modSettings['search_custom_index_config']);
            $words = text2words($row['body'], $customIndexSettings['bytes_per_word'], true);
            if (!empty($words)) {
                $smcFunc['db_query']('', '
					DELETE FROM {db_prefix}log_search_words
					WHERE id_word IN ({array_int:word_list})
						AND id_msg = {int:id_msg}', array('word_list' => $words, 'id_msg' => $message));
            }
        }
        // Delete attachment(s) if they exist.
        require_once $sourcedir . '/ManageAttachments.php';
        $attachmentQuery = array('attachment_type' => 0, 'id_msg' => $message);
        removeAttachments($attachmentQuery);
        // Allow mods to remove message related data of their own (likes, maybe?)
        call_integration_hook('integrate_remove_message', array($message));
    }
    // Update the pesky statistics.
    updateStats('message');
    updateStats('topic');
    updateSettings(array('calendar_updated' => time()));
    // And now to update the last message of each board we messed with.
    require_once $sourcedir . '/Subs-Post.php';
    if ($recycle) {
        updateLastMessages(array($row['id_board'], $modSettings['recycle_board']));
    } else {
        updateLastMessages($row['id_board']);
    }
    return false;
}
コード例 #29
0
ファイル: Calendar.php プロジェクト: VBGAMER45/SMFMods
function CalendarPost()
{
    global $context, $txt, $db_prefix, $user_info, $sourcedir, $scripturl;
    global $modSettings, $topic, $ID_MEMBER, $func;
    // Well - can they?
    isAllowedTo('calendar_post');
    // Cast this for safety...
    if (isset($_REQUEST['eventid'])) {
        $_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
    }
    // Submitting?
    if (isset($_POST['sc'], $_REQUEST['eventid'])) {
        checkSession();
        // Validate the post...
        if (!isset($_POST['link_to_board'])) {
            require_once $sourcedir . '/Subs-Post.php';
            calendarValidatePost();
        }
        // If you're not allowed to edit any events, you have to be the poster.
        if ($_REQUEST['eventid'] > 0 && !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']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__);
            list($poster) = mysql_fetch_row($request);
            mysql_free_result($request);
            // Finally, test if they can either edit ANY, or just their own...
            if (!allowedTo('calendar_edit_any')) {
                isAllowedTo('calendar_edit_' . ($poster == $ID_MEMBER ? 'own' : 'any'));
            }
        }
        // New - and directing?
        if ($_REQUEST['eventid'] == -1 && isset($_POST['link_to_board'])) {
            $_REQUEST['calendar'] = 1;
            require_once $sourcedir . '/Post.php';
            return Post();
        } elseif ($_REQUEST['eventid'] == -1) {
            calendarInsertEvent(0, 0, $_POST['evtitle'], $ID_MEMBER, $_POST['month'], $_POST['day'], $_POST['year'], isset($_POST['span']) ? $_POST['span'] : null);
        } elseif (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 {
            // Calculate the eventDate depending on span.
            $span = empty($modSettings['cal_allowspan']) || empty($_POST['span']) || $_POST['span'] == 1 || empty($modSettings['cal_maxspan']) || $_POST['span'] > $modSettings['cal_maxspan'] ? 0 : min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1);
            $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 \n\t\t\t\t\tstartDate = '" . strftime('%Y-%m-%d', $start_time) . "',\n\t\t\t\t\tendDate = '" . strftime('%Y-%m-%d', $start_time + $span * 86400) . "', \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');
        // No point hanging around here now...
        redirectexit($scripturl . '?action=calendar;month=' . $_POST['month'] . ';year=' . $_POST['year']);
    }
    // If we are not enabled... we are not enabled.
    if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid'])) {
        $_REQUEST['calendar'] = 1;
        require_once $sourcedir . '/Post.php';
        return Post();
    }
    // New?
    if (!isset($_REQUEST['eventid'])) {
        $today = getdate();
        $context['event'] = array('boards' => array(), 'board' => !empty($modSettings['cal_defaultboard']) ? $modSettings['cal_defaultboard'] : 0, 'new' => 1, 'eventid' => -1, 'year' => isset($_REQUEST['year']) ? $_REQUEST['year'] : $today['year'], 'month' => isset($_REQUEST['month']) ? $_REQUEST['month'] : $today['mon'], 'day' => isset($_REQUEST['day']) ? $_REQUEST['day'] : $today['mday'], 'title' => '', 'span' => 1);
        // Get list of boards that can be posted in.
        $boards = boardsAllowedTo('post_new');
        if (empty($boards)) {
            fatal_lang_error('cannot_post_new');
        }
        $request = db_query("\n\t\t\tSELECT c.name AS catName, c.ID_CAT, b.ID_BOARD, b.name AS boardName, b.childLevel\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\tWHERE {$user_info['query_see_board']}" . (in_array(0, $boards) ? '' : "\n\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $boards) . ")"), __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            $context['event']['boards'][] = array('id' => $row['ID_BOARD'], 'name' => $row['boardName'], 'childLevel' => $row['childLevel'], 'prefix' => str_repeat('&nbsp;', $row['childLevel'] * 3), 'cat' => array('id' => $row['ID_CAT'], 'name' => $row['catName']));
        }
        mysql_free_result($request);
    } else {
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tc.ID_EVENT, c.ID_BOARD, c.ID_TOPIC, MONTH(c.startDate) AS month,\n\t\t\t\tDAYOFMONTH(c.startDate) AS day, YEAR(c.startDate) AS year,\n\t\t\t\t(TO_DAYS(c.endDate) - TO_DAYS(c.startDate)) AS span, c.ID_MEMBER, c.title,\n\t\t\t\tt.ID_FIRST_MSG, t.ID_MEMBER_STARTED\n\t\t\tFROM {$db_prefix}calendar AS c\n\t\t\t\tLEFT JOIN {$db_prefix}topics AS t ON (t.ID_TOPIC = c.ID_TOPIC)\n\t\t\tWHERE c.ID_EVENT = {$_REQUEST['eventid']}", __FILE__, __LINE__);
        // If nothing returned, we are in poo, poo.
        if (mysql_num_rows($request) == 0) {
            fatal_lang_error(1);
        }
        $row = mysql_fetch_assoc($request);
        mysql_free_result($request);
        // If it has a board, then they should be editing it within the topic.
        if ($row['ID_TOPIC'] && $row['ID_FIRST_MSG']) {
            // We load the board up, for a check on the board access rights...
            $topic = $row['ID_TOPIC'];
            loadBoard();
        }
        // Make sure the user is allowed to edit this event.
        if ($row['ID_MEMBER'] != $ID_MEMBER) {
            isAllowedTo('calendar_edit_any');
        } elseif (!allowedTo('calendar_edit_any')) {
            isAllowedTo('calendar_edit_own');
        }
        $context['event'] = array('boards' => array(), 'board' => $row['ID_BOARD'], 'new' => 0, 'eventid' => $_REQUEST['eventid'], 'year' => $row['year'], 'month' => $row['month'], 'day' => $row['day'], 'title' => $row['title'], 'span' => 1 + $row['span']);
    }
    $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
    // Template, sub template, etc.
    loadTemplate('Calendar');
    $context['sub_template'] = 'event_post';
    $context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar20'] : $txt['calendar23'];
    $context['linktree'][] = array('name' => $context['page_title']);
}
コード例 #30
0
function RecentPosts()
{
    global $txt, $scripturl, $user_info, $context, $modSettings, $sourcedir, $board, $smcFunc;
    loadTemplate('Recent');
    $context['page_title'] = $txt['recent_posts'];
    if (isset($_REQUEST['start']) && $_REQUEST['start'] > 95) {
        $_REQUEST['start'] = 95;
    }
    $query_parameters = array();
    if (!empty($_REQUEST['c']) && empty($board)) {
        $_REQUEST['c'] = explode(',', $_REQUEST['c']);
        foreach ($_REQUEST['c'] as $i => $c) {
            $_REQUEST['c'][$i] = (int) $c;
        }
        if (count($_REQUEST['c']) == 1) {
            $request = $smcFunc['db_query']('', '
				SELECT name
				FROM {db_prefix}categories
				WHERE id_cat = {int:id_cat}
				LIMIT 1', array('id_cat' => $_REQUEST['c'][0]));
            list($name) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            if (empty($name)) {
                fatal_lang_error('no_access', false);
            }
            $context['linktree'][] = array('url' => $scripturl . '#c' . (int) $_REQUEST['c'], 'name' => $name);
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board, b.num_posts
			FROM {db_prefix}boards AS b
			WHERE b.id_cat IN ({array_int:category_list})
				AND {query_see_board}', array('category_list' => $_REQUEST['c']));
        $total_cat_posts = 0;
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
            $total_cat_posts += $row['num_posts'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'b.id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        // If this category has a significant number of posts in it...
        if ($total_cat_posts > 100 && $total_cat_posts > $modSettings['totalMessages'] / 15) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 400 - $_REQUEST['start'] * 7);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;c=' . implode(',', $_REQUEST['c']), $_REQUEST['start'], min(100, $total_cat_posts), 10, false);
    } elseif (!empty($_REQUEST['boards'])) {
        $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
        foreach ($_REQUEST['boards'] as $i => $b) {
            $_REQUEST['boards'][$i] = (int) $b;
        }
        $request = $smcFunc['db_query']('', '
			SELECT b.id_board, b.num_posts
			FROM {db_prefix}boards AS b
			WHERE b.id_board IN ({array_int:board_list})
				AND {query_see_board}
			LIMIT {int:limit}', array('board_list' => $_REQUEST['boards'], 'limit' => count($_REQUEST['boards'])));
        $total_posts = 0;
        $boards = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $boards[] = $row['id_board'];
            $total_posts += $row['num_posts'];
        }
        $smcFunc['db_free_result']($request);
        if (empty($boards)) {
            fatal_lang_error('error_no_boards_selected');
        }
        $query_this_board = 'b.id_board IN ({array_int:boards})';
        $query_parameters['boards'] = $boards;
        // If these boards have a significant number of posts in them...
        if ($total_posts > 100 && $total_posts > $modSettings['totalMessages'] / 12) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 500 - $_REQUEST['start'] * 9);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;boards=' . implode(',', $_REQUEST['boards']), $_REQUEST['start'], min(100, $total_posts), 10, false);
    } elseif (!empty($board)) {
        $request = $smcFunc['db_query']('', '
			SELECT num_posts
			FROM {db_prefix}boards
			WHERE id_board = {int:current_board}
			LIMIT 1', array('current_board' => $board));
        list($total_posts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $query_this_board = 'b.id_board = {int:board}';
        $query_parameters['board'] = $board;
        // If this board has a significant number of posts in it...
        if ($total_posts > 80 && $total_posts > $modSettings['totalMessages'] / 10) {
            $query_this_board .= '
					AND m.id_msg >= {int:max_id_msg}';
            $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 600 - $_REQUEST['start'] * 10);
        }
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent;board=' . $board . '.%1$d', $_REQUEST['start'], min(100, $total_posts), 10, true);
    } else {
        $query_this_board = '{query_wanna_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? '
					AND b.id_board != {int:recycle_board}' : '') . '
					AND m.id_msg >= {int:max_id_msg}';
        $query_parameters['max_id_msg'] = max(0, $modSettings['maxMsgID'] - 100 - $_REQUEST['start'] * 6);
        $query_parameters['recycle_board'] = $modSettings['recycle_board'];
        // !!! This isn't accurate because we ignore the recycle bin.
        $context['page_index'] = constructPageIndex($scripturl . '?action=recent', $_REQUEST['start'], min(100, $modSettings['totalMessages']), 10, false);
    }
    $context['linktree'][] = array('url' => $scripturl . '?action=recent' . (empty($board) ? empty($_REQUEST['c']) ? '' : ';c=' . (int) $_REQUEST['c'] : ';board=' . $board . '.0'), 'name' => $context['page_title']);
    $key = 'recent-' . $user_info['id'] . '-' . md5(serialize(array_diff_key($query_parameters, array('max_id_msg' => 0)))) . '-' . (int) $_REQUEST['start'];
    if (empty($modSettings['cache_enable']) || ($messages = cache_get_data($key, 120)) == null) {
        $done = false;
        while (!$done) {
            // Find the 10 most recent messages they can *view*.
            // !!!SLOW This query is really slow still, probably?
            $request = $smcFunc['db_query']('', '
				SELECT m.id_msg
				FROM {db_prefix}messages AS m
					INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
				WHERE ' . $query_this_board . '
					AND m.approved = {int:is_approved}
				ORDER BY m.id_msg DESC
				LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('is_approved' => 1, 'offset' => $_REQUEST['start'], 'limit' => 10)));
            // If we don't have 10 results, try again with an unoptimized version covering all rows, and cache the result.
            if (isset($query_parameters['max_id_msg']) && $smcFunc['db_num_rows']($request) < 10) {
                $smcFunc['db_free_result']($request);
                $query_this_board = str_replace('AND m.id_msg >= {int:max_id_msg}', '', $query_this_board);
                $cache_results = true;
                unset($query_parameters['max_id_msg']);
            } else {
                $done = true;
            }
        }
        $messages = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $messages[] = $row['id_msg'];
        }
        $smcFunc['db_free_result']($request);
        if (!empty($cache_results)) {
            cache_put_data($key, $messages, 120);
        }
    }
    // Nothing here... Or at least, nothing you can see...
    if (empty($messages)) {
        $context['posts'] = array();
        return;
    }
    // Get all the most recent posts.
    $request = $smcFunc['db_query']('', '
		SELECT
			m.id_msg, m.subject, m.smileys_enabled, m.poster_time, m.body, m.id_topic, t.id_board, b.id_cat,
			b.name AS bname, c.name AS cname, t.num_replies, m.id_member, m2.id_member AS id_first_member,
			IFNULL(mem2.real_name, m2.poster_name) AS first_poster_name, t.id_first_msg,
			IFNULL(mem.real_name, m.poster_name) AS poster_name, t.id_last_msg
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
			INNER JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
			INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_first_msg)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
			LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member)
		WHERE m.id_msg IN ({array_int:message_list})
		ORDER BY m.id_msg DESC
		LIMIT ' . count($messages), array('message_list' => $messages));
    $counter = $_REQUEST['start'] + 1;
    $context['posts'] = array();
    $board_ids = array('own' => array(), 'any' => array());
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // Censor everything.
        censorText($row['body']);
        censorText($row['subject']);
        // BBC-atize the message.
        $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']);
        // And build the array.
        $context['posts'][$row['id_msg']] = array('id' => $row['id_msg'], 'counter' => $counter++, 'alternate' => $counter % 2, 'category' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'href' => $scripturl . '#c' . $row['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $row['id_cat'] . '">' . $row['cname'] . '</a>'), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['bname'] . '</a>'), 'topic' => $row['id_topic'], 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'] . '" rel="nofollow">' . $row['subject'] . '</a>', 'start' => $row['num_replies'], 'subject' => $row['subject'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'first_poster' => array('id' => $row['id_first_member'], 'name' => $row['first_poster_name'], 'href' => empty($row['id_first_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_first_member'], 'link' => empty($row['id_first_member']) ? $row['first_poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_first_member'] . '">' . $row['first_poster_name'] . '</a>'), 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => empty($row['id_member']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>'), 'message' => $row['body'], 'can_reply' => false, 'can_mark_notify' => false, 'can_delete' => false, 'delete_possible' => ($row['id_first_msg'] != $row['id_msg'] || $row['id_last_msg'] == $row['id_msg']) && (empty($modSettings['edit_disable_time']) || $row['poster_time'] + $modSettings['edit_disable_time'] * 60 >= time()));
        if ($user_info['id'] == $row['id_first_member']) {
            $board_ids['own'][$row['id_board']][] = $row['id_msg'];
        }
        $board_ids['any'][$row['id_board']][] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    // There might be - and are - different permissions between any and own.
    $permissions = array('own' => array('post_reply_own' => 'can_reply', 'delete_own' => 'can_delete'), 'any' => array('post_reply_any' => 'can_reply', 'mark_any_notify' => 'can_mark_notify', 'delete_any' => 'can_delete'));
    // Now go through all the permissions, looking for boards they can do it on.
    foreach ($permissions as $type => $list) {
        foreach ($list as $permission => $allowed) {
            // They can do it on these boards...
            $boards = boardsAllowedTo($permission);
            // If 0 is the only thing in the array, they can do it everywhere!
            if (!empty($boards) && $boards[0] == 0) {
                $boards = array_keys($board_ids[$type]);
            }
            // Go through the boards, and look for posts they can do this on.
            foreach ($boards as $board_id) {
                // Hmm, they have permission, but there are no topics from that board on this page.
                if (!isset($board_ids[$type][$board_id])) {
                    continue;
                }
                // Okay, looks like they can do it for these posts.
                foreach ($board_ids[$type][$board_id] as $counter) {
                    if ($type == 'any' || $context['posts'][$counter]['poster']['id'] == $user_info['id']) {
                        $context['posts'][$counter][$allowed] = true;
                    }
                }
            }
        }
    }
    $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC']));
    foreach ($context['posts'] as $counter => $dummy) {
        // Some posts - the first posts - can't just be deleted.
        $context['posts'][$counter]['can_delete'] &= $context['posts'][$counter]['delete_possible'];
        // And some cannot be quoted...
        $context['posts'][$counter]['can_quote'] = $context['posts'][$counter]['can_reply'] && $quote_enabled;
    }
}