Пример #1
0
/**
 * Find the ID of the "current" member
 *
 * @param boolean $fatal if the function ends in a fatal error in case of problems (default true)
 * @param boolean $reload_id if true the already set value is ignored (default false)
 *
 * @return mixed and integer if no error, false in case of problems if $fatal is false
 */
function currentMemberID($fatal = true, $reload_id = false)
{
    global $user_info;
    static $memID;
    // If we already know who we're dealing with
    if (isset($memID) && !$reload_id) {
        return $memID;
    }
    // Did we get the user by name...
    if (isset($_REQUEST['user'])) {
        $memberResult = loadMemberData($_REQUEST['user'], true, 'profile');
    } elseif (!empty($_REQUEST['u'])) {
        $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile');
    } else {
        $memberResult = loadMemberData($user_info['id'], false, 'profile');
    }
    // Check if loadMemberData() has returned a valid result.
    if (!is_array($memberResult)) {
        // Members only...
        is_not_guest('', $fatal);
        if ($fatal) {
            fatal_lang_error('not_a_user', false);
        } else {
            return false;
        }
    }
    // If all went well, we have a valid member ID!
    list($memID) = $memberResult;
    return $memID;
}
function teknoromisidebarsag()
{
    global $boarddir, $modSettings, $txt, $context;
    require_once $boarddir . '/SSI.php';
    echo '</td></tr></tbody></table>';
    if (!empty($modSettings['sideright']) && empty($context['current_action'])) {
        echo '<td valign="top" id="upshrinkRightBarTD">
				<div id="upshrinkRightBar" style="width:', $modSettings['siderightwidth'] ? $modSettings['siderightwidth'] : '200px', '; margin-right:4px; overflow:auto;">';
        if (!empty($modSettings['sideright1'])) {
            echo '<div class="cat_bar"><h3 class="catbg">' . $modSettings['righthtmlbaslik'] . '</h3></div>';
            echo '' . $modSettings['sideright1'] . '';
        }
        if (!empty($modSettings['siderightphp'])) {
            echo '<div class="cat_bar"><h3 class="catbg">' . $modSettings['rightphpbaslik'] . '</h3></div>';
            eval($modSettings['siderightphp']);
        }
        if (!empty($modSettings['siderighthaberetkin'])) {
            $array = ssi_boardNews($modSettings['siderighthaber'], $modSettings['siderightsay'], null, 1000, 'array');
            echo '<div class="cat_bar">
							<h3 class="catbg">', $modSettings['rbaslik'], '</h3>
						</div>';
            global $memberContext;
            foreach ($array as $news) {
                loadMemberData($news['poster']['id']);
                loadMemberContext($news['poster']['id']);
                echo '<div class="sidehaber">
								<div class="sideBaslik">
								', $news['icon'], '
								<h3><a href="', $news['href'], '">', $news['subject'], '</a></h3>
								</div>
								<div class="snrj"> ', $memberContext[$news['poster']['id']]['avatar']['image'], ' 
								<p>', $txt['by'], '', $news['poster']['link'], '</p>
								</div>
								</div><hr/>';
            }
        }
        echo '</div>
			</td>
			<td valign="top">
			<button type="button" onclick="rightPanel.toggle();" id="teknoright"></button>
			</td>';
    }
    echo '
		</tr></tbody></table>';
}
Пример #3
0
/**
 * @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
/**
 * Allows to edit Personal Message Settings.
 *
 * @uses Profile.php
 * @uses Profile-Modify.php
 * @uses Profile template.
 * @uses Profile language file.
 */
function MessageSettings()
{
    global $txt, $user_settings, $user_info, $context, $sourcedir, $smcFunc;
    global $scripturl, $profile_vars, $cur_profile, $user_profile;
    // Need this for the display.
    require_once $sourcedir . '/Profile.php';
    require_once $sourcedir . '/Profile-Modify.php';
    // We want them to submit back to here.
    $context['profile_custom_submit_url'] = $scripturl . '?action=pm;sa=settings;save';
    loadMemberData($user_info['id'], false, 'profile');
    $cur_profile = $user_profile[$user_info['id']];
    loadLanguage('Profile');
    loadTemplate('Profile');
    $context['page_title'] = $txt['pm_settings'];
    $context['user']['is_owner'] = true;
    $context['id_member'] = $user_info['id'];
    $context['require_password'] = false;
    $context['menu_item_selected'] = 'settings';
    $context['submit_button_text'] = $txt['pm_settings'];
    $context['profile_header_text'] = $txt['personal_messages'];
    // Add our position to the linktree.
    $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=settings', 'name' => $txt['pm_settings']);
    // Are they saving?
    if (isset($_REQUEST['save'])) {
        checkSession('post');
        // Mimic what profile would do.
        $_POST = htmltrim__recursive($_POST);
        $_POST = htmlspecialchars__recursive($_POST);
        // Save the fields.
        saveProfileFields();
        if (!empty($profile_vars)) {
            updateMemberData($user_info['id'], $profile_vars);
        }
    }
    // Load up the fields.
    pmprefs($user_info['id']);
}
Пример #5
0
function template_main()
{
    global $scripturl, $context, $txt, $settings, $modSettings, $user_profile, $memberContext;
    // Check if the user is an Admin
    $manage_staff = allowedTo('admin_forum');
    $bbc_check = function_exists('parse_bbc');
    echo '<div class="tborder">';
    echo '<br />';
    $totalcols = 1;
    if ($modSettings['smfstaff_showavatar']) {
        $totalcols++;
    }
    if ($modSettings['smfstaff_showlastactive']) {
        $totalcols++;
    }
    if ($modSettings['smfstaff_showdateregistered']) {
        $totalcols++;
    }
    if ($modSettings['smfstaff_showcontactinfo']) {
        $totalcols++;
    }
    foreach ($context['smfstaff_groups'] as $id => $data) {
        $count_users = count(@$context['smfstaff_users'][$data['id']]);
        if ($count_users == 0) {
            continue;
        }
        echo '<table border="0" cellspacing="0" cellpadding="2" width="100%">';
        echo '<tr>';
        echo '<td class="catbg2" width="30%">', $data['name'], '</td>';
        if ($modSettings['smfstaff_showavatar']) {
            echo '<td class="catbg2" width="25%">', $txt['smfstaff_avatar'], '</td>';
        }
        if ($modSettings['smfstaff_showlastactive']) {
            echo '<td class="catbg2" width="25%">', $txt['smfstaff_lastactive'], '</td>';
        }
        if ($modSettings['smfstaff_showdateregistered']) {
            echo '<td class="catbg2" width="25%">', $txt['smfstaff_dateregistered'], '</td>';
        }
        if ($modSettings['smfstaff_showcontactinfo']) {
            echo '<td class="catbg2" width="30%">', $txt['smfstaff_contact'], '</td>';
        }
        echo '</tr>';
        foreach (@$context['smfstaff_users'][$data['id']] as $id => $row2) {
            echo '<tr>';
            echo '<td class="windowbg"><a href="' . $scripturl . '?action=profile;u=' . $row2['ID_MEMBER'] . '"><font color="' . $data['color'] . '">' . $row2['realName'] . '</font></a></td>';
            if ($modSettings['smfstaff_showavatar']) {
                echo '<td class="windowbg">';
                // Display the users avatar
                $memCommID = $row2['ID_MEMBER'];
                loadMemberData($memCommID);
                loadMemberContext($memCommID);
                echo $memberContext[$memCommID]['avatar']['image'];
                echo '</td>';
            }
            if ($modSettings['smfstaff_showlastactive']) {
                echo '<td class="windowbg">' . timeformat($row2['lastLogin']) . '</td>';
            }
            if ($modSettings['smfstaff_showdateregistered']) {
                echo '<td class="windowbg">' . timeformat($row2['dateRegistered']) . '</td>';
            }
            if ($modSettings['smfstaff_showcontactinfo']) {
                echo '<td class="windowbg">';
                //Send email row
                if ($row2['hideEmail'] == 0) {
                    echo '<a href="mailto:', $row2['emailAddress'], '"><img src="' . $settings['images_url'] . '/email_sm.gif" alt="email" /></a>&nbsp;';
                }
                if ($row2['ICQ'] != '') {
                    echo '<a href="http://www.icq.com/whitepages/about_me.php?uin=' . $row2['ICQ'] . '" target="_blank"><img src="http://status.icq.com/online.gif?img=5&amp;icq=' . $row2['ICQ'] . '" alt="' . $row2['ICQ'] . '" width="18" height="18" border="0" /></a>&nbsp;';
                }
                if ($row2['AIM'] != '') {
                    echo '<a href="aim:goim?screenname=' . urlencode(strtr($row2['AIM'], array(' ' => '%20'))) . '&amp;message=' . $txt['aim_default_message'] . '"><img src="' . $settings['images_url'] . '/aim.gif" alt="' . $row2['AIM'] . '" border="0" /></a>&nbsp;';
                }
                if ($row2['YIM'] != '') {
                    echo '<a href="http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($row2['YIM']) . '"><img src="http://opi.yahoo.com/online?u=' . urlencode($row2['YIM']) . '&amp;m=g&amp;t=0" alt="' . $row2['YIM'] . '" border="0" /></a>&nbsp;';
                }
                if ($row2['MSN'] != '') {
                    echo '<a href="http://members.msn.com/' . $row2['MSN'] . '" target="_blank"><img src="' . $settings['images_url'] . '/msntalk.gif" alt="' . $row2['MSN'] . '" border="0" /></a>&nbsp;';
                }
                // Send PM row
                echo '<a href="' . $scripturl . '?action=pm;sa=send;u=' . $row2['ID_MEMBER'] . '">' . $txt['smfstaff_sendpm'] . '</a>';
                echo '</td>';
            }
            // End Contact Information
            echo '</tr>';
        }
        // If they are allowed to manage the staff page give them the option
        if ($manage_staff) {
            echo '<tr>
					<td align="center" colspan="', $totalcols, '" class="windowbg">
					<a href="' . $scripturl . '?action=staff;sa=catdown&id=' . $data['id'] . '">' . $txt['smfstaff_down'] . '</a> | <a href="' . $scripturl . '?action=staff;sa=catup&id=' . $data['id'] . '">' . $txt['smfstaff_up'] . '</a> | <a href="' . $scripturl . '?action=staff;sa=delete&id=' . $data['id'] . ';ret">' . $txt['smfstaff_delgroup'] . '</a></td></tr>';
        }
        echo '</table>';
        // Seperate the groups from the local mods.
        echo '<br />';
    }
    // End of Main staff listing
    if ($modSettings['smfstaff_showlocalmods']) {
        $localcount = count($context['smfstaff_localmods']);
        if ($localcount > 0) {
            echo '<table border="0" cellspacing="0" cellpadding="2" width="100%">';
            echo '<tr>';
            echo '<td class="catbg2" width="25%">', $txt['smfstaff_local'], '</td>';
            if ($modSettings['smfstaff_showavatar']) {
                echo '<td class="catbg2" width="25%">', $txt['smfstaff_avatar'], '</td>';
            }
            if ($modSettings['smfstaff_showlastactive']) {
                echo '<td class="catbg2" width="25%">', $txt['smfstaff_lastactive'], '</td>';
            }
            if ($modSettings['smfstaff_showdateregistered']) {
                echo '<td class="catbg2" width="25%">', $txt['smfstaff_dateregistered'], '</td>';
            }
            echo '<td class="catbg2" width="25%">', $txt['smfstaff_forums'], '</td>';
            if ($modSettings['smfstaff_showcontactinfo']) {
                echo '<td class="catbg2" width="25%">', $txt['smfstaff_contact'], '</td>';
            }
            echo '</tr>';
            foreach ($context['smfstaff_localmods'] as $id => $data) {
                echo '<tr>';
                echo '<td class="windowbg"><a href="', $scripturl, '?action=profile;u=', $data['id'], '">', $data['realName'], '</a></td>';
                if ($modSettings['smfstaff_showavatar']) {
                    echo '<td class="windowbg">';
                    //Display the users avatar
                    $memCommID = $data['id'];
                    loadMemberData($memCommID);
                    loadMemberContext($memCommID);
                    echo $memberContext[$memCommID]['avatar']['image'];
                    echo '</td>';
                }
                if ($modSettings['smfstaff_showlastactive']) {
                    echo '<td class="windowbg">', timeformat($data['lastLogin']), '</td>';
                }
                if ($modSettings['smfstaff_showdateregistered']) {
                    echo '<td class="windowbg">', timeformat($data['dateRegistered']), '</td>';
                }
                echo '<td class="windowbg">', $data['forums'], '</td>';
                if ($modSettings['smfstaff_showcontactinfo']) {
                    echo '<td class="windowbg" align="center">';
                    // Send email row
                    if ($data['hideEmail'] == 0) {
                        echo '<a href="mailto:', $data['emailAddress'], '"><img src="', $settings['images_url'], '/email_sm.gif" alt="email" /></a>&nbsp;';
                    }
                    if ($data['ICQ'] != '') {
                        echo '<a href="http://www.icq.com/whitepages/about_me.php?uin=', $data['ICQ'], '" target="_blank"><img src="http://status.icq.com/online.gif?img=5&amp;icq=', $data['ICQ'], '" alt="', $data['ICQ'], '" width="18" height="18" border="0" /></a>&nbsp;';
                    }
                    if ($data['AIM'] != '') {
                        echo '<a href="aim:goim?screenname=', urlencode(strtr($data['AIM'], array(' ' => '%20'))), '&amp;message=', $txt['aim_default_message'], '"><img src="', $settings['images_url'], '/aim.gif" alt="', $data['AIM'], '" border="0" /></a>&nbsp;';
                    }
                    if ($data['YIM'] != '') {
                        echo '<a href="http://edit.yahoo.com/config/send_webmesg?.target=', urlencode($data['YIM']), '"><img src="http://opi.yahoo.com/online?u=', urlencode($data['YIM']), '&amp;m=g&amp;t=0" alt="', $data['YIM'], '" border="0" /></a>&nbsp;';
                    }
                    if ($data['MSN'] != '') {
                        echo '<a href="http://members.msn.com/', $data['MSN'], '" target="_blank"><img src="', $settings['images_url'], '/msntalk.gif" alt="', $data['MSN'], '" border="0" /></a>&nbsp;';
                    }
                    //Send PM row
                    echo '<a href="', $scripturl, '?action=pm;sa=send;u=', $data['id'], '">', $txt['smfstaff_sendpm'], '</a>';
                    echo '</td>';
                }
                // End smfstaff_showcontactinfo
                echo '</tr>';
            }
            echo '</table>';
        }
        // End of local mods count
    }
    // End of modSettings local mods check
    // If they can manage the staff page show them the link
    if ($manage_staff) {
        echo '<div align="center"><a href="', $scripturl, '?action=staff;sa=admin">', $txt['smfstaff_admin'], '</a></div><br />';
    }
    echo '</div>';
    // The Copyright is required to remain or contact me to purchase link removal.
    echo '<div align="center"><a href="http://www.smfhacks.com" target="blank">SMF Staff</a></div>';
}
/**
 *	Creates a new ticket or reply in the database.
 *
 *	This function handles all of the creation of posts and tickets within SimpleDesk, even with respect to managing tickets spawned
 *	from forum topics being moved. New tickets' contents as well as replies to tickets generally hold the same format.
 *
 *	All three parameters are by <b>reference</b> meaning they WILL be updated if things change. Note that this function
 *	is not validating that they are sensible values; it is up to the calling function to ascertain that.
 *
 *	@param array &$msgOptions A hash array by reference, containing details of the post you wish to add.
 *	<ul>
 *	<li>id: Not required on input (and is ignored) - and will be overwritten with the new message id when the function completes.</li>
 *	<li>body: Required string, the principle body content of the message to post. Assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and preparsecode)</li>
 *	<li>smileys_enabled: Optional, boolean denoting whether smileys should be active on this post; defaults to false</li>
 *	<li>time: Optional, timestamp of the post. If omitted, time() will be used instead (for "now" based on server clock)</li>
 *	<li>modified: Optional, hash array containing items relating to modification (if 'modified' key exists, all of these should be set)
 *		<ul>
 *			<li> time: Unsigned int timestamp of the change</li>
 *			<li> name: String; user name of the user making the change; if omitted, modified will be ignored</li>
 *			<li> id: Unsigned int user id of the user making the change; if not provided, id MUST be. If id isn't, or it doesn't exist, modified will be ignored entirely</li>
 *		</ul>
 *	</li>
 *	<li> attachments: Optional, array of attachment ids that need attaching to this message; if omitted no changes will occur
 *	</ul>
 *
 *	@param array &$ticketOptions A hash array by reference, containing details of the ticket as a whole.
 *	<ul>
 *	<li>id: Required if replying to a ticket, 0 if a new ticket (will default to 0 if not specified)</li>
 *	<li>mark_as_read: Optional boolean, whether to mark the ticket as read by the person posting it ($posterOptions['id'] is required to use this)</li>
 *	<li>mark_as_read_proxy: Optional integer for proxy tickets, if $ticketOptions['mark_as_read'] is true. Mark the ticket as read for the user with this id.</li>
 *	<li>subject: Semi-optional string with the new subject in; required for a new ticket, ignored if adding a reply. If set, assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and strtr)</li>
 *	<li>private: Semi-optional boolean with ticket privacy (true = private); required for a new ticket, ignored if adding a reply.</li>
 *	<li>status: Integer to denote new status of the ticket, defaults to TICKET_STATUS_NEW. Calling function to determine new status.</li>
 *	<li>urgency: Semi-optional integer with the ticket urgency; required for a new ticket, ignored if adding a reply. If not stated on a new ticket, TICKET_URGENCY_LOW will be used.</li>
 *	<li>assigned: Optional integer of user id, used to create a ticket with assignment, ignored if not a new ticket.</li>
 *	<li>dept: Required if creating a new ticket, to indicate which department the ticket should belong to.</li>
 *	</ul>
 *
 *	@param array &$posterOptions A hash array by reference, containing details of the person the reply is written by.
 *	<ul>
 *	<li>id: User id to credit the post to. Uses 0 if not specified.</li>
 *	<li>ip: IP address the post came from. Uses the current user's IP address if not specified.</li>
 *	<li>name: Name to credit against the post. If not specified, and a user id was supplied, look that up in the member table, otherwise just use 'Guest'.</li>
 *	<li>email: Email address to list against the post. If not specified, and a user id was supplied, look that up in the member table, otherwise just use ''.</li>
 *	</ul>
 *	@return bool True on success, false on failure.
 *	@since 1.0
 */
function shd_create_ticket_post(&$msgOptions, &$ticketOptions, &$posterOptions)
{
    global $user_info, $txt, $modSettings, $smcFunc, $context, $user_profile;
    // Clean them incoming vars up good 'n' proper
    $msgOptions['smileys_enabled'] = !empty($msgOptions['smileys_enabled']);
    $msgOptions['attachments'] = empty($msgOptions['attachments']) ? array() : $msgOptions['attachments'];
    $msgOptions['time'] = empty($msgOptions['time']) ? time() : (int) $msgOptions['time'];
    $ticketOptions['id'] = empty($ticketOptions['id']) ? 0 : (int) $ticketOptions['id'];
    $ticketOptions['private'] = !empty($ticketOptions['private']);
    $ticketOptions['urgency'] = empty($ticketOptions['urgency']) ? TICKET_URGENCY_LOW : (int) $ticketOptions['urgency'];
    $ticketOptions['assigned'] = empty($ticketOptions['assigned']) ? 0 : (int) $ticketOptions['assigned'];
    $ticketOptions['status'] = empty($ticketOptions['status']) ? TICKET_STATUS_NEW : (int) $ticketOptions['status'];
    $posterOptions['id'] = empty($posterOptions['id']) ? 0 : (int) $posterOptions['id'];
    $posterOptions['ip'] = empty($posterOptions['ip']) ? $user_info['ip'] : $posterOptions['ip'];
    // If nothing was filled in as name/e-mail address, try the member table.
    if (!isset($posterOptions['name']) || $posterOptions['name'] == '' || empty($posterOptions['email']) && !empty($posterOptions['id'])) {
        if (empty($posterOptions['id'])) {
            $posterOptions['id'] = 0;
            $posterOptions['name'] = $txt['guest_title'];
            $posterOptions['email'] = '';
        } elseif ($posterOptions['id'] != $user_info['id']) {
            if (empty($user_profile[$posterOptions['id']])) {
                loadMemberData($posterOptions['id'], false, 'minimal');
            }
            // Couldn't find the current poster?
            if (empty($user_profile[$posterOptions['id']])) {
                trigger_error('shd_create_ticket_post(): Invalid member id ' . $posterOptions['id'], E_USER_NOTICE);
                $posterOptions['id'] = 0;
                $posterOptions['name'] = $txt['guest_title'];
                $posterOptions['email'] = '';
            } else {
                $posterOptions['name'] = $user_profile[$posterOptions['id']]['real_name'];
                $posterOptions['email'] = $user_profile[$posterOptions['id']]['email_address'];
            }
        } else {
            $posterOptions['name'] = $user_info['name'];
            $posterOptions['email'] = $user_info['email'];
        }
    }
    // Is there modified name data? (For topic->ticket)
    $modified = true;
    if (isset($msgOptions['modified'])) {
        $msgOptions['modified']['time'] = empty($msgOptions['modified']['time']) ? 0 : (int) $msgOptions['modified']['time'];
        $msgOptions['modified']['id'] = empty($msgOptions['modified']['id']) ? 0 : (int) $msgOptions['modified']['id'];
        $msgOptions['modified']['name'] = empty($msgOptions['modified']['name']) ? '' : $msgOptions['modified']['name'];
        $cancel = false;
        if (empty($msgOptions['modified']['time']) || empty($msgOptions['modified']['name']) && empty($msgOptions['modified']['id'])) {
            $modified = false;
        }
        if ($modified) {
            // So they have a time, and name or id (or even both). Let's see what we need.
            if (empty($msgOptions['modified']['name'])) {
                loadMemberData($msgOptions['modified']['id'], false, 'minimal');
                if (empty($user_profile[$msgOptions['modified']['id']])) {
                    $modified = false;
                }
                // oops, they gave us a user id that doesn't exist -- and we don't have a name
            }
            // Otherwise, we have a name and no id, which is fine. Can't be doing with trying to figure out usernames.
        }
    } else {
        $modified = false;
    }
    if (!$modified) {
        $msgOptions['modified'] = array('id' => 0, 'name' => '', 'time' => 0);
    }
    // It's do or die time: forget any user aborts!
    $previous_ignore_user_abort = ignore_user_abort(true);
    $new_ticket = empty($ticketOptions['id']);
    // OK, so let's add the reply. Even if it's a new ticket and stuff, let's still add the msg first so we have our friendly msg id
    $smcFunc['db_insert']('', '{db_prefix}helpdesk_ticket_replies', array('id_ticket' => 'int', 'id_member' => 'int', 'body' => 'string-65534', 'poster_name' => 'string-255', 'poster_email' => 'string-255', 'poster_time' => 'int', 'poster_ip' => 'string-255', 'smileys_enabled' => 'int', 'modified_member' => 'int', 'modified_name' => 'string', 'modified_time' => 'int'), array($ticketOptions['id'], $posterOptions['id'], $msgOptions['body'], $posterOptions['name'], $posterOptions['email'], $msgOptions['time'], $posterOptions['ip'], $msgOptions['smileys_enabled'] ? 1 : 0, $msgOptions['modified']['id'], $msgOptions['modified']['name'], $msgOptions['modified']['time']), array('id_msg'));
    $msgOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}messages', 'id_msg');
    // Something went wrong creating the message...
    if (empty($msgOptions['id'])) {
        return false;
    }
    // Insert a new ticket (if the ID was left empty)
    if ($new_ticket) {
        $smcFunc['db_insert']('', '{db_prefix}helpdesk_tickets', array('id_dept' => 'int', 'id_first_msg' => 'int', 'id_member_started' => 'int', 'id_last_msg' => 'int', 'id_member_updated' => 'int', 'id_member_assigned' => 'int', 'subject' => 'string-100', 'urgency' => 'int', 'status' => 'int', 'private' => 'int'), array($ticketOptions['dept'], $msgOptions['id'], $posterOptions['id'], $msgOptions['id'], $posterOptions['id'], $ticketOptions['assigned'], $ticketOptions['subject'], $ticketOptions['urgency'], $ticketOptions['status'], $ticketOptions['private'] ? 1 : 0), array('id_ticket'));
        $ticketOptions['id'] = $smcFunc['db_insert_id']('{db_prefix}helpdesk_tickets', 'id_ticket');
        // The ticket couldn't be created for some reason.
        if (empty($ticketOptions['id'])) {
            // We should delete the post that did work, though...
            shd_db_query('', '
				DELETE FROM {db_prefix}helpdesk_ticket_replies
				WHERE id_msg = {int:id_msg}', array('id_msg' => $msgOptions['id']));
            return false;
        }
        // Fix the message with the ticket.
        shd_db_query('', '
			UPDATE {db_prefix}helpdesk_ticket_replies
			SET id_ticket = {int:id_ticket}
			WHERE id_msg = {int:id_msg}', array('id_ticket' => $ticketOptions['id'], 'id_msg' => $msgOptions['id']));
    } else {
        shd_db_query('', '
			UPDATE {db_prefix}helpdesk_tickets
			SET
				id_member_updated = {int:poster_id},
				id_last_msg = {int:id_msg},
				num_replies = num_replies + 1,
				status = {int:status}
			WHERE id_ticket = {int:id_ticket}', array('poster_id' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'status' => $ticketOptions['status'], 'id_ticket' => $ticketOptions['id']));
    }
    // Fix the attachments.
    if (!empty($msgOptions['attachments'])) {
        $array = array();
        foreach ($msgOptions['attachments'] as $attach) {
            $array[] = array($attach, $msgOptions['id'], $ticketOptions['id']);
        }
        $smcFunc['db_insert']('replace', '{db_prefix}helpdesk_attachments', array('id_attach' => 'int', 'id_msg' => 'int', 'id_ticket' => 'int'), $array, array('id_attach'));
    }
    // Mark inserted ticket as read (only for the user listed as the author -- oftentimes will be the current user though)
    if (!empty($ticketOptions['mark_as_read']) && !empty($posterOptions['id'])) {
        // Since it's likely they *read* it before replying, let's try an UPDATE first.
        if (!$new_ticket) {
            shd_db_query('', '
				UPDATE {db_prefix}helpdesk_log_read
				SET id_msg = {int:id_msg}
				WHERE id_member = {int:current_member}
					AND id_ticket = {int:id_ticket}', array('current_member' => $posterOptions['id'], 'id_msg' => $msgOptions['id'], 'id_ticket' => $ticketOptions['id']));
            $flag = $smcFunc['db_affected_rows']() != 0;
        }
        if (empty($flag)) {
            // Hold on a second... If this is a proxy ticket... We'll want to mark it read for the staff member, not the member for whom it was posted.
            $mark_read_user = !empty($ticketOptions['mark_as_read_proxy']) ? $ticketOptions['mark_as_read_proxy'] : $posterOptions['id'];
            $smcFunc['db_insert']('replace', '{db_prefix}helpdesk_log_read', array('id_ticket' => 'int', 'id_member' => 'int', 'id_msg' => 'int'), array($ticketOptions['id'], $mark_read_user, $msgOptions['id']), array('id_ticket', 'id_member'));
        }
    }
    // Are we saving custom fields?
    $rows = array();
    if (!empty($ticketOptions['custom_fields'])) {
        // We shouldn't need to be bothering with pre-existing ones. This is a new message in whatever form, after all.
        foreach ($ticketOptions['custom_fields'] as $field_id => $field) {
            if (isset($field['new_value'])) {
                $rows[] = array('id_post' => $ticketOptions['id'], 'id_field' => $field_id, 'value' => $field['new_value'], 'post_type' => CFIELD_TICKET);
            }
        }
    }
    // Same deal, just this time for message fields.
    if (!empty($msgOptions['custom_fields'])) {
        foreach ($msgOptions['custom_fields'] as $field_id => $field) {
            if (isset($field['new_value'])) {
                $rows[] = array('id_post' => $msgOptions['id'], 'id_field' => $field_id, 'value' => $field['new_value'], 'post_type' => CFIELD_REPLY);
            }
        }
    }
    if (!empty($rows)) {
        $smcFunc['db_insert']('replace', '{db_prefix}helpdesk_custom_fields_values', array('id_post' => 'int', 'id_field' => 'int', 'value' => 'string-65534', 'post_type' => 'int'), $rows, array('id_post', 'id_field'));
    }
    // Int hooks
    $hook = $new_ticket ? 'shd_hook_newticket' : 'shd_hook_newreply';
    call_integration_hook($hook, array(&$msgOptions, &$ticketOptions, &$posterOptions));
    ignore_user_abort($previous_ignore_user_abort);
    if (empty($ticketOptions['dept']) && !empty($ticketOptions['id'])) {
        // So we're making a reply, we need the department id. The ticket will already exist - we just added to it!
        $query = $smcFunc['db_query']('', '
			SELECT id_dept
			FROM {db_prefix}helpdesk_tickets
			WHERE id_ticket = {int:id_ticket}', array('id_ticket' => $ticketOptions['id']));
        list($ticketOptions['dept']) = $smcFunc['db_fetch_row']($query);
        $smcFunc['db_free_result']($query);
    }
    if (!empty($ticketOptions['dept'])) {
        shd_clear_active_tickets($ticketOptions['dept']);
    }
    // Success.
    return true;
}
Пример #7
0
function Who()
{
    global $context, $scripturl, $user_info, $txt, $modSettings, $memberContext, $smcFunc;
    // Permissions, permissions, permissions.
    isAllowedTo('who_view');
    // You can't do anything if this is off.
    if (empty($modSettings['who_enabled'])) {
        fatal_lang_error('who_off', false);
    }
    // Load the 'Who' template.
    loadTemplate('Who');
    loadLanguage('Who');
    // Sort out... the column sorting.
    $sort_methods = array('user' => 'mem.real_name', 'time' => 'lo.log_time');
    $show_methods = array('members' => '(lo.id_member != 0)', 'guests' => '(lo.id_member = 0)', 'all' => '1=1');
    // Store the sort methods and the show types for use in the template.
    $context['sort_methods'] = array('user' => $txt['who_user'], 'time' => $txt['who_time']);
    $context['show_methods'] = array('all' => $txt['who_show_all'], 'members' => $txt['who_show_members_only'], 'guests' => $txt['who_show_guests_only']);
    // Can they see spiders too?
    if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) {
        $show_methods['spiders'] = '(lo.id_member = 0 AND lo.id_spider > 0)';
        $show_methods['guests'] = '(lo.id_member = 0 AND lo.id_spider = 0)';
        $context['show_methods']['spiders'] = $txt['who_show_spiders_only'];
    } elseif (empty($modSettings['show_spider_online']) && isset($_SESSION['who_online_filter']) && $_SESSION['who_online_filter'] == 'spiders') {
        unset($_SESSION['who_online_filter']);
    }
    // Does the user prefer a different sort direction?
    if (isset($_REQUEST['sort']) && isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = $_SESSION['who_online_sort_by'] = $_REQUEST['sort'];
        $sort_method = $sort_methods[$_REQUEST['sort']];
    } elseif (isset($_SESSION['who_online_sort_by'])) {
        $context['sort_by'] = $_SESSION['who_online_sort_by'];
        $sort_method = $sort_methods[$_SESSION['who_online_sort_by']];
    } else {
        $context['sort_by'] = $_SESSION['who_online_sort_by'] = 'time';
        $sort_method = 'lo.log_time';
    }
    $context['sort_direction'] = isset($_REQUEST['asc']) || isset($_REQUEST['sort_dir']) && $_REQUEST['sort_dir'] == 'asc' ? 'up' : 'down';
    $conditions = array();
    if (!allowedTo('moderate_forum')) {
        $conditions[] = '(IFNULL(mem.show_online, 1) = 1)';
    }
    // Fallback to top filter?
    if (isset($_REQUEST['submit_top']) && isset($_REQUEST['show_top'])) {
        $_REQUEST['show'] = $_REQUEST['show_top'];
    }
    // Does the user wish to apply a filter?
    if (isset($_REQUEST['show']) && isset($show_methods[$_REQUEST['show']])) {
        $context['show_by'] = $_SESSION['who_online_filter'] = $_REQUEST['show'];
        $conditions[] = $show_methods[$_REQUEST['show']];
    } elseif (isset($_SESSION['who_online_filter'])) {
        $context['show_by'] = $_SESSION['who_online_filter'];
        $conditions[] = $show_methods[$_SESSION['who_online_filter']];
    } else {
        $context['show_by'] = $_SESSION['who_online_filter'] = 'all';
    }
    // Get the total amount of members online.
    $request = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}log_online AS lo
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)' . (!empty($conditions) ? '
		WHERE ' . implode(' AND ', $conditions) : ''), array());
    list($totalMembers) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Prepare some page index variables.
    $context['page_index'] = constructPageIndex($scripturl . '?action=who;sort=' . $context['sort_by'] . ($context['sort_direction'] == 'up' ? ';asc' : '') . ';show=' . $context['show_by'], $_REQUEST['start'], $totalMembers, $modSettings['defaultMaxMembers']);
    $context['start'] = $_REQUEST['start'];
    // Look for people online, provided they don't mind if you see they are.
    $request = $smcFunc['db_query']('', '
		SELECT
			lo.log_time, lo.id_member, lo.url, INET_NTOA(lo.ip) AS ip, mem.real_name,
			lo.session, mg.online_color, IFNULL(mem.show_online, 1) AS show_online,
			lo.id_spider
		FROM {db_prefix}log_online AS lo
			LEFT JOIN {db_prefix}members AS mem ON (lo.id_member = mem.id_member)
			LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:regular_member} THEN mem.id_post_group ELSE mem.id_group END)' . (!empty($conditions) ? '
		WHERE ' . implode(' AND ', $conditions) : '') . '
		ORDER BY {raw:sort_method} {raw:sort_direction}
		LIMIT {int:offset}, {int:limit}', array('regular_member' => 0, 'sort_method' => $sort_method, 'sort_direction' => $context['sort_direction'] == 'up' ? 'ASC' : 'DESC', 'offset' => $context['start'], 'limit' => $modSettings['defaultMaxMembers']));
    $context['members'] = array();
    $member_ids = array();
    $url_data = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $actions = @unserialize($row['url']);
        if ($actions === false) {
            continue;
        }
        // Send the information to the template.
        $context['members'][$row['session']] = array('id' => $row['id_member'], 'ip' => allowedTo('moderate_forum') ? $row['ip'] : '', 'time' => strtr(timeformat($row['log_time']), array($txt['today'] => '', $txt['yesterday'] => '')), 'timestamp' => forum_time(true, $row['log_time']), 'query' => $actions, 'is_hidden' => $row['show_online'] == 0, 'id_spider' => $row['id_spider'], 'color' => empty($row['online_color']) ? '' : $row['online_color']);
        $url_data[$row['session']] = array($row['url'], $row['id_member']);
        $member_ids[] = $row['id_member'];
    }
    $smcFunc['db_free_result']($request);
    // Load the user data for these members.
    loadMemberData($member_ids);
    // Load up the guest user.
    $memberContext[0] = array('id' => 0, 'name' => $txt['guest_title'], 'group' => $txt['guest_title'], 'href' => '', 'link' => $txt['guest_title'], 'email' => $txt['guest_title'], 'is_guest' => true);
    // Are we showing spiders?
    $spiderContext = array();
    if (!empty($modSettings['show_spider_online']) && ($modSettings['show_spider_online'] == 2 || allowedTo('admin_forum')) && !empty($modSettings['spider_name_cache'])) {
        foreach (unserialize($modSettings['spider_name_cache']) as $id => $name) {
            $spiderContext[$id] = array('id' => 0, 'name' => $name, 'group' => $txt['spiders'], 'href' => '', 'link' => $name, 'email' => $name, 'is_guest' => true);
        }
    }
    $url_data = determineActions($url_data);
    // Setup the linktree and page title (do it down here because the language files are now loaded..)
    $context['page_title'] = $txt['who_title'];
    $context['linktree'][] = array('url' => $scripturl . '?action=who', 'name' => $txt['who_title']);
    // Put it in the context variables.
    foreach ($context['members'] as $i => $member) {
        if ($member['id'] != 0) {
            $member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0;
        }
        // Keep the IP that came from the database.
        $memberContext[$member['id']]['ip'] = $member['ip'];
        $context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : $txt['who_hidden'];
        if ($member['id'] == 0 && isset($spiderContext[$member['id_spider']])) {
            $context['members'][$i] += $spiderContext[$member['id_spider']];
        } else {
            $context['members'][$i] += $memberContext[$member['id']];
        }
    }
    // Some people can't send personal messages...
    $context['can_send_pm'] = allowedTo('pm_send');
    // any profile fields disabled?
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
}
Пример #8
0
/**
 * @param $memID	int member ID
 * 
 * show the settings to customize opt-outs for activity entries and notifications
 * to receive.
 * 
 * todo: we need to find a way to filter out notifications that are for
 * admins/mods only. probably needs a db scheme change...
 */
function showActivitiesProfileSettings($memID)
{
    global $modSettings, $context, $user_info, $txt, $user_profile, $scripturl;
    loadLanguage('Activities-Profile');
    if (empty($modSettings['astream_active']) || $user_info['id'] != $memID && !$user_info['is_admin']) {
        fatal_lang_error('no_access');
    }
    Eos_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'profile/astream_settings');
    $context['submiturl'] = $scripturl . '?action=profile;area=activities;sa=settings;save;u=' . $memID;
    $context['page_title'] = $txt['showActivities'] . ' - ' . $user_profile[$memID]['real_name'];
    $context[$context['profile_menu_name']]['tab_data'] = array('title' => $txt['showActivitiesSettings'], 'description' => $txt['showActivitiesSettings_desc'], 'tabs' => array());
    $result = smf_db_query('SELECT * FROM {db_prefix}activity_types ORDER BY id_type ASC');
    if ($user_info['id'] == $memID) {
        $my_act_optout = empty($user_info['act_optout']) ? array(0) : explode(',', $user_info['act_optout']);
        $my_notify_optout = empty($user_info['notify_optout']) ? array(0) : explode(',', $user_info['notify_optout']);
    } else {
        loadMemberData($memID, false, 'minimal');
        $my_act_optout = empty($user_profile[$memID]['act_optout']) ? array(0) : explode(',', $user_profile[$memID]['act_optout']);
        $my_notify_optout = empty($user_profile[$memID]['notify_optout']) ? array(0) : explode(',', $user_profile[$memID]['notify_optout']);
    }
    $context['activity_types'] = array();
    while ($row = mysql_fetch_assoc($result)) {
        $context['activity_types'][] = array('id' => $row['id_type'], 'shortdesc' => $row['id_desc'], 'longdesc_act' => $txt['actdesc_' . trim($row['id_desc'])], 'longdesc_not' => isset($txt['ndesc_' . trim($row['id_desc'])]) ? $txt['ndesc_' . trim($row['id_desc'])] : '', 'act_optout' => in_array($row['id_type'], $my_act_optout), 'notify_optout' => in_array($row['id_type'], $my_notify_optout));
    }
    mysql_free_result($result);
    if (isset($_GET['save'])) {
        $new_not_optout = array();
        $new_act_optout = array();
        $update_array = array();
        foreach ($context['activity_types'] as $t) {
            $_id = trim($t['id']);
            if (!empty($t['longdesc_act']) && (!isset($_REQUEST['act_check_' . $_id]) || empty($_REQUEST['act_check_' . $_id]))) {
                $new_act_optout[] = $_id;
            }
            if (!empty($t['longdesc_not']) && (!isset($_REQUEST['not_check_' . $_id]) || empty($_REQUEST['not_check_' . $_id]))) {
                $new_not_optout[] = $_id;
            }
        }
        //if(count(array_unique($new_act_optout)) > 0)
        $update_array['act_optout'] = implode(',', array_unique($new_act_optout));
        //if(count(array_unique($new_not_optout)) > 0)
        $update_array['notify_optout'] = implode(',', array_unique($new_not_optout));
        if (count($update_array)) {
            updateMemberData($memID, $update_array);
        }
        redirectexit($scripturl . '?action=profile;area=activities;sa=settings;u=' . $memID);
    }
}
Пример #9
0
        $return = ssi_topPoster($topNumber, 'array');
        cache_put_data('bk_top_poster', $return, 1800);
    } else {
        $return = cache_get_data('bk_top_poster', 1800);
    }
} else {
    $return = ssi_topPoster($topNumber, 'array');
}
// Make a quick array to list the links in.
echo '
	<table  style="border-spacing:5px;width:100%;" border="0" cellspacing="1" cellpadding="3">
		';
$count = 0;
foreach ($return as $member) {
    //load member data
    loadMemberData($member['id']);
    loadMemberContext($member['id']);
    //end load member data...
    $count++;
    echo '
		<tr>
		<td align="left">';
    if (!empty($memberContext[$member['id']]['avatar']['href'])) {
        echo '<img src="' . $memberContext[$member['id']]['avatar']['href'] . '" 
				style="-moz-box-shadow: 0px 0px 5px #444;
                       -webkit-box-shadow: 0px 0px 5px #444;
                       box-shadow: 0px 0px 5px #444;" width="50px;" alt="" />';
    }
    echo '</td>
			<td width="100%" valign="middle">
				', $count == 1 ? '<img src="' . $settings['default_images_url'] . '/ultimate-portal/icons/1.gif" width="22px" alt="" />' : '', ' 
Пример #10
0
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;
            }
        }
    }
}
Пример #11
0
function ModifyProfile($post_errors = array())
{
    global $txt, $scripturl, $user_info, $context, $sourcedir, $user_profile, $cur_profile;
    global $modSettings, $memberContext, $profile_vars, $smcFunc, $post_errors, $options, $user_settings;
    // Don't reload this as we may have processed error strings.
    if (empty($post_errors)) {
        loadLanguage('Profile');
    }
    loadTemplate('Profile');
    require_once $sourcedir . '/Subs-Menu.php';
    // Did we get the user by name...
    if (isset($_REQUEST['user'])) {
        $memberResult = loadMemberData($_REQUEST['user'], true, 'profile');
    } elseif (!empty($_REQUEST['u'])) {
        $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile');
    } else {
        $memberResult = loadMemberData($user_info['id'], false, 'profile');
    }
    // Check if loadMemberData() has returned a valid result.
    if (!is_array($memberResult)) {
        fatal_lang_error('not_a_user', false);
    }
    // If all went well, we have a valid member ID!
    list($memID) = $memberResult;
    $context['id_member'] = $memID;
    $cur_profile = $user_profile[$memID];
    // Let's have some information about this member ready, too.
    loadMemberContext($memID);
    $context['member'] = $memberContext[$memID];
    // Is this the profile of the user himself or herself?
    $context['user']['is_owner'] = $memID == $user_info['id'];
    /* Define all the sections within the profile area!
    		We start by defining the permission required - then SMF takes this and turns it into the relevant context ;)
    		Possible fields:
    			For Section:
    				string $title:		Section title.
    				array $areas:		Array of areas within this section.
    
    			For Areas:
    				string $label:		Text string that will be used to show the area in the menu.
    				string $file:		Optional text string that may contain a file name that's needed for inclusion in order to display the area properly.
    				string $custom_url:	Optional href for area.
    				string $function:	Function to execute for this section.
    				bool $enabled:		Should area be shown?
    				string $sc:		Session check validation to do on save - note without this save will get unset - if set.
    				bool $hidden:		Does this not actually appear on the menu?
    				bool $password:		Whether to require the user's password in order to save the data in the area.
    				array $subsections:	Array of subsections, in order of appearance.
    				array $permission:	Array of permissions to determine who can access this area. Should contain arrays $own and $any.
    	*/
    $profile_areas = array('info' => array('title' => $txt['profileInfo'], 'areas' => array('summary' => array('label' => $txt['summary'], 'file' => 'Profile-View.php', 'function' => 'summary', 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'statistics' => array('label' => $txt['statPanel'], 'file' => 'Profile-View.php', 'function' => 'statPanel', 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'showposts' => array('label' => $txt['showPosts'], 'file' => 'Profile-View.php', 'function' => 'showPosts', 'subsections' => array('messages' => array($txt['showMessages'], array('profile_view_own', 'profile_view_any')), 'topics' => array($txt['showTopics'], array('profile_view_own', 'profile_view_any')), 'attach' => array($txt['showAttachments'], array('profile_view_own', 'profile_view_any'))), 'permission' => array('own' => 'profile_view_own', 'any' => 'profile_view_any')), 'permissions' => array('label' => $txt['showPermissions'], 'file' => 'Profile-View.php', 'function' => 'showPermissions', 'permission' => array('own' => 'manage_permissions', 'any' => 'manage_permissions')), 'tracking' => array('label' => $txt['trackUser'], 'file' => 'Profile-View.php', 'function' => 'tracking', 'subsections' => array('activity' => array($txt['trackActivity'], 'moderate_forum'), 'ip' => array($txt['trackIP'], 'moderate_forum'), 'edits' => array($txt['trackEdits'], 'moderate_forum')), 'permission' => array('own' => 'moderate_forum', 'any' => 'moderate_forum')), 'viewwarning' => array('label' => $txt['profile_view_warnings'], 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && $cur_profile['warning'] && $context['user']['is_owner'] && !empty($modSettings['warning_show']), 'file' => 'Profile-View.php', 'function' => 'viewWarning', 'permission' => array('own' => 'profile_view_own', 'any' => 'issue_warning')))), 'edit_profile' => array('title' => $txt['profileEdit'], 'areas' => array('account' => array('label' => $txt['account'], 'file' => 'Profile-Modify.php', 'function' => 'account', 'enabled' => $context['user']['is_admin'] || $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])), 'sc' => 'post', 'password' => true, 'permission' => array('own' => array('profile_identity_any', 'profile_identity_own', 'manage_membergroups'), 'any' => array('profile_identity_any', 'manage_membergroups'))), 'forumprofile' => array('label' => $txt['forumprofile'], 'file' => 'Profile-Modify.php', 'function' => 'forumProfile', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own', 'profile_title_own', 'profile_title_any'), 'any' => array('profile_extra_any', 'profile_title_any'))), 'theme' => array('label' => $txt['theme'], 'file' => 'Profile-Modify.php', 'function' => 'theme', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'authentication' => array('label' => $txt['authentication'], 'file' => 'Profile-Modify.php', 'function' => 'authentication', 'enabled' => !empty($modSettings['enableOpenID']) || !empty($cur_profile['openid_uri']), 'sc' => 'post', 'hidden' => empty($modSettings['enableOpenID']) && empty($cur_profile['openid_uri']), 'password' => true, 'permission' => array('own' => array('profile_identity_any', 'profile_identity_own'), 'any' => array('profile_identity_any'))), 'notification' => array('label' => $txt['notification'], 'file' => 'Profile-Modify.php', 'function' => 'notification', 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'pmprefs' => array('label' => $txt['pmprefs'], 'file' => 'Profile-Modify.php', 'function' => 'pmprefs', 'enabled' => allowedTo(array('profile_extra_own', 'profile_extra_any')), 'sc' => 'post', 'permission' => array('own' => array('pm_read'), 'any' => array('profile_extra_any'))), 'ignoreboards' => array('label' => $txt['ignoreboards'], 'file' => 'Profile-Modify.php', 'function' => 'ignoreboards', 'enabled' => !empty($modSettings['allow_ignore_boards']), 'sc' => 'post', 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array('profile_extra_any'))), 'lists' => array('label' => $txt['editBuddyIgnoreLists'], 'file' => 'Profile-Modify.php', 'function' => 'editBuddyIgnoreLists', 'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'], 'sc' => 'post', 'subsections' => array('buddies' => array($txt['editBuddies']), 'ignore' => array($txt['editIgnoreList'])), 'permission' => array('own' => array('profile_extra_any', 'profile_extra_own'), 'any' => array())), 'groupmembership' => array('label' => $txt['groupmembership'], 'file' => 'Profile-Modify.php', 'function' => 'groupMembership', 'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'], 'sc' => 'request', 'permission' => array('own' => array('profile_view_own'), 'any' => array('manage_membergroups'))))), 'profile_action' => array('title' => $txt['profileAction'], 'areas' => array('sendpm' => array('label' => $txt['profileSendIm'], 'custom_url' => $scripturl . '?action=pm;sa=send', 'permission' => array('own' => array(), 'any' => array('pm_send'))), 'issuewarning' => array('label' => $txt['profile_issue_warning'], 'enabled' => in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1 && (!$context['user']['is_owner'] || $context['user']['is_admin']), 'file' => 'Profile-Actions.php', 'function' => 'issueWarning', 'permission' => array('own' => array('issue_warning'), 'any' => array('issue_warning'))), 'banuser' => array('label' => $txt['profileBanUser'], 'custom_url' => $scripturl . '?action=admin;area=ban;sa=add', 'enabled' => $cur_profile['id_group'] != 1 && !in_array(1, explode(',', $cur_profile['additional_groups'])), 'permission' => array('own' => array(), 'any' => array('manage_bans'))), 'subscriptions' => array('label' => $txt['subscriptions'], 'file' => 'Profile-Actions.php', 'function' => 'subscriptions', 'enabled' => !empty($modSettings['paid_enabled']), 'permission' => array('own' => array('profile_view_own'), 'any' => array('moderate_forum'))), 'deleteaccount' => array('label' => $txt['deleteAccount'], 'file' => 'Profile-Actions.php', 'function' => 'deleteAccount', 'sc' => 'post', 'password' => true, 'permission' => array('own' => array('profile_remove_any', 'profile_remove_own'), 'any' => array('profile_remove_any'))), 'activateaccount' => array('file' => 'Profile-Actions.php', 'function' => 'activateAccount', 'sc' => 'get', 'permission' => array('own' => array(), 'any' => array('moderate_forum'))))));
    // Let them modify profile areas easily.
    call_integration_hook('integrate_profile_areas', array(&$profile_areas));
    // Do some cleaning ready for the menu function.
    $context['password_areas'] = array();
    $current_area = isset($_REQUEST['area']) ? $_REQUEST['area'] : '';
    foreach ($profile_areas as $section_id => $section) {
        // Do a bit of spring cleaning so to speak.
        foreach ($section['areas'] as $area_id => $area) {
            // If it said no permissions that meant it wasn't valid!
            if (empty($area['permission'][$context['user']['is_owner'] ? 'own' : 'any'])) {
                $profile_areas[$section_id]['areas'][$area_id]['enabled'] = false;
            } else {
                $profile_areas[$section_id]['areas'][$area_id]['permission'] = $area['permission'][$context['user']['is_owner'] ? 'own' : 'any'];
            }
            // Password required - only if not on OpenID.
            if (!empty($area['password'])) {
                $context['password_areas'][] = $area_id;
            }
        }
    }
    // Is there an updated message to show?
    if (isset($_GET['updated'])) {
        $context['profile_updated'] = $txt['profile_updated_own'];
    }
    // Set a few options for the menu.
    $menuOptions = array('disable_url_session_check' => true, 'current_area' => $current_area, 'extra_url_parameters' => array('u' => $context['id_member']));
    // Actually create the menu!
    $profile_include_data = createMenu($profile_areas, $menuOptions);
    // No menu means no access.
    if (!$profile_include_data && (!$user_info['is_guest'] || validateSession())) {
        fatal_lang_error('no_access', false);
    }
    // Make a note of the Unique ID for this menu.
    $context['profile_menu_id'] = $context['max_menu_id'];
    $context['profile_menu_name'] = 'menu_data_' . $context['profile_menu_id'];
    // Set the selected item - now it's been validated.
    $current_area = $profile_include_data['current_area'];
    $context['menu_item_selected'] = $current_area;
    // Before we go any further, let's work on the area we've said is valid. Note this is done here just in case we every compromise the menu function in error!
    $context['completed_save'] = false;
    $security_checks = array();
    $found_area = false;
    foreach ($profile_areas as $section_id => $section) {
        // Do a bit of spring cleaning so to speak.
        foreach ($section['areas'] as $area_id => $area) {
            // Is this our area?
            if ($current_area == $area_id) {
                // This can't happen - but is a security check.
                if (isset($section['enabled']) && $section['enabled'] == false || isset($area['enabled']) && $area['enabled'] == false) {
                    fatal_lang_error('no_access', false);
                }
                // Are we saving data in a valid area?
                if (isset($area['sc']) && isset($_REQUEST['save'])) {
                    $security_checks['session'] = $area['sc'];
                    $context['completed_save'] = true;
                }
                // Does this require session validating?
                if (!empty($area['validate'])) {
                    $security_checks['validate'] = true;
                }
                // Permissions for good measure.
                if (!empty($profile_include_data['permission'])) {
                    $security_checks['permission'] = $profile_include_data['permission'];
                }
                // Either way got something.
                $found_area = true;
            }
        }
    }
    // Oh dear, some serious security lapse is going on here... we'll put a stop to that!
    if (!$found_area) {
        fatal_lang_error('no_access', false);
    }
    // Release this now.
    unset($profile_areas);
    // Now the context is setup have we got any security checks to carry out additional to that above?
    if (isset($security_checks['session'])) {
        checkSession($security_checks['session']);
    }
    if (isset($security_checks['validate'])) {
        validateSession();
    }
    if (isset($security_checks['permission'])) {
        isAllowedTo($security_checks['permission']);
    }
    // File to include?
    if (isset($profile_include_data['file'])) {
        require_once $sourcedir . '/' . $profile_include_data['file'];
    }
    // Make sure that the area function does exist!
    if (!isset($profile_include_data['function']) || !function_exists($profile_include_data['function'])) {
        destroyMenu();
        fatal_lang_error('no_access', false);
    }
    // Build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : ''), 'name' => sprintf($txt['profile_of_username'], $context['member']['name']));
    if (!empty($profile_include_data['label'])) {
        $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'], 'name' => $profile_include_data['label']);
    }
    if (!empty($profile_include_data['current_subsection']) && $profile_include_data['subsections'][$profile_include_data['current_subsection']][0] != $profile_include_data['label']) {
        $context['linktree'][] = array('url' => $scripturl . '?action=profile' . ($memID != $user_info['id'] ? ';u=' . $memID : '') . ';area=' . $profile_include_data['current_area'] . ';sa=' . $profile_include_data['current_subsection'], 'name' => $profile_include_data['subsections'][$profile_include_data['current_subsection']][0]);
    }
    // Set the template for this area and add the profile layer.
    $context['sub_template'] = $profile_include_data['function'];
    $context['template_layers'][] = 'profile';
    // All the subactions that require a user password in order to validate.
    $check_password = $context['user']['is_owner'] && in_array($profile_include_data['current_area'], $context['password_areas']);
    $context['require_password'] = $check_password && empty($user_settings['openid_uri']);
    // If we're in wireless then we have a cut down template...
    if (WIRELESS && $context['sub_template'] == 'summary' && WIRELESS_PROTOCOL != 'wap') {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_profile';
    }
    // These will get populated soon!
    $post_errors = array();
    $profile_vars = array();
    // Right - are we saving - if so let's save the old data first.
    if ($context['completed_save']) {
        // If it's someone elses profile then validate the session.
        if (!$context['user']['is_owner']) {
            validateSession();
        }
        // Clean up the POST variables.
        $_POST = htmltrim__recursive($_POST);
        $_POST = htmlspecialchars__recursive($_POST);
        if ($check_password) {
            // If we're using OpenID try to revalidate.
            if (!empty($user_settings['openid_uri'])) {
                require_once $sourcedir . '/Subs-OpenID.php';
                smf_openID_revalidate();
            } else {
                // You didn't even enter a password!
                if (trim($_POST['oldpasswrd']) == '') {
                    $post_errors[] = 'no_password';
                }
                // Since the password got modified due to all the $_POST cleaning, lets undo it so we can get the correct password
                $_POST['oldpasswrd'] = un_htmlspecialchars($_POST['oldpasswrd']);
                // Does the integration want to check passwords?
                $good_password = in_array(true, call_integration_hook('integrate_verify_password', array($cur_profile['member_name'], $_POST['oldpasswrd'], false)), true);
                // Bad password!!!
                if (!$good_password && $user_info['passwd'] != sha1(strtolower($cur_profile['member_name']) . $_POST['oldpasswrd'])) {
                    $post_errors[] = 'bad_password';
                }
                // Warn other elements not to jump the gun and do custom changes!
                if (in_array('bad_password', $post_errors)) {
                    $context['password_auth_failed'] = true;
                }
            }
        }
        // Change the IP address in the database.
        if ($context['user']['is_owner']) {
            $profile_vars['member_ip'] = $user_info['ip'];
        }
        // Now call the sub-action function...
        if ($current_area == 'activateaccount') {
            if (empty($post_errors)) {
                activateAccount($memID);
            }
        } elseif ($current_area == 'deleteaccount') {
            if (empty($post_errors)) {
                deleteAccount2($profile_vars, $post_errors, $memID);
                redirectexit();
            }
        } elseif ($current_area == 'groupmembership' && empty($post_errors)) {
            $msg = groupMembership2($profile_vars, $post_errors, $memID);
            // Whatever we've done, we have nothing else to do here...
            redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=groupmembership' . (!empty($msg) ? ';msg=' . $msg : ''));
        } elseif ($current_area == 'authentication') {
            authentication($memID, true);
        } elseif (in_array($current_area, array('account', 'forumprofile', 'theme', 'pmprefs'))) {
            saveProfileFields();
        } else {
            $force_redirect = true;
            // Ensure we include this.
            require_once $sourcedir . '/Profile-Modify.php';
            saveProfileChanges($profile_vars, $post_errors, $memID);
        }
        // There was a problem, let them try to re-enter.
        if (!empty($post_errors)) {
            // Load the language file so we can give a nice explanation of the errors.
            loadLanguage('Errors');
            $context['post_errors'] = $post_errors;
        } elseif (!empty($profile_vars)) {
            // If we've changed the password, notify any integration that may be listening in.
            if (isset($profile_vars['passwd'])) {
                call_integration_hook('integrate_reset_pass', array($cur_profile['member_name'], $cur_profile['member_name'], $_POST['passwrd2']));
            }
            updateMemberData($memID, $profile_vars);
            // What if this is the newest member?
            if ($modSettings['latestMember'] == $memID) {
                updateStats('member');
            } elseif (isset($profile_vars['real_name'])) {
                updateSettings(array('memberlist_updated' => time()));
            }
            // If the member changed his/her birthdate, update calendar statistics.
            if (isset($profile_vars['birthdate']) || isset($profile_vars['real_name'])) {
                updateSettings(array('calendar_updated' => time()));
            }
            // Anything worth logging?
            if (!empty($context['log_changes']) && !empty($modSettings['modlog_enabled'])) {
                $log_changes = array();
                foreach ($context['log_changes'] as $k => $v) {
                    $log_changes[] = array('action' => $k, 'id_log' => 2, 'log_time' => time(), 'id_member' => $memID, 'ip' => $user_info['ip'], 'extra' => serialize(array_merge($v, array('applicator' => $user_info['id']))));
                }
                $smcFunc['db_insert']('', '{db_prefix}log_actions', array('action' => 'string', 'id_log' => 'int', 'log_time' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'extra' => 'string-65534'), $log_changes, array('id_action'));
            }
            // Have we got any post save functions to execute?
            if (!empty($context['profile_execute_on_save'])) {
                foreach ($context['profile_execute_on_save'] as $saveFunc) {
                    $saveFunc();
                }
            }
            // Let them know it worked!
            $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $cur_profile['member_name']);
            // Invalidate any cached data.
            cache_put_data('member_data-profile-' . $memID, null, 0);
        }
    }
    // Have some errors for some reason?
    if (!empty($post_errors)) {
        // Set all the errors so the template knows what went wrong.
        foreach ($post_errors as $error_type) {
            $context['modify_error'][$error_type] = true;
        }
    } elseif (!empty($profile_vars) && $context['user']['is_owner']) {
        redirectexit('action=profile;area=' . $current_area . ';updated');
    } elseif (!empty($force_redirect)) {
        redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $memID) . ';area=' . $current_area);
    }
    // Call the appropriate subaction function.
    $profile_include_data['function']($memID);
    // Set the page title if it's not already set...
    if (!isset($context['page_title'])) {
        $context['page_title'] = $txt['profile'] . (isset($txt[$current_area]) ? ' - ' . $txt[$current_area] : '');
    }
}
Пример #12
0
/**
 *	Gather the data and prepare to display the ticket blocks.
 *
 *	Actually performs the queries to get data for each block, subject to the parameters specified by the calling functions.
 *
 *	It also sets up per-block pagination links, collects a variety of data (enough to populate all the columns as listed in shd_main_helpdesk,
 *	even if not entirely applicable, and populates it all into $context['ticket_blocks']['tickets'], extending the array that was
 *	already there.
 *
 *	@see shd_main_helpdesk()
 *	@see shd_closed_tickets()
 *	@see shd_recycle_bin()
 *	@since 1.0
*/
function shd_helpdesk_listing()
{
    global $context, $txt, $smcFunc, $user_profile, $scripturl, $settings, $user_info, $modSettings, $language;
    if (!empty($context['shd_permission'])) {
        shd_is_allowed_to($context['shd_permission']);
    }
    $block_list = array_keys($context['ticket_blocks']);
    $primary_url = '?action=helpdesk;sa=' . $_REQUEST['sa'];
    // First figure out the start positions of each item and sanitise them
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        if (empty($block['viewing_as_block'])) {
            $num_per_page = !empty($context['shd_preferences']['blocks_' . $block_key . '_count']) ? $context['shd_preferences']['blocks_' . $block_key . '_count'] : $context['items_per_page'];
            $start = empty($_REQUEST['st_' . $block_key]) ? 0 : (int) $_REQUEST['st_' . $block_key];
            $max_value = $block['count'];
            // easier to read
        } else {
            $num_per_page = $context['items_per_page'];
            $max_value = $context['items_per_page'];
            $start = 0;
        }
        if ($start < 0) {
            $start = 0;
        } elseif ($start >= $max_value) {
            $start = max(0, (int) $max_value - ((int) $max_value % (int) $num_per_page == 0 ? $num_per_page : (int) $max_value % (int) $num_per_page));
        } else {
            $start = max(0, (int) $start - (int) $start % (int) $num_per_page);
        }
        $context['ticket_blocks'][$block_key]['start'] = $start;
        $context['ticket_blocks'][$block_key]['num_per_page'] = $num_per_page;
        if ($start != 0) {
            $_REQUEST['st_' . $block_key] = $start;
        } elseif (isset($_REQUEST['st_' . $block_key])) {
            unset($_REQUEST['st_' . $block_key]);
        }
    }
    // Now ordering the columns, separate loop for breaking the two processes apart
    $sort_methods = array('ticketid' => array('sql' => 'hdt.id_ticket'), 'ticketname' => array('sql' => 'hdt.subject'), 'replies' => array('sql' => 'hdt.num_replies'), 'allreplies' => array('sql' => '(hdt.num_replies + hdt.deleted_replies)'), 'urgency' => array('sql' => 'hdt.urgency'), 'updated' => array('sql' => 'hdt.last_updated'), 'assigned' => array('sql' => 'assigned_name', 'sql_select' => 'IFNULL(mem.real_name, 0) AS assigned_name', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_assigned = mem.id_member)'), 'status' => array('sql' => 'hdt.status'), 'starter' => array('sql' => 'starter_name', 'sql_select' => 'IFNULL(mem.real_name, 0) AS starter_name', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member)'), 'lastreply' => array('sql' => 'last_reply', 'sql_select' => 'IFNULL(mem.real_name, 0) AS last_reply', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdtr_last.id_member = mem.id_member)'));
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        $sort = isset($_REQUEST['so_' . $block_key]) ? $_REQUEST['so_' . $block_key] : (!empty($context['shd_preferences']['block_order_' . $block_key . '_block']) ? $context['shd_preferences']['block_order_' . $block_key . '_block'] : '');
        if (strpos($sort, '_') > 0 && substr_count($sort, '_') == 1) {
            list($sort_item, $sort_dir) = explode('_', $sort);
            if (empty($sort_methods[$sort_item])) {
                $sort_item = 'updated';
                $sort = '';
            }
            if (!in_array($sort_dir, array('asc', 'desc'))) {
                $sort = '';
                $sort_dir = 'asc';
            }
        } else {
            $sort = '';
            $sort_item = 'updated';
            $sort_dir = $_REQUEST['sa'] == 'closedtickets' || $_REQUEST['sa'] == 'recyclebin' ? 'desc' : 'asc';
            // default to newest first if on recyclebin or closed tickets, otherwise oldest first
        }
        if ($sort != '') {
            $_REQUEST['so_' . $block_key] = $sort;
        } elseif (isset($_REQUEST['so_' . $block_key])) {
            unset($_REQUEST['so_' . $block_key]);
        }
        $context['ticket_blocks'][$block_key]['sort'] = array('item' => $sort_item, 'direction' => $sort_dir, 'add_link' => $sort != '', 'sql' => array('select' => !empty($sort_methods[$sort_item]['sql_select']) ? $sort_methods[$sort_item]['sql_select'] : '', 'join' => !empty($sort_methods[$sort_item]['sql_join']) ? $sort_methods[$sort_item]['sql_join'] : '', 'sort' => $sort_methods[$sort_item]['sql'] . ' ' . strtoupper($sort_dir)), 'link_bits' => array());
    }
    // Having got all that, step through the blocks again to determine the full URL fragments
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        foreach ($sort_methods as $method => $sort_details) {
            $context['ticket_blocks'][$block_key]['sort']['link_bits'][$method] = ';so_' . $block_key . '=' . $method . '_' . $block['sort']['direction'];
        }
    }
    // Figure out if the user is filtering on anything, and if so, set up containers for the extra joins, selects, pagination link fragments, etc
    $_REQUEST['field'] = isset($_REQUEST['field']) ? (int) $_REQUEST['field'] : 0;
    $_REQUEST['filter'] = isset($_REQUEST['filter']) ? (int) $_REQUEST['filter'] : 0;
    if ($_REQUEST['field'] > 0 && $_REQUEST['filter'] > 0) {
        $context['filter_fragment'] = ';field=' . $_REQUEST['field'] . ';filter=' . $_REQUEST['filter'];
        $context['filter_join'] = '
				INNER JOIN {db_prefix}helpdesk_custom_fields_values AS hdcfv ON (hdcfv.id_post = hdt.id_ticket AND hdcfv.id_field = {int:field} AND hdcfv.post_type = {int:type_ticket})
				INNER JOIN {db_prefix}helpdesk_custom_fields AS hdcf ON (hdcf.id_field = hdcfv.id_field AND hdcf.active = {int:active})';
        $context['filter_where'] = '
				AND hdcfv.value = {string:filter}';
    } else {
        $context['filter_fragment'] = '';
        $context['filter_join'] = '';
        $context['filter_where'] = '';
    }
    // Now go actually do the whole block thang, setting up space for a list of users and tickets as we go along
    $users = array();
    $tickets = array();
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        if (empty($block['display']) || !empty($block['collapsed'])) {
            continue;
        }
        $context['ticket_blocks'][$block_key]['tickets'] = array();
        // If we're filtering, we have to query it first to figure out how many rows there are in this block. It's not pretty.
        if (!empty($context['filter_join'])) {
            $query = shd_db_query('', '
				SELECT COUNT(hdt.id_ticket)
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
					INNER JOIN {db_prefix}helpdesk_depts AS hdd ON (hdt.id_dept = hdd.id_dept)
					' . (!empty($block['sort']['sql']['join']) ? $block['sort']['sql']['join'] : '') . $context['filter_join'] . '
				WHERE {query_see_ticket}' . (!empty($block['where']) ? ' AND ' . $block['where'] : '') . (!empty($context['shd_department']) ? ' AND hdt.id_dept = {int:dept}' : '') . $context['filter_where'], array('dept' => $context['shd_department'], 'user' => $context['user']['id'], 'field' => $_REQUEST['field'], 'filter' => $_REQUEST['filter'], 'type_ticket' => CFIELD_TICKET, 'active' => 1));
            list($context['ticket_blocks'][$block_key]['count']) = $smcFunc['db_fetch_row']($query);
            $block['count'] = $context['ticket_blocks'][$block_key]['count'];
            $smcFunc['db_free_result']($query);
            if ($block['start'] >= $block['count']) {
                $context['ticket_blocks'][$block_key]['start'] = max(0, (int) $block['count'] - ((int) $block['count'] % (int) $block['num_per_page'] == 0 ? $block['num_per_page'] : (int) $block['count'] % (int) $block['num_per_page']));
                $block['start'] = $context['ticket_blocks'][$block_key]['start'];
            }
        }
        $query = shd_db_query('', '
			SELECT hdt.id_ticket, hdt.id_dept, hdd.dept_name, hdt.id_last_msg, hdt.id_member_started, hdt.id_member_updated,
				hdt.id_member_assigned, hdt.subject, hdt.status, hdt.num_replies, hdt.deleted_replies, hdt.private, hdt.urgency,
				hdt.last_updated, hdtr_first.poster_name AS ticket_opener, hdtr_last.poster_name AS respondent, hdtr_last.poster_time,
				IFNULL(hdlr.id_msg, 0) AS log_read' . (!empty($block['sort']['sql']['select']) ? ', ' . $block['sort']['sql']['select'] : '') . '
			FROM {db_prefix}helpdesk_tickets AS hdt
				INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
				INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
				INNER JOIN {db_prefix}helpdesk_depts AS hdd ON (hdt.id_dept = hdd.id_dept)
				LEFT JOIN {db_prefix}helpdesk_log_read AS hdlr ON (hdt.id_ticket = hdlr.id_ticket AND hdlr.id_member = {int:user})
				' . (!empty($block['sort']['sql']['join']) ? $block['sort']['sql']['join'] : '') . $context['filter_join'] . '
			WHERE {query_see_ticket}' . (!empty($block['where']) ? ' AND ' . $block['where'] : '') . (!empty($context['shd_department']) ? ' AND hdt.id_dept = {int:dept}' : '') . $context['filter_where'] . '
			ORDER BY ' . (!empty($block['sort']['sql']['sort']) ? $block['sort']['sql']['sort'] : 'hdt.id_last_msg ASC') . '
			LIMIT {int:start}, {int:items_per_page}', array('dept' => $context['shd_department'], 'user' => $context['user']['id'], 'start' => $block['start'], 'items_per_page' => $block['num_per_page'], 'field' => $_REQUEST['field'], 'filter' => $_REQUEST['filter'], 'type_ticket' => CFIELD_TICKET, 'active' => 1));
        while ($row = $smcFunc['db_fetch_assoc']($query)) {
            $is_own = $user_info['id'] == $row['id_member_started'];
            censorText($row['subject']);
            $new_block = array('id' => $row['id_ticket'], 'display_id' => str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), 'dept_link' => empty($context['shd_department']) && $context['shd_multi_dept'] ? '[<a href="' . $scripturl . '?' . $context['shd_home'] . ';dept=' . $row['id_dept'] . '">' . $row['dept_name'] . '</a>] ' : '', 'link' => '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '">' . $row['subject'] . '</a>', 'subject' => $row['subject'], 'status' => array('level' => $row['status'], 'label' => $txt['shd_status_' . $row['status']]), 'starter' => array('id' => $row['id_member_started'], 'name' => $row['ticket_opener']), 'last_update' => timeformat($row['last_updated']), 'assigned' => array('id' => $row['id_member_assigned']), 'respondent' => array('id' => $row['id_member_updated'], 'name' => $row['respondent']), 'urgency' => array('level' => $row['urgency'], 'label' => $row['urgency'] > TICKET_URGENCY_HIGH ? '<span class="error">' . $txt['shd_urgency_' . $row['urgency']] . '</span>' : $txt['shd_urgency_' . $row['urgency']]), 'is_unread' => $row['id_last_msg'] > $row['log_read'], 'new_href' => $row['id_last_msg'] <= $row['log_read'] ? '' : $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . '.new' . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '#new', 'private' => $row['private'], 'actions' => array('movedept' => !empty($context['shd_multi_dept']) && (shd_allowed_to('shd_move_dept_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_move_dept_own', $context['shd_department'])) ? '<a href="' . $scripturl . '?action=helpdesk;sa=movedept;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_move_dept'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/movedept.png" alt="' . $txt['shd_move_dept'] . '" /></a>' : ''), 'num_replies' => $row['num_replies'], 'replies_href' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . '.msg' . $row['id_last_msg'] . '#msg' . $row['id_last_msg'] . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : ''), 'all_replies' => (int) $row['num_replies'] + (int) $row['deleted_replies']);
            if ($row['status'] == TICKET_STATUS_CLOSED) {
                $new_block['actions'] += array('resolve' => shd_allowed_to('shd_unresolve_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_unresolve_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_unresolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/unresolved.png" alt="' . $txt['shd_ticket_unresolved'] . '" /></a>' : '');
            } elseif ($row['status'] == TICKET_STATUS_DELETED) {
                $new_block['actions'] += array('restore' => shd_allowed_to('shd_restore_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_restore_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=restoreticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_restore'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/restore.png" alt="' . $txt['shd_ticket_restore'] . '" /></a>' : '', 'permadelete' => shd_allowed_to('shd_delete_recycling', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=permadelete;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_delete_permanently'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_permanently_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_delete_permanently'] . '" /></a>' : '');
            } else {
                $langstring = '';
                if (shd_allowed_to('shd_assign_ticket_any', $context['shd_department'])) {
                    $langstring = empty($row['id_member_assigned']) ? $txt['shd_ticket_assign'] : $txt['shd_ticket_reassign'];
                } elseif (shd_allowed_to('shd_assign_ticket_own', $context['shd_department']) && (empty($row['id_member_assigned']) || $row['id_member_assigned'] == $context['user']['id'])) {
                    $langstring = $row['id_member_assigned'] == $context['user']['id'] ? $txt['shd_ticket_unassign'] : $txt['shd_ticket_assign_self'];
                }
                if (!empty($langstring)) {
                    $new_block['actions']['assign'] = '<a href="' . $scripturl . '?action=helpdesk;sa=assign;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $langstring . '"><img src="' . $settings['default_images_url'] . '/simpledesk/assign.png" alt="' . $langstring . '" /></a>';
                }
                $new_block['actions'] += array('resolve' => shd_allowed_to('shd_resolve_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_resolve_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_resolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/resolved.png" alt="' . $txt['shd_ticket_resolved'] . '" /></a>' : '', 'tickettotopic' => empty($modSettings['shd_helpdesk_only']) && shd_allowed_to('shd_ticket_to_topic', $context['shd_department']) && ($row['deleted_replies'] == 0 || shd_allowed_to('shd_access_recyclebin')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=tickettotopic;ticket=' . $row['id_ticket'] . ';' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_move_to_topic'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/tickettotopic.png" alt="' . $txt['shd_ticket_move_to_topic'] . '" /></a>' : '', 'delete' => shd_allowed_to('shd_delete_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_delete_ticket_own') ? '<a href="' . $scripturl . '?action=helpdesk;sa=deleteticket;ticket=' . $row['id_ticket'] . ';' . $context['shd_dept_link'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_delete'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_ticket_delete'] . '" /></a>' : '');
            }
            $context['ticket_blocks'][$block_key]['tickets'][$row['id_ticket']] = $new_block;
            $users[] = $row['id_member_started'];
            $users[] = $row['id_member_updated'];
            $users[] = $row['id_member_assigned'];
            $tickets[$row['id_ticket']] = array();
        }
        $smcFunc['db_free_result']($query);
    }
    $users = array_unique($users);
    if (!empty($users)) {
        loadMemberData($users, false, 'minimal');
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['tickets'])) {
            continue;
        }
        foreach ($block['tickets'] as $tid => $ticket) {
            // Set up names and profile links for topic starter
            if (!empty($user_profile[$ticket['starter']['id']])) {
                // We found the name, so let's use their current name and profile link
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name'] = $user_profile[$ticket['starter']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = shd_profile_link($user_profile[$ticket['starter']['id']]['real_name'], $ticket['starter']['id']);
            } else {
                // We didn't, so keep using the name we found previously and don't make an actual link
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name'];
            }
            // Set up names and profile links for assigned user
            if ($ticket['assigned']['id'] == 0 || empty($user_profile[$ticket['assigned']['id']])) {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $txt['shd_unassigned'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = '<span class="error">' . $txt['shd_unassigned'] . '</span>';
            } else {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $user_profile[$ticket['assigned']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = shd_profile_link($user_profile[$ticket['assigned']['id']]['real_name'], $ticket['assigned']['id']);
            }
            // And last respondent
            if ($ticket['respondent']['id'] == 0 || empty($user_profile[$ticket['respondent']['id']])) {
                // Didn't find the name, so reuse what we have
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name'];
            } else {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name'] = $user_profile[$ticket['respondent']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = shd_profile_link($user_profile[$ticket['respondent']['id']]['real_name'], $ticket['respondent']['id']);
            }
        }
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['display']) || empty($block['count']) && !$block['required'] && empty($block['collapsed'])) {
            unset($context['ticket_blocks'][$block_id]);
        }
    }
    $base_url = '';
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if ($block['sort']['add_link']) {
            $base_url .= $block['sort']['link_bits'][$block['sort']['item']];
        }
    }
    if ($_REQUEST['sa'] != 'viewblock') {
        foreach ($context['ticket_blocks'] as $block_id => $block) {
            $num_per_page = !empty($context['shd_preferences']['blocks_' . $block_key . '_count']) ? $context['shd_preferences']['blocks_' . $block_key . '_count'] : $context['items_per_page'];
            $url_fragment = $base_url;
            foreach ($block_list as $block_item) {
                if ($block_item == $block_id) {
                    $url_fragment .= ';st_' . $block_item . '=%1$d';
                } elseif (!empty($context['ticket_blocks'][$block_item]['start'])) {
                    $url_fragment .= ';st_' . $block_item . '=' . $context['ticket_blocks'][$block_item]['start'];
                }
            }
            $context['start'] = $context['ticket_blocks'][$block_id]['start'];
            $context['ticket_blocks'][$block_id]['page_index'] = shd_no_expand_pageindex($scripturl . $primary_url . $url_fragment . $context['shd_dept_link'] . $context['filter_fragment'] . '#shd_block_' . $block_id, $context['start'], $block['count'], $block['num_per_page'], true);
        }
    }
    // Just need to deal with those pesky prefix fields, if there are any.
    if (empty($tickets)) {
        return;
    }
    // We're all done here.
    // 1. Figure out if there are any custom fields that apply to us or not.
    if ($context['shd_multi_dept'] && empty($context['shd_department'])) {
        $dept_list = shd_allowed_to('access_helpdesk', false);
    } else {
        $dept_list = array($context['shd_department']);
    }
    $fields = array();
    $query = $smcFunc['db_query']('', '
		SELECT hdcf.id_field, can_see, field_type, field_options, placement, field_name
		FROM {db_prefix}helpdesk_custom_fields AS hdcf
			INNER JOIN {db_prefix}helpdesk_custom_fields_depts AS hdcfd ON (hdcfd.id_field = hdcf.id_field)
		WHERE placement IN ({array_int:placement_prefix})
			AND field_loc IN ({array_int:locations})
			AND hdcfd.id_dept IN ({array_int:dept_list})
			AND active = {int:active}
		GROUP BY hdcf.id_field
		ORDER BY field_order', array('locations' => array(CFIELD_TICKET, CFIELD_TICKET | CFIELD_REPLY), 'placement_prefix' => array(CFIELD_PLACE_PREFIX, CFIELD_PLACE_PREFIXFILTER), 'active' => 1, 'dept_list' => $dept_list));
    $is_staff = shd_allowed_to('shd_staff', $context['shd_department']);
    $is_admin = $context['user']['is_admin'] || shd_allowed_to('admin_helpdesk', $context['shd_department']);
    $context['shd_filter_fields'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        list($user_see, $staff_see) = explode(',', $row['can_see']);
        if ($is_admin || $is_staff && $staff_see == '1' || !$is_staff && $user_see == '1') {
            if (!empty($row['field_options'])) {
                $row['field_options'] = unserialize($row['field_options']);
                if (isset($row['field_options']['inactive'])) {
                    unset($row['field_options']['inactive']);
                }
                foreach ($row['field_options'] as $k => $v) {
                    if (strpos($v, '[') !== false) {
                        $row['field_options'][$k] = parse_bbc($v);
                    }
                }
            }
            $fields[$row['id_field']] = $row;
            if ($row['placement'] == CFIELD_PLACE_PREFIXFILTER) {
                $context['shd_filter_fields'][$row['id_field']] = array('name' => $row['field_name'], 'options' => $row['field_options'], 'in_use' => array());
            }
        }
    }
    $smcFunc['db_free_result']($query);
    if (empty($fields)) {
        return;
    }
    // No fields to process, time to go.
    // 2. Get the relevant values.
    $query = $smcFunc['db_query']('', '
		SELECT id_post, id_field, value
		FROM {db_prefix}helpdesk_custom_fields_values
		WHERE id_post IN ({array_int:tickets})
			AND id_field IN ({array_int:fields})
			AND post_type = {int:ticket}', array('tickets' => array_keys($tickets), 'fields' => array_keys($fields), 'ticket' => CFIELD_TICKET));
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $tickets[$row['id_post']][$row['id_field']] = $row['value'];
    }
    // 3. Apply the values into the tickets.
    if ($_REQUEST['sa'] == 'closedtickets') {
        $context['filterbase'] = $scripturl . '?action=helpdesk;sa=closedtickets';
    } elseif ($_REQUEST['sa'] == 'recyclebin') {
        $context['filterbase'] = $scripturl . '?action=helpdesk;sa=recyclebin';
    } else {
        $context['filterbase'] = $scripturl . '?' . $context['shd_home'];
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['tickets'])) {
            continue;
        }
        foreach ($block['tickets'] as $ticket_id => $ticket) {
            if (isset($tickets[$ticket_id])) {
                $prefix_filter = '';
                $prefix = '';
                foreach ($fields as $field_id => $field) {
                    if (empty($tickets[$ticket_id][$field_id])) {
                        continue;
                    }
                    if ($field['placement'] == CFIELD_PLACE_PREFIXFILTER) {
                        if (!isset($field['field_options'][$tickets[$ticket_id][$field_id]])) {
                            continue;
                        }
                        $prefix_filter .= '[<a href="' . $context['filterbase'] . $context['shd_dept_link'] . ';field=' . $field_id . ';filter=' . $tickets[$ticket_id][$field_id] . '">' . $field['field_options'][$tickets[$ticket_id][$field_id]] . '</a>] ';
                    } else {
                        if ($field['field_type'] == CFIELD_TYPE_CHECKBOX) {
                            $prefix .= !empty($tickets[$ticket_id][$field_id]) ? $txt['yes'] . ' ' : $txt['no'] . ' ';
                        } elseif ($field['field_type'] == CFIELD_TYPE_SELECT || $field['field_type'] == CFIELD_TYPE_RADIO) {
                            $prefix .= $field['field_options'][$tickets[$ticket_id][$field_id]] . ' ';
                        } elseif ($field['field_type'] == CFIELD_TYPE_MULTI) {
                            $values = explode(',', $tickets[$ticket_id][$field_id]);
                            foreach ($values as $value) {
                                $prefix .= $field['field_options'][$value] . ' ';
                            }
                        } else {
                            $prefix .= $tickets[$ticket_id][$field_id] . ' ';
                        }
                    }
                }
                // First, set aside the subject, and if there is a non category prefix, strip links from it.
                $subject = $ticket['subject'];
                if (!empty($prefix)) {
                    $prefix = '[' . trim(preg_replace('~<a (.*?)</a>~is', '', $prefix)) . '] ';
                }
                // Then, if we have a category prefix, prepend that to any other prefix we have.
                if (!empty($prefix_filter)) {
                    $prefix = $prefix_filter . $prefix;
                }
                // Lastly, if we have some kind of prefix to put in front of this ticket, do so.
                if (!empty($prefix)) {
                    $context['ticket_blocks'][$block_id]['tickets'][$ticket_id]['subject'] = $prefix . $subject;
                    $context['ticket_blocks'][$block_id]['tickets'][$ticket_id]['link'] = $prefix . '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $ticket_id . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '">' . $subject . '</a>';
                }
            }
        }
    }
    // 4. We've collected the list of prefix-filter fields in use, now establish which values are actually in use.
    if (!empty($context['shd_filter_fields'])) {
        $query = $smcFunc['db_query']('', '
			SELECT id_field, value
			FROM {db_prefix}helpdesk_custom_fields_values
			WHERE id_field IN ({array_int:fields})', array('fields' => array_keys($context['shd_filter_fields'])));
        while ($row = $smcFunc['db_fetch_assoc']($query)) {
            $context['shd_filter_fields'][$row['id_field']]['in_use'][$row['value']] = true;
        }
        $smcFunc['db_free_result']($query);
        foreach ($context['shd_filter_fields'] as $id_field => $field) {
            if (empty($field['in_use'])) {
                unset($context['shd_filter_fields'][$id_field]);
            } else {
                foreach ($field['options'] as $k => $v) {
                    if (!isset($field['in_use'][$k])) {
                        unset($context['shd_filter_fields'][$id_field]['options'][$k]);
                    }
                }
                if (empty($context['shd_filter_fields'][$id_field]['options'])) {
                    unset($context['shd_filter_fields'][$id_field]);
                }
            }
        }
    }
}
Пример #13
0
if (!isset($website)) {
    header('HTTP/1.1 404 Not Found');
    die;
}
if (!is_logged()) {
    if (file_exists($smf_forum . 'SSI.php')) {
        include $smf_forum . 'SSI.php';
        global $context, $txt, $scripturl;
        if ($context["user"]["id"] >= 1) {
            $SMF_id = $context["user"]["id"];
            $SMF_session_var = $context['session_var'];
            $SMF_sid =& $context['session_id'];
            $SMF_username = $context["user"]["name"];
            $SMF_email = $context["user"]["email"];
            $SMF_website = $smf_forum_url . "index.php?action=profile;u=" . $SMF_id;
            $userID = loadMemberData($SMF_username, true, 'profile');
            loadMemberContext($userID[0]);
            $SMF_avatar = $memberContext[$userID[0]]['avatar']['href'];
            require_once 'inc/common.php';
            require_once 'inc/class.db.PDO.php';
            //require_once('inc/db_connect.php');
            $OSDB = new db("mysql:host=" . OSDB_SERVER . ";dbname=" . OSDB_DATABASE . "", OSDB_USERNAME, OSDB_PASSWORD);
            $sth = $db->prepare("SELECT * FROM " . OSDB_USERS . " \n\t\t WHERE user_email = :SMF_email AND smf_id = :SMF_id ");
            $sth->bindValue(':SMF_email', $SMF_email, PDO::PARAM_STR);
            $sth->bindValue(':SMF_id', $SMF_id, PDO::PARAM_STR);
            $result = $sth->execute();
            if ($sth->rowCount() <= 0) {
                //CREATE NEW USER (from phpbb database)
                $sth = $db->prepare("SELECT * FROM " . OSDB_USERS . " WHERE LOWER(user_name) = :SMF_username ");
                $sth->bindValue(':SMF_username', strtolower($SMF_username), PDO::PARAM_STR);
                $result = $sth->execute();
Пример #14
0
function MessageSearch2()
{
    global $scripturl, $modSettings, $user_info, $context, $txt, $db_prefix;
    global $ID_MEMBER, $memberContext, $func;
    if (!empty($context['load_average']) && !empty($modSettings['loadavg_search']) && $context['load_average'] >= $modSettings['loadavg_search']) {
        fatal_lang_error('loadavg_search_disabled', false);
    }
    // !!! For the moment force the folder to the inbox.
    $context['folder'] = 'inbox';
    // Some useful general permissions.
    $context['can_send_pm'] = allowedTo('pm_send');
    // Some hardcoded veriables that can be tweaked if required.
    $maxMembersToSearch = 500;
    // Extract all the search parameters.
    $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);
        }
    }
    $context['start'] = isset($_GET['start']) ? (int) $_GET['start'] : 0;
    // 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'];
    }
    $search_params['subject_only'] = !empty($search_params['subject_only']) || !empty($_REQUEST['subject_only']);
    $search_params['show_complete'] = !empty($search_params['show_complete']) || !empty($_REQUEST['show_complete']);
    // Default the user name to a wildcard matching every user (*).
    if (!empty($search_params['user_spec']) || !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]);
            }
        }
        // Who matches those criteria?
        // !!! This doesn't support outbox searching.
        $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 = "AND pm.ID_MEMBER_FROM = 0 AND (pm.fromName LIKE '" . implode("' OR pm.fromName LIKE '", $possible_users) . "')";
        } else {
            $memberlist = array();
            while ($row = mysql_fetch_assoc($request)) {
                $memberlist[] = $row['ID_MEMBER'];
            }
            $userQuery = "AND (pm.ID_MEMBER_FROM IN (" . implode(', ', $memberlist) . ") OR (pm.ID_MEMBER_FROM = 0 AND (pm.fromName LIKE '" . implode("' OR pm.fromName LIKE '", $possible_users) . "')))";
        }
        mysql_free_result($request);
    }
    // Setup the sorting variables...
    // !!! Add more in here!
    $sort_columns = array('ID_PM');
    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'] : 'ID_PM';
    $search_params['sort_dir'] = !empty($search_params['sort_dir']) && $search_params['sort_dir'] == 'asc' ? 'asc' : 'desc';
    // Sort out any labels we may be searching by.
    $labelQuery = '';
    if ($context['folder'] == 'inbox' && !empty($search_params['advanced']) && $context['currently_using_labels']) {
        // Came here from pagination?  Put them back into $_REQUEST for sanitization.
        if (isset($search_params['labels'])) {
            $_REQUEST['searchlabel'] = explode(',', $search_params['labels']);
        }
        // Assuming we have some labels - make them all integers.
        if (!empty($_REQUEST['searchlabel']) && is_array($_REQUEST['searchlabel'])) {
            foreach ($_REQUEST['searchlabel'] as $key => $id) {
                $_REQUEST['searchlabel'][$key] = (int) $id;
            }
        } else {
            $_REQUEST['searchlabel'] = array();
        }
        // Now that everything is cleaned up a bit, make the labels a param.
        $search_params['labels'] = implode(',', $_REQUEST['searchlabel']);
        // No labels selected? That must be an error!
        if (empty($_REQUEST['searchlabel'])) {
            $context['search_errors']['no_labels_selected'] = true;
        } elseif (count($_REQUEST['searchlabel']) != count($context['labels'])) {
            $labelQuery = "\n\t\t\tAND (FIND_IN_SET('" . implode("', pmr.labels) OR FIND_IN_SET('", $_REQUEST['searchlabel']) . "', pmr.labels))";
        }
    }
    // What are we actually searching for?
    $search_params['search'] = !empty($search_params['search']) ? $search_params['search'] : (isset($_REQUEST['search']) ? stripslashes($_REQUEST['search']) : '');
    // If we ain't got nothing - we should error!
    if (!isset($search_params['search']) || $search_params['search'] == '') {
        $context['search_errors']['invalid_search_string'] = true;
    }
    // Extract phrase parts first (e.g. some words "this is a phrase" some more words.)
    preg_match_all('~(?:^|\\s)([-]?)"([^"]+)"(?:$|\\s)~' . ($context['utf8'] ? 'u' : ''), $search_params['search'], $matches, PREG_PATTERN_ORDER);
    $searchArray = $matches[2];
    // Remove the phrase parts and extract the words.
    $tempSearch = 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();
    // .. first, we check for things like -"some words", but not "-some words".
    foreach ($matches[1] as $index => $word) {
        if ($word == '-') {
            $word = $func['strtolower'](trim($searchArray[$index]));
            if (strlen($word) > 0) {
                $excludedWords[] = addslashes($word);
            }
            unset($searchArray[$index]);
        }
    }
    // Now we look for -test, etc.... normaller.
    foreach ($tempSearch as $index => $word) {
        if (strpos(trim($word), '-') === 0) {
            $word = substr($func['strtolower'](trim($word)), 1);
            if (strlen($word) > 0) {
                $excludedWords[] = addslashes($word);
            }
            unset($tempSearch[$index]);
        }
    }
    $searchArray = array_merge($searchArray, $tempSearch);
    // Trim everything and make sure there are no words that are the same.
    foreach ($searchArray as $index => $value) {
        $searchArray[$index] = $func['strtolower'](trim($value));
        if ($searchArray[$index] == '') {
            unset($searchArray[$index]);
        } else {
            // Sort out entities first.
            $searchArray[$index] = $func['htmlspecialchars']($searchArray[$index]);
            $searchArray[$index] = addslashes($searchArray[$index]);
        }
    }
    $searchArray = array_unique($searchArray);
    // Create an array of replacements for highlighting.
    $context['mark'] = array();
    foreach ($searchArray as $word) {
        $context['mark'][$word] = '<b class="highlight">' . $word . '</b>';
    }
    // This contains *everything*
    $searchWords = array_merge($searchArray, $excludedWords);
    // Make sure at least one word is being searched for.
    if (empty($searchArray)) {
        $context['search_errors']['invalid_search_string'] = true;
    }
    // Sort out the search query so the user can edit it - if they want.
    $context['search_params'] = $search_params;
    if (isset($context['search_params']['search'])) {
        $context['search_params']['search'] = htmlspecialchars($context['search_params']['search']);
    }
    if (isset($context['search_params']['userspec'])) {
        $context['search_params']['userspec'] = htmlspecialchars($context['search_params']['userspec']);
    }
    // Now we have all the parameters, combine them together for pagination and the like...
    $context['params'] = array();
    foreach ($search_params as $k => $v) {
        $context['params'][] = $k . '|\'|' . addslashes($v);
    }
    $context['params'] = base64_encode(implode('|"|', $context['params']));
    // Compile the subject query part.
    $andQueryParts = array();
    foreach ($searchWords as $index => $word) {
        if ($word == '') {
            continue;
        }
        if ($search_params['subject_only']) {
            $andQueryParts[] = "pm.subject" . (in_array($word, $excludedWords) ? ' NOT' : '') . " LIKE '%" . strtr($word, array('_' => '\\_', '%' => '\\%')) . "%'";
        } else {
            $andQueryParts[] = '(pm.subject' . (in_array($word, $excludedWords) ? ' NOT' : '') . " LIKE '%" . strtr($word, array('_' => '\\_', '%' => '\\%')) . "%' " . (in_array($word, $excludedWords) ? 'AND pm.body NOT' : 'OR pm.body') . " LIKE '%" . strtr($word, array('_' => '\\_', '%' => '\\%')) . "%')";
        }
    }
    $searchQuery = ' 1';
    if (!empty($andQueryParts)) {
        $searchQuery = implode(!empty($search_params['searchtype']) && $search_params['searchtype'] == 2 ? ' OR ' : ' AND ', $andQueryParts);
    }
    // If we have errors - return back to the first screen...
    if (!empty($context['search_errors'])) {
        $_REQUEST['params'] = $context['params'];
        return MessageSearch();
    }
    // Get the amount of results.
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM ({$db_prefix}pm_recipients AS pmr, {$db_prefix}personal_messages AS pm)\n\t\tWHERE pm.ID_PM = pmr.ID_PM" . ($context['folder'] == 'inbox' ? "\n\t\t\tAND pmr.ID_MEMBER = {$ID_MEMBER}\n\t\t\tAND pmr.deleted = 0" : "\n\t\t\tAND pm.ID_MEMBER_FROM = {$ID_MEMBER}\n\t\t\tAND pm.deletedBySender = 0") . "\n\t\t\t{$userQuery}{$labelQuery}\n\t\t\tAND ({$searchQuery})", __FILE__, __LINE__);
    list($numResults) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Get all the matching messages... using standard search only (No caching and the like!)
    // !!! This doesn't support outbox searching yet.
    $request = db_query("\n\t\tSELECT pm.ID_PM, pm.ID_MEMBER_FROM\n\t\tFROM ({$db_prefix}pm_recipients AS pmr, {$db_prefix}personal_messages AS pm)\n\t\tWHERE pm.ID_PM = pmr.ID_PM" . ($context['folder'] == 'inbox' ? "\n\t\t\tAND pmr.ID_MEMBER = {$ID_MEMBER}\n\t\t\tAND pmr.deleted = 0" : "\n\t\t\tAND pm.ID_MEMBER_FROM = {$ID_MEMBER}\n\t\t\tAND pm.deletedBySender = 0") . "\n\t\t\t{$userQuery}{$labelQuery}\n\t\t\tAND ({$searchQuery})\n\t\tORDER BY {$search_params['sort']} {$search_params['sort_dir']}\n\t\tLIMIT {$context['start']}, {$modSettings['search_results_per_page']}", __FILE__, __LINE__);
    $foundMessages = array();
    $posters = array();
    while ($row = mysql_fetch_assoc($request)) {
        $foundMessages[] = $row['ID_PM'];
        $posters[] = $row['ID_MEMBER_FROM'];
    }
    mysql_free_result($request);
    // Load the users...
    $posters = array_unique($posters);
    if (!empty($posters)) {
        loadMemberData($posters);
    }
    // Sort out the page index.
    $context['page_index'] = constructPageIndex($scripturl . '?action=pm;sa=search2;params=' . $context['params'], $_GET['start'], $numResults, $modSettings['search_results_per_page'], false);
    $context['message_labels'] = array();
    $context['message_replied'] = array();
    $context['personal_messages'] = array();
    if (!empty($foundMessages)) {
        // Now get recipients (but don't include bcc-recipients for your inbox, you're not supposed to know :P!)
        $request = db_query("\n\t\t\tSELECT\n\t\t\t\tpmr.ID_PM, mem_to.ID_MEMBER AS ID_MEMBER_TO, mem_to.realName AS toName,\n\t\t\t\tpmr.bcc, pmr.labels, pmr.is_read\n\t\t\tFROM {$db_prefix}pm_recipients AS pmr\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem_to ON (mem_to.ID_MEMBER = pmr.ID_MEMBER)\n\t\t\tWHERE pmr.ID_PM IN (" . implode(', ', $foundMessages) . ")", __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($request)) {
            if ($context['folder'] == 'outbox' || empty($row['bcc'])) {
                $recipients[$row['ID_PM']][empty($row['bcc']) ? 'to' : 'bcc'][] = empty($row['ID_MEMBER_TO']) ? $txt[28] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER_TO'] . '">' . $row['toName'] . '</a>';
            }
            if ($row['ID_MEMBER_TO'] == $ID_MEMBER && $context['folder'] != 'outbox') {
                $context['message_replied'][$row['ID_PM']] = $row['is_read'] & 2;
                $row['labels'] = $row['labels'] == '' ? array() : explode(',', $row['labels']);
                // This is a special need for linking to messages.
                foreach ($row['labels'] as $v) {
                    if (isset($context['labels'][(int) $v])) {
                        $context['message_labels'][$row['ID_PM']][(int) $v] = array('id' => $v, 'name' => $context['labels'][(int) $v]['name']);
                    }
                    // Here we find the first label on a message - for linking to posts in results
                    if (!isset($context['first_label'][$row['ID_PM']]) && !in_array('-1', $row['labels'])) {
                        $context['first_label'][$row['ID_PM']] = (int) $v;
                    }
                }
            }
        }
        // Prepare the query for the callback!
        $request = db_query("\n\t\t\tSELECT pm.ID_PM, pm.subject, pm.ID_MEMBER_FROM, pm.body, pm.msgtime, pm.fromName\n\t\t\tFROM {$db_prefix}personal_messages AS pm\n\t\t\tWHERE pm.ID_PM IN (" . implode(',', $foundMessages) . ")\n\t\t\tORDER BY {$search_params['sort']} {$search_params['sort_dir']}\n\t\t\tLIMIT " . count($foundMessages), __FILE__, __LINE__);
        $counter = 0;
        while ($row = mysql_fetch_assoc($request)) {
            // If there's no message subject, use the default.
            $row['subject'] = $row['subject'] == '' ? $txt[24] : $row['subject'];
            // Load this posters context info, if it ain't there then fill in the essentials...
            if (!loadMemberContext($row['ID_MEMBER_FROM'])) {
                $memberContext[$row['ID_MEMBER_FROM']]['name'] = $row['fromName'];
                $memberContext[$row['ID_MEMBER_FROM']]['id'] = 0;
                $memberContext[$row['ID_MEMBER_FROM']]['group'] = $txt[28];
                $memberContext[$row['ID_MEMBER_FROM']]['link'] = $row['fromName'];
                $memberContext[$row['ID_MEMBER_FROM']]['email'] = '';
                $memberContext[$row['ID_MEMBER_FROM']]['hide_email'] = true;
                $memberContext[$row['ID_MEMBER_FROM']]['is_guest'] = true;
            }
            // Censor anything we don't want to see...
            censorText($row['body']);
            censorText($row['subject']);
            // Parse out any BBC...
            $row['body'] = parse_bbc($row['body'], true, 'pm' . $row['ID_PM']);
            $href = $scripturl . '?action=pm;f=' . $context['folder'] . (isset($context['first_label'][$row['ID_PM']]) ? ';l=' . $context['first_label'][$row['ID_PM']] : '') . ';pmid=' . $row['ID_PM'] . '#msg' . $row['ID_PM'];
            $context['personal_messages'][] = array('id' => $row['ID_PM'], 'member' => &$memberContext[$row['ID_MEMBER_FROM']], 'subject' => $row['subject'], 'body' => $row['body'], 'time' => timeformat($row['msgtime']), 'recipients' => &$recipients[$row['ID_PM']], 'labels' => &$context['message_labels'][$row['ID_PM']], 'fully_labeled' => count($context['message_labels'][$row['ID_PM']]) == count($context['labels']), 'is_replied_to' => &$context['message_replied'][$row['ID_PM']], 'href' => $href, 'link' => '<a href="' . $href . '">' . $row['subject'] . '</a>', 'counter' => ++$counter);
        }
        mysql_free_result($request);
    }
    // Finish off the context.
    $context['page_title'] = $txt['pm_search_title'];
    $context['sub_template'] = 'search_results';
    $context['pm_area'] = 'search';
    $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=search', 'name' => $txt['pm_search_bar_title']);
}
Пример #15
0
function editBuddies($memID)
{
    global $txt, $scripturl, $modSettings, $db_prefix;
    global $context, $user_profile, $memberContext, $func;
    // Do a quick check to ensure people aren't getting here illegally!
    if (!$context['user']['is_owner'] || empty($modSettings['enable_buddylist'])) {
        fatal_lang_error(1, false);
    }
    // !!! No page_title.
    // For making changes!
    $buddiesArray = explode(',', $user_profile[$memID]['buddy_list']);
    foreach ($buddiesArray as $k => $dummy) {
        if ($dummy == '') {
            unset($buddiesArray[$k]);
        }
    }
    // Removing a buddy?
    if (isset($_GET['remove'])) {
        // Heh, I'm lazy, do it the easy way...
        foreach ($buddiesArray as $key => $buddy) {
            if ($buddy == (int) $_GET['remove']) {
                unset($buddiesArray[$key]);
            }
        }
        // Make the changes.
        $user_profile[$memID]['buddy_list'] = implode(',', $buddiesArray);
        updateMemberData($memID, array('buddy_list' => "'" . $user_profile[$memID]['buddy_list'] . "'"));
        // Redirect off the page because we don't like all this ugly query stuff to stick in the history.
        redirectexit('action=profile;u=' . $memID . ';sa=editBuddies');
    } elseif (isset($_POST['new_buddy'])) {
        // Prepare the string for extraction...
        $_POST['new_buddy'] = strtr(addslashes($func['htmlspecialchars'](stripslashes($_POST['new_buddy']), ENT_QUOTES)), array('&quot;' => '"'));
        preg_match_all('~"([^"]+)"~', $_POST['new_buddy'], $matches);
        $new_buddies = array_unique(array_merge($matches[1], explode(',', preg_replace('~"([^"]+)"~', '', $_POST['new_buddy']))));
        foreach ($new_buddies as $k => $dummy) {
            $new_buddies[$k] = strtr(trim($new_buddies[$k]), array('\\\'' => '&#039;'));
            if (strlen($new_buddies[$k]) == 0) {
                unset($new_buddies[$k]);
            }
        }
        if (!empty($new_buddies)) {
            // Now find out the ID_MEMBER of the buddy.
            $request = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE memberName IN ('" . implode("','", $new_buddies) . "') OR realName IN ('" . implode("','", $new_buddies) . "')\n\t\t\t\tLIMIT " . count($new_buddies), __FILE__, __LINE__);
            // Add the new member to the buddies array.
            while ($row = mysql_fetch_assoc($request)) {
                $buddiesArray[] = (int) $row['ID_MEMBER'];
            }
            mysql_free_result($request);
            // Now update the current users buddy list.
            $user_profile[$memID]['buddy_list'] = implode(',', $buddiesArray);
            updateMemberData($memID, array('buddy_list' => "'" . $user_profile[$memID]['buddy_list'] . "'"));
        }
        // Back to the buddy list!
        redirectexit('action=profile;u=' . $memID . ';sa=editBuddies');
    }
    // Get all the users "buddies"...
    $buddies = array();
    if (!empty($buddiesArray)) {
        $result = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}members\n\t\t\tWHERE ID_MEMBER IN (" . implode(', ', $buddiesArray) . ")\n\t\t\tORDER BY realName\n\t\t\tLIMIT " . (substr_count($user_profile[$memID]['buddy_list'], ',') + 1), __FILE__, __LINE__);
        while ($row = mysql_fetch_assoc($result)) {
            $buddies[] = $row['ID_MEMBER'];
        }
        mysql_free_result($result);
    }
    $context['buddy_count'] = count($buddies);
    // Load all the members up.
    loadMemberData($buddies, false, 'profile');
    // Setup the context for each buddy.
    $context['buddies'] = array();
    foreach ($buddies as $buddy) {
        loadMemberContext($buddy);
        $context['buddies'][$buddy] = $memberContext[$buddy];
    }
}
Пример #16
0
function BuddyRemove()
{
    global $smcFunc, $user_info, $user_profile, $context;
    checkSession('get');
    $_GET['u'] = (int) $_GET['u'];
    $smcFunc['db_query']('', '
		DELETE FROM {db_prefix}buddies 
		WHERE id_member = {int:id_member}
			AND buddy_id = {int:buddy_id}', array('id_member' => $context['user']['id'], 'buddy_id' => $_GET['u']));
    $smcFunc['db_query']('', '
		DELETE FROM {db_prefix}buddies 
		WHERE buddy_id = {int:buddy_id}
			AND id_member = {int:id_member}', array('buddy_id' => $context['user']['id'], 'id_member' => $_GET['u']));
    // Update SMF's system as well...
    $user_info['buddies'] = array_diff($user_info['buddies'], array($_GET['u']));
    updateMemberData($context['user']['id'], array('buddy_list' => implode(',', $user_info['buddies'])));
    loadMemberData($_GET['u'], false, 'normal');
    $buddies = explode(',', $user_profile[$_GET['u']]['buddy_list']);
    $buddies = array_diff($buddies, array($context['user']['id']));
    updateMemberData($_GET['u'], array('buddy_list' => implode(',', $buddies)));
    redirectexit('action=profile;area=lists;sa=buddies;u=' . $context['user']['id']);
}
Пример #17
0
function getXmlProfile($xml_format)
{
    global $scripturl, $memberContext, $user_profile, $modSettings, $user_info;
    // You must input a valid user....
    if (empty($_GET['u']) || loadMemberData((int) $_GET['u']) === false) {
        return array();
    }
    // Make sure the id is a number and not "I like trying to hack the database".
    $_GET['u'] = (int) $_GET['u'];
    // Load the member's contextual information!
    if (!loadMemberContext($_GET['u']) || !allowedTo('profile_view_any')) {
        return array();
    }
    // Okay, I admit it, I'm lazy.  Stupid $_GET['u'] is long and hard to type.
    $profile =& $memberContext[$_GET['u']];
    if ($xml_format == 'rss' || $xml_format == 'rss2') {
        $data = array(array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'description' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group']), 'comments' => $scripturl . '?action=pm;sa=send;u=' . $profile['id'], 'pubDate' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['dateRegistered']), 'guid' => $scripturl . '?action=profile;u=' . $profile['id']));
    } elseif ($xml_format == 'rdf') {
        $data = array(array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'description' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group'])));
    } elseif ($xml_format == 'atom') {
        $data[] = array('title' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'summary' => cdata_parse(isset($profile['group']) ? $profile['group'] : $profile['post_group']), 'created' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user_profile[$profile['id']]['dateRegistered']), 'issued' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user_profile[$profile['id']]['dateRegistered']), 'modified' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $user_profile[$profile['id']]['lastLogin']), 'id' => $scripturl . '?action=profile;u=' . $profile['id']);
    } else {
        $data = array('username' => cdata_parse($profile['username']), 'name' => cdata_parse($profile['name']), 'link' => $scripturl . '?action=profile;u=' . $profile['id'], 'posts' => $profile['posts'], 'post-group' => cdata_parse($profile['post_group']), 'language' => cdata_parse($profile['language']), 'last-login' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['lastLogin']), 'registered' => gmdate('D, d M Y H:i:s \\G\\M\\T', $user_profile[$profile['id']]['dateRegistered']));
        // Everything below here might not be set, and thus maybe shouldn't be displayed.
        if ($profile['gender']['name'] != '') {
            $data['gender'] = cdata_parse($profile['gender']['name']);
        }
        if ($profile['avatar']['name'] != '') {
            $data['avatar'] = $profile['avatar']['url'];
        }
        // If they are online, show an empty tag... no reason to put anything inside it.
        if ($profile['online']['is_online']) {
            $data['online'] = '';
        }
        if ($profile['signature'] != '') {
            $data['signature'] = cdata_parse($profile['signature']);
        }
        if ($profile['blurb'] != '') {
            $data['blurb'] = cdata_parse($profile['blurb']);
        }
        if ($profile['location'] != '') {
            $data['location'] = cdata_parse($profile['location']);
        }
        if ($profile['title'] != '') {
            $data['title'] = cdata_parse($profile['title']);
        }
        if (!empty($profile['icq']['name']) && !(!empty($modSettings['guest_hideContacts']) && $user_info['is_guest'])) {
            $data['icq'] = $profile['icq']['name'];
        }
        if ($profile['aim']['name'] != '' && !(!empty($modSettings['guest_hideContacts']) && $user_info['is_guest'])) {
            $data['aim'] = $profile['aim']['name'];
        }
        if ($profile['msn']['name'] != '' && !(!empty($modSettings['guest_hideContacts']) && $user_info['is_guest'])) {
            $data['msn'] = $profile['msn']['name'];
        }
        if ($profile['yim']['name'] != '' && !(!empty($modSettings['guest_hideContacts']) && $user_info['is_guest'])) {
            $data['yim'] = $profile['yim']['name'];
        }
        if ($profile['website']['title'] != '') {
            $data['website'] = array('title' => cdata_parse($profile['website']['title']), 'link' => $profile['website']['url']);
        }
        if ($profile['group'] != '') {
            $data['postition'] = cdata_parse($profile['group']);
        }
        if (!empty($modSettings['karmaMode'])) {
            $data['karma'] = array('good' => $profile['karma']['good'], 'bad' => $profile['karma']['bad']);
        }
        if ((empty($profile['hide_email']) || empty($modSettings['allow_hideEmail'])) && !(!empty($modSettings['guest_hideContacts']) && $user_info['is_guest'])) {
            $data['email'] = $profile['email'];
        }
        if (!empty($profile['birth_date']) && substr($profile['birth_date'], 0, 4) != '0000') {
            list($birth_year, $birth_month, $birth_day) = sscanf($profile['birth_date'], '%d-%d-%d');
            $datearray = getdate(forum_time());
            $data['age'] = $datearray['year'] - $birth_year - ($datearray['mon'] > $birth_month || $datearray['mon'] == $birth_month && $datearray['mday'] >= $birth_day ? 0 : 1);
        }
    }
    // Save some memory.
    unset($profile);
    unset($memberContext[$_GET['u']]);
    return $data;
}
Пример #18
0
/**
 *	Handles the actual assignment form, validates it and carries it out.
 *
 *	Primarily this is just about receiving the form, making the same checks that {@link shd_assign()} does and then
 *	logging the action before passing over to {@link shd_commit_assignment()} to actually assign the ticket.
 *
 *	@see shd_assign()
 *	@see shd_commit_assignment()
 *	@since 1.0
*/
function shd_assign2()
{
    global $context, $smcFunc, $user_info, $sourcedir;
    checkSession();
    checkSubmitOnce('check');
    if (empty($context['ticket_id'])) {
        fatal_lang_error('shd_no_ticket');
    }
    $context['shd_return_to'] = isset($_REQUEST['home']) ? 'home' : 'ticket';
    $assignee = isset($_REQUEST['to_user']) ? (int) $_REQUEST['to_user'] : 0;
    // Get ticket details - and kick it out if they shouldn't be able to see it.
    $query = shd_db_query('', '
		SELECT id_member_started, id_member_assigned, private, subject, status, id_dept
		FROM {db_prefix}helpdesk_tickets AS hdt
		WHERE {query_see_ticket} AND id_ticket = {int:ticket}', array('ticket' => $context['ticket_id']));
    $log_params = array();
    if ($row = $smcFunc['db_fetch_row']($query)) {
        list($ticket_starter, $ticket_owner, $private, $subject, $status, $dept) = $row;
        // The core details that we'll be logging
        $log_params = array('subject' => $subject, 'ticket' => $context['ticket_id']);
    } else {
        $smcFunc['db_free_result']($query);
        fatal_lang_error('shd_no_ticket');
    }
    // Just in case, are they cancelling?
    if (isset($_REQUEST['cancel'])) {
        redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']);
    }
    if ($status == TICKET_STATUS_CLOSED || $status == TICKET_STATUS_DELETED) {
        fatal_lang_error('shd_cannot_assign', false);
    }
    if (shd_allowed_to('shd_assign_ticket_any', $dept)) {
        if ($assignee == 0) {
            shd_log_action('unassign', $log_params);
            shd_commit_assignment($context['ticket_id'], 0);
        } else {
            $members = shd_get_possible_assignees($private, $ticket_starter, $dept);
            if (in_array($assignee, $members)) {
                global $user_profile;
                loadMemberData($assignee, false, 'minimal');
                $log_params += array('user_id' => $assignee, 'user_name' => $user_profile[$assignee]['real_name']);
                shd_log_action('assign', $log_params);
                shd_commit_assignment($context['ticket_id'], $assignee);
            } else {
                fatal_lang_error('shd_assigned_not_permitted', false);
            }
        }
    } elseif (shd_allowed_to('shd_assign_ticket_own', $dept) && shd_allowed_to('shd_staff', $dept)) {
        if ($ticket_owner == 0) {
            $log_params += array('user_id' => $user_info['id'], 'user_name' => $user_info['name']);
            shd_log_action('assign', $log_params);
            shd_commit_assignment($context['ticket_id'], $user_info['id']);
        } elseif ($ticket_starter == $user_info['id']) {
            shd_log_action('unassign', $log_params);
            shd_commit_assignment($context['ticket_id'], 0);
        } else {
            // oops, assigned to somebody else
            fatal_lang_error('shd_cannot_assign_other', false);
        }
    } else {
        fatal_lang_error('shd_cannot_assign', false);
    }
}
Пример #19
0
    function __construct($request, $total_items, $not_profile = false)
    {
        global $context, $txt, $user_info, $scripturl, $options, $memberContext, $modSettings;
        if (!isset($context['pageindex_multiplier'])) {
            $context['pageindex_multiplier'] = commonAPI::getMessagesPerPage();
        }
        $cb_name = isset($context['cb_name']) ? $context['cb_name'] : 'topics[]';
        while ($row = mysql_fetch_assoc($request)) {
            censorText($row['subject']);
            $this->topic_ids[] = $row['id_topic'];
            $f_post_mem_href = !empty($row['id_member']) ? URL::user($row['id_member'], $row['first_member_name']) : '';
            $t_href = URL::topic($row['id_topic'], $row['subject'], 0);
            $l_post_mem_href = !empty($row['id_member_updated']) ? URL::user($row['id_member_updated'], $row['last_real_name']) : '';
            $l_post_msg_href = URL::topic($row['id_topic'], $row['last_subject'], $user_info['is_guest'] ? !empty($options['view_newest_first']) ? 0 : (int) ($row['num_replies'] / $context['pageindex_multiplier']) * $context['pageindex_multiplier'] : 0, $user_info['is_guest'] ? true : false, $user_info['is_guest'] ? '' : '.msg' . $row['id_last_msg'], $user_info['is_guest'] ? '#msg' . $row['id_last_msg'] : '#new');
            $this->topiclist[$row['id_topic']] = array('id' => $row['id_topic'], 'id_member_started' => empty($row['id_member']) ? 0 : $row['id_member'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_member_name'], 'id' => empty($row['id_member']) ? 0 : $row['id_member'], 'href' => $f_post_mem_href, 'link' => !empty($row['id_member']) ? '<a onclick="getMcard(' . $row['id_member'] . ', $(this));return(false);" href="' . $f_post_mem_href . '" title="' . $txt['profile_of'] . ' ' . $row['first_member_name'] . '">' . $row['first_member_name'] . '</a>' : $row['first_member_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['subject'], 'icon' => $row['first_icon'], 'icon_url' => getPostIcon($row['first_icon']), 'href' => $t_href, 'link' => '<a href="' . $t_href . '">' . $row['subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_real_name'], 'name' => $row['last_real_name'], 'id' => $row['id_member_updated'], 'href' => $l_post_mem_href, 'link' => !empty($row['id_member_updated']) ? '<a onclick="getMcard(' . $row['id_member_updated'] . ', $(this));return(false);" href="' . $l_post_mem_href . '">' . $row['last_real_name'] . '</a>' : $row['last_real_name']), 'time' => timeformat($row['last_post_time']), 'timestamp' => forum_time(true, $row['last_post_time']), 'subject' => $row['last_subject'], 'href' => $l_post_msg_href, 'link' => '<a href="' . $l_post_msg_href . ($row['num_replies'] == 0 ? '' : ' rel="nofollow"') . '>' . $row['last_subject'] . '</a>'), 'checkbox_name' => $cb_name, 'subject' => $row['subject'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'updated' => timeformat($row['poster_time']), 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new', 'new_link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new">' . $row['subject'] . '</a>', 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts'], 'is_old' => !empty($modSettings['oldTopicDays']) ? $context['time_now'] - $row['last_post_time'] > $modSettings['oldTopicDays'] * 86400 : false, 'is_posted_in' => false, 'prefix' => '', 'pages' => '', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => false, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'board' => isset($row['id_board']) && !empty($row['id_board']) ? array('name' => $row['board_name'], 'id' => $row['id_board'], 'href' => URL::board($row['id_board'], $row['board_name'])) : array('name' => '', 'id' => 0, 'href' => ''));
            determineTopicClass($this->topiclist[$row['id_topic']]);
            if (!empty($row['id_member']) && ($row['id_member'] != $user_info['id'] || $not_profile)) {
                $this->users_to_load[$row['id_member']] = $row['id_member'];
            }
        }
        loadMemberData($this->users_to_load);
        foreach ($this->topiclist as &$topic) {
            if (!isset($memberContext[$topic['id_member_started']])) {
                loadMemberContext($topic['id_member_started']);
            }
            $topic['first_post']['member']['avatar'] =& $memberContext[$topic['id_member_started']]['avatar']['image'];
        }
        // figure out whether we have posted in a topic (but only if we are not the topic starter)
        if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($this->topic_ids)) {
            $result = smf_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($this->topic_ids), array('current_member' => $user_info['id'], 'topic_list' => $this->topic_ids));
            while ($row = mysql_fetch_assoc($result)) {
                if ($this->topiclist[$row['id_topic']]['first_post']['member']['id'] != $user_info['id']) {
                    $this->topiclist[$row['id_topic']]['is_posted_in'] = true;
                }
            }
            mysql_free_result($result);
        }
    }
Пример #20
0
/**
 * Fetch some member data!
 *
 * @param string|null $query_where
 * @param string|string[] $query_where_params
 * @param string $query_limit
 * @param string $query_order
 * @param string $output_method
 */
function ssi_queryMembers($query_where = null, $query_where_params = array(), $query_limit = '', $query_order = 'id_member DESC', $output_method = 'echo')
{
    global $memberContext;
    if ($query_where === null) {
        return;
    }
    require_once SUBSDIR . '/Members.subs.php';
    $members_data = retrieveMemberData(array($query_where => $query_where_params, 'limit' => !empty($query_limit) ? (int) $query_limit : 10, 'order_by' => $query_order, 'activated_status' => 1));
    $members = array();
    foreach ($members_data['member_info'] as $row) {
        $members[] = $row['id'];
    }
    if (empty($members)) {
        return array();
    }
    // Load the members.
    loadMemberData($members);
    // Draw the table!
    if ($output_method == 'echo') {
        echo '
		<table class="ssi_table">';
    }
    $query_members = array();
    foreach ($members as $member) {
        // Load their context data.
        if (!loadMemberContext($member)) {
            continue;
        }
        // Store this member's information.
        $query_members[$member] = $memberContext[$member];
        // Only do something if we're echo'ing.
        if ($output_method == 'echo') {
            echo '
			<tr>
				<td class="centertext">
					', $query_members[$member]['link'], '
					<br />', $query_members[$member]['blurb'], '
					<br />', $query_members[$member]['avatar']['image'], '
				</td>
			</tr>';
        }
    }
    // End the table if appropriate.
    if ($output_method == 'echo') {
        echo '
		</table>';
    }
    // Send back the data.
    return $query_members;
}
Пример #21
0
 *  Spelling mistakes and fixes from community members.
 *
 */
require_once $_SERVER['DOCUMENT_ROOT'] . '/functions.php';
require_once $link['root'] . 'classes/MailManager.php';
//Initalize Value
$from = "*****@*****.**";
$pending_addon_count = 5;
$dashboard_link = "";
$official_link = "";
$memberContext = null;
//Clear any previously stored value
//Unfortunately we don't store user personal details such as email in website's database
//so get them from SMF using user ID
foreach (MailManager::getAdminEmailList() as $user) {
    loadMemberData($user['ID_MEMBER']);
    loadMemberContext($user['ID_MEMBER']);
}
$subject = "There are " . $pending_addon_count . " addons require your approval!";
$message = file_get_contents($link['root'] . 'pages/mail_templates/pending.addon.dashboard.html');
//now loop through member data and put all the valid email in an array
foreach ($memberContext as $user) {
    //Make sure the emails are valid
    if (!filter_var($user['email'], FILTER_VALIDATE_EMAIL) === false) {
        $bindedvalarray = array("{username}" => $user['username'], "{pending_request_count}" => $pending_addon_count, "{dashboard_link}" => $link['addon']['dashboard'], "{official_link}" => $link['home'], "{subject}" => $subject);
        if (MailManager::sendMail($user['email'], $from, "UTF-8", "text/html", $subject, $message, $bindedvalarray)) {
            //put some logging function to monitor
            echo "Mail delivered to " . $user['username'] . "<br/>";
        } else {
            //put some logging function to monitor
            echo "Mail Could not be delivered";
Пример #22
0
    /**
     * The central part of the board - topic display.
     *
     * What it does:
     * - This function loads the posts in a topic up so they can be displayed.
     * - It uses the main sub template of the Display template.
     * - It requires a topic, and can go to the previous or next topic from it.
     * - It jumps to the correct post depending on a number/time/IS_MSG passed.
     * - It depends on the messages_per_page, defaultMaxMessages and enableAllMessages settings.
     * - It is accessed by ?topic=id_topic.START.
     */
    public function action_display()
    {
        global $scripturl, $txt, $modSettings, $context, $settings;
        global $options, $user_info, $board_info, $topic, $board;
        global $attachments, $messages_request;
        // What are you gonna display if these are empty?!
        if (empty($topic)) {
            fatal_lang_error('no_board', false);
        }
        // Load the template
        loadTemplate('Display');
        $context['sub_template'] = 'messages';
        // And the topic functions
        require_once SUBSDIR . '/Topic.subs.php';
        require_once SUBSDIR . '/Messages.subs.php';
        // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
        if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
            @ob_end_clean();
            header('HTTP/1.1 403 Prefetch Forbidden');
            die;
        }
        // How much are we sticking on each page?
        $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
        $template_layers = Template_Layers::getInstance();
        $template_layers->addEnd('messages_informations');
        $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
        // Let's do some work on what to search index.
        if (count($_GET) > 2) {
            foreach ($_GET as $k => $v) {
                if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                    $context['robot_no_index'] = true;
                }
            }
        }
        if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
            $context['robot_no_index'] = true;
        }
        // Find the previous or next topic.  Make a fuss if there are no more.
        if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
            // No use in calculating the next topic if there's only one.
            if ($board_info['num_topics'] > 1) {
                $includeStickies = !empty($modSettings['enableStickyTopics']);
                $topic = $_REQUEST['prev_next'] === 'prev' ? previousTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies) : nextTopic($topic, $board, $user_info['id'], $includeUnapproved, $includeStickies);
                $context['current_topic'] = $topic;
            }
            // Go to the newest message on this topic.
            $_REQUEST['start'] = 'new';
        }
        // Add 1 to the number of views of this topic (except for robots).
        if (!$user_info['possibly_robot'] && (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic)) {
            increaseViewCounter($topic);
            $_SESSION['last_read_topic'] = $topic;
        }
        $topic_selects = array();
        $topic_tables = array();
        $topic_parameters = array('topic' => $topic, 'member' => $user_info['id'], 'board' => (int) $board);
        // Allow addons to add additional details to the topic query
        call_integration_hook('integrate_topic_query', array(&$topic_selects, &$topic_tables, &$topic_parameters));
        // Load the topic details
        $topicinfo = getTopicInfo($topic_parameters, 'all', $topic_selects, $topic_tables);
        if (empty($topicinfo)) {
            fatal_lang_error('not_a_topic', false);
        }
        // Is this a moved topic that we are redirecting to?
        if (!empty($topicinfo['id_redirect_topic']) && !isset($_GET['noredir'])) {
            markTopicsRead(array($user_info['id'], $topic, $topicinfo['id_last_msg'], 0), $topicinfo['new_from'] !== 0);
            redirectexit('topic=' . $topicinfo['id_redirect_topic'] . '.0;redirfrom=' . $topicinfo['id_topic']);
        }
        $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
        $context['topic_first_message'] = $topicinfo['id_first_msg'];
        $context['topic_last_message'] = $topicinfo['id_last_msg'];
        $context['topic_unwatched'] = isset($topicinfo['unwatched']) ? $topicinfo['unwatched'] : 0;
        if (isset($_GET['redirfrom'])) {
            $redir_topics = topicsList(array((int) $_GET['redirfrom']));
            if (!empty($redir_topics[(int) $_GET['redirfrom']])) {
                $context['topic_redirected_from'] = $redir_topics[(int) $_GET['redirfrom']];
                $context['topic_redirected_from']['redir_href'] = $scripturl . '?topic=' . $context['topic_redirected_from']['id_topic'] . '.0;noredir';
            }
        }
        // Add up unapproved replies to get real number of replies...
        if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
            $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
        }
        // If this topic was derived from another, set the followup details
        if (!empty($topicinfo['derived_from'])) {
            require_once SUBSDIR . '/FollowUps.subs.php';
            $context['topic_derived_from'] = topicStartedHere($topic, $includeUnapproved);
        }
        // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
        if (!$includeUnapproved && $topicinfo['unapproved_posts'] && !$user_info['is_guest']) {
            $myUnapprovedPosts = unapprovedPosts($topic, $user_info['id']);
            $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
        } elseif ($user_info['is_guest']) {
            $context['total_visible_posts'] = $context['num_replies'] + ($topicinfo['approved'] ? 1 : 0);
        } else {
            $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
        }
        // When was the last time this topic was replied to?  Should we warn them about it?
        if (!empty($modSettings['oldTopicDays'])) {
            $mgsOptions = basicMessageInfo($topicinfo['id_last_msg'], true);
            $context['oldTopicError'] = $mgsOptions['poster_time'] + $modSettings['oldTopicDays'] * 86400 < time() && empty($topicinfo['is_sticky']);
        } else {
            $context['oldTopicError'] = false;
        }
        // The start isn't a number; it's information about what to do, where to go.
        if (!is_numeric($_REQUEST['start'])) {
            // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
            if ($_REQUEST['start'] == 'new') {
                // Guests automatically go to the last post.
                if ($user_info['is_guest']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                    $_REQUEST['start'] = $context['start_from'];
                } else {
                    // Fall through to the next if statement.
                    $_REQUEST['start'] = 'msg' . $topicinfo['new_from'];
                }
            }
            // Start from a certain time index, not a message.
            if (substr($_REQUEST['start'], 0, 4) == 'from') {
                $timestamp = (int) substr($_REQUEST['start'], 4);
                if ($timestamp === 0) {
                    $_REQUEST['start'] = 0;
                } else {
                    // Find the number of messages posted before said time...
                    $context['start_from'] = countNewPosts($topic, $topicinfo, $timestamp);
                    $_REQUEST['start'] = $context['start_from'];
                }
            } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
                $virtual_msg = (int) substr($_REQUEST['start'], 3);
                if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                    $context['start_from'] = $context['total_visible_posts'] - 1;
                } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                    $context['start_from'] = 0;
                } else {
                    $only_approved = $modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts');
                    $context['start_from'] = countMessagesBefore($topic, $virtual_msg, false, $only_approved, !$user_info['is_guest']);
                }
                // We need to reverse the start as well in this case.
                $_REQUEST['start'] = $context['start_from'];
            }
        }
        // Mark the mention as read if requested
        if (isset($_REQUEST['mentionread']) && !empty($virtual_msg)) {
            require_once CONTROLLERDIR . '/Mentions.controller.php';
            $mentions = new Mentions_Controller();
            $mentions->setData(array('id_mention' => $_REQUEST['item'], 'mark' => $_REQUEST['mark']));
            $mentions->action_markread();
        }
        // Create a previous next string if the selected theme has it as a selected option.
        if ($modSettings['enablePreviousNext']) {
            $context['links'] += array('go_prev' => $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new', 'go_next' => $scripturl . '?topic=' . $topic . '.0;prev_next=next#new');
        }
        // Derived from, set the link back
        if (!empty($context['topic_derived_from'])) {
            $context['links']['derived_from'] = $scripturl . '?msg=' . $context['topic_derived_from']['derived_from'];
        }
        // Check if spellchecking is both enabled and actually working. (for quick reply.)
        $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
        if ($context['show_spellchecking']) {
            loadJavascriptFile('spellcheck.js', array('defer' => true));
        }
        // Do we need to show the visual verification image?
        $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
        if ($context['require_verification']) {
            require_once SUBSDIR . '/VerificationControls.class.php';
            $verificationOptions = array('id' => 'post');
            $context['require_verification'] = create_control_verification($verificationOptions);
            $context['visual_verification_id'] = $verificationOptions['id'];
        }
        // Are we showing signatures - or disabled fields?
        $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
        $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
        // Censor the title...
        censorText($topicinfo['subject']);
        $context['page_title'] = $topicinfo['subject'];
        // Is this topic sticky, or can it even be?
        $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
        // Allow addons access to the topicinfo array
        call_integration_hook('integrate_display_topic', array($topicinfo));
        // Default this topic to not marked for notifications... of course...
        $context['is_marked_notify'] = false;
        // Did we report a post to a moderator just now?
        $context['report_sent'] = isset($_GET['reportsent']);
        if ($context['report_sent']) {
            $template_layers->add('report_sent');
        }
        // Let's get nosey, who is viewing this topic?
        if (!empty($settings['display_who_viewing'])) {
            require_once SUBSDIR . '/Who.subs.php';
            formatViewers($topic, 'topic');
        }
        // If all is set, but not allowed... just unset it.
        $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
        if (isset($_REQUEST['all']) && !$can_show_all) {
            unset($_REQUEST['all']);
        } elseif (isset($_REQUEST['all'])) {
            $_REQUEST['start'] = -1;
        }
        // Construct the page index, allowing for the .START method...
        $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true, array('all' => $can_show_all, 'all_selected' => isset($_REQUEST['all'])));
        $context['start'] = $_REQUEST['start'];
        // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
        $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
        // Figure out all the link to the next/prev
        $context['links'] += array('prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '');
        // If they are viewing all the posts, show all the posts, otherwise limit the number.
        if ($can_show_all && isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        }
        // Build the link tree.
        $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject']);
        // Build a list of this board's moderators.
        $context['moderators'] =& $board_info['moderators'];
        $context['link_moderators'] = array();
        // Information about the current topic...
        $context['is_locked'] = $topicinfo['locked'];
        $context['is_sticky'] = $topicinfo['is_sticky'];
        $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
        $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
        $context['is_approved'] = $topicinfo['approved'];
        $context['is_poll'] = $topicinfo['id_poll'] > 0 && !empty($modSettings['pollMode']) && allowedTo('poll_view');
        determineTopicClass($context);
        // Did this user start the topic or not?
        $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
        $context['topic_starter_id'] = $topicinfo['id_member_started'];
        // Set the topic's information for the template.
        $context['subject'] = $topicinfo['subject'];
        $context['num_views'] = $topicinfo['num_views'];
        $context['num_views_text'] = $context['num_views'] == 1 ? $txt['read_one_time'] : sprintf($txt['read_many_times'], $context['num_views']);
        $context['mark_unread_time'] = !empty($virtual_msg) ? $virtual_msg : $topicinfo['new_from'];
        // Set a canonical URL for this page.
        $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
        // For quick reply we need a response prefix in the default forum language.
        $context['response_prefix'] = response_prefix();
        // If we want to show event information in the topic, prepare the data.
        if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
            // We need events details and all that jazz
            require_once SUBSDIR . '/Calendar.subs.php';
            // First, try create a better time format, ignoring the "time" elements.
            if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
                $date_string = $user_info['time_format'];
            } else {
                $date_string = $matches[0];
            }
            // Get event information for this topic.
            $events = eventInfoForTopic($topic);
            $context['linked_calendar_events'] = array();
            foreach ($events as $event) {
                // Prepare the dates for being formatted.
                $start_date = sscanf($event['start_date'], '%04d-%02d-%02d');
                $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
                $end_date = sscanf($event['end_date'], '%04d-%02d-%02d');
                $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
                $context['linked_calendar_events'][] = array('id' => $event['id_event'], 'title' => $event['title'], 'can_edit' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'can_export' => allowedTo('calendar_edit_any') || $event['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'export_href' => $scripturl . '?action=calendar;sa=ical;eventid=' . $event['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => standardTime($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => standardTime($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
            }
            if (!empty($context['linked_calendar_events'])) {
                $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
                $template_layers->add('display_calendar');
            }
        }
        // Create the poll info if it exists.
        if ($context['is_poll']) {
            $template_layers->add('display_poll');
            require_once SUBSDIR . '/Poll.subs.php';
            loadPollContext($topicinfo['id_poll']);
            // Build the poll moderation button array.
            $context['poll_buttons'] = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'allow_poll_view', 'text' => 'poll_results', 'image' => 'poll_results.png', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start'] . ';viewresults'), 'change_vote' => array('test' => 'allow_change_vote', 'text' => 'poll_change_vote', 'image' => 'poll_change_vote.png', 'lang' => true, 'url' => $scripturl . '?action=poll;sa=vote;topic=' . $context['current_topic'] . '.' . $context['start'] . ';poll=' . $context['poll']['id'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'allow_lock_poll', 'text' => !$context['poll']['is_locked'] ? 'poll_lock' : 'poll_unlock', 'image' => 'poll_lock.png', 'lang' => true, 'url' => $scripturl . '?action=lockvoting;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'edit' => array('test' => 'allow_edit_poll', 'text' => 'poll_edit', 'image' => 'poll_edit.png', 'lang' => true, 'url' => $scripturl . '?action=editpoll;topic=' . $context['current_topic'] . '.' . $context['start']), 'remove_poll' => array('test' => 'can_remove_poll', 'text' => 'poll_remove', 'image' => 'admin_remove_poll.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['poll_remove_warn'] . '\');"', 'url' => $scripturl . '?action=poll;sa=remove;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']));
            // Allow mods to add additional buttons here
            call_integration_hook('integrate_poll_buttons');
        }
        // Calculate the fastest way to get the messages!
        $ascending = true;
        $start = $_REQUEST['start'];
        $limit = $context['messages_per_page'];
        $firstIndex = 0;
        if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
            $ascending = !$ascending;
            $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
            $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
            $firstIndex = $limit - 1;
        }
        // Taking care of member specific settings
        $limit_settings = array('messages_per_page' => $context['messages_per_page'], 'start' => $start, 'offset' => $limit);
        // Get each post and poster in this topic.
        $topic_details = getTopicsPostsAndPoster($topic, $limit_settings, $ascending);
        $messages = $topic_details['messages'];
        $posters = array_unique($topic_details['all_posters']);
        $all_posters = $topic_details['all_posters'];
        unset($topic_details);
        call_integration_hook('integrate_display_message_list', array(&$messages, &$posters));
        // Guests can't mark topics read or for notifications, just can't sorry.
        if (!$user_info['is_guest'] && !empty($messages)) {
            $mark_at_msg = max($messages);
            if ($mark_at_msg >= $topicinfo['id_last_msg']) {
                $mark_at_msg = $modSettings['maxMsgID'];
            }
            if ($mark_at_msg >= $topicinfo['new_from']) {
                markTopicsRead(array($user_info['id'], $topic, $mark_at_msg, $topicinfo['unwatched']), $topicinfo['new_from'] !== 0);
            }
            updateReadNotificationsFor($topic, $board);
            // Have we recently cached the number of new topics in this board, and it's still a lot?
            if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
                $_SESSION['topicseen_cache'][$board]--;
            } elseif (isset($_REQUEST['topicseen'])) {
                // Use the mark read tables... and the last visit to figure out if this should be read or not.
                $numNewTopics = getUnreadCountSince($board, empty($_SESSION['id_msg_last_visit']) ? 0 : $_SESSION['id_msg_last_visit']);
                // If there're no real new topics in this board, mark the board as seen.
                if (empty($numNewTopics)) {
                    $_REQUEST['boardseen'] = true;
                } else {
                    $_SESSION['topicseen_cache'][$board] = $numNewTopics;
                }
            } elseif (isset($_SESSION['topicseen_cache'][$board])) {
                $_SESSION['topicseen_cache'][$board]--;
            }
            // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
            if (isset($_REQUEST['boardseen'])) {
                require_once SUBSDIR . '/Boards.subs.php';
                markBoardsRead($board, false, false);
            }
        }
        $attachments = array();
        // If there _are_ messages here... (probably an error otherwise :!)
        if (!empty($messages)) {
            require_once SUBSDIR . '/Attachments.subs.php';
            // Fetch attachments.
            $includeUnapproved = !$modSettings['postmod_active'] || allowedTo('approve_posts');
            if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
                $attachments = getAttachments($messages, $includeUnapproved, 'filter_accessible_attachment', $all_posters);
            }
            $msg_parameters = array('message_list' => $messages, 'new_from' => $topicinfo['new_from']);
            $msg_selects = array();
            $msg_tables = array();
            call_integration_hook('integrate_message_query', array(&$msg_selects, &$msg_tables, &$msg_parameters));
            // What?  It's not like it *couldn't* be only guests in this topic...
            if (!empty($posters)) {
                loadMemberData($posters);
            }
            // Load in the likes for this group of messages
            if (!empty($modSettings['likes_enabled'])) {
                require_once SUBSDIR . '/Likes.subs.php';
                $context['likes'] = loadLikes($messages, true);
                // ajax controller for likes
                loadJavascriptFile('like_posts.js', array('defer' => true));
                loadLanguage('Errors');
                // Initiate likes and the tooltips for likes
                addInlineJavascript('
				$(document).ready(function () {
					var likePostInstance = likePosts.prototype.init({
						oTxt: ({
							btnText : ' . JavaScriptEscape($txt['ok_uppercase']) . ',
							likeHeadingError : ' . JavaScriptEscape($txt['like_heading_error']) . ',
							error_occurred : ' . JavaScriptEscape($txt['error_occurred']) . '
						}),
					});

					$(".like_button, .unlike_button").SiteTooltip({
						hoverIntent: {
							sensitivity: 10,
							interval: 150,
							timeout: 50
						}
					});
				});', true);
            }
            $messages_request = loadMessageRequest($msg_selects, $msg_tables, $msg_parameters);
            if (!empty($modSettings['enableFollowup'])) {
                require_once SUBSDIR . '/FollowUps.subs.php';
                $context['follow_ups'] = followupTopics($messages, $includeUnapproved);
            }
            // Go to the last message if the given time is beyond the time of the last message.
            if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
                $context['start_from'] = $topicinfo['num_replies'];
            }
            // Since the anchor information is needed on the top of the page we load these variables beforehand.
            $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $messages_request = false;
            $context['first_message'] = 0;
            $context['first_new_message'] = false;
        }
        $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&')), ENT_COMPAT, 'UTF-8'), 'child_level' => $board_info['child_level']);
        // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
        // This will be called from the template.
        $context['get_message'] = array($this, 'prepareDisplayContext_callback');
        // Now set all the wonderful, wonderful permissions... like moderation ones...
        $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_send_email' => 'send_email_to_members', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
        foreach ($common_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm);
        }
        // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
        $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
        foreach ($anyown_permissions as $contextual => $perm) {
            $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
        }
        // Cleanup all the permissions with extra stuff...
        $context['can_mark_notify'] &= !$context['user']['is_guest'];
        $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
        $context['calendar_post'] &= !empty($modSettings['cal_enabled']) && (allowedTo('modify_any') || $context['user']['started'] && allowedTo('modify_own'));
        $context['can_add_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] <= 0;
        $context['can_remove_poll'] &= !empty($modSettings['pollMode']) && $topicinfo['id_poll'] > 0;
        $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
        $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
        $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && !empty($modSettings['warning_enable']);
        // Handle approval flags...
        $context['can_reply_approved'] = $context['can_reply'];
        $context['can_reply'] |= $context['can_reply_unapproved'];
        $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
        $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
        $context['can_unwatch'] = !$user_info['is_guest'] && $modSettings['enable_unwatch'];
        $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
        $context['can_print'] = empty($modSettings['disable_print_topic']);
        // Start this off for quick moderation - it will be or'd for each post.
        $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
        // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
        $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
        $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
        $context['can_follow_up'] = !empty($modSettings['enableFollowup']) && boardsallowedto('post_new') !== array();
        // Check if the draft functions are enabled and that they have permission to use them (for quick reply.)
        $context['drafts_save'] = !empty($modSettings['drafts_enabled']) && !empty($modSettings['drafts_post_enabled']) && allowedTo('post_draft') && $context['can_reply'];
        $context['drafts_autosave'] = !empty($context['drafts_save']) && !empty($modSettings['drafts_autosave_enabled']) && allowedTo('post_autosave_draft');
        if (!empty($context['drafts_save'])) {
            loadLanguage('Drafts');
        }
        if (!empty($context['drafts_autosave']) && empty($options['use_editor_quick_reply'])) {
            loadJavascriptFile('drafts.js');
        }
        if (!empty($modSettings['mentions_enabled'])) {
            $context['mentions_enabled'] = true;
            // Just using the plain text quick reply and not the editor
            if (empty($options['use_editor_quick_reply'])) {
                loadJavascriptFile(array('jquery.atwho.js', 'jquery.caret.min.js', 'mentioning.js'));
            }
            loadCSSFile('jquery.atwho.css');
            addInlineJavascript('
			$(document).ready(function () {
				for (var i = 0, count = all_elk_mentions.length; i < count; i++)
					all_elk_mentions[i].oMention = new elk_mentions(all_elk_mentions[i].oOptions);
			});');
        }
        // Load up the Quick ModifyTopic and Quick Reply scripts
        loadJavascriptFile('topic.js');
        // Auto video embeding enabled?
        if (!empty($modSettings['enableVideoEmbeding'])) {
            addInlineJavascript('
		$(document).ready(function() {
			$().linkifyvideo(oEmbedtext);
		});');
        }
        // Load up the "double post" sequencing magic.
        if (!empty($options['display_quick_reply'])) {
            checkSubmitOnce('register');
            $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
            $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
            if (!empty($options['use_editor_quick_reply']) && $context['can_reply']) {
                // Needed for the editor and message icons.
                require_once SUBSDIR . '/Editor.subs.php';
                // Now create the editor.
                $editorOptions = array('id' => 'message', 'value' => '', 'labels' => array('post_button' => $txt['post']), 'height' => '250px', 'width' => '100%', 'preview_type' => 0);
                create_control_richedit($editorOptions);
                $context['attached'] = '';
                $context['make_poll'] = isset($_REQUEST['poll']);
                // Message icons - customized icons are off?
                $context['icons'] = getMessageIcons($board);
                if (!empty($context['icons'])) {
                    $context['icons'][count($context['icons']) - 1]['is_last'] = true;
                }
            }
        }
        addJavascriptVar(array('notification_topic_notice' => $context['is_marked_notify'] ? $txt['notification_disable_topic'] : $txt['notification_enable_topic']), true);
        if ($context['can_send_topic']) {
            addJavascriptVar(array('sendtopic_cancel' => $txt['modify_cancel'], 'sendtopic_back' => $txt['back'], 'sendtopic_close' => $txt['find_close'], 'sendtopic_error' => $txt['send_error_occurred'], 'required_field' => $txt['require_field']), true);
        }
        // Build the normal button array.
        $context['normal_buttons'] = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'image' => 'reply.png', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'notify' => array('test' => 'can_mark_notify', 'text' => $context['is_marked_notify'] ? 'unnotify' : 'notify', 'image' => ($context['is_marked_notify'] ? 'un' : '') . 'notify.png', 'lang' => true, 'custom' => 'onclick="return notifyButton(this);"', 'url' => $scripturl . '?action=notify;sa=' . ($context['is_marked_notify'] ? 'off' : 'on') . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.png', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=topic;t=' . $context['mark_unread_time'] . ';topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'unwatch' => array('test' => 'can_unwatch', 'text' => ($context['topic_unwatched'] ? '' : 'un') . 'watch', 'image' => ($context['topic_unwatched'] ? '' : 'un') . 'watched.png', 'lang' => true, 'custom' => 'onclick="return unwatchButton(this);"', 'url' => $scripturl . '?action=unwatchtopic;topic=' . $context['current_topic'] . '.' . $context['start'] . ';sa=' . ($context['topic_unwatched'] ? 'off' : 'on') . ';' . $context['session_var'] . '=' . $context['session_id']), 'send' => array('test' => 'can_send_topic', 'text' => 'send_topic', 'image' => 'sendtopic.png', 'lang' => true, 'url' => $scripturl . '?action=emailuser;sa=sendtopic;topic=' . $context['current_topic'] . '.0', 'custom' => 'onclick="return sendtopicOverlayDiv(this.href, \'' . $txt['send_topic'] . '\');"'), 'print' => array('test' => 'can_print', 'text' => 'print', 'image' => 'print.png', 'lang' => true, 'custom' => 'rel="nofollow"', 'class' => 'new_win', 'url' => $scripturl . '?action=topic;sa=printpage;topic=' . $context['current_topic'] . '.0'));
        // Build the mod button array
        $context['mod_buttons'] = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.png', 'lang' => true, 'url' => $scripturl . '?action=movetopic;current_board=' . $context['current_board'] . ';topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.png', 'lang' => true, 'custom' => 'onclick="return confirm(\'' . $txt['are_sure_remove_topic'] . '\');"', 'url' => $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=lock;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'sticky' => array('test' => 'can_sticky', 'text' => empty($context['is_sticky']) ? 'set_sticky' : 'set_nonsticky', 'image' => 'admin_sticky.png', 'lang' => true, 'url' => $scripturl . '?action=topic;sa=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.png', 'lang' => true, 'url' => $scripturl . '?action=mergetopics;board=' . $context['current_board'] . '.0;from=' . $context['current_topic']), 'calendar' => array('test' => 'calendar_post', 'text' => 'calendar_link', 'image' => 'linktocal.png', 'lang' => true, 'url' => $scripturl . '?action=post;calendar;msg=' . $context['topic_first_message'] . ';topic=' . $context['current_topic'] . '.0'));
        // Restore topic. eh?  No monkey business.
        if ($context['can_restore_topic']) {
            $context['mod_buttons'][] = array('text' => 'restore_topic', 'image' => '', 'lang' => true, 'url' => $scripturl . '?action=restoretopic;topics=' . $context['current_topic'] . ';' . $context['session_var'] . '=' . $context['session_id']);
        }
        if ($context['can_reply'] && !empty($options['display_quick_reply'])) {
            $template_layers->add('quickreply');
        }
        $template_layers->add('pages_and_buttons');
        // Allow adding new buttons easily.
        call_integration_hook('integrate_display_buttons');
        call_integration_hook('integrate_mod_buttons');
    }
Пример #23
0
function get_recommended_user_func()
{
    global $context, $smcFunc, $user_info, $profile, $user_profile, $settings, $scripturl;
    $user_id = $user_info['id'];
    if (!empty($user_id)) {
        $return_user_lists = array();
        $total = 0;
        $user_lists = $context['recommend'];
        $start = $_REQUEST['start'];
        $end = $_REQUEST['end'];
        $return_user_lists = array();
        if (isset($user_lists[$user_id])) {
            unset($user_lists[$user_id]);
        }
        if (!empty($user_lists)) {
            if (isset($_REQUEST['mode']) && $_REQUEST['mode'] == 2) {
                $check_users = array_keys($user_lists);
                $valid_users_result = $smcFunc['db_query']('', '
                    SELECT *
                    FROM {db_prefix}tapatalk_users 
                    WHERE userid IN ({array_int:check_users})', array('check_users' => $check_users));
                while ($tapausers = $smcFunc['db_fetch_assoc']($valid_users_result)) {
                    unset($user_lists[$tapausers['userid']]);
                }
                if ($is_tapa_user) {
                    continue;
                }
            }
            $total = count($user_lists);
            arsort($user_lists);
            $num_track = 0;
            foreach ($user_lists as $uid => $score) {
                if ($num_track > $start - 1 && $num_track < $end) {
                    loadMemberData($uid);
                    $profile = $user_profile[$uid];
                    if (!empty($settings['show_user_images']) && empty($profile['options']['show_no_avatars'])) {
                        $avatar = $profile['avatar'] == '' ? $profile['id_attach'] > 0 ? empty($profile['attachment_type']) ? $scripturl . '?action=dlattach;attach=' . $profile['id_attach'] . ';type=avatar' : $modSettings['custom_avatar_url'] . '/' . $profile['filename'] : '' : (stristr($profile['avatar'], 'http://') ? $profile['avatar'] : $modSettings['avatar_url'] . '/' . $profile['avatar']);
                    } else {
                        $avatar = '';
                    }
                    if (!empty($profile)) {
                        $return_user_lists[] = new xmlrpcval(array('username' => new xmlrpcval(basic_clean($user_profile[$uid]['member_name']), 'base64'), 'user_id' => new xmlrpcval($user_profile[$uid]['id_member'], 'string'), 'icon_url' => new xmlrpcval($avatar, 'string')), 'struct');
                    }
                    $num_track++;
                }
            }
        }
    }
    $suggested_users = new xmlrpcval(array('total' => new xmlrpcval($total, 'int'), 'list' => new xmlrpcval($return_user_lists, 'array')), 'struct');
    return new xmlrpcresp($suggested_users);
}
Пример #24
0
function getComments($id_page, $limit = array())
{
    //Check if page exists
    global $context, $smcFunc, $memberContext;
    $page = getPage($id_page, true, false);
    if (empty($page)) {
        return array();
    }
    $query = $smcFunc['db_query']('', '
		SELECT id_comment, id_member, body, date
		FROM {db_prefix}adk_pages_comments
		WHERE id_page = {int:id_page}
		ORDER BY date ASC
		' . (!empty($limit) ? 'LIMIT {int:start}, {int:end}' : ''), array('id_page' => $id_page, 'start' => !empty($limit) ? $limit[0] : '', 'end' => !empty($limit) ? $limit[1] : ''));
    $comments = array();
    $id_members = array();
    $num_replie = !empty($context['start']) ? $context['start'] : 0;
    $context['load_id_comments'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $num_replie++;
        $context['load_id_comments'][] = $row['id_comment'];
        $comments[$row['id_comment']] = array('id_page' => $id_page, 'id_comment' => $row['id_comment'], 'body' => parse_bbc($row['body']), 'date' => timeformat($row['date']), 'member_info' => array(), 'num_replie' => $num_replie, 'is_new' => false);
        $id_members[] = array('id_member' => $row['id_member'], 'id_comment' => $row['id_comment']);
    }
    $dont_load_members = array();
    //Load Memberinfo
    if (!empty($id_members)) {
        foreach ($id_members as $comment) {
            if (!in_array($comment['id_member'], $dont_load_members)) {
                loadMemberData($comment['id_member'], false, 'profile');
                loadMemberContext($comment['id_member']);
                //Finaly, make my context string ;)
                $comments[$comment['id_comment']]['member_info'] = $memberContext[$comment['id_member']];
                $dont_load_members[] = $comment['id_member'];
            } else {
                $comments[$comment['id_comment']]['member_info'] = $memberContext[$comment['id_member']];
            }
        }
    }
    $smcFunc['db_free_result']($query);
    return $comments;
}
Пример #25
0
function Who()
{
    global $db_prefix, $context, $scripturl, $user_info, $txt, $modSettings, $ID_MEMBER, $memberContext;
    // Permissions, permissions, permissions.
    isAllowedTo('who_view');
    // You can't do anything if this is off.
    if (empty($modSettings['who_enabled'])) {
        fatal_lang_error('who_off', false);
    }
    // Load the 'Who' template.
    loadTemplate('Who');
    // Sort out... the column sorting.
    $sort_methods = array('user' => 'mem.realName', 'time' => 'lo.logTime');
    // By default order by last time online.
    if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
        $context['sort_by'] = 'time';
        $_REQUEST['sort'] = 'lo.logTime';
    } else {
        $context['sort_by'] = $_REQUEST['sort'];
        $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
    }
    $context['sort_direction'] = isset($_REQUEST['asc']) ? 'up' : 'down';
    // Get the total amount of members online.
    $request = db_query("\n\t\tSELECT COUNT(*)\n\t\tFROM {$db_prefix}log_online AS lo\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (lo.ID_MEMBER = mem.ID_MEMBER)" . (!allowedTo('moderate_forum') ? "\n\t\tWHERE IFNULL(mem.showOnline, 1) = 1" : ''), __FILE__, __LINE__);
    list($totalMembers) = mysql_fetch_row($request);
    mysql_free_result($request);
    // Prepare some page index variables.
    $context['page_index'] = constructPageIndex($scripturl . '?action=who;sort=' . $context['sort_by'] . (isset($_REQUEST['asc']) ? ';asc' : ''), $_REQUEST['start'], $totalMembers, $modSettings['defaultMaxMembers']);
    $context['start'] = $_REQUEST['start'];
    // Look for people online, provided they don't mind if you see they are.
    $request = db_query("\n\t\tSELECT\n\t\t\t(UNIX_TIMESTAMP(lo.logTime) - UNIX_TIMESTAMP() + " . time() . ") AS logTime,\n\t\t\tlo.ID_MEMBER, lo.url, INET_NTOA(lo.ip) AS ip, mem.realName, lo.session,\n\t\t\tmg.onlineColor, IFNULL(mem.showOnline, 1) AS showOnline\n\t\tFROM {$db_prefix}log_online AS lo\n\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (lo.ID_MEMBER = mem.ID_MEMBER)\n\t\t\tLEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = IF(mem.ID_GROUP = 0, mem.ID_POST_GROUP, mem.ID_GROUP))" . (!allowedTo('moderate_forum') ? "\n\t\tWHERE IFNULL(mem.showOnline, 1) = 1" : '') . "\n\t\tORDER BY {$_REQUEST['sort']} " . (isset($_REQUEST['asc']) ? 'ASC' : 'DESC') . "\n\t\tLIMIT {$context['start']}, {$modSettings['defaultMaxMembers']}", __FILE__, __LINE__);
    $context['members'] = array();
    $member_ids = array();
    $url_data = array();
    while ($row = mysql_fetch_assoc($request)) {
        $actions = @unserialize($row['url']);
        if ($actions === false) {
            continue;
        }
        // Send the information to the template.
        $context['members'][$row['session']] = array('id' => $row['ID_MEMBER'], 'ip' => allowedTo('moderate_forum') ? $row['ip'] : '', 'time' => strtr(timeformat($row['logTime']), array($txt['smf10'] => '', $txt['smf10b'] => '')), 'timestamp' => forum_time(true, $row['logTime']), 'query' => $actions, 'is_hidden' => $row['showOnline'] == 0, 'color' => empty($row['onlineColor']) ? '' : $row['onlineColor']);
        $url_data[$row['session']] = array($row['url'], $row['ID_MEMBER']);
        $member_ids[] = $row['ID_MEMBER'];
    }
    mysql_free_result($request);
    // Load the user data for these members.
    loadMemberData($member_ids);
    // Load up the guest user.
    $memberContext[0] = array('id' => 0, 'name' => $txt[28], 'group' => $txt[28], 'href' => '', 'link' => $txt[28], 'email' => $txt[28], 'is_guest' => true);
    $url_data = determineActions($url_data);
    // Setup the linktree and page title (do it down here because the language files are now loaded..)
    $context['page_title'] = $txt['who_title'];
    $context['linktree'][] = array('url' => $scripturl . '?action=who', 'name' => $txt['who_title']);
    // Put it in the context variables.
    foreach ($context['members'] as $i => $member) {
        if ($member['id'] != 0) {
            $member['id'] = loadMemberContext($member['id']) ? $member['id'] : 0;
        }
        // Keep the IP that came from the database.
        $memberContext[$member['id']]['ip'] = $member['ip'];
        $context['members'][$i]['action'] = isset($url_data[$i]) ? $url_data[$i] : $txt['who_hidden'];
        $context['members'][$i] += $memberContext[$member['id']];
    }
    // Some people can't send personal messages...
    $context['can_send_pm'] = allowedTo('pm_send');
}
Пример #26
0
/**
 *	Handles fetching the information for the helpdesk display within the unread and unread replies pages.
 *
 *	The content is 'appended' below the unread posts information by way of a template layer.
 *
 *	@since 2.0
*/
function shd_unread_posts()
{
    global $smcFunc, $context, $user_info, $sourcedir, $txt, $scripturl, $user_profile, $modSettings;
    // Are we using Dragooon's very swish mobile theme, or other wireless? If so, disable this.
    if (WIRELESS || isset($_REQUEST['thememode']) && $_REQUEST['thememode'] == 'mobile' || isset($_COOKIE['smf4m_cookie']) && $_COOKIE['smf4m_cookie'] == 'mobile') {
        $modSettings['shd_disable_unread'] = true;
    }
    // We're only displaying this to staff. We didn't do this check on bootstrapping, no sense doing it every page load.
    if (shd_allowed_to('shd_staff', 0) && empty($modSettings['shd_disable_unread'])) {
        // Get the data
        $context['shd_preferences'] = shd_load_user_prefs();
        $context['shd_unread_info'] = array();
        if (empty($context['shd_preferences']['display_unread_type']) || $context['shd_preferences']['display_unread_type'] == 'outstanding') {
            // Get all the outstanding tickets
            $context['block_title'] = $txt['shd_tickets_open'];
            $request = shd_db_query('', '
				SELECT hdt.id_ticket, hdt.subject, hdt.id_ticket, hdt.num_replies, hdt.last_updated,
					hdtr_first.poster_name, hdt.urgency, hdt.status, hdt.id_member_started, hdt.id_member_assigned, hdt.id_last_msg AS log_read
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
				WHERE {query_see_ticket}
					AND hdt.status IN ({array_int:status})
				ORDER BY hdt.urgency DESC, hdt.last_updated', array('status' => array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF)));
        } elseif ($context['shd_preferences']['display_unread_type'] == 'unread') {
            // Only unread ones
            $context['block_title'] = $txt['shd_unread_tickets'];
            $request = shd_db_query('', '
				SELECT hdt.id_ticket, hdt.subject, hdt.id_ticket, hdt.num_replies, hdt.last_updated,
					hdtr_first.poster_name, hdt.urgency, hdt.status, hdt.id_member_started, hdt.id_member_assigned, IFNULL(hdlr.id_msg, 0) AS log_read
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
					LEFT JOIN {db_prefix}helpdesk_log_read AS hdlr ON (hdt.id_ticket = hdlr.id_ticket AND hdlr.id_member = {int:user})
				WHERE {query_see_ticket}
					AND hdt.status IN ({array_int:status})
					AND (hdlr.id_msg IS NULL OR hdlr.id_msg < hdt.id_last_msg)
				ORDER BY hdt.urgency DESC, hdt.last_updated', array('user' => $context['user']['id'], 'status' => array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF)));
        }
        if (!empty($request)) {
            $members = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $row['id_ticket_display'] = str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT);
                $row['updated'] = timeformat($row['last_updated']);
                $context['shd_unread_info'][] = $row;
                if ($row['id_member_started'] != 0) {
                    $members[] = $row['id_member_started'];
                }
                if ($row['id_member_assigned'] != 0) {
                    $members[] = $row['id_member_assigned'];
                }
            }
            loadMemberData(array_unique($members));
            foreach ($context['shd_unread_info'] as $key => $ticket) {
                if (!empty($user_profile[$ticket['id_member_started']])) {
                    $context['shd_unread_info'][$key]['ticket_starter'] = shd_profile_link($user_profile[$ticket['id_member_started']]['member_name'], $ticket['id_member_started']);
                } else {
                    $context['shd_unread_info'][$key]['ticket_starter'] = $ticket['poster_name'];
                }
                if (!empty($user_profile[$ticket['id_member_assigned']])) {
                    $context['shd_unread_info'][$key]['ticket_assigned'] = shd_profile_link($user_profile[$ticket['id_member_assigned']]['member_name'], $ticket['id_member_assigned']);
                } else {
                    $context['shd_unread_info'][$key]['ticket_assigned'] = '<span class="error">' . $txt['shd_unassigned'] . '</span>';
                }
            }
            // And set up the template too.
            loadTemplate('sd_template/SimpleDesk-Unread', 'helpdesk');
            $context['template_layers'][] = 'shd_unread';
        }
    }
    // OK, time to get out of here. If we're here, it's because we have a $_REQUEST['action'] of 'unread' or 'unreadreplies', both of which
    // are defined in $context['shd_unread_actions'] thanks to shd_init_actions back in Subs-SimpleDesk.php.
    require_once $sourcedir . '/' . $context['shd_unread_actions'][$_REQUEST['action']][0];
    $context['shd_unread_actions'][$_REQUEST['action']][1]();
}
Пример #27
0
function Display()
{
    global $scripturl, $txt, $modSettings, $context, $settings;
    global $options, $sourcedir, $user_info, $board_info, $topic, $board;
    global $attachments, $messages_request, $topicinfo, $language, $smcFunc;
    // What are you gonna display if these are empty?!
    if (empty($topic)) {
        fatal_lang_error('no_board', false);
    }
    // Load the proper template and/or sub template.
    if (WIRELESS) {
        $context['sub_template'] = WIRELESS_PROTOCOL . '_display';
    } else {
        loadTemplate('Display');
    }
    // Not only does a prefetch make things slower for the server, but it makes it impossible to know if they read it.
    if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
        ob_end_clean();
        header('HTTP/1.1 403 Prefetch Forbidden');
        die;
    }
    // How much are we sticking on each page?
    $context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
    // Let's do some work on what to search index.
    if (count($_GET) > 2) {
        foreach ($_GET as $k => $v) {
            if (!in_array($k, array('topic', 'board', 'start', session_name()))) {
                $context['robot_no_index'] = true;
            }
        }
    }
    if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0)) {
        $context['robot_no_index'] = true;
    }
    // Find the previous or next topic.  Make a fuss if there are no more.
    if (isset($_REQUEST['prev_next']) && ($_REQUEST['prev_next'] == 'prev' || $_REQUEST['prev_next'] == 'next')) {
        // No use in calculating the next topic if there's only one.
        if ($board_info['num_topics'] > 1) {
            // Just prepare some variables that are used in the query.
            $gt_lt = $_REQUEST['prev_next'] == 'prev' ? '>' : '<';
            $order = $_REQUEST['prev_next'] == 'prev' ? '' : ' DESC';
            $request = $smcFunc['db_query']('', '
				SELECT t2.id_topic
				FROM {db_prefix}topics AS t
					INNER JOIN {db_prefix}topics AS t2 ON (' . (empty($modSettings['enableStickyTopics']) ? '
					t2.id_last_msg ' . $gt_lt . ' t.id_last_msg' : '
					(t2.id_last_msg ' . $gt_lt . ' t.id_last_msg AND t2.is_sticky ' . $gt_lt . '= t.is_sticky) OR t2.is_sticky ' . $gt_lt . ' t.is_sticky') . ')
				WHERE t.id_topic = {int:current_topic}
					AND t2.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
					AND (t2.approved = {int:is_approved} OR (t2.id_member_started != {int:id_member_started} AND t2.id_member_started = {int:current_member}))') . '
				ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' t2.is_sticky' . $order . ',') . ' t2.id_last_msg' . $order . '
				LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'id_member_started' => 0));
            // No more left.
            if ($smcFunc['db_num_rows']($request) == 0) {
                $smcFunc['db_free_result']($request);
                // Roll over - if we're going prev, get the last - otherwise the first.
                $request = $smcFunc['db_query']('', '
					SELECT id_topic
					FROM {db_prefix}topics
					WHERE id_board = {int:current_board}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
						AND (approved = {int:is_approved} OR (id_member_started != {int:id_member_started} AND id_member_started = {int:current_member}))') . '
					ORDER BY' . (empty($modSettings['enableStickyTopics']) ? '' : ' is_sticky' . $order . ',') . ' id_last_msg' . $order . '
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'id_member_started' => 0));
            }
            // Now you can be sure $topic is the id_topic to view.
            list($topic) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            $context['current_topic'] = $topic;
        }
        // Go to the newest message on this topic.
        $_REQUEST['start'] = 'new';
    }
    // Add 1 to the number of views of this topic.
    if (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $topic) {
        $smcFunc['db_query']('', '
			UPDATE {db_prefix}topics
			SET num_views = num_views + 1
			WHERE id_topic = {int:current_topic}', array('current_topic' => $topic));
        $_SESSION['last_read_topic'] = $topic;
    }
    // Get all the important topic info.
    $request = $smcFunc['db_query']('', '
		SELECT
			t.num_replies, t.num_views, t.locked, ms.subject, t.is_sticky, t.id_poll,
			t.id_member_started, t.id_first_msg, t.id_last_msg, t.approved, t.unapproved_posts,
			' . ($user_info['is_guest'] ? 't.id_last_msg + 1' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from
			' . (!empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $board ? ', id_previous_board, id_previous_topic' : '') . '
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)' . ($user_info['is_guest'] ? '' : '
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
			LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . '
		WHERE t.id_topic = {int:current_topic}
		LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic, 'current_board' => $board));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('not_a_topic', false);
    }
    $topicinfo = $smcFunc['db_fetch_assoc']($request);
    $smcFunc['db_free_result']($request);
    $context['real_num_replies'] = $context['num_replies'] = $topicinfo['num_replies'];
    $context['topic_first_message'] = $topicinfo['id_first_msg'];
    $context['topic_last_message'] = $topicinfo['id_last_msg'];
    // Add up unapproved replies to get real number of replies...
    if ($modSettings['postmod_active'] && allowedTo('approve_posts')) {
        $context['real_num_replies'] += $topicinfo['unapproved_posts'] - ($topicinfo['approved'] ? 0 : 1);
    }
    // If this topic has unapproved posts, we need to work out how many posts the user can see, for page indexing.
    if ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !$user_info['is_guest'] && !allowedTo('approve_posts')) {
        $request = $smcFunc['db_query']('', '
			SELECT COUNT(id_member) AS my_unapproved_posts
			FROM {db_prefix}messages
			WHERE id_topic = {int:current_topic}
				AND id_member = {int:current_member}
				AND approved = 0', array('current_topic' => $topic, 'current_member' => $user_info['id']));
        list($myUnapprovedPosts) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        $context['total_visible_posts'] = $context['num_replies'] + $myUnapprovedPosts + ($topicinfo['approved'] ? 1 : 0);
    } else {
        $context['total_visible_posts'] = $context['num_replies'] + $topicinfo['unapproved_posts'] + ($topicinfo['approved'] ? 1 : 0);
    }
    // When was the last time this topic was replied to?  Should we warn them about it?
    $request = $smcFunc['db_query']('', '
		SELECT poster_time
		FROM {db_prefix}messages
		WHERE id_msg = {int:id_last_msg}
		LIMIT 1', array('id_last_msg' => $topicinfo['id_last_msg']));
    list($lastPostTime) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    $context['oldTopicError'] = !empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky);
    // The start isn't a number; it's information about what to do, where to go.
    if (!is_numeric($_REQUEST['start'])) {
        // Redirect to the page and post with new messages, originally by Omar Bazavilvazo.
        if ($_REQUEST['start'] == 'new') {
            // Guests automatically go to the last post.
            if ($user_info['is_guest']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : 0;
            } else {
                // Find the earliest unread message in the topic. (the use of topics here is just for both tables.)
                $request = $smcFunc['db_query']('', '
					SELECT IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from
					FROM {db_prefix}topics AS t
						LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = {int:current_topic} AND lt.id_member = {int:current_member})
						LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})
					WHERE t.id_topic = {int:current_topic}
					LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
                list($new_from) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Fall through to the next if statement.
                $_REQUEST['start'] = 'msg' . $new_from;
            }
        }
        // Start from a certain time index, not a message.
        if (substr($_REQUEST['start'], 0, 4) == 'from') {
            $timestamp = (int) substr($_REQUEST['start'], 4);
            if ($timestamp === 0) {
                $_REQUEST['start'] = 0;
            } else {
                // Find the number of messages posted before said time...
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE poster_time < {int:timestamp}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_topic' => $topic, 'current_member' => $user_info['id'], 'is_approved' => 1, 'timestamp' => $timestamp));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
                // Handle view_newest_first options, and get the correct start value.
                $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
            }
        } elseif (substr($_REQUEST['start'], 0, 3) == 'msg') {
            $virtual_msg = (int) substr($_REQUEST['start'], 3);
            if (!$topicinfo['unapproved_posts'] && $virtual_msg >= $topicinfo['id_last_msg']) {
                $context['start_from'] = $context['total_visible_posts'] - 1;
            } elseif (!$topicinfo['unapproved_posts'] && $virtual_msg <= $topicinfo['id_first_msg']) {
                $context['start_from'] = 0;
            } else {
                // Find the start value for that message......
                $request = $smcFunc['db_query']('', '
					SELECT COUNT(*)
					FROM {db_prefix}messages
					WHERE id_msg < {int:virtual_msg}
						AND id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && $topicinfo['unapproved_posts'] && !allowedTo('approve_posts') ? '
						AND (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')' : ''), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'virtual_msg' => $virtual_msg, 'is_approved' => 1, 'no_member' => 0));
                list($context['start_from']) = $smcFunc['db_fetch_row']($request);
                $smcFunc['db_free_result']($request);
            }
            // We need to reverse the start as well in this case.
            $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $context['total_visible_posts'] - $context['start_from'] - 1;
        }
    }
    // Create a previous next string if the selected theme has it as a selected option.
    $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
    // Check if spellchecking is both enabled and actually working. (for quick reply.)
    $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
    // Do we need to show the visual verification image?
    $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1);
    if ($context['require_verification']) {
        require_once $sourcedir . '/Subs-Editor.php';
        $verificationOptions = array('id' => 'post');
        $context['require_verification'] = create_control_verification($verificationOptions);
        $context['visual_verification_id'] = $verificationOptions['id'];
    }
    // Are we showing signatures - or disabled fields?
    $context['signature_enabled'] = substr($modSettings['signature_settings'], 0, 1) == 1;
    $context['disabled_fields'] = isset($modSettings['disabled_profile_fields']) ? array_flip(explode(',', $modSettings['disabled_profile_fields'])) : array();
    // Censor the title...
    censorText($topicinfo['subject']);
    $context['page_title'] = $topicinfo['subject'];
    // Is this already an article?
    $request = $smcFunc['db_query']('', '
		SELECT id_message
		FROM {db_prefix}sp_articles
		WHERE id_message = {int:message}', array('message' => $context['topic_first_message']));
    list($context['topic_is_article']) = $smcFunc['db_fetch_row']($request);
    $smcFunc['db_free_result']($request);
    // Is this topic sticky, or can it even be?
    $topicinfo['is_sticky'] = empty($modSettings['enableStickyTopics']) ? '0' : $topicinfo['is_sticky'];
    // Default this topic to not marked for notifications... of course...
    $context['is_marked_notify'] = false;
    // Did we report a post to a moderator just now?
    $context['report_sent'] = isset($_GET['reportsent']);
    // Let's get nosey, who is viewing this topic?
    if (!empty($settings['display_who_viewing'])) {
        // Start out with no one at all viewing it.
        $context['view_members'] = array();
        $context['view_members_list'] = array();
        $context['view_num_hidden'] = 0;
        // Search for members who have this topic set in their GET data.
        $request = $smcFunc['db_query']('', '
			SELECT
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
				mg.online_color, mg.id_group, mg.group_name
			FROM {db_prefix}log_online AS lo
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_id_group} THEN mem.id_post_group ELSE mem.id_group END)
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('reg_id_group' => 0, 'in_url_string' => 's:5:"topic";i:' . $topic . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id()));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (empty($row['id_member'])) {
                continue;
            }
            if (!empty($row['online_color'])) {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
            } else {
                $link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
            }
            $is_buddy = in_array($row['id_member'], $user_info['buddies']);
            if ($is_buddy) {
                $link = '<strong>' . $link . '</strong>';
            }
            // Add them both to the list and to the more detailed list.
            if (!empty($row['show_online']) || allowedTo('moderate_forum')) {
                $context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
            }
            $context['view_members'][$row['log_time'] . $row['member_name']] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'group' => $row['id_group'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member'], 'link' => $link, 'is_buddy' => $is_buddy, 'hidden' => empty($row['show_online']));
            if (empty($row['show_online'])) {
                $context['view_num_hidden']++;
            }
        }
        // The number of guests is equal to the rows minus the ones we actually used ;).
        $context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
        $smcFunc['db_free_result']($request);
        // Sort the list.
        krsort($context['view_members']);
        krsort($context['view_members_list']);
    }
    // If all is set, but not allowed... just unset it.
    $can_show_all = !empty($modSettings['enableAllMessages']) && $context['total_visible_posts'] > $context['messages_per_page'] && $context['total_visible_posts'] < $modSettings['enableAllMessages'];
    if (isset($_REQUEST['all']) && !$can_show_all) {
        unset($_REQUEST['all']);
    } elseif (isset($_REQUEST['all'])) {
        $_REQUEST['start'] = -1;
    }
    // Construct the page index, allowing for the .START method...
    $context['page_index'] = constructPageIndex($scripturl . '?topic=' . $topic . '.%1$d', $_REQUEST['start'], $context['total_visible_posts'], $context['messages_per_page'], true);
    $context['start'] = $_REQUEST['start'];
    // This is information about which page is current, and which page we're on - in case you don't like the constructed page index. (again, wireles..)
    $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['messages_per_page'] + 1, 'num_pages' => floor(($context['total_visible_posts'] - 1) / $context['messages_per_page']) + 1);
    // Figure out all the link to the next/prev/first/last/etc. for wireless mainly.
    $context['links'] = array('first' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.0' : '', 'prev' => $_REQUEST['start'] >= $context['messages_per_page'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] - $context['messages_per_page']) : '', 'next' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . ($_REQUEST['start'] + $context['messages_per_page']) : '', 'last' => $_REQUEST['start'] + $context['messages_per_page'] < $context['total_visible_posts'] ? $scripturl . '?topic=' . $topic . '.' . floor($context['total_visible_posts'] / $context['messages_per_page']) * $context['messages_per_page'] : '', 'up' => $scripturl . '?board=' . $board . '.0');
    // If they are viewing all the posts, show all the posts, otherwise limit the number.
    if ($can_show_all) {
        if (isset($_REQUEST['all'])) {
            // No limit! (actually, there is a limit, but...)
            $context['messages_per_page'] = -1;
            $context['page_index'] .= empty($modSettings['compactTopicPagesEnable']) ? '<strong>' . $txt['all'] . '</strong> ' : '[<strong>' . $txt['all'] . '</strong>] ';
            // Set start back to 0...
            $_REQUEST['start'] = 0;
        } else {
            $context['page_index'] .= '&nbsp;<a href="' . $scripturl . '?topic=' . $topic . '.0;all">' . $txt['all'] . '</a> ';
        }
    }
    // Build the link tree.
    $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $topicinfo['subject'], 'extra_before' => $settings['linktree_inline'] ? $txt['topic'] . ': ' : '');
    // Build a list of this board's moderators.
    $context['moderators'] =& $board_info['moderators'];
    $context['link_moderators'] = array();
    if (!empty($board_info['moderators'])) {
        // Add a link for each moderator...
        foreach ($board_info['moderators'] as $mod) {
            $context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
        }
        // And show it after the board's name.
        $context['linktree'][count($context['linktree']) - 2]['extra_after'] = ' (' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')';
    }
    // Information about the current topic...
    $context['is_locked'] = $topicinfo['locked'];
    $context['is_sticky'] = $topicinfo['is_sticky'];
    $context['is_very_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicVeryPosts'];
    $context['is_hot'] = $topicinfo['num_replies'] >= $modSettings['hotTopicPosts'];
    $context['is_approved'] = $topicinfo['approved'];
    // We don't want to show the poll icon in the topic class here, so pretend it's not one.
    $context['is_poll'] = false;
    determineTopicClass($context);
    $context['is_poll'] = $topicinfo['id_poll'] > 0 && $modSettings['pollMode'] == '1' && allowedTo('poll_view');
    // Did this user start the topic or not?
    $context['user']['started'] = $user_info['id'] == $topicinfo['id_member_started'] && !$user_info['is_guest'];
    $context['topic_starter_id'] = $topicinfo['id_member_started'];
    // Set the topic's information for the template.
    $context['subject'] = $topicinfo['subject'];
    $context['num_views'] = $topicinfo['num_views'];
    $context['mark_unread_time'] = $topicinfo['new_from'];
    // Set a canonical URL for this page.
    $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.' . $context['start'];
    // For quick reply we need a response prefix in the default forum language.
    if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix', 600))) {
        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);
    }
    // If we want to show event information in the topic, prepare the data.
    if (allowedTo('calendar_view') && !empty($modSettings['cal_showInTopic']) && !empty($modSettings['cal_enabled'])) {
        // First, try create a better time format, ignoring the "time" elements.
        if (preg_match('~%[AaBbCcDdeGghjmuYy](?:[^%]*%[AaBbCcDdeGghjmuYy])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) {
            $date_string = $user_info['time_format'];
        } else {
            $date_string = $matches[0];
        }
        // Any calendar information for this topic?
        $request = $smcFunc['db_query']('', '
			SELECT cal.id_event, cal.start_date, cal.end_date, cal.title, cal.id_member, mem.real_name
			FROM {db_prefix}calendar AS cal
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = cal.id_member)
			WHERE cal.id_topic = {int:current_topic}
			ORDER BY start_date', array('current_topic' => $topic));
        $context['linked_calendar_events'] = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Prepare the dates for being formatted.
            $start_date = sscanf($row['start_date'], '%04d-%02d-%02d');
            $start_date = mktime(12, 0, 0, $start_date[1], $start_date[2], $start_date[0]);
            $end_date = sscanf($row['end_date'], '%04d-%02d-%02d');
            $end_date = mktime(12, 0, 0, $end_date[1], $end_date[2], $end_date[0]);
            $context['linked_calendar_events'][] = array('id' => $row['id_event'], 'title' => $row['title'], 'can_edit' => allowedTo('calendar_edit_any') || $row['id_member'] == $user_info['id'] && allowedTo('calendar_edit_own'), 'modify_href' => $scripturl . '?action=post;msg=' . $topicinfo['id_first_msg'] . ';topic=' . $topic . '.0;calendar;eventid=' . $row['id_event'] . ';' . $context['session_var'] . '=' . $context['session_id'], 'start_date' => timeformat($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => timeformat($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false);
        }
        $smcFunc['db_free_result']($request);
        if (!empty($context['linked_calendar_events'])) {
            $context['linked_calendar_events'][count($context['linked_calendar_events']) - 1]['is_last'] = true;
        }
    }
    // Create the poll info if it exists.
    if ($context['is_poll']) {
        // Get the question and if it's locked.
        $request = $smcFunc['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
			FROM {db_prefix}polls AS p
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member)
			WHERE p.id_poll = {int:id_poll}
			LIMIT 1', array('id_poll' => $topicinfo['id_poll']));
        $pollinfo = $smcFunc['db_fetch_assoc']($request);
        $smcFunc['db_free_result']($request);
        $request = $smcFunc['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' => $topicinfo['id_poll'], 'not_guest' => 0));
        list($pollinfo['total']) = $smcFunc['db_fetch_row']($request);
        $smcFunc['db_free_result']($request);
        // Total voters needs to include guest voters
        $pollinfo['total'] += $pollinfo['num_guest_voters'];
        // Get all the options, and calculate the total votes.
        $request = $smcFunc['db_query']('', '
			SELECT pc.id_choice, pc.label, pc.votes, IFNULL(lp.id_choice, -1) AS voted_this
			FROM {db_prefix}poll_choices AS pc
				LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest})
			WHERE pc.id_poll = {int:id_poll}', array('current_member' => $user_info['id'], 'id_poll' => $topicinfo['id_poll'], 'not_guest' => 0));
        $pollOptions = array();
        $realtotal = 0;
        $pollinfo['has_voted'] = false;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            censorText($row['label']);
            $pollOptions[$row['id_choice']] = $row;
            $realtotal += $row['votes'];
            $pollinfo['has_voted'] |= $row['voted_this'] != -1;
        }
        $smcFunc['db_free_result']($request);
        // If this is a guest we need to do our best to work out if they have voted, and what they voted for.
        if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote')) {
            if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $topicinfo['id_poll'] . ',') !== false) {
                // ;id,timestamp,[vote,vote...]; etc
                $guestinfo = explode(';', $_COOKIE['guest_poll_vote']);
                // Find the poll we're after.
                foreach ($guestinfo as $i => $guestvoted) {
                    $guestvoted = explode(',', $guestvoted);
                    if ($guestvoted[0] == $topicinfo['id_poll']) {
                        break;
                    }
                }
                // Has the poll been reset since guest voted?
                if ($pollinfo['reset_poll'] > $guestvoted[1]) {
                    // Remove the poll info from the cookie to allow guest to vote again
                    unset($guestinfo[$i]);
                    if (!empty($guestinfo)) {
                        $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo);
                    } else {
                        unset($_COOKIE['guest_poll_vote']);
                    }
                } else {
                    // What did they vote for?
                    unset($guestvoted[0], $guestvoted[1]);
                    foreach ($pollOptions as $choice => $details) {
                        $pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1;
                        $pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1;
                    }
                    unset($choice, $details, $guestvoted);
                }
                unset($guestinfo, $guestvoted, $i);
            }
        }
        // Set up the basic poll information.
        $context['poll'] = array('id' => $topicinfo['id_poll'], 'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'), 'question' => parse_bbc($pollinfo['question']), 'total_votes' => $pollinfo['total'], 'change_vote' => !empty($pollinfo['change_vote']), 'is_locked' => !empty($pollinfo['voting_locked']), 'options' => array(), 'lock' => allowedTo('poll_lock_any') || $context['user']['started'] && allowedTo('poll_lock_own'), 'edit' => allowedTo('poll_edit_any') || $context['user']['started'] && allowedTo('poll_edit_own'), 'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '', 'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(), 'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0, 'has_voted' => !empty($pollinfo['has_voted']), 'starter' => array('id' => $pollinfo['id_member'], 'name' => $row['poster_name'], 'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'], 'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>'));
        // Make the lock and edit permissions defined above more directly accessible.
        $context['allow_lock_poll'] = $context['poll']['lock'];
        $context['allow_edit_poll'] = $context['poll']['edit'];
        // You're allowed to vote if:
        // 1. the poll did not expire, and
        // 2. you're either not a guest OR guest voting is enabled... and
        // 3. you're not trying to view the results, and
        // 4. the poll is not locked, and
        // 5. you have the proper permissions, and
        // 6. you haven't already voted before.
        $context['allow_vote'] = !$context['poll']['is_expired'] && (!$user_info['is_guest'] || $pollinfo['guest_vote'] && allowedTo('poll_vote')) && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && !$context['poll']['has_voted'];
        // You're allowed to view the results if:
        // 1. you're just a super-nice-guy, or
        // 2. anyone can see them (hide_results == 0), or
        // 3. you can see them after you voted (hide_results == 1), or
        // 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.)
        $context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || $pollinfo['hide_results'] == 1 && $context['poll']['has_voted'] || $context['poll']['is_expired'];
        $context['poll']['show_results'] = $context['allow_poll_view'] && (isset($_REQUEST['viewresults']) || isset($_REQUEST['viewResults']));
        $context['show_view_results_button'] = $context['allow_vote'] && (!$context['allow_poll_view'] || !$context['poll']['show_results'] || !$context['poll']['has_voted']);
        // You're allowed to change your vote if:
        // 1. the poll did not expire, and
        // 2. you're not a guest... and
        // 3. the poll is not locked, and
        // 4. you have the proper permissions, and
        // 5. you have already voted, and
        // 6. the poll creator has said you can!
        $context['allow_change_vote'] = !$context['poll']['is_expired'] && !$user_info['is_guest'] && empty($pollinfo['voting_locked']) && allowedTo('poll_vote') && $context['poll']['has_voted'] && $context['poll']['change_vote'];
        // You're allowed to return to voting options if:
        // 1. you are (still) allowed to vote.
        // 2. you are currently seeing the results.
        $context['allow_return_vote'] = $context['allow_vote'] && $context['poll']['show_results'];
        // Calculate the percentages and bar lengths...
        $divisor = $realtotal == 0 ? 1 : $realtotal;
        // Determine if a decimal point is needed in order for the options to add to 100%.
        $precision = $realtotal == 100 ? 0 : 1;
        // Now look through each option, and...
        foreach ($pollOptions as $i => $option) {
            // First calculate the percentage, and then the width of the bar...
            $bar = round($option['votes'] * 100 / $divisor, $precision);
            $barWide = $bar == 0 ? 1 : floor($bar * 8 / 3);
            // Now add it to the poll's contextual theme data.
            $context['poll']['options'][$i] = array('id' => 'options-' . $i, 'percent' => $bar, 'votes' => $option['votes'], 'voted_this' => $option['voted_this'] != -1, 'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'right' : 'left') . '.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_' . ($context['right_to_left'] ? 'left' : 'right') . '.gif" alt="" /></span>', 'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '', 'bar_width' => $barWide, 'option' => parse_bbc($option['label']), 'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '" />');
        }
    }
    // Calculate the fastest way to get the messages!
    $ascending = empty($options['view_newest_first']);
    $start = $_REQUEST['start'];
    $limit = $context['messages_per_page'];
    $firstIndex = 0;
    if ($start >= $context['total_visible_posts'] / 2 && $context['messages_per_page'] != -1) {
        $ascending = !$ascending;
        $limit = $context['total_visible_posts'] <= $start + $limit ? $context['total_visible_posts'] - $start : $limit;
        $start = $context['total_visible_posts'] <= $start + $limit ? 0 : $context['total_visible_posts'] - $start - $limit;
        $firstIndex = $limit - 1;
    }
    // Get each post and poster in this topic.
    $request = $smcFunc['db_query']('display_get_post_poster', '
		SELECT id_msg, id_member, approved
		FROM {db_prefix}messages
		WHERE id_topic = {int:current_topic}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : (!empty($modSettings['db_mysql_group_by_fix']) ? '' : '
		GROUP BY id_msg') . '
		HAVING (approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR id_member = {int:current_member}') . ')') . '
		ORDER BY id_msg ' . ($ascending ? '' : 'DESC') . ($context['messages_per_page'] == -1 ? '' : '
		LIMIT ' . $start . ', ' . $limit), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'is_approved' => 1, 'blank_id_member' => 0));
    $messages = array();
    $all_posters = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        if (!empty($row['id_member'])) {
            $all_posters[$row['id_msg']] = $row['id_member'];
        }
        $messages[] = $row['id_msg'];
    }
    $smcFunc['db_free_result']($request);
    $posters = array_unique($all_posters);
    // Guests can't mark topics read or for notifications, just can't sorry.
    if (!$user_info['is_guest']) {
        $mark_at_msg = max($messages);
        if ($mark_at_msg >= $topicinfo['id_last_msg']) {
            $mark_at_msg = $modSettings['maxMsgID'];
        }
        if ($mark_at_msg >= $topicinfo['new_from']) {
            $smcFunc['db_insert']($topicinfo['new_from'] == 0 ? 'ignore' : 'replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), array($user_info['id'], $topic, $mark_at_msg), array('id_member', 'id_topic'));
        }
        // Check for notifications on this topic OR board.
        $request = $smcFunc['db_query']('', '
			SELECT sent, id_topic
			FROM {db_prefix}log_notify
			WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
				AND id_member = {int:current_member}
			LIMIT 2', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic));
        $do_once = true;
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            // Find if this topic is marked for notification...
            if (!empty($row['id_topic'])) {
                $context['is_marked_notify'] = true;
            }
            // Only do this once, but mark the notifications as "not sent yet" for next time.
            if (!empty($row['sent']) && $do_once) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}log_notify
					SET sent = {int:is_not_sent}
					WHERE (id_topic = {int:current_topic} OR id_board = {int:current_board})
						AND id_member = {int:current_member}', array('current_board' => $board, 'current_member' => $user_info['id'], 'current_topic' => $topic, 'is_not_sent' => 0));
                $do_once = false;
            }
        }
        // Have we recently cached the number of new topics in this board, and it's still a lot?
        if (isset($_REQUEST['topicseen']) && isset($_SESSION['topicseen_cache'][$board]) && $_SESSION['topicseen_cache'][$board] > 5) {
            $_SESSION['topicseen_cache'][$board]--;
        } elseif (isset($_REQUEST['topicseen'])) {
            // Use the mark read tables... and the last visit to figure out if this should be read or not.
            $request = $smcFunc['db_query']('', '
				SELECT COUNT(*)
				FROM {db_prefix}topics AS t
					LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = {int:current_board} AND lb.id_member = {int:current_member})
					LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
				WHERE t.id_board = {int:current_board}
					AND t.id_last_msg > IFNULL(lb.id_msg, 0)
					AND t.id_last_msg > IFNULL(lt.id_msg, 0)' . (empty($_SESSION['id_msg_last_visit']) ? '' : '
					AND t.id_last_msg > {int:id_msg_last_visit}'), array('current_board' => $board, 'current_member' => $user_info['id'], 'id_msg_last_visit' => (int) $_SESSION['id_msg_last_visit']));
            list($numNewTopics) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // If there're no real new topics in this board, mark the board as seen.
            if (empty($numNewTopics)) {
                $_REQUEST['boardseen'] = true;
            } else {
                $_SESSION['topicseen_cache'][$board] = $numNewTopics;
            }
        } elseif (isset($_SESSION['topicseen_cache'][$board])) {
            $_SESSION['topicseen_cache'][$board]--;
        }
        // Mark board as seen if we came using last post link from BoardIndex. (or other places...)
        if (isset($_REQUEST['boardseen'])) {
            $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), array($modSettings['maxMsgID'], $user_info['id'], $board), array('id_member', 'id_board'));
        }
    }
    $attachments = array();
    // If there _are_ messages here... (probably an error otherwise :!)
    if (!empty($messages)) {
        // Fetch attachments.
        if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) {
            $request = $smcFunc['db_query']('', '
				SELECT
					a.id_attach, a.id_folder, a.id_msg, a.filename, a.file_hash, IFNULL(a.size, 0) AS filesize, a.downloads, a.approved,
					a.width, a.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 a' . (empty($modSettings['attachmentShowImages']) || empty($modSettings['attachmentThumbnails']) ? '' : '
					LEFT JOIN {db_prefix}attachments AS thumb ON (thumb.id_attach = a.id_thumb)') . '
				WHERE a.id_msg IN ({array_int:message_list})
					AND a.attachment_type = {int:attachment_type}', array('message_list' => $messages, 'attachment_type' => 0, 'is_approved' => 1));
            $temp = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                if (!$row['approved'] && $modSettings['postmod_active'] && !allowedTo('approve_posts') && (!isset($all_posters[$row['id_msg']]) || $all_posters[$row['id_msg']] != $user_info['id'])) {
                    continue;
                }
                $temp[$row['id_attach']] = $row;
                if (!isset($attachments[$row['id_msg']])) {
                    $attachments[$row['id_msg']] = array();
                }
            }
            $smcFunc['db_free_result']($request);
            // This is better than sorting it with the query...
            ksort($temp);
            foreach ($temp as $row) {
                $attachments[$row['id_msg']][] = $row;
            }
        }
        // What?  It's not like it *couldn't* be only guests in this topic...
        if (!empty($posters)) {
            loadMemberData($posters);
        }
        $messages_request = $smcFunc['db_query']('', '
			SELECT
				id_msg, icon, subject, poster_time, poster_ip, id_member, modified_time, modified_name, body,
				smileys_enabled, poster_name, poster_email, approved,
				id_msg_modified < {int:new_from} AS is_read
			FROM {db_prefix}messages
			WHERE id_msg IN ({array_int:message_list})
			ORDER BY id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'), array('message_list' => $messages, 'new_from' => $topicinfo['new_from']));
        // Go to the last message if the given time is beyond the time of the last message.
        if (isset($context['start_from']) && $context['start_from'] >= $topicinfo['num_replies']) {
            $context['start_from'] = $topicinfo['num_replies'];
        }
        // Since the anchor information is needed on the top of the page we load these variables beforehand.
        $context['first_message'] = isset($messages[$firstIndex]) ? $messages[$firstIndex] : $messages[0];
        if (empty($options['view_newest_first'])) {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $context['start_from'];
        } else {
            $context['first_new_message'] = isset($context['start_from']) && $_REQUEST['start'] == $topicinfo['num_replies'] - $context['start_from'];
        }
    } else {
        $messages_request = false;
        $context['first_message'] = 0;
        $context['first_new_message'] = false;
    }
    $context['jump_to'] = array('label' => addslashes(un_htmlspecialchars($txt['jump_to'])), 'board_name' => htmlspecialchars(strtr(strip_tags($board_info['name']), array('&amp;' => '&'))), 'child_level' => $board_info['child_level']);
    // Set the callback.  (do you REALIZE how much memory all the messages would take?!?)
    $context['get_message'] = 'prepareDisplayContext';
    // Now set all the wonderful, wonderful permissions... like moderation ones...
    $common_permissions = array('can_approve' => 'approve_posts', 'can_ban' => 'manage_bans', 'can_sticky' => 'make_sticky', 'can_merge' => 'merge_any', 'can_split' => 'split_any', 'calendar_post' => 'calendar_post', 'can_mark_notify' => 'mark_any_notify', 'can_send_topic' => 'send_topic', 'can_send_pm' => 'pm_send', 'can_report_moderator' => 'report_any', 'can_moderate_forum' => 'moderate_forum', 'can_issue_warning' => 'issue_warning', 'can_restore_topic' => 'move_any', 'can_restore_msg' => 'move_any');
    foreach ($common_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm);
    }
    // Permissions with _any/_own versions.  $context[YYY] => ZZZ_any/_own.
    $anyown_permissions = array('can_move' => 'move', 'can_lock' => 'lock', 'can_delete' => 'remove', 'can_add_poll' => 'poll_add', 'can_remove_poll' => 'poll_remove', 'can_reply' => 'post_reply', 'can_reply_unapproved' => 'post_unapproved_replies');
    foreach ($anyown_permissions as $contextual => $perm) {
        $context[$contextual] = allowedTo($perm . '_any') || $context['user']['started'] && allowedTo($perm . '_own');
    }
    // Cleanup all the permissions with extra stuff...
    $context['can_mark_notify'] &= !$context['user']['is_guest'];
    $context['can_sticky'] &= !empty($modSettings['enableStickyTopics']);
    $context['calendar_post'] &= !empty($modSettings['cal_enabled']);
    $context['can_add_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] <= 0;
    $context['can_remove_poll'] &= $modSettings['pollMode'] == '1' && $topicinfo['id_poll'] > 0;
    $context['can_reply'] &= empty($topicinfo['locked']) || allowedTo('moderate_board');
    $context['can_reply_unapproved'] &= $modSettings['postmod_active'] && (empty($topicinfo['locked']) || allowedTo('moderate_board'));
    $context['can_issue_warning'] &= in_array('w', $context['admin_features']) && $modSettings['warning_settings'][0] == 1;
    // Handle approval flags...
    $context['can_reply_approved'] = $context['can_reply'];
    $context['can_reply'] |= $context['can_reply_unapproved'];
    $context['can_quote'] = $context['can_reply'] && (empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])));
    $context['can_mark_unread'] = !$user_info['is_guest'] && $settings['show_mark_read'];
    $context['can_send_topic'] = (!$modSettings['postmod_active'] || $topicinfo['approved']) && allowedTo('send_topic');
    // Start this off for quick moderation - it will be or'd for each post.
    $context['can_remove_post'] = allowedTo('delete_any') || allowedTo('delete_replies') && $context['user']['started'];
    // Can restore topic?  That's if the topic is in the recycle board and has a previous restore state.
    $context['can_restore_topic'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_board']);
    $context['can_restore_msg'] &= !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $board && !empty($topicinfo['id_previous_topic']);
    // Wireless shows a "more" if you can do anything special.
    if (WIRELESS && WIRELESS_PROTOCOL != 'wap') {
        $context['wireless_more'] = $context['can_sticky'] || $context['can_lock'] || allowedTo('modify_any');
        $context['wireless_moderate'] = isset($_GET['moderate']) ? ';moderate' : '';
    }
    // Load up the "double post" sequencing magic.
    if (!empty($options['display_quick_reply'])) {
        checkSubmitOnce('register');
        $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : '';
        $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : '';
    }
}
Пример #28
0
    AutoTask();
}
// Register an error handler.
set_error_handler('error_handler');
// Start the session. (assuming it hasn't already been.)
loadSession();
$sc = $_SESSION['session_value'];
$_GET[$_SESSION['session_var']] = $_SESSION['session_value'];
$_POST[$_SESSION['session_var']] = $_SESSION['session_value'];
define('WIRELESS', false);
if (isset($_GET['user_id'])) {
    $user = loadMemberData(intval($_GET['user_id']), false, 'profile');
} elseif (isset($_GET['username'])) {
    $user = loadMemberData(base64_decode($_GET['username']), true, 'profile');
    if (empty($user)) {
        $user = loadMemberData($_GET['username'], true, 'profile');
    }
} else {
    exit;
}
$url = '';
if (isset($user[0]) && !empty($user[0])) {
    if (empty($url)) {
        $memID = $user[0];
        $context['id_member'] = $user[0];
        $GLOBALS['cur_profile'] = $GLOBALS['user_profile'][$memID];
        loadMemberContext($memID);
        if (isset($GLOBALS['memberContext'][$memID]['avatar']['href'])) {
            $url = $GLOBALS['memberContext'][$memID]['avatar']['href'];
            header("Location: {$url}", 0, 303);
            @ob_end_clean();
Пример #29
0
function ViewErrorLog()
{
    global $scripturl, $txt, $context, $modSettings, $user_profile, $filter, $boarddir, $sourcedir, $themedir, $smcFunc;
    // Viewing contents of a file?
    if (isset($_GET['file'])) {
        return ViewFile();
    }
    // Check for the administrative permission to do this.
    isAllowedTo('admin_forum');
    // Templates, etc...
    loadLanguage('ManageMaintenance');
    loadTemplate('Errors');
    // You can filter by any of the following columns:
    $filters = array('id_member' => $txt['username'], 'ip' => $txt['ip_address'], 'session' => $txt['session'], 'url' => $txt['error_url'], 'message' => $txt['error_message'], 'error_type' => $txt['error_type'], 'file' => $txt['file'], 'line' => $txt['line']);
    // Set up the filtering...
    if (isset($_GET['value'], $_GET['filter']) && isset($filters[$_GET['filter']])) {
        $filter = array('variable' => $_GET['filter'], 'value' => array('sql' => in_array($_GET['filter'], array('message', 'url', 'file')) ? base64_decode(strtr($_GET['value'], array(' ' => '+'))) : $smcFunc['db_escape_wildcard_string']($_GET['value'])), 'href' => ';filter=' . $_GET['filter'] . ';value=' . $_GET['value'], 'entity' => $filters[$_GET['filter']]);
    }
    // Deleting, are we?
    if (isset($_POST['delall']) || isset($_POST['delete'])) {
        deleteErrors();
    }
    // Just how many errors are there?
    $result = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}log_errors' . (isset($filter) ? '
		WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : ''), array('filter' => isset($filter) ? $filter['value']['sql'] : ''));
    list($num_errors) = $smcFunc['db_fetch_row']($result);
    $smcFunc['db_free_result']($result);
    // If this filter is empty...
    if ($num_errors == 0 && isset($filter)) {
        redirectexit('action=admin;area=logs;sa=errorlog' . (isset($_REQUEST['desc']) ? ';desc' : ''));
    }
    // Clean up start.
    if (!isset($_GET['start']) || $_GET['start'] < 0) {
        $_GET['start'] = 0;
    }
    // Do we want to reverse error listing?
    $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up';
    // Set the page listing up.
    $context['page_index'] = constructPageIndex($scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . (isset($filter) ? $filter['href'] : ''), $_GET['start'], $num_errors, $modSettings['defaultMaxMessages']);
    $context['start'] = $_GET['start'];
    // Find and sort out the errors.
    $request = $smcFunc['db_query']('', '
		SELECT id_error, id_member, ip, url, log_time, message, session, error_type, file, line
		FROM {db_prefix}log_errors' . (isset($filter) ? '
		WHERE ' . $filter['variable'] . ' LIKE {string:filter}' : '') . '
		ORDER BY id_error ' . ($context['sort_direction'] == 'down' ? 'DESC' : '') . '
		LIMIT ' . $_GET['start'] . ', ' . $modSettings['defaultMaxMessages'], array('filter' => isset($filter) ? $filter['value']['sql'] : ''));
    $context['errors'] = array();
    $members = array();
    for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i++) {
        $search_message = preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '%', $smcFunc['db_escape_wildcard_string']($row['message']));
        if ($search_message == $filter['value']['sql']) {
            $search_message = $smcFunc['db_escape_wildcard_string']($row['message']);
        }
        $show_message = strtr(strtr(preg_replace('~&lt;span class=&quot;remove&quot;&gt;(.+?)&lt;/span&gt;~', '$1', $row['message']), array("\r" => '', '<br />' => "\n", '<' => '&lt;', '>' => '&gt;', '"' => '&quot;')), array("\n" => '<br />'));
        $context['errors'][$row['id_error']] = array('alternate' => $i % 2 == 0, 'member' => array('id' => $row['id_member'], 'ip' => $row['ip'], 'session' => $row['session']), 'time' => timeformat($row['log_time']), 'timestamp' => $row['log_time'], 'url' => array('html' => htmlspecialchars((substr($row['url'], 0, 1) == '?' ? $scripturl : '') . $row['url']), 'href' => base64_encode($smcFunc['db_escape_wildcard_string']($row['url']))), 'message' => array('html' => $show_message, 'href' => base64_encode($search_message)), 'id' => $row['id_error'], 'error_type' => array('type' => $row['error_type'], 'name' => isset($txt['errortype_' . $row['error_type']]) ? $txt['errortype_' . $row['error_type']] : $row['error_type']), 'file' => array());
        if (!empty($row['file']) && !empty($row['line'])) {
            // Eval'd files rarely point to the right location and cause havoc for linking, so don't link them.
            $linkfile = strpos($row['file'], 'eval') === false || strpos($row['file'], '?') === false;
            // De Morgan's Law.  Want this true unless both are present.
            $context['errors'][$row['id_error']]['file'] = array('file' => $row['file'], 'line' => $row['line'], 'href' => $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'], 'link' => $linkfile ? '<a href="' . $scripturl . '?action=admin;area=logs;sa=errorlog;file=' . base64_encode($row['file']) . ';line=' . $row['line'] . '" onclick="return reqWin(this.href, 600, 400, false);">' . $row['file'] . '</a>' : $row['file'], 'search' => base64_encode($row['file']));
        }
        // Make a list of members to load later.
        $members[$row['id_member']] = $row['id_member'];
    }
    $smcFunc['db_free_result']($request);
    // Load the member data.
    if (!empty($members)) {
        // Get some additional member info...
        $request = $smcFunc['db_query']('', '
			SELECT id_member, member_name, real_name
			FROM {db_prefix}members
			WHERE id_member IN ({array_int:member_list})
			LIMIT ' . count($members), array('member_list' => $members));
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            $members[$row['id_member']] = $row;
        }
        $smcFunc['db_free_result']($request);
        // This is a guest...
        $members[0] = array('id_member' => 0, 'member_name' => '', 'real_name' => $txt['guest_title']);
        // Go through each error and tack the data on.
        foreach ($context['errors'] as $id => $dummy) {
            $memID = $context['errors'][$id]['member']['id'];
            $context['errors'][$id]['member']['username'] = $members[$memID]['member_name'];
            $context['errors'][$id]['member']['name'] = $members[$memID]['real_name'];
            $context['errors'][$id]['member']['href'] = empty($memID) ? '' : $scripturl . '?action=profile;u=' . $memID;
            $context['errors'][$id]['member']['link'] = empty($memID) ? $txt['guest_title'] : '<a href="' . $scripturl . '?action=profile;u=' . $memID . '">' . $context['errors'][$id]['member']['name'] . '</a>';
        }
    }
    // Filtering anything?
    if (isset($filter)) {
        $context['filter'] =& $filter;
        // Set the filtering context.
        if ($filter['variable'] == 'id_member') {
            $id = $filter['value']['sql'];
            loadMemberData($id, false, 'minimal');
            $context['filter']['value']['html'] = '<a href="' . $scripturl . '?action=profile;u=' . $id . '">' . $user_profile[$id]['real_name'] . '</a>';
        } elseif ($filter['variable'] == 'url') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars((substr($filter['value']['sql'], 0, 1) == '?' ? $scripturl : '') . $filter['value']['sql']), array('\\_' => '_')) . '\'';
        } elseif ($filter['variable'] == 'message') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '&lt;br /&gt;' => '<br />', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\'';
            $context['filter']['value']['html'] = preg_replace('~&amp;lt;span class=&amp;quot;remove&amp;quot;&amp;gt;(.+?)&amp;lt;/span&amp;gt;~', '$1', $context['filter']['value']['html']);
        } elseif ($filter['variable'] == 'error_type') {
            $context['filter']['value']['html'] = '\'' . strtr(htmlspecialchars($filter['value']['sql']), array("\n" => '<br />', '&lt;br /&gt;' => '<br />', "\t" => '&nbsp;&nbsp;&nbsp;', '\\_' => '_', '\\%' => '%', '\\\\' => '\\')) . '\'';
        } else {
            $context['filter']['value']['html'] =& $filter['value']['sql'];
        }
    }
    $context['error_types'] = array();
    $context['error_types']['all'] = array('label' => $txt['errortype_all'], 'description' => isset($txt['errortype_all_desc']) ? $txt['errortype_all_desc'] : '', 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : ''), 'is_selected' => empty($filter));
    $sum = 0;
    // What type of errors do we have and how many do we have?
    $request = $smcFunc['db_query']('', '
		SELECT error_type, COUNT(*) AS num_errors
		FROM {db_prefix}log_errors
		GROUP BY error_type
		ORDER BY error_type = {string:critical_type} DESC, error_type ASC', array('critical_type' => 'critical'));
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        // Total errors so far?
        $sum += $row['num_errors'];
        $context['error_types'][$sum] = array('label' => (isset($txt['errortype_' . $row['error_type']]) ? $txt['errortype_' . $row['error_type']] : $row['error_type']) . ' (' . $row['num_errors'] . ')', 'description' => isset($txt['errortype_' . $row['error_type'] . '_desc']) ? $txt['errortype_' . $row['error_type'] . '_desc'] : '', 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog' . ($context['sort_direction'] == 'down' ? ';desc' : '') . ';filter=error_type;value=' . $row['error_type'], 'is_selected' => isset($filter) && $filter['value']['sql'] == $smcFunc['db_escape_wildcard_string']($row['error_type']));
    }
    $smcFunc['db_free_result']($request);
    // Update the all errors tab with the total number of errors
    $context['error_types']['all']['label'] .= ' (' . $sum . ')';
    // Finally, work out what is the last tab!
    if (isset($context['error_types'][$sum])) {
        $context['error_types'][$sum]['is_last'] = true;
    } else {
        $context['error_types']['all']['is_last'] = true;
    }
    // And this is pretty basic ;).
    $context['page_title'] = $txt['errlog'];
    $context['has_filter'] = isset($filter);
    $context['sub_template'] = 'error_log';
}
Пример #30
0
function verify_smf_userids_from_names($names)
{
    $direct_ids = array();
    $valid_names = array();
    $verified_ids = array();
    foreach ($names as $index => $user) {
        if (is_numeric($user) && $user == intval($user)) {
            $direct_ids[] = $user;
        } else {
            $valid_names[] = $user;
        }
    }
    if (!empty($valid_names)) {
        $loaded_ids = loadMemberData($valid_names, true);
        //make sure tids only contains integer values
        if (is_array($loaded_ids)) {
            foreach ($loaded_ids as $idx => $loaded_id) {
                if (is_numeric($loaded_id) && $loaded_id == intval($loaded_id)) {
                    $verified_ids[] = $loaded_id;
                }
            }
        } else {
            if (is_numeric($loaded_ids) && $loaded_ids == intval($loaded_ids)) {
                $verified_ids[] = $loaded_ids;
            }
        }
    }
    $verified_ids = array_unique(array_merge($direct_ids, $verified_ids));
    return $verified_ids;
}