function PrintTopic() { global $topic, $txt, $scripturl, $context, $user_info; global $board_info, $smcFunc, $modSettings; // Redirect to the boardindex if no valid topic id is provided. if (empty($topic)) { redirectexit(); } // Whatever happens don't index this. $context['robot_no_index'] = true; // Get the topic starter information. $request = smf_db_query(' SELECT m.poster_time, IFNULL(mem.real_name, m.poster_name) AS poster_name FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_topic = {int:current_topic} ORDER BY m.id_msg LIMIT 1', array('current_topic' => $topic)); // Redirect to the boardindex if no valid topic id is provided. if (mysql_num_rows($request) == 0) { redirectexit(); } $row = mysql_fetch_assoc($request); mysql_free_result($request); // Lets "output" all that info. EoS_Smarty::loadTemplate('topic/printpage'); $context['board_name'] = $board_info['name']; $context['category_name'] = $board_info['cat']['name']; $context['poster_name'] = $row['poster_name']; $context['post_time'] = timeformat($row['poster_time'], false); $context['parent_boards'] = array(); foreach ($board_info['parent_boards'] as $parent) { $context['parent_boards'][] = $parent['name']; } // Split the topics up so we can print them. $request = smf_db_query(' SELECT subject, poster_time, body, IFNULL(mem.real_name, poster_name) AS poster_name FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && !allowedTo('approve_posts') ? ' AND (m.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR m.id_member = {int:current_member}') . ')' : '') . ' ORDER BY m.id_msg', array('current_topic' => $topic, 'is_approved' => 1, 'current_member' => $user_info['id'])); $context['posts'] = array(); while ($row = mysql_fetch_assoc($request)) { // Censor the subject and message. censorText($row['subject']); censorText($row['body']); $context['posts'][] = array('subject' => $row['subject'], 'member' => $row['poster_name'], 'time' => timeformat($row['poster_time'], false), 'timestamp' => forum_time(true, $row['poster_time']), 'body' => parse_bbc($row['body'], 'print')); if (!isset($context['topic_subject'])) { $context['topic_subject'] = $row['subject']; } } mysql_free_result($request); // Set a canonical URL for this page. $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.0'; }
function template_folder() { global $context, $settings, $options, $scripturl, $modSettings, $txt; $imgsrc = $settings['images_url'] . '/clipsrc.png'; // The every helpful javascript! echo ' <script type="text/javascript"><!-- // --><![CDATA[ var allLabels = {}; var currentLabels = {}; function loadLabelChoices() { var listing = document.forms.pmFolder.elements; var theSelect = document.forms.pmFolder.pm_action; var add, remove, toAdd = {length: 0}, toRemove = {length: 0}; if (theSelect.childNodes.length == 0) return;'; // This is done this way for internationalization reasons. echo ' if (!(\'-1\' in allLabels)) { for (var o = 0; o < theSelect.options.length; o++) if (theSelect.options[o].value.substr(0, 4) == "rem_") allLabels[theSelect.options[o].value.substr(4)] = theSelect.options[o].text; } for (var i = 0; i < listing.length; i++) { if (listing[i].name != "pms[]" || !listing[i].checked) continue; var alreadyThere = [], x; for (x in currentLabels[listing[i].value]) { if (!(x in toRemove)) { toRemove[x] = allLabels[x]; toRemove.length++; } alreadyThere[x] = allLabels[x]; } for (x in allLabels) { if (!(x in alreadyThere)) { toAdd[x] = allLabels[x]; toAdd.length++; } } } while (theSelect.options.length > 2) theSelect.options[2] = null; if (toAdd.length != 0) { theSelect.options[theSelect.options.length] = new Option("', $txt['pm_msg_label_apply'], '", ""); setInnerHTML(theSelect.options[theSelect.options.length - 1], "', $txt['pm_msg_label_apply'], '"); theSelect.options[theSelect.options.length - 1].disabled = true; for (i in toAdd) { if (i != "length") theSelect.options[theSelect.options.length] = new Option(toAdd[i], "add_" + i); } } if (toRemove.length != 0) { theSelect.options[theSelect.options.length] = new Option("', $txt['pm_msg_label_remove'], '", ""); setInnerHTML(theSelect.options[theSelect.options.length - 1], "', $txt['pm_msg_label_remove'], '"); theSelect.options[theSelect.options.length - 1].disabled = true; for (i in toRemove) { if (i != "length") theSelect.options[theSelect.options.length] = new Option(toRemove[i], "rem_" + i); } } } // ]]></script>'; echo ' <form style="padding-right:5px;" action="', $scripturl, '?action=pm;sa=pmactions;', $context['display_mode'] == 2 ? 'conversation;' : '', 'f=', $context['folder'], ';start=', $context['start'], $context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '', '" method="post" accept-charset="UTF-8" name="pmFolder">'; // If we are not in single display mode show the subjects on the top! if ($context['display_mode'] == 2) { template_subject_list(); echo '<div class="clear"><br /></div>'; } else { echo ' <div class="cat_bar2"> <div class="floatright tinytext"> <a href="', $scripturl, '?action=pm;view;f=', $context['folder'], ';start=', $context['start'], ';sort=', $context['sort_by'], $context['sort_direction'] == 'up' ? '' : ';desc', $context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '', '">', $txt['pm_change_view'], '</a> </div> <h3>', $context['pmboxname'], ' (', $context['display_mode'] == 1 ? $txt['pm_single_view'] : $txt['pm_flat_view'], ')</h3> </div>'; } echo ' <div class="clear"></div>'; // Got some messages to display? echo '<div class="posts_container">'; if ($context['get_pmessage']('message', true)) { // Show a few buttons if we are in conversation mode and outputting the first message. if ($context['display_mode'] == 2) { // Build the normal button array. $conversation_buttons = array('reply' => array('text' => 'reply_to_all', 'image' => 'reply.gif', 'lang' => true, 'url' => $scripturl . '?action=pm;sa=send;f=' . $context['folder'] . ($context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '') . ';pmsg=' . $context['current_pm'] . ';u=all', 'active' => true), 'delete' => array('text' => 'delete_conversation', 'image' => 'delete.gif', 'lang' => true, 'url' => $scripturl . '?action=pm;sa=pmactions;pm_actions[' . $context['current_pm'] . ']=delete;conversation;f=' . $context['folder'] . ';start=' . $context['start'] . ($context['current_label_id'] != -1 ? ';l=' . $context['current_label_id'] : '') . ';' . $context['session_var'] . '=' . $context['session_id'], 'custom' => 'onclick="return confirm(\'' . addslashes($txt['remove_message']) . '?\');"')); // Show the conversation buttons. echo ' <div class="pagesection">'; template_button_strip($conversation_buttons, 'right'); echo ' </div>'; } while ($message = $context['get_pmessage']('message')) { EoS_Smarty::getSmartyInstance()->display('pm/pmbit.tpl'); } echo ' </div>'; if (empty($context['display_mode'])) { echo ' <div class="pagesection"> <div class="floatleft pagelinks">', $context['page_index'], '</div> <div class="floatright"><input type="submit" name="del_selected" value="', $txt['quickmod_delete_selected'], '" style="font-weight: normal;" onclick="if (!confirm(\'', $txt['delete_selected_confirm'], '\')) return false;" class="button_submit" /></div> </div>'; } elseif ($context['display_mode'] == 2 && isset($conversation_buttons)) { echo ' <div class="pagesection">'; template_button_strip($conversation_buttons, 'right'); echo ' </div>'; } } else { echo ' <div class="red_container norounded mediumpadding">', $txt['pm_no_messages'], ' </div>'; } // Individual messages = buttom list! if ($context['display_mode'] == 1) { template_subject_list(); echo '<br />'; } echo ' <input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" /> </form>'; }
function loadBoard() { global $txt, $scripturl, $context, $modSettings; global $board_info, $board, $topic, $user_info, $db_show_debug; // Assume they are not a moderator. $user_info['is_mod'] = false; $context['user']['is_mod'] =& $user_info['is_mod']; // Start the linktree off empty.. $context['linktree'] = array(); // Have they by chance specified a message id but nothing else? if (empty($_REQUEST['action']) && empty($topic) && empty($board) && !empty($_REQUEST['msg'])) { // Make sure the message id is really an int. $_REQUEST['msg'] = (int) $_REQUEST['msg']; // Looking through the message table can be slow, so try using the cache first. if (($topic = CacheAPI::getCache('msg_topic-' . $_REQUEST['msg'], 120)) === NULL) { $request = smf_db_query(' SELECT id_topic FROM {db_prefix}messages WHERE id_msg = {int:id_msg} LIMIT 1', array('id_msg' => $_REQUEST['msg'])); // So did it find anything? if (mysql_num_rows($request)) { list($topic) = mysql_fetch_row($request); mysql_free_result($request); // Save save save. CacheAPI::putCache('msg_topic-' . $_REQUEST['msg'], $topic, 120); } } // Remember redirection is the key to avoiding fallout from your bosses. if (!empty($topic)) { if (isset($_REQUEST['perma'])) { redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . ';perma' . (isset($_REQUEST['xml']) ? ';xml' : '')); } else { redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']); } } else { loadPermissions(); loadTheme(); EoS_Smarty::init($db_show_debug); fatal_lang_error('topic_gone', false); } } // Load this board only if it is specified. if (empty($board) && empty($topic)) { $board_info = array('moderators' => array()); return; } if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) { // !!! SLOW? if (!empty($topic)) { $temp = CacheAPI::getCache('topic_board-' . $topic, 120); } else { $temp = CacheAPI::getCache('board-' . $board, 120); } if (!empty($temp)) { $board_info = $temp; $board = $board_info['id']; } } if (empty($temp)) { $request = smf_db_query(' SELECT c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups, b.id_parent, c.name AS cname, IFNULL(mem.id_member, 0) AS id_moderator, mem.real_name' . (!empty($topic) ? ', b.id_board' : '') . ', b.child_level, b.id_theme, b.override_theme, b.count_posts, b.id_profile, b.redirect, b.allow_topics, b.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . ' FROM {db_prefix}boards AS b' . (!empty($topic) ? ' INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . ' LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = {raw:board_link}) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member) WHERE b.id_board = {raw:board_link}', array('current_topic' => $topic, 'board_link' => empty($topic) ? smf_db_quote('{int:current_board}', array('current_board' => $board)) : 't.id_board')); // If there aren't any, skip. if (mysql_num_rows($request) > 0) { $row = mysql_fetch_assoc($request); // Set the current board. if (!empty($row['id_board'])) { $board = $row['id_board']; } // Basic operating information. (globals... :/) $board_info = array('id' => $board, 'moderators' => array(), 'cat' => array('id' => $row['id_cat'], 'name' => $row['cname'], 'is_root' => $row['cname'][0] === '!' ? true : false), 'name' => $row['bname'], 'allow_topics' => $row['allow_topics'], 'description' => $row['description'], 'num_topics' => $row['num_topics'], 'unapproved_topics' => $row['unapproved_topics'], 'unapproved_posts' => $row['unapproved_posts'], 'unapproved_user_topics' => 0, 'parent_boards' => getBoardParents($row['id_parent']), 'parent' => $row['id_parent'], 'child_level' => $row['child_level'], 'theme' => $row['id_theme'], 'override_theme' => !empty($row['override_theme']), 'profile' => $row['id_profile'], 'redirect' => $row['redirect'], 'posts_count' => empty($row['count_posts']), 'cur_topic_approved' => empty($topic) || $row['approved'], 'cur_topic_starter' => empty($topic) ? 0 : $row['id_member_started']); // Load the membergroups allowed, and check permissions. $board_info['groups'] = $row['member_groups'] == '' ? array() : explode(',', $row['member_groups']); do { if (!empty($row['id_moderator'])) { $board_info['moderators'][$row['id_moderator']] = array('id' => $row['id_moderator'], 'name' => $row['real_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_moderator'] . '">' . $row['real_name'] . '</a>'); } } while ($row = mysql_fetch_assoc($request)); // If the board only contains unapproved posts and the user isn't an approver then they can't see any topics. // If that is the case do an additional check to see if they have any topics waiting to be approved. if ($board_info['num_topics'] == 0 && $modSettings['postmod_active'] && !allowedTo('approve_posts')) { mysql_free_result($request); // Free the previous result $request = smf_db_query(' SELECT COUNT(id_topic) FROM {db_prefix}topics WHERE id_member_started={int:id_member} AND approved = {int:unapproved} AND id_board = {int:board}', array('id_member' => $user_info['id'], 'unapproved' => 0, 'board' => $board)); list($board_info['unapproved_user_topics']) = mysql_fetch_row($request); } if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) { // !!! SLOW? if (!empty($topic)) { CacheAPI::putCache('topic_board-' . $topic, $board_info, 120); } CacheAPI::putCache('board-' . $board, $board_info, 120); } } else { // Otherwise the topic is invalid, there are no moderators, etc. $board_info = array('moderators' => array(), 'error' => 'exist'); $topic = null; $board = 0; } mysql_free_result($request); } if (!empty($topic)) { $_GET['board'] = (int) $board; } /* * if we are in topic view, set up the breadcrumb so that it * gives a link back to the last active message index page instead of * always pointing back to page one, but ignore the cookie when the board has changed. * the cookie is set in MessageIndex.php */ $stored_topicstart = 0; if (isset($_COOKIE['smf_topicstart']) && !empty($topic)) { $topicstart_cookie = $_COOKIE['smf_topicstart']; $_t = explode('_', $topicstart_cookie); if (isset($_t[0]) && isset($_t[1]) && intval($_t[1]) > 0) { if ($_t[0] == $board) { $stored_topicstart = $_t[1]; } $topics_per_page = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']; } } if (!empty($board)) { // Now check if the user is a moderator. $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]); if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) { $board_info['error'] = 'access'; } // Build up the linktree. $context['linktree'] = array_merge($context['linktree'], $board_info['cat']['is_root'] ? array() : array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => URL::board($board, $board_info['name'], $stored_topicstart > 0 ? $stored_topicstart : 0, false), 'name' => $board_info['name'] . ($stored_topicstart > 0 ? ' [' . ($stored_topicstart / $topics_per_page + 1) . ']' : '')))); } // Set the template contextual information. $context['user']['is_mod'] =& $user_info['is_mod']; $context['current_topic'] = $topic; $context['current_board'] = $board; // Hacker... you can't see this topic, I'll tell you that. (but moderators can!) if (!empty($board_info['error']) && ($board_info['error'] != 'access' || !$user_info['is_mod'])) { // The permissions and theme need loading, just to make sure everything goes smoothly. loadPermissions(); loadTheme(); EoS_Smarty::init($db_show_debug); $_GET['board'] = ''; $_GET['topic'] = ''; // The linktree should not give the game away mate! $context['linktree'] = array(array('url' => URL::home(), 'name' => $context['forum_name_html_safe'])); // If it's a prefetching agent or we're requesting an attachment. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch' || !empty($_REQUEST['action']) && $_REQUEST['action'] === 'dlattach') { ob_end_clean(); header('HTTP/1.1 403 Forbidden'); die; } elseif ($user_info['is_guest']) { loadLanguage('Errors'); is_not_guest($txt['topic_gone']); } else { fatal_lang_error('topic_gone', false); } } if ($user_info['is_mod']) { $user_info['groups'][] = 3; } }
function setup_fatal_error_context($error_message) { global $context, $txt, $ssi_on_error_method; static $level = 0; // Attempt to prevent a recursive loop. ++$level; if ($level > 1) { return false; } // Maybe they came from dlattach or similar? if (SMF != 'SSI' && empty($context['theme_loaded'])) { loadTheme(); } // Don't bother indexing errors mate... $context['robot_no_index'] = true; if (!isset($context['error_title'])) { $context['error_title'] = $txt['error_occured']; } $context['error_message'] = isset($context['error_message']) ? $context['error_message'] : $error_message; if (empty($context['page_title'])) { $context['page_title'] = $context['error_title']; } EoS_Smarty::resetTemplates(); // discard all templates loaded so far. We don't need them any longer EoS_Smarty::loadTemplate('errors'); // If this is SSI, what do they want us to do? if (SMF == 'SSI') { if (!empty($ssi_on_error_method) && $ssi_on_error_method !== true && is_callable($ssi_on_error_method)) { call_user_func($ssi_on_error_method); } elseif (empty($ssi_on_error_method) || $ssi_on_error_method !== true) { loadSubTemplate('fatal_error'); } // No layers? if (empty($ssi_on_error_method) || $ssi_on_error_method !== true) { exit; } } // We want whatever for the header, and a footer. (footer includes sub template!) obExit(null, true, false, true); /* DO NOT IGNORE: If you are creating a bridge to SMF or modifying this function, you MUST make ABSOLUTELY SURE that this function quits and DOES NOT RETURN TO NORMAL PROGRAM FLOW. Otherwise, security error messages will not be shown, and your forum will be in a very easily hackable state. */ trigger_error('Hacking attempt...', E_USER_ERROR); }
function VerificationCode() { global $sourcedir, $context, $scripturl; $verification_id = isset($_GET['vid']) ? $_GET['vid'] : ''; $code = $verification_id && isset($_SESSION[$verification_id . '_vv']) ? $_SESSION[$verification_id . '_vv']['code'] : (isset($_SESSION['visual_verification_code']) ? $_SESSION['visual_verification_code'] : ''); // Somehow no code was generated or the session was lost. if (empty($code)) { header('Content-Type: image/gif'); die("GIF89a€!ù,D;"); } elseif (isset($_REQUEST['sound'])) { loadLanguage('Login'); EoS_Smarty::loadTemplate('generics/verification_sound'); $context['verification_sound_href'] = $scripturl . '?action=verificationcode;rand=' . md5(mt_rand()) . ($verification_id ? ';vid=' . $verification_id : '') . ';format=.wav'; $context['template_layers'] = array(); obExit(); } elseif (empty($_REQUEST['format'])) { require_once $sourcedir . '/lib/Subs-Graphics.php'; if (in_array('gd', get_loaded_extensions()) && !showCodeImage($code)) { header('HTTP/1.1 400 Bad Request'); } elseif (isset($_REQUEST['letter'])) { $_REQUEST['letter'] = (int) $_REQUEST['letter']; if ($_REQUEST['letter'] > 0 && $_REQUEST['letter'] <= strlen($code) && !showLetterImage(strtolower($code[$_REQUEST['letter'] - 1]))) { header('Content-Type: image/gif'); die("GIF89a€!ù,D;"); } } else { header('Content-Type: image/gif'); die("GIF89a€!ù,D;"); } } elseif ($_REQUEST['format'] === '.wav') { require_once $sourcedir . '/lib/Subs-Sound.php'; if (!createWaveFile($code)) { header('HTTP/1.1 400 Bad Request'); } } // We all die one day... die; }
function BoardNotify() { global $scripturl, $txt, $board, $user_info, $context, $smcFunc; // Permissions are an important part of anything ;). is_not_guest(); isAllowedTo('mark_notify'); // You have to specify a board to turn notifications on! if (empty($board)) { fatal_lang_error('no_board', false); } // No subaction: find out what to do. if (empty($_GET['sa'])) { // We're gonna need the notify template... Eos_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'notify/notify_board'); // Find out if they have notification set for this topic already. $request = smf_db_query(' SELECT id_member FROM {db_prefix}log_notify WHERE id_member = {int:current_member} AND id_board = {int:current_board} LIMIT 1', array('current_board' => $board, 'current_member' => $user_info['id'])); $context['notification_set'] = mysql_num_rows($request) != 0; mysql_free_result($request); // Set the template variables... $context['board_href'] = $scripturl . '?board=' . $board . '.' . $_REQUEST['start']; $context['start'] = $_REQUEST['start']; $context['page_title'] = $txt['notification']; return; } elseif ($_GET['sa'] == 'on') { checkSession('get'); // Turn notification on. (note this just blows smoke if it's already on.) smf_db_insert('ignore', '{db_prefix}log_notify', array('id_member' => 'int', 'id_board' => 'int'), array($user_info['id'], $board), array('id_member', 'id_board')); } else { checkSession('get'); // Turn notification off for this board. smf_db_query(' DELETE FROM {db_prefix}log_notify WHERE id_member = {int:current_member} AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'])); } // Back to the board! redirectexit('board=' . $board . '.' . $_REQUEST['start']); }
function adminLogin() { global $context, $scripturl, $txt, $user_info, $user_settings; loadLanguage('Admin'); EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/adminlogin'); // They used a wrong password, log it and unset that. if (isset($_POST['admin_hash_pass']) || isset($_POST['admin_pass'])) { $txt['security_wrong'] = sprintf($txt['security_wrong'], isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $txt['unknown'], $_SERVER['HTTP_USER_AGENT'], $user_info['ip']); log_error($txt['security_wrong'], 'critical'); if (isset($_POST['admin_hash_pass'])) { unset($_POST['admin_hash_pass']); } if (isset($_POST['admin_pass'])) { unset($_POST['admin_pass']); } $context['incorrect_password'] = true; } // Figure out the get data and post data. $context['get_data'] = '?' . construct_query_string($_GET); $context['post_data'] = ''; // Now go through $_POST. Make sure the session hash is sent. $_POST[$context['session_var']] = $context['session_id']; foreach ($_POST as $k => $v) { $context['post_data'] .= adminLogin_outputPostVars($k, $v); } // And title the page something like "Login". if (!isset($context['page_title'])) { $context['page_title'] = $txt['login']; } obExit(); // We MUST exit at this point, because otherwise we CANNOT KNOW that the user is privileged. trigger_error('Hacking attempt...', E_USER_ERROR); }
function BoardIndex() { global $txt, $user_info, $sourcedir, $modSettings, $context, $settings, $scripturl, $boardurl, $boarddir; EoS_Smarty::loadTemplate('boardindex'); $context['is_board_index'] = true; $context['sidebar_template'] = 'sidebars/sidebar_on_index.tpl'; $context['show_sidebar'] = true; $context['sidebar_class'] = 'index'; GetSidebarVisibility('index'); // Set a canonical URL for this page. $context['canonical_url'] = $scripturl; $context['share_url'] = $boardurl; // Do not let search engines index anything if there is a random thing in $_GET. if (!empty($_GET)) { $context['robot_no_index'] = true; } // Retrieve the categories and boards. require_once $sourcedir . '/lib/Subs-BoardIndex.php'; $boardIndexOptions = array('include_categories' => true, 'base_level' => 0, 'parent_id' => 0, 'set_latest_post' => true, 'countChildPosts' => !empty($modSettings['countChildPosts'])); $context['categories'] = getBoardIndex($boardIndexOptions); // Get the user online list. require_once $sourcedir . '/lib/Subs-MembersOnline.php'; $membersOnlineOptions = array('show_hidden' => allowedTo('moderate_forum'), 'sort' => 'log_time', 'reverse_sort' => true); $context += getMembersOnlineStats($membersOnlineOptions); $context['show_buddies'] = !empty($user_info['buddies']); // Are we showing all membergroups on the board index? if (!empty($settings['show_group_key'])) { $context['membergroups'] = cache_quick_get('membergroup_list', 'lib/Subs-Membergroups.php', 'cache_getMembergroupList', array()); } // Track most online statistics? (Subs-MembersOnline.php) if (!empty($modSettings['trackStats'])) { trackStatsUsersOnline($context['num_guests'] + $context['num_spiders'] + $context['num_users_online']); } // Retrieve the latest posts if the theme settings require it. if (isset($settings['number_recent_posts']) && $settings['number_recent_posts'] > 1) { $latestPostOptions = array('number_posts' => $settings['number_recent_posts']); $context['latest_posts'] = cache_quick_get('boardindex-latest_posts:' . md5($user_info['query_wanna_see_board'] . $user_info['language']), 'lib/Subs-Recent.php', 'cache_getLastPosts', array($latestPostOptions)); } $settings['display_recent_bar'] = !empty($settings['number_recent_posts']) ? $settings['number_recent_posts'] : 0; $settings['show_member_bar'] &= allowedTo('view_mlist'); $context['show_stats'] = allowedTo('view_stats') && !empty($modSettings['trackStats']); $context['show_member_list'] = allowedTo('view_mlist'); $context['show_who'] = allowedTo('who_view') && !empty($modSettings['who_enabled']); // Load the calendar? if (!empty($modSettings['cal_enabled']) && allowedTo('calendar_view')) { // Retrieve the calendar data (events, birthdays, holidays). $eventOptions = array('include_holidays' => $modSettings['cal_showholidays'] > 1, 'include_birthdays' => $modSettings['cal_showbdays'] > 1, 'include_events' => $modSettings['cal_showevents'] > 1, 'num_days_shown' => empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index']); $context += cache_quick_get('calendar_index_offset_' . ($user_info['time_offset'] + $modSettings['time_offset']), 'lib/Subs-Calendar.php', 'cache_getRecentEvents', array($eventOptions)); // Whether one or multiple days are shown on the board index. $context['calendar_only_today'] = $modSettings['cal_days_for_index'] == 1; // This is used to show the "how-do-I-edit" help. $context['calendar_can_edit'] = allowedTo('calendar_edit_any'); } else { $context['show_calendar'] = false; } $context['page_title'] = sprintf($txt['forum_index'], $context['forum_name']); $context['template_hooks']['boardindex'] = array('above_boardlisting' => '', 'below_boardlisting' => ''); if (isset($context['show_who'])) { $bracketList = array(); if ($context['show_buddies']) { $bracketList[] = comma_format($context['num_buddies']) . ' ' . ($context['num_buddies'] == 1 ? $txt['buddy'] : $txt['buddies']); } if (!empty($context['num_spiders'])) { $bracketList[] = comma_format($context['num_spiders']) . ' ' . ($context['num_spiders'] == 1 ? $txt['spider'] : $txt['spiders']); } if (!empty($context['num_users_hidden'])) { $bracketList[] = comma_format($context['num_users_hidden']) . ' ' . $txt['hidden']; } if (!empty($bracketList)) { $context['show_who_formatted'] = ' (' . implode(', ', $bracketList) . ')'; } } $context['mark_read_button'] = array('markread' => array('text' => 'mark_as_read', 'image' => 'markread.gif', 'lang' => true, 'url' => $scripturl . '?action=markasread;sa=all;' . $context['session_var'] . '=' . $context['session_id'])); HookAPI::callHook('boardindex', array()); fetchNewsItems(0, 0); }
function WhoPosted() { global $context; $tid = isset($_REQUEST['t']) ? (int) $_REQUEST['t'] : 0; if ($tid) { $result = smf_db_query('SELECT t.id_board FROM {db_prefix}topics AS t INNER JOIN {db_prefix}boards AS b ON b.id_board = t.id_board WHERE t.id_topic = {int:topic} AND {query_see_board}', array('topic' => $tid)); $b = mysql_fetch_row($result); mysql_free_result($result); if ($b) { $result = smf_db_query(' SELECT mem.real_name, m.id_member, count(m.id_member) AS count FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}members AS mem ON mem.id_member = m.id_member WHERE m.id_topic = {int:topic} GROUP BY m.id_member ORDER BY count DESC limit 20', array('topic' => $tid)); while ($row = mysql_fetch_assoc($result)) { $context['posters'][] = $row; } mysql_free_result($result); EoS_Smarty::loadTemplate('xml_blocks'); $context['template_functions'] = array('who_posted_xml'); } } }
/** * @param $memID int member's ID * * grab a list of news items that were dismissed previously. Dismissed news item ids are * stored in the member's meta array. * * TODO: implement paging(?) - are we ever going to have that many board notices? */ function profileManageBoardNews($memID) { global $context, $user_info, $scripturl, $txt; EoS_Smarty::loadTemplate('profile/profile_base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_content_area', 'profile/manage_news'); $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0; if (isset($_REQUEST['sa']) && $_REQUEST['sa'] === 'reactivateall' && $user_info['id'] == $memID) { unset($user_info['meta']['dismissed_news_items']); updateMemberData($memID, array('meta' => @serialize($user_info['meta']))); redirectexit('action=profile;area=boardnews;u=' . $memID); } $context['items_per_page'] = commonAPI::getMessagesPerPage(); $context['dismissed_items'] = array(); if (!isset($user_info['meta']['dismissed_news_items'])) { $user_info['meta']['dismissed_news_items'] = array(); } if (count($user_info['meta']['dismissed_news_items'])) { $request = smf_db_query('SELECT * FROM {db_prefix}news WHERE id_news IN({array_int:ids}) LIMIT {int:start}, {int:perpage}', array('ids' => $user_info['meta']['dismissed_news_items'], 'start' => $start, 'perpage' => $context['items_per_page'])); while ($row = mysql_fetch_assoc($request)) { $groups_allowed = explode(',', $row['groups']); if (!empty($groups_allowed[0]) && !in_array($user_info['groups'], $groups_allowed)) { continue; } $context['dismissed_items'][$row['id_news']] = array('id' => $row['id_news'], 'teaser' => !empty($row['teaser']) ? parse_bbc($row['teaser']) : '', 'body' => parse_bbc($row['body']), 'groups' => explode(',', $row['groups']), 'on_index' => $row['on_index'] ? true : false, 'can_dismiss' => $row['can_dismiss'], 'topics' => explode(',', $row['topics']), 'boards' => explode(',', $row['boards'])); } mysql_free_result($request); } $context['have_items'] = count($context['dismissed_items']); $context['reactivate_link'] = $context['have_items'] ? '<a class="active" href="' . $scripturl . '?action=profile;area=boardnews;sa=reactivateall;u=' . $memID . '">' . $txt['news_items_reactivate'] . '</a>' : ''; }
public static function boardindex() { global $context, $txt, $sourcedir, $user_info; $data = array(); if (($data = CacheAPI::getCache('github-feed-index', 1800)) === null) { $f = curl_init(); if ($f) { curl_setopt_array($f, array(CURLOPT_URL => self::$my_git_api_url, CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false)); $json_response = curl_exec($f); $data = json_decode($json_response, true); CacheAPI::putCache('github-feed-index', $data, 1800); curl_close($f); } } $n = 0; foreach ($data as $commit) { if (is_array($commit) && isset($commit['commit'])) { $context['gitfeed'][] = array('message_short' => shorten_subject($commit['commit']['message'], 60), 'message' => nl2br($commit['commit']['message']), 'dateline' => timeformat(strtotime($commit['commit']['committer']['date'])), 'sha' => $commit['sha'], 'href' => self::$my_git_url . 'commit/' . $commit['sha']); } if (++$n > 5) { break; } } if (!empty($data)) { /* * add our plugin directory to the list of directories to search for templates * and register the template hook. * only do this if we actually have something to display */ EoS_Smarty::addTemplateDir(dirname(__FILE__)); EoS_Smarty::getConfigInstance()->registerHookTemplate('sidebar_below_userblock', 'gitfeed_sidebar_top'); $context['gitfeed_global']['see_all']['href'] = self::$my_git_url . 'commits/master'; $context['gitfeed_global']['see_all']['txt'] = 'Browse all commits'; } }
public static function profile_summary(&$memID, &$user_profile) { global $context, $user_info, $txt; // only show this to either admins or profile owners if ($user_info['is_admin'] || $memID == $user_info['id']) { $txt['geoip_profile_summary_label'] = 'GeoIP location info:'; $context['region_info'] = self::getLocationRecord($user_profile[$memID]['member_ip']); EoS_Smarty::addTemplateDir(dirname(__FILE__)); EoS_Smarty::getConfigInstance()->registerHookTemplate('profile_summary_extend_basic', 'geoip_profile_summary'); } }
public function __construct() { global $output; EoS_Smarty::getSmartyInstance()->assignByRef('SEARCHCONTEXT', $this); EoS_Smarty::getSmartyInstance()->assignByRef('topic', $output); }
function is_not_guest($message = '') { global $user_info, $txt, $context, $scripturl; // Luckily, this person isn't a guest. if (!$user_info['is_guest']) { return; } // People always worry when they see people doing things they aren't actually doing... $_GET['action'] = ''; $_GET['board'] = ''; $_GET['topic'] = ''; writeLog(true); // Just die. if (isset($_REQUEST['xml'])) { obExit(false); } // Attempt to detect if they came from dlattach. if (SMF != 'SSI' && empty($context['theme_loaded'])) { loadTheme(); } // Never redirect to an attachment if (strpos($_SERVER['REQUEST_URL'], 'dlattach') === false) { $_SESSION['login_url'] = $_SERVER['REQUEST_URL']; } // Load the Login template and language file. loadLanguage('Login'); // Apparently we're not in a position to handle this now. Let's go to a safer location for now. if (empty($context['template_layers'])) { $_SESSION['login_url'] = $scripturl . '?' . $_SERVER['QUERY_STRING']; redirectexit('action=login'); } else { EoS_Smarty::resetTemplates(); EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/login'); $context['is_kick_guest'] = true; $context['robot_no_index'] = true; } // Use the kick_guest sub template... $context['kick_message'] = $message; $context['page_title'] = $txt['login']; obExit(); // We should never get to this point, but if we did we wouldn't know the user isn't a guest. trigger_error('Hacking attempt...', E_USER_ERROR); }
function smf_main() { global $context, $modSettings, $settings, $user_info, $board, $topic, $board_info, $maintenance, $sourcedir, $backend_subdir, $db_show_debug; // Special case: session keep-alive, output a transparent pixel. if (isset($_GET['action']) && $_GET['action'] == 'keepalive') { header('Content-Type: image/gif'); die("GIF89a€!ù,D;"); } // Load the user's cookie (or set as guest) and load their settings. loadUserSettings(); // Load the current board's information. loadBoard(); // Load the current user's permissions. loadPermissions(); $context['can_search'] = allowedTo('search_posts'); $context['additional_admin_errors'] .= CacheAPI::verifyFileCache(); // Attachments don't require the entire theme to be loaded. if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'dlattach' && (!empty($modSettings['allow_guestAccess']) && $user_info['is_guest'])) { detectBrowser(); $context['forum_name_html_safe'] = ''; } else { loadTheme(); EoS_Smarty::init($db_show_debug); } $user_info['notify_count'] += !empty($context['open_mod_reports']) ? 1 : 0; URL::setSID(); array_unshift($context['linktree'], array('url' => URL::home(), 'name' => $context['forum_name_html_safe'])); // Check if the user should be disallowed access. is_not_banned(); $context['can_see_hidden_level1'] = allowedTo('see_hidden1'); $context['can_see_hidden_level2'] = allowedTo('see_hidden2'); $context['can_see_hidden_level2'] = allowedTo('see_hidden2'); // If we are in a topic and don't have permission to approve it then duck out now. if (!empty($topic) && empty($board_info['cur_topic_approved']) && !allowedTo('approve_posts') && ($user_info['id'] != $board_info['cur_topic_starter'] || $user_info['is_guest'])) { fatal_lang_error('not_a_topic', false); } // Do some logging, unless this is an attachment, avatar, toggle of editor buttons, theme option, XML feed etc. if (empty($_REQUEST['action']) || !in_array($_REQUEST['action'], array('dlattach', 'findmember', 'jseditor', 'jsoption', 'requestmembers', 'smstats', '.xml', 'xmlhttp', 'verificationcode', 'viewquery', 'viewsmfile'))) { // Log this user as online. writeLog(); // Track forum statistics and hits...? if (!empty($modSettings['hitStats'])) { trackStats(array('hits' => '+')); } } // Is the forum in maintenance mode? (doesn't apply to administrators.) if (!empty($maintenance) && !allowedTo('admin_forum')) { // You can only login.... otherwise, you're getting the "maintenance mode" display. if (isset($_REQUEST['action']) && ($_REQUEST['action'] == 'login2' || $_REQUEST['action'] == 'logout')) { require_once $sourcedir . '/LogInOut.php'; return $_REQUEST['action'] == 'login2' ? 'Login2' : 'Logout'; } else { require_once $sourcedir . '/lib/Subs-Auth.php'; return 'InMaintenance'; } } elseif (empty($modSettings['allow_guestAccess']) && $user_info['is_guest'] && (!isset($_REQUEST['action']) || !in_array($_REQUEST['action'], array('coppa', 'login', 'login2', 'register', 'register2', 'reminder', 'activate', 'help', 'smstats', 'mailq', 'verificationcode', 'openidreturn')))) { require_once $sourcedir . '/lib/Subs-Auth.php'; return 'KickGuest'; } elseif (empty($_REQUEST['action'])) { // Action and board are both empty... BoardIndex! if (empty($board) && empty($topic)) { require_once $sourcedir . '/BoardIndex.php'; return 'BoardIndex'; } elseif (empty($topic)) { require_once $sourcedir . '/MessageIndex.php'; return 'MessageIndex'; } else { require_once $sourcedir . '/Display.php'; return 'Display'; } } // Here's the monstrous $_REQUEST['action'] array - $_REQUEST['action'] => array($file, $function). $actionArray = array('activate' => array('Register.php', 'Activate'), 'admin' => array($backend_subdir . '/Admin.php', 'AdminMain'), 'announce' => array('Post.php', 'AnnounceTopic'), 'attachapprove' => array('lib/Subs-ManageAttachments.php', 'ApproveAttach'), 'buddy' => array('lib/Subs-Members.php', 'BuddyListToggle'), 'calendar' => array('Calendar.php', 'CalendarMain'), 'clock' => array('Calendar.php', 'clock'), 'collapse' => array('BoardIndex.php', 'CollapseCategory'), 'coppa' => array('Register.php', 'CoppaForm'), 'credits' => array('Who.php', 'Credits'), 'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'), 'display' => array('Display.php', 'Display'), 'dlattach' => array('Display.php', 'Download'), 'editpoll' => array('Poll.php', 'EditPoll'), 'editpoll2' => array('Poll.php', 'EditPoll2'), 'emailuser' => array('SendTopic.php', 'EmailUser'), 'findmember' => array('lib/Subs-Auth.php', 'JSMembers'), 'groups' => array('Groups.php', 'Groups'), 'help' => array('Help.php', 'ShowHelp'), 'helpadmin' => array('Help.php', 'ShowAdminHelp'), 'im' => array('PersonalMessage.php', 'MessageMain'), 'jseditor' => array('lib/Subs-Editor.php', 'EditorMain'), 'jsmodify' => array('Post.php', 'JavaScriptModify'), 'jsoption' => array($backend_subdir . '/Themes.php', 'SetJavaScript'), 'lock' => array('LockTopic.php', 'LockTopic'), 'lockvoting' => array('Poll.php', 'LockVoting'), 'login' => array('LogInOut.php', 'Login'), 'login2' => array('LogInOut.php', 'Login2'), 'logout' => array('LogInOut.php', 'Logout'), 'markasread' => array('lib/Subs-Boards.php', 'MarkRead'), 'mergetopics' => array('SplitTopics.php', 'MergeTopics'), 'mlist' => array('Memberlist.php', 'Memberlist'), 'moderate' => array('ModerationCenter.php', 'ModerationMain'), 'modifycat' => array('ManageBoards.php', 'ModifyCat'), 'movetopic' => array('MoveTopic.php', 'MoveTopic'), 'movetopic2' => array('MoveTopic.php', 'MoveTopic2'), 'notify' => array('Notify.php', 'Notify'), 'notifyboard' => array('Notify.php', 'BoardNotify'), 'openidreturn' => array('lib/Subs-OpenID.php', 'smf_openID_return'), 'pm' => array('PersonalMessage.php', 'MessageMain'), 'post' => array('Post.php', 'Post'), 'post2' => array('Post.php', 'Post2'), 'printpage' => array('Printpage.php', 'PrintTopic'), 'profile' => array('Profile.php', 'ModifyProfile'), 'quotefast' => array('Post.php', 'QuoteFast'), 'quickmod' => array('MessageIndex.php', 'QuickModeration'), 'quickmod2' => array('Display.php', 'QuickInTopicModeration'), 'recent' => array('Recent.php', 'RecentPosts'), 'register' => array('Register.php', 'Register'), 'register2' => array('Register.php', 'Register2'), 'reminder' => array('Reminder.php', 'RemindMe'), 'removepoll' => array('Poll.php', 'RemovePoll'), 'removetopic2' => array('RemoveTopic.php', 'RemoveTopic2'), 'reporttm' => array('SendTopic.php', 'ReportToModerator'), 'requestmembers' => array('lib/Subs-Auth.php', 'RequestMembers'), 'restoretopic' => array('RemoveTopic.php', 'RestoreTopic'), 'search' => array('Search.php', 'PlushSearch1'), 'search2' => array('Search.php', 'PlushSearch2'), 'sendtopic' => array('SendTopic.php', 'EmailUser'), 'smstats' => array('Stats.php', 'SMStats'), 'suggest' => array('lib/Subs-Editor.php', 'AutoSuggestHandler'), 'splittopics' => array('SplitTopics.php', 'SplitTopics'), 'stats' => array('Stats.php', 'DisplayStats'), 'sticky' => array('LockTopic.php', 'Sticky'), 'theme' => array($backend_subdir . '/Themes.php', 'ThemesMain'), 'trackip' => array('Profile-View.php', 'trackIP'), 'about:unknown' => array('Karma.php', 'BookOfUnknown'), 'unread' => array('Recent.php', 'UnreadTopics'), 'unreadreplies' => array('Recent.php', 'UnreadTopics'), 'verificationcode' => array('Register.php', 'VerificationCode'), 'viewprofile' => array('Profile.php', 'ModifyProfile'), 'vote' => array('Poll.php', 'Vote'), 'viewquery' => array('ViewQuery.php', 'ViewQuery'), 'who' => array('Who.php', 'Who'), '.xml' => array('News.php', 'ShowXmlFeed'), 'xmlhttp' => array('Xml.php', 'XMLhttpMain'), 'like' => array('Ratings.php', 'LikeDispatch'), 'tags' => array('Tagging.php', 'TagsMain'), 'astream' => array('Activities.php', 'aStreamDispatch'), 'dismissnews' => array('Profile-Actions.php', 'DismissNews'), 'whatsnew' => array('Recent.php', 'WhatsNew')); // Allow modifying $actionArray easily. HookAPI::callHook('integrate_actions', array(&$actionArray)); // Get the function and file to include - if it's not there, do the board index. if (!isset($_REQUEST['action']) || !isset($actionArray[$_REQUEST['action']])) { // Catch the action with the theme? if (!empty($settings['catch_action'])) { require_once $sourcedir . '/' . $backend_subdir . '/Themes.php'; return 'WrapAction'; } // Fall through to the board index then... require_once $sourcedir . '/BoardIndex.php'; return 'BoardIndex'; } // Otherwise, it was set - so let's go to that action. require_once $sourcedir . '/' . $actionArray[$_REQUEST['action']][0]; return $actionArray[$_REQUEST['action']][1]; }
function QuoteFast() { global $modSettings, $user_info, $context, $options, $board; global $sourcedir; loadLanguage('Post'); if (!isset($_REQUEST['xml'])) { EoS_Smarty::loadTemplate('post/quotefast_response'); } include_once $sourcedir . '/lib/Subs-Post.php'; $moderate_boards = boardsAllowedTo('moderate_board'); // Where we going if we need to? $context['post_box_name'] = isset($_GET['pb']) ? $_GET['pb'] : ''; $request = smf_db_query(' SELECT IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body, m.id_topic, m.subject, m.id_board, m.id_member, m.approved FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board AND {query_see_board}) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_msg = {int:id_msg}' . (isset($_REQUEST['modify']) || !empty($moderate_boards) && $moderate_boards[0] == 0 ? '' : ' AND (t.locked = {int:not_locked}' . (empty($moderate_boards) ? '' : ' OR b.id_board IN ({array_int:moderation_board_list})') . ')') . ' LIMIT 1', array('current_member' => $user_info['id'], 'moderation_board_list' => $moderate_boards, 'id_msg' => (int) $_REQUEST['quote'], 'not_locked' => 0)); $context['close_window'] = mysql_num_rows($request) == 0; $row = mysql_fetch_assoc($request); mysql_free_result($request); $board = $row['id_board']; // quick modify, attempt to find existing drafts and load them /* todo: drafts -> plugin if(!$context['close_window'] && isset($_REQUEST['modify']) && !$user_info['is_guest'] && in_array('dr', $context['admin_features']) && allowedTo('drafts_allow', $row['id_board']) && !empty($options['use_drafts'])) { $draftrequest = smf_db_query( ' SELECT body FROM {db_prefix}drafts WHERE id_msg = {int:id_msg} AND id_member = {int:user}', array('id_msg' => (int)$_REQUEST['quote'], 'user' => $user_info['id'])); $draftrow = mysql_fetch_assoc($draftrequest); mysql_free_result($draftrequest); } */ if (isset($_REQUEST['modify']) && isset($draftrow) && !empty($draftrow['body']) && !empty($row)) { $row['body'] = $draftrow['body']; } $context['sub_template'] = 'quotefast'; if (!empty($row)) { $can_view_post = $row['approved'] || $row['id_member'] != 0 && $row['id_member'] == $user_info['id'] || allowedTo('approve_posts', $row['id_board']); } if (!empty($can_view_post)) { // Remove special formatting we don't want anymore. $row['body'] = un_preparsecode($row['body']); // Censor the message! censorText($row['body']); $row['body'] = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']); // Want to modify a single message by double clicking it? if (isset($_REQUEST['modify'])) { censorText($row['subject']); $context['sub_template'] = 'modifyfast'; $context['message'] = array('id' => $_REQUEST['quote'], 'body' => $row['body'], 'subject' => addcslashes($row['subject'], '"')); parse_bbc_stage2($context['message']['body'], 0, true); return; } // Remove any nested quotes. if (!empty($modSettings['removeNestedQuotes'])) { $row['body'] = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $row['body']); } // Make the body HTML if need be. if (!empty($_REQUEST['mode'])) { require_once $sourcedir . '/lib/Subs-Editor.php'; $row['body'] = strtr($row['body'], array('<' => '#smlt#', '>' => '#smgt#', '&' => '#smamp#')); $row['body'] = bbc_to_html($row['body']); $lb = '<br />'; } else { $lb = "\n"; } parse_bbc_stage2($row['body'], 0, true); // Add a quote string on the front and end. $context['quote']['xml'] = '[quote author=' . $row['poster_name'] . ' link=topic=' . $row['id_topic'] . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $row['poster_time'] . ']' . $lb . $row['body'] . $lb . '[/quote]' . "\n\n"; //$context['quote']['xml'] = '[quote author=' . $row['poster_name'] . ' link=topic=' . $row['id_topic'] . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $row['poster_time'] . ']' . $lb . $row['body'] . $lb . '[/quote]'; $context['quote']['text'] = strtr(un_htmlspecialchars($context['quote']['xml']), array('\'' => '\\\'', '\\' => '\\\\', "\n" => '\\n', '</script>' => '</\' + \'script>')); $context['quote']['xml'] = strtr($context['quote']['xml'], array(' ' => ' ', '<' => '<', '>' => '>')); $context['quote']['mozilla'] = strtr(commonAPI::htmlspecialchars($context['quote']['text']), array('"' => '"')); } elseif (isset($_REQUEST['modify'])) { $context['sub_template'] = 'modifyfast'; $context['message'] = array('id' => 0, 'body' => '', 'subject' => ''); } else { $context['quote'] = array('xml' => '', 'mozilla' => '', 'text' => ''); } }
function DismissNews() { global $context, $user_info, $txt; EoS_Smarty::loadTemplate('xml_blocks'); $context['template_functions'] = array('dismiss_newsitem'); $id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0; $xml = isset($_REQUEST['xml']) ? true : false; $context['sub_template'] = 'dismiss_handler' . ($xml ? '_xml' : ''); $effective_id = 0; if ($id) { $result = smf_db_query('SELECT id_news, can_dismiss FROM {db_prefix}news WHERE id_news = {int:id}', array('id' => $id)); if (mysql_num_rows($result) > 0) { list($effective_id, $can_dismiss_item) = mysql_fetch_row($result); } mysql_free_result($result); if (!empty($effective_id)) { $context['raw_item_id'] = $effective_id; if ($user_info['is_admin'] || allowedTo('can_dismiss_news') && $can_dismiss_item != 0) { $context['item_to_dismiss'] = json_encode(array('id' => $effective_id)); if (!isset($user_info['meta']['dismissed_news_items'][$effective_id])) { $user_info['meta']['dismissed_news_items'][$effective_id] = $effective_id; updateMemberData($user_info['id'], array('meta' => @serialize($user_info['meta']))); } if ($xml) { $context['template_layers'] = array(); } return; } } } loadLanguage('Errors'); if (isset($_REQUEST['xml'])) { AjaxErrorMsg($txt['no_access']); } else { fatal_lang_error('no_access'); } }
function Credits($in_admin = false) { global $context, $modSettings, $forum_copyright, $forum_version, $boardurl, $txt, $user_info; // Don't blink. Don't even blink. Blink and you're dead. loadLanguage('Who'); $context['credits_intro'] = '<strong><span style="color:blue;">EosAlpha BBS</span></strong> is a software product based on the popular and successful <a href="http://www.simplemachines.org">Simple Machines Forum</a>, also known as simply SMF.<br> It started around mid-2011 as a fork of the then current code base of SMF 2.0 which had been released under a OSF compliant <a href="http://www.simplemachines.org/about/smf/license.php">BSD-style license</a> in June 2011. The goal is to create a new forum software with a fresh, modern and social touch. <br> <br> <dl><dt><strong>Developers</strong></dt> <dd>Alex "Silvercircle" Vie, Annika "Velvet" Ostrovsky</dd></dl>'; $context['credits'] = array(array('pretext' => $txt['credits_intro'], 'title' => $txt['credits_team'], 'groups' => array(array('title' => $txt['credits_groups_ps'], 'members' => array('Michael "Oldiesmann" Eshom', 'Amacythe', 'Jeremy "SleePy" Darwood', 'Justin "metallica48423" O\'Leary')), array('title' => $txt['credits_groups_dev'], 'members' => array('Norv', 'Aaron van Geffen', 'Antechinus', 'Bjoern "Bloc" Kristiansen', 'Hendrik Jan "Compuart" Visser', 'Juan "JayBachatero" Hernandez', 'Karl "RegularExpression" Benson', $user_info['is_admin'] ? 'Matt "Grudge" Wolf' : 'Grudge', 'Michael "Thantos" Miller', 'Selman "[SiNaN]" Eser', 'Theodore "Orstio" Hildebrandt', 'Thorsten "TE" Eurich', 'winrules')), array('title' => $txt['credits_groups_support'], 'members' => array('JimM', 'Adish "(F.L.A.M.E.R)" Patel', 'Aleksi "Lex" Kilpinen', 'Ben Scott', 'Bigguy', 'CapadY', 'Chas Large', 'Duncan85', 'Eliana Tamerin', 'Fiery', 'gbsothere', 'Harro', 'Huw', 'Jan-Olof "Owdy" Eriksson', 'Jeremy "jerm" Strike', 'Jessica "Miss All Sunday" Gonzales', 'K@', 'Kevin "greyknight17" Hou', 'KGIII', 'Kill Em All', 'Mattitude', 'Mashby', 'Mick G.', 'Michele "Illori" Davis', 'MrPhil', 'Nick "Fizzy" Dyer', 'Nick "Ha²"', 'Paul_Pauline', 'Piro "Sarge" Dhima', 'Rumbaar', 'Pitti', 'RedOne', 'S-Ace', 'Wade "sησω" Poulsen', 'xenovanis')), array('title' => $txt['credits_groups_customize'], 'members' => array('Brad "IchBin™" Grow', 'ディン1031', 'Brannon "B" Hall', 'Bryan "Runic" Deakin', 'Bulakbol', 'Colin "Shadow82x" Blaber', 'Daniel15', 'Eren Yasarkurt', 'Gary M. Gadsdon', 'Jason "JBlaze" Clemons', 'Jerry', 'Jonathan "vbgamer45" Valentin', 'Kays', 'Killer Possum', 'Kirby', 'Matt "SlammedDime" Zuba', 'Matthew "Labradoodle-360" Kerle', 'Nibogo', 'Niko', 'Peter "Arantor" Spicer', 'snork13', 'Spuds', 'Steven "Fustrate" Hoffman', 'Joey "Tyrsson" Smith')), array('title' => $txt['credits_groups_docs'], 'members' => array('Joshua "groundup" Dickerson', 'AngellinaBelle', 'Daniel Diehl', 'Dannii Willis', 'emanuele', 'Graeme Spence', 'Jack "akabugeyes" Thorsen', 'Jade Elizabeth Trainor', 'Peter Duggan')), array('title' => $txt['credits_groups_marketing'], 'members' => array('Kindred', 'Marcus "cσσкιє мσηѕтєя" Forsberg', 'Ralph "[n3rve]" Otowo', 'rickC', 'Tony Reid')), array('title' => $txt['credits_groups_internationalizers'], 'members' => array('Relyana', 'Akyhne', 'GravuTrad')), array('title' => $txt['credits_groups_servers'], 'members' => array('Derek Schwab', 'Liroy "CoreISP" van Hoewijk'))))); // Give the translators some credit for their hard work. if (!empty($txt['translation_credits'])) { $context['credits'][] = array('title' => $txt['credits_groups_translation'], 'groups' => array(array('title' => $txt['credits_groups_translation'], 'members' => $txt['translation_credits']))); } $context['credits'][] = array('title' => $txt['credits_special'], 'posttext' => $txt['credits_anyone'], 'groups' => array(array('title' => $txt['credits_groups_consultants'], 'members' => array('Brett Flannigan', 'Mark Rose', 'René-Gilles "Nao 尚" Deberdt')), array('title' => $txt['credits_groups_beta'], 'members' => array($txt['credits_beta_message'])), array('title' => $txt['credits_groups_translators'], 'members' => array($txt['credits_translators_message'])), array('title' => $txt['credits_groups_founder'], 'members' => array('Unknown W. "[Unknown]" Brackets')), array('title' => $txt['credits_groups_orignal_pm'], 'members' => array('Jeff Lewis', 'Joseph Fung', 'David Recordon')))); $context['copyrights'] = array('smf' => sprintf($forum_copyright, $forum_version), 'mods' => array()); foreach ($context['credits'] as &$credit) { foreach ($credit['groups'] as &$group) { if (count($group['members']) > 2) { $group['last_peep'] = array_pop($group['members']); } } } if (!$in_admin) { EoS_Smarty::loadTemplate('credits'); $context['robot_no_index'] = true; $context['page_title'] = $txt['credits']; } }
function ReportToModerator() { global $txt, $topic, $sourcedir, $modSettings, $user_info, $context, $smcFunc; $context['robot_no_index'] = true; // You can't use this if it's off or you are not allowed to do it. isAllowedTo('report_any'); // If they're posting, it should be processed by ReportToModerator2. if ((isset($_POST[$context['session_var']]) || isset($_POST['submit'])) && empty($context['post_errors'])) { ReportToModerator2(); } // We need a message ID to check! if (empty($_REQUEST['msg']) && empty($_REQUEST['mid'])) { fatal_lang_error('no_access', false); } // For compatibility, accept mid, but we should be using msg. (not the flavor kind!) $_REQUEST['msg'] = empty($_REQUEST['msg']) ? (int) $_REQUEST['mid'] : (int) $_REQUEST['msg']; // Check the message's ID - don't want anyone reporting a post they can't even see! $result = smf_db_query(' SELECT m.id_msg, m.id_member, t.id_member_started FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic}) WHERE m.id_msg = {int:id_msg} AND m.id_topic = {int:current_topic} LIMIT 1', array('current_topic' => $topic, 'id_msg' => $_REQUEST['msg'])); if (mysql_num_rows($result) == 0) { fatal_lang_error('no_board', false); } list($_REQUEST['msg'], $member, $starter) = mysql_fetch_row($result); mysql_free_result($result); // Do we need to show the visual verification image? $context['require_verification'] = $user_info['is_guest'] && !empty($modSettings['guests_report_require_captcha']); if ($context['require_verification']) { require_once $sourcedir . '/lib/Subs-Editor.php'; $verificationOptions = array('id' => 'report'); $context['require_verification'] = create_control_verification($verificationOptions); $context['visual_verification_id'] = $verificationOptions['id']; } // Show the inputs for the comment, etc. loadLanguage('Post'); EoS_Smarty::loadTemplate('topic/send_or_report'); EoS_Smarty::getConfigInstance()->registerHookTemplate('send_report_content_area', 'topic/reporttm'); $context['comment_body'] = !isset($_POST['comment']) ? '' : trim($_POST['comment']); $context['email_address'] = !isset($_POST['email']) ? '' : trim($_POST['email']); // This is here so that the user could, in theory, be redirected back to the topic. $context['start'] = $_REQUEST['start']; $context['message_id'] = $_REQUEST['msg']; $context['page_title'] = $txt['report_to_mod']; $context['sub_template'] = 'report'; }
public static function setActive() { self::$_is_Active = true; }
function Login2() { global $txt, $scripturl, $user_info, $user_settings, $smcFunc; global $cookiename, $maintenance, $modSettings, $context, $sc, $sourcedir; // Load cookie authentication stuff. require_once $sourcedir . '/lib/Subs-Auth.php'; if (isset($_GET['sa']) && $_GET['sa'] == 'salt' && !$user_info['is_guest']) { if (isset($_COOKIE[$cookiename]) && preg_match('~^a:[34]:\\{i:0;(i:\\d{1,6}|s:[1-8]:"\\d{1,8}");i:1;s:(0|40):"([a-fA-F0-9]{40})?";i:2;[id]:\\d{1,14};(i:3;i:\\d;)?\\}$~', $_COOKIE[$cookiename]) === 1) { list(, , $timeout) = @unserialize($_COOKIE[$cookiename]); } elseif (isset($_SESSION['login_' . $cookiename])) { list(, , $timeout) = @unserialize($_SESSION['login_' . $cookiename]); } else { trigger_error('Login2(): Cannot be logged in without a session or cookie', E_USER_ERROR); } $user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4); updateMemberData($user_info['id'], array('password_salt' => $user_settings['password_salt'])); setLoginCookie($timeout - time(), $user_info['id'], sha1($user_settings['passwd'] . $user_settings['password_salt'])); redirectexit('action=login2;sa=check;member=' . $user_info['id'], $context['server']['needs_login_fix']); } elseif (isset($_GET['sa']) && $_GET['sa'] == 'check') { // Strike! You're outta there! if ($_GET['member'] != $user_info['id']) { fatal_lang_error('login_cookie_error', false); } // Some whitelisting for login_url... if (empty($_SESSION['login_url'])) { redirectexit(); } else { // Best not to clutter the session data too much... $temp = $_SESSION['login_url']; unset($_SESSION['login_url']); redirectexit($temp); } } // Beyond this point you are assumed to be a guest trying to login. if (!$user_info['is_guest']) { redirectexit(); } // Are you guessing with a script? spamProtection('login'); // Set the login_url if it's not already set (but careful not to send us to an attachment). if (empty($_SESSION['login_url']) && isset($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'dlattach') === false && preg_match('~(board|topic)[=,]~', $_SESSION['old_url']) != 0) { $_SESSION['login_url'] = $_SESSION['old_url']; } // Been guessing a lot, haven't we? if (isset($_SESSION['failed_login']) && $_SESSION['failed_login'] >= $modSettings['failed_login_threshold'] * 3) { fatal_lang_error('login_threshold_fail', 'critical'); } // Set up the cookie length. (if it's invalid, just fall through and use the default.) if (isset($_POST['cookieneverexp']) || !empty($_POST['cookielength']) && $_POST['cookielength'] == -1) { $modSettings['cookieTime'] = 3153600; } elseif (!empty($_POST['cookielength']) && ($_POST['cookielength'] >= 1 || $_POST['cookielength'] <= 525600)) { $modSettings['cookieTime'] = (int) $_POST['cookielength']; } loadLanguage('Login'); EoS_Smarty::loadTemplate('generic_skeleton'); EoS_Smarty::getConfigInstance()->registerHookTemplate('generic_content_area', 'loginout/login'); // Set up the default/fallback stuff. $context['default_username'] = isset($_POST['user']) ? preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~', '&#\\1;', htmlspecialchars($_POST['user'])) : ''; $context['default_password'] = ''; $context['never_expire'] = $modSettings['cookieTime'] == 525600 || $modSettings['cookieTime'] == 3153600; $context['login_errors'] = array($txt['error_occured']); $context['page_title'] = $txt['login']; // Add the login chain to the link tree. $context['linktree'][] = array('url' => $scripturl . '?action=login', 'name' => $txt['login']); if (!empty($_POST['openid_identifier']) && !empty($modSettings['enableOpenID'])) { require_once $sourcedir . '/lib/Subs-OpenID.php'; if (($open_id = smf_openID_validate($_POST['openid_identifier'])) !== 'no_data') { return $open_id; } } // You forgot to type your username, dummy! if (!isset($_POST['user']) || $_POST['user'] == '') { $context['login_errors'] = array($txt['need_username']); return; } // Hmm... maybe 'admin' will login with no password. Uhh... NO! if ((!isset($_POST['passwrd']) || $_POST['passwrd'] == '') && (!isset($_POST['hash_passwrd']) || strlen($_POST['hash_passwrd']) != 40)) { $context['login_errors'] = array($txt['no_password']); return; } // No funky symbols either. if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~(&#(\\d{1,7}|x[0-9a-fA-F]{1,6});)~', '', $_POST['user'])) != 0) { $context['login_errors'] = array($txt['error_invalid_characters_username']); return; } // Are we using any sort of integration to validate the login? if (in_array('retry', HookAPI::callHook('integrate_validate_login', array($_POST['user'], isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40 ? $_POST['hash_passwrd'] : null, $modSettings['cookieTime'])), true)) { $context['login_errors'] = array($txt['login_hash_error']); $context['disable_login_hashing'] = true; return; } // Load the data up! $request = smf_db_query(' SELECT passwd, id_member, id_group, lngfile, is_activated, email_address, additional_groups, member_name, password_salt, openid_uri, passwd_flood FROM {db_prefix}members WHERE ' . 'member_name = {string:user_name}' . ' LIMIT 1', array('user_name' => $_POST['user'])); // Probably mistyped or their email, try it as an email address. (member_name first, though!) if (mysql_num_rows($request) == 0) { mysql_free_result($request); $request = smf_db_query(' SELECT passwd, id_member, id_group, lngfile, is_activated, email_address, additional_groups, member_name, password_salt, openid_uri, passwd_flood FROM {db_prefix}members WHERE email_address = {string:user_name} LIMIT 1', array('user_name' => $_POST['user'])); // Let them try again, it didn't match anything... if (mysql_num_rows($request) == 0) { $context['login_errors'] = array($txt['username_no_exist']); return; } } $user_settings = mysql_fetch_assoc($request); mysql_free_result($request); // Figure out the password using SMF's encryption - if what they typed is right. if (isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40) { // Needs upgrading? if (strlen($user_settings['passwd']) != 40) { $context['login_errors'] = array($txt['login_hash_error']); $context['disable_login_hashing'] = true; unset($user_settings); return; } elseif ($_POST['hash_passwrd'] == sha1($user_settings['passwd'] . $sc)) { $sha_passwd = $user_settings['passwd']; } else { // Don't allow this! validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood']); $_SESSION['failed_login'] = @$_SESSION['failed_login'] + 1; if ($_SESSION['failed_login'] >= $modSettings['failed_login_threshold']) { redirectexit('action=reminder'); } else { log_error($txt['incorrect_password'] . ' - <span class="remove">' . $user_settings['member_name'] . '</span>', 'user'); $context['disable_login_hashing'] = true; $context['login_errors'] = array($txt['incorrect_password']); unset($user_settings); return; } } } else { $sha_passwd = sha1(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd'])); } // Bad password! Thought you could fool the database?! if ($user_settings['passwd'] != $sha_passwd) { // Let's be cautious, no hacking please. thanx. validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood']); // Maybe we were too hasty... let's try some other authentication methods. $other_passwords = array(); // None of the below cases will be used most of the time (because the salt is normally set.) if ($user_settings['password_salt'] == '') { // YaBB SE, Discus, MD5 (used a lot), SHA-1 (used some), SMF 1.0.x, IkonBoard, and none at all. $other_passwords[] = crypt($_POST['passwrd'], substr($_POST['passwrd'], 0, 2)); $other_passwords[] = crypt($_POST['passwrd'], substr($user_settings['passwd'], 0, 2)); $other_passwords[] = md5($_POST['passwrd']); $other_passwords[] = sha1($_POST['passwrd']); $other_passwords[] = md5_hmac($_POST['passwrd'], strtolower($user_settings['member_name'])); $other_passwords[] = md5($_POST['passwrd'] . strtolower($user_settings['member_name'])); $other_passwords[] = md5(md5($_POST['passwrd'])); $other_passwords[] = $_POST['passwrd']; // This one is a strange one... MyPHP, crypt() on the MD5 hash. $other_passwords[] = crypt(md5($_POST['passwrd']), md5($_POST['passwrd'])); // Snitz style - SHA-256. Technically, this is a downgrade, but most PHP configurations don't support sha256 anyway. if (strlen($user_settings['passwd']) == 64 && function_exists('mhash') && defined('MHASH_SHA256')) { $other_passwords[] = bin2hex(mhash(MHASH_SHA256, $_POST['passwrd'])); } // phpBB3 users new hashing. We now support it as well ;). $other_passwords[] = phpBB3_password_check($_POST['passwrd'], $user_settings['passwd']); // APBoard 2 Login Method. $other_passwords[] = md5(crypt($_POST['passwrd'], 'CRYPT_MD5')); } elseif (strlen($user_settings['passwd']) == 32) { // vBulletin 3 style hashing? Let's welcome them with open arms \o/. $other_passwords[] = md5(md5($_POST['passwrd']) . $user_settings['password_salt']); // Hmm.. p'raps it's Invision 2 style? $other_passwords[] = md5(md5($user_settings['password_salt']) . md5($_POST['passwrd'])); // Some common md5 ones. $other_passwords[] = md5($user_settings['password_salt'] . $_POST['passwrd']); $other_passwords[] = md5($_POST['passwrd'] . $user_settings['password_salt']); } elseif (strlen($user_settings['passwd']) == 40) { // Maybe they are using a hash from before the password fix. $other_passwords[] = sha1(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd'])); // BurningBoard3 style of hashing. $other_passwords[] = sha1($user_settings['password_salt'] . sha1($user_settings['password_salt'] . sha1($_POST['passwrd']))); // Perhaps we converted to UTF-8 and have a valid password being hashed differently. if ($context['character_set'] == 'utf8' && !empty($modSettings['previousCharacterSet']) && $modSettings['previousCharacterSet'] != 'utf8') { // Try iconv first, for no particular reason. if (function_exists('iconv')) { $other_passwords['iconv'] = sha1(strtolower(iconv('UTF-8', $modSettings['previousCharacterSet'], $user_settings['member_name'])) . un_htmlspecialchars(iconv('UTF-8', $modSettings['previousCharacterSet'], $_POST['passwrd']))); } // Say it aint so, iconv failed! if (empty($other_passwords['iconv']) && function_exists('mb_convert_encoding')) { $other_passwords[] = sha1(strtolower(mb_convert_encoding($user_settings['member_name'], 'UTF-8', $modSettings['previousCharacterSet'])) . un_htmlspecialchars(mb_convert_encoding($_POST['passwrd'], 'UTF-8', $modSettings['previousCharacterSet']))); } } } // SMF's sha1 function can give a funny result on Linux (Not our fault!). If we've now got the real one let the old one be valid! if (strpos(strtolower(PHP_OS), 'win') !== 0) { require_once $sourcedir . '/lib/Subs-Compat.php'; $other_passwords[] = sha1_smf(strtolower($user_settings['member_name']) . un_htmlspecialchars($_POST['passwrd'])); } // Whichever encryption it was using, let's make it use SMF's now ;). if (in_array($user_settings['passwd'], $other_passwords)) { $user_settings['passwd'] = $sha_passwd; $user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4); // Update the password and set up the hash. updateMemberData($user_settings['id_member'], array('passwd' => $user_settings['passwd'], 'password_salt' => $user_settings['password_salt'], 'passwd_flood' => '')); } else { // They've messed up again - keep a count to see if they need a hand. $_SESSION['failed_login'] = @$_SESSION['failed_login'] + 1; // Hmm... don't remember it, do you? Here, try the password reminder ;). if ($_SESSION['failed_login'] >= $modSettings['failed_login_threshold']) { redirectexit('action=reminder'); } else { // Log an error so we know that it didn't go well in the error log. log_error($txt['incorrect_password'] . ' - <span class="remove">' . $user_settings['member_name'] . '</span>', 'user'); $context['login_errors'] = array($txt['incorrect_password']); return; } } } elseif (!empty($user_settings['passwd_flood'])) { // Let's be sure they weren't a little hacker. validatePasswordFlood($user_settings['id_member'], $user_settings['passwd_flood'], true); // If we got here then we can reset the flood counter. updateMemberData($user_settings['id_member'], array('passwd_flood' => '')); } // Correct password, but they've got no salt; fix it! if ($user_settings['password_salt'] == '') { $user_settings['password_salt'] = substr(md5(mt_rand()), 0, 4); updateMemberData($user_settings['id_member'], array('password_salt' => $user_settings['password_salt'])); } // Check their activation status. if (!checkActivation()) { return; } DoLogin(); }
function MoveTopic() { global $txt, $board, $topic, $user_info, $context, $language, $scripturl, $settings, $smcFunc, $modSettings; if (empty($topic)) { fatal_lang_error('no_access', false); } $request = smf_db_query(' SELECT t.id_member_started, ms.subject, t.approved FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg) WHERE t.id_topic = {int:current_topic} LIMIT 1', array('current_topic' => $topic)); list($id_member_started, $context['subject'], $context['is_approved']) = mysql_fetch_row($request); mysql_free_result($request); // Can they see it - if not approved? if ($modSettings['postmod_active'] && !$context['is_approved']) { isAllowedTo('approve_posts'); } // Permission check! // !!! if (!allowedTo('move_any')) { if ($id_member_started == $user_info['id']) { isAllowedTo('move_own'); //$boards = array_merge(boardsAllowedTo('move_own'), boardsAllowedTo('move_any')); } else { isAllowedTo('move_any'); } } //else //$boards = boardsAllowedTo('move_any'); EoS_Smarty::loadTemplate('topic/movetopic'); // Get a list of boards this moderator can move to. $request = smf_db_query(' SELECT b.id_board, b.name, b.child_level, c.name AS cat_name, c.id_cat FROM {db_prefix}boards AS b LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) WHERE {query_see_board} AND b.redirect = {string:blank_redirect} AND b.id_board != {int:current_board}', array('blank_redirect' => '', 'current_board' => $board)); $context['boards'] = array(); while ($row = mysql_fetch_assoc($request)) { if (!isset($context['categories'][$row['id_cat']])) { $context['categories'][$row['id_cat']] = array('name' => strip_tags($row['cat_name']), 'boards' => array()); } $context['categories'][$row['id_cat']]['boards'][] = array('id' => $row['id_board'], 'name' => strip_tags($row['name']), 'category' => strip_tags($row['cat_name']), 'child_level' => $row['child_level'], 'selected' => !empty($_SESSION['move_to_topic']) && $_SESSION['move_to_topic'] == $row['id_board'] && $row['id_board'] != $board); } mysql_free_result($request); if (empty($context['categories'])) { fatal_lang_error('moveto_noboards', false); } $context['page_title'] = $txt['move_topic']; $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $context['subject'], 'extra_before' => $settings['linktree_inline'] ? $txt['topic'] . ': ' : ''); $context['linktree'][] = array('name' => $txt['move_topic']); $context['back_to_topic'] = isset($_REQUEST['goback']); if ($user_info['language'] != $language) { loadLanguage('index', $language); $temp = $txt['movetopic_default']; loadLanguage('index'); $txt['movetopic_default'] = $temp; } // Register this form and get a sequence number in $context. checkSubmitOnce('register'); }
function GroupRequests() { global $txt, $context, $scripturl, $user_info, $sourcedir, $smcFunc, $modSettings, $language; //if(isset($_REQUEST['action']) && $_REQUEST['action'] === 'moderate') EoS_Smarty::loadTemplate('modcenter/modcenter_base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('modcenter_content_area', 'modcenter/list_groups'); // Set up the template stuff... $context['page_title'] = $txt['mc_group_requests']; //$context['sub_template'] = 'show_list'; // Verify we can be here. if ($user_info['mod_cache']['gq'] == '0=1') { isAllowedTo('manage_membergroups'); } // Normally, we act normally... $where = $user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']; $where_parameters = array(); // We've submitted? if (isset($_POST[$context['session_var']]) && !empty($_POST['groupr']) && !empty($_POST['req_action'])) { checkSession('post'); // Clean the values. foreach ($_POST['groupr'] as $k => $request) { $_POST['groupr'][$k] = (int) $request; } // If we are giving a reason (And why shouldn't we?), then we don't actually do much. if ($_POST['req_action'] == 'reason') { // Different sub template... $context['sub_template'] = 'group_request_reason'; // And a limitation. We don't care that the page number bit makes no sense, as we don't need it! $where .= ' AND lgr.id_request IN ({array_int:request_ids})'; $where_parameters['request_ids'] = $_POST['groupr']; $context['group_requests'] = list_getGroupRequests(0, $modSettings['defaultMaxMessages'], 'lgr.id_request', $where, $where_parameters); // Let obExit etc sort things out. obExit(); } else { // Get the details of all the members concerned... $request = smf_db_query(' SELECT lgr.id_request, lgr.id_member, lgr.id_group, mem.email_address, mem.id_group AS primary_group, mem.additional_groups AS additional_groups, mem.lngfile, mem.member_name, mem.notify_types, mg.hidden, mg.group_name FROM {db_prefix}log_group_requests AS lgr INNER JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member) INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group) WHERE ' . $where . ' AND lgr.id_request IN ({array_int:request_list}) ORDER BY mem.lngfile', array('request_list' => $_POST['groupr'])); $email_details = array(); $group_changes = array(); while ($row = mysql_fetch_assoc($request)) { $row['lngfile'] = empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']; // If we are approving work out what their new group is. if ($_POST['req_action'] == 'approve') { // For people with more than one request at once. if (isset($group_changes[$row['id_member']])) { $row['additional_groups'] = $group_changes[$row['id_member']]['add']; $row['primary_group'] = $group_changes[$row['id_member']]['primary']; } else { $row['additional_groups'] = explode(',', $row['additional_groups']); } // Don't have it already? if ($row['primary_group'] == $row['id_group'] || in_array($row['id_group'], $row['additional_groups'])) { continue; } // Should it become their primary? if ($row['primary_group'] == 0 && $row['hidden'] == 0) { $row['primary_group'] = $row['id_group']; } else { $row['additional_groups'][] = $row['id_group']; } // Add them to the group master list. $group_changes[$row['id_member']] = array('primary' => $row['primary_group'], 'add' => $row['additional_groups']); } // Add required information to email them. if ($row['notify_types'] != 4) { $email_details[] = array('rid' => $row['id_request'], 'member_id' => $row['id_member'], 'member_name' => $row['member_name'], 'group_id' => $row['id_group'], 'group_name' => $row['group_name'], 'email' => $row['email_address'], 'language' => $row['lngfile']); } } mysql_free_result($request); // Remove the evidence... smf_db_query(' DELETE FROM {db_prefix}log_group_requests WHERE id_request IN ({array_int:request_list})', array('request_list' => $_POST['groupr'])); // Ensure everyone who is online gets their changes right away. updateSettings(array('settings_updated' => time())); if (!empty($email_details)) { require_once $sourcedir . '/lib/Subs-Post.php'; // They are being approved? if ($_POST['req_action'] == 'approve') { // Make the group changes. foreach ($group_changes as $id => $groups) { // Sanity check! foreach ($groups['add'] as $key => $value) { if ($value == 0 || trim($value) == '') { unset($groups['add'][$key]); } } smf_db_query(' UPDATE {db_prefix}members SET id_group = {int:primary_group}, additional_groups = {string:additional_groups} WHERE id_member = {int:selected_member}', array('primary_group' => $groups['primary'], 'selected_member' => $id, 'additional_groups' => implode(',', $groups['add']))); } $lastLng = $user_info['language']; foreach ($email_details as $email) { $replacements = array('USERNAME' => $email['member_name'], 'GROUPNAME' => $email['group_name']); $emaildata = loadEmailTemplate('mc_group_approve', $replacements, $email['language']); sendmail($email['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 2); } } else { // Same as for approving, kind of. $lastLng = $user_info['language']; foreach ($email_details as $email) { $custom_reason = isset($_POST['groupreason']) && isset($_POST['groupreason'][$email['rid']]) ? $_POST['groupreason'][$email['rid']] : ''; $replacements = array('USERNAME' => $email['member_name'], 'GROUPNAME' => $email['group_name']); if (!empty($custom_reason)) { $replacements['REASON'] = $custom_reason; } $emaildata = loadEmailTemplate(empty($custom_reason) ? 'mc_group_reject' : 'mc_group_reject_reason', $replacements, $email['language']); sendmail($email['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 2); } } } // Restore the current language. loadLanguage('ModerationCenter'); } } // We're going to want this for making our list. require_once $sourcedir . '/lib/Subs-List.php'; // This is all the information required for a group listing. $listOptions = array('id' => 'group_request_list', 'title' => $txt['mc_group_requests'], 'width' => '100%', 'items_per_page' => $modSettings['defaultMaxMessages'], 'no_items_label' => $txt['mc_groupr_none_found'], 'base_href' => $scripturl . '?action=groups;sa=requests', 'default_sort_col' => 'member', 'get_items' => array('function' => 'list_getGroupRequests', 'params' => array($where, $where_parameters)), 'get_count' => array('function' => 'list_getGroupRequestCount', 'params' => array($where, $where_parameters)), 'columns' => array('member' => array('header' => array('value' => $txt['mc_groupr_member']), 'data' => array('db' => 'member_link'), 'sort' => array('default' => 'mem.member_name', 'reverse' => 'mem.member_name DESC')), 'group' => array('header' => array('value' => $txt['mc_groupr_group']), 'data' => array('db' => 'group_link'), 'sort' => array('default' => 'mg.group_name', 'reverse' => 'mg.group_name DESC')), 'reason' => array('header' => array('value' => $txt['mc_groupr_reason']), 'data' => array('db' => 'reason')), 'action' => array('header' => array('value' => '<input type="checkbox" class="input_check" onclick="invertAll(this, this.form);" />', 'style' => 'width: 4%;'), 'data' => array('sprintf' => array('format' => '<input type="checkbox" name="groupr[]" value="%1$d" class="input_check" />', 'params' => array('id' => false)), 'style' => 'text-align: center;'))), 'form' => array('href' => $scripturl . '?action=groups;sa=requests', 'include_sort' => true, 'include_start' => true, 'hidden_fields' => array($context['session_var'] => $context['session_id'])), 'additional_rows' => array(array('position' => 'bottom_of_list', 'value' => ' <select name="req_action" onchange="if (this.value != 0 && (this.value == \'reason\' || confirm(\'' . $txt['mc_groupr_warning'] . '\'))) this.form.submit();"> <option value="0">' . $txt['with_selected'] . ':</option> <option value="0">---------------------</option> <option value="approve">' . $txt['mc_groupr_approve'] . '</option> <option value="reject">' . $txt['mc_groupr_reject'] . '</option> <option value="reason">' . $txt['mc_groupr_reject_w_reason'] . '</option> </select> <input type="submit" name="go" value="' . $txt['go'] . '" onclick="var sel = document.getElementById(\'req_action\'); if (sel.value != 0 && sel.value != \'reason\' && !confirm(\'' . $txt['mc_groupr_warning'] . '\')) return false;" class="button_submit" />', 'align' => 'right'))); // Create the request list. createList($listOptions); $context['default_list'] = 'group_request_list'; }
function Display() { global $scripturl, $txt, $modSettings, $context, $settings, $memberContext, $output; global $options, $sourcedir, $user_info, $user_profile, $board_info, $topic, $board; global $attachments, $messages_request, $topicinfo, $language; $context['response_prefixlen'] = strlen($txt['response_prefix']); $context['need_synhlt'] = true; $context['is_display_std'] = true; $context['pcache_update_counter'] = !empty($modSettings['use_post_cache']) ? 0 : PCACHE_UPDATE_PER_VIEW + 1; $context['time_cutoff_ref'] = time(); $context['template_hooks']['display'] = array('header' => '', 'extend_topicheader' => '', 'above_posts' => '', 'below_posts' => '', 'footer' => ''); //EoS_Smarty::getConfigInstance()->registerHookTemplate('postbit_below', 'overrides/foo'); if (!empty($modSettings['karmaMode'])) { require_once $sourcedir . '/lib/Subs-Ratings.php'; } else { $context['can_see_like'] = $context['can_give_like'] = false; } // What are you gonna display if these are empty?! if (empty($topic)) { fatal_lang_error('no_board', false); } // 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'] = commonAPI::getMessagesPerPage(); $context['page_number'] = isset($_REQUEST['start']) ? $_REQUEST['start'] / $context['messages_per_page'] : 0; // Let's do some work on what to search index. //$context['multiquote_cookiename'] = 'mq_' . $context['current_topic']; $context['multiquote_posts'] = array(); if (isset($_COOKIE[$context['multiquote_cookiename']]) && strlen($_COOKIE[$context['multiquote_cookiename']]) > 1) { $context['multiquote_posts'] = explode(',', $_COOKIE[$context['multiquote_cookiename']]); } $context['multiquote_posts_count'] = count($context['multiquote_posts']); 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 = smf_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 (mysql_num_rows($request) == 0) { mysql_free_result($request); // Roll over - if we're going prev, get the last - otherwise the first. $request = smf_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) = mysql_fetch_row($request); mysql_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) { smf_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; } if ($modSettings['tags_active']) { $dbresult = smf_db_query(' SELECT t.tag,l.ID,t.ID_TAG FROM {db_prefix}tags_log as l, {db_prefix}tags as t WHERE t.ID_TAG = l.ID_TAG && l.ID_TOPIC = {int:topic}', array('topic' => $topic)); $context['topic_tags'] = array(); while ($row = mysql_fetch_assoc($dbresult)) { $context['topic_tags'][] = array('ID' => $row['ID'], 'ID_TAG' => $row['ID_TAG'], 'tag' => $row['tag']); } mysql_free_result($dbresult); $context['tags_active'] = true; } else { $context['topic_tags'] = $context['tags_active'] = 0; } // Get all the important topic info. $request = smf_db_query('SELECT t.num_replies, t.num_views, t.locked, ms.poster_name, ms.subject, ms.poster_email, ms.poster_time AS first_post_time, t.is_sticky, t.id_poll, t.id_member_started, t.id_first_msg, t.id_last_msg, t.approved, t.unapproved_posts, t.id_layout, ' . ($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' : '') . ', p.name AS prefix_name, ms1.poster_time AS last_post_time, ms1.modified_time AS last_modified_time, IFNULL(b.automerge, 0) AS automerge FROM {db_prefix}topics AS t INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) INNER JOIN {db_prefix}messages AS ms1 ON (ms1.id_msg = t.id_last_msg) 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})') . ' LEFT JOIN {db_prefix}prefixes as p ON p.id_prefix = t.id_prefix WHERE t.id_topic = {int:current_topic} LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic, 'current_board' => $board)); if (mysql_num_rows($request) == 0) { fatal_lang_error('not_a_topic', false); } // Added by Related Topics if (isset($modSettings['have_related_topics']) && $modSettings['have_related_topics'] && !empty($modSettings['relatedTopicsEnabled'])) { require_once $sourcedir . '/lib/Subs-Related.php'; loadRelated($topic); } $topicinfo = mysql_fetch_assoc($request); mysql_free_result($request); $context['topic_banned_members'] = array(); $request = smf_db_query('SELECT id_member FROM {db_prefix}topicbans WHERE id_topic = {int:topic}', array('topic' => $topic)); if (mysql_num_rows($request) != 0) { while ($row = mysql_fetch_row($request)) { $context['topic_banned_members'][] = $row[0]; } } mysql_free_result($request); $context['topic_banned_members_count'] = count($context['topic_banned_members']); $context['topic_last_modified'] = max($topicinfo['last_post_time'], $topicinfo['last_modified_time']); // todo: considering - make post cutoff time for the cache depend on the modification time of the topic's last post $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['first_subject'] = $topicinfo['subject']; $context['prefix'] = !empty($topicinfo['prefix_name']) ? html_entity_decode($topicinfo['prefix_name']) . ' ' : ''; $context['automerge'] = $topicinfo['automerge'] > 0; // 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 = smf_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) = mysql_fetch_row($request); mysql_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? /* redundant query? last_post_time is already in $topicinfo[] $request = smf_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) = mysql_fetch_row($request); mysql_free_result($request); */ $lastPostTime = $topicinfo['last_post_time']; $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 = smf_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) = mysql_fetch_row($request); mysql_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 = smf_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']) = mysql_fetch_row($request); mysql_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 = smf_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']) = mysql_fetch_row($request); mysql_free_result($request); } // We need to reverse the start as well in this case. if (isset($_REQUEST['perma'])) { $_REQUEST['start'] = $virtual_msg; } else { $_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>' : ''; // 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 . '/lib/Subs-Editor.php'; $verificationOptions = array('id' => 'post', 'skip_template' => true); $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'] . ((int) $context['page_number'] > 0 ? ' - ' . $txt['page'] . ' ' . ($context['page_number'] + 1) : ''); // 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 = smf_db_query(' SELECT lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online, mem.id_group, mem.id_post_group FROM {db_prefix}log_online AS lo LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member) WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}', array('in_url_string' => 's:5:"topic";i:' . $topic . ';', 'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id())); while ($row = mysql_fetch_assoc($request)) { if (empty($row['id_member'])) { continue; } $class = 'member group_' . (empty($row['id_group']) ? $row['id_post_group'] : $row['id_group']) . (in_array($row['id_member'], $user_info['buddies']) ? ' buddy' : ''); $href = URL::user($row['id_member'], $row['real_name']); if ($row['id_member'] == $user_info['id']) { $link = '<strong>' . $txt['you'] . '</strong>'; } else { $link = '<a onclick="getMcard(' . $row['id_member'] . ');return(false);" class="' . $class . '" href="' . $href . '">' . $row['real_name'] . '</a>'; } // 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' => $href, 'link' => $link, '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'] = mysql_num_rows($request) - count($context['view_members']); mysql_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... if (!isset($_REQUEST['perma'])) { $context['page_index'] = constructPageIndex(URL::topic($topic, $topicinfo['subject'], '%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); $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'] .= '[<strong>' . $txt['all'] . '</strong>] '; // Set start back to 0... $_REQUEST['start'] = 0; } else { if (!isset($context['page_index'])) { $context['page_index'] = ''; } $context['page_index'] .= ' <a href="' . $scripturl . '?topic=' . $topic . '.0;all">' . $txt['all'] . '</a> '; } } // Build the link tree. $context['linktree'][] = array('url' => URL::topic($topic, $topicinfo['subject'], 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'] = URL::topic($topic, $topicinfo['subject'], $context['start']); $context['share_url'] = $scripturl . '?topic=' . $topic; // For quick reply we need a response prefix in the default forum language. if (!isset($context['response_prefix']) && !($context['response_prefix'] = CacheAPI::getCache('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'); } CacheAPI::putCache('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 = smf_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 = mysql_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_static($start_date, $date_string, 'none'), 'start_timestamp' => $start_date, 'end_date' => timeformat_static($end_date, $date_string, 'none'), 'end_timestamp' => $end_date, 'is_last' => false); } mysql_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 = smf_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 = mysql_fetch_assoc($request); mysql_free_result($request); $request = smf_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']) = mysql_fetch_row($request); mysql_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 = smf_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 = mysql_fetch_assoc($request)) { censorText($row['label']); $pollOptions[$row['id_choice']] = $row; $realtotal += $row['votes']; $pollinfo['has_voted'] |= $row['voted_this'] != -1; } mysql_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>' : '', '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; } if (!isset($_REQUEST['perma'])) { // Get each post and poster in this topic. $request = smf_db_query(' 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 = mysql_fetch_assoc($request)) { if (!empty($row['id_member'])) { $all_posters[$row['id_msg']] = $row['id_member']; } $messages[] = $row['id_msg']; } mysql_free_result($request); $posters[$context['topic_first_message']] = $context['topic_starter_id']; $posters = array_unique($all_posters); } else { $request = smf_db_query(' SELECT id_member, approved FROM {db_prefix}messages WHERE id_msg = {int:id_msg}', array('id_msg' => $virtual_msg)); list($id_member, $approved) = mysql_fetch_row($request); mysql_free_result($request); EoS_Smarty::loadTemplate('topic/topic_singlepost'); //loadTemplate('DisplaySingle'); $context['sub_template'] = isset($_REQUEST['xml']) ? 'single_post_xml' : 'single_post'; if (isset($_REQUEST['xml'])) { $context['template_layers'] = array(); header('Content-Type: text/xml; charset=UTF-8'); } $messages = array($virtual_msg); $posters[$virtual_msg] = $id_member; } // 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']) { smf_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 = smf_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 = mysql_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) { smf_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 = smf_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) = mysql_fetch_row($request); mysql_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'])) { smf_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(); // deal with possible sticky posts and different postbit layouts for // the first post // topic.id_layout meanings: bit 0-6 > layout id, bit 7 > first post sticky on every page. // don't blame me for using bit magic here. I'm a C guy and a 8bits can store more than just one bool :P $layout = (int) ($topicinfo['id_layout'] & 0x7f); $postbit_classes =& EoS_Smarty::getConfigInstance()->getPostbitClasses(); // set defaults... $context['postbit_callbacks'] = array('firstpost' => 'template_postbit_normal', 'post' => 'template_postbit_normal'); $context['postbit_template_class'] = array('firstpost' => $postbit_classes['normal'], 'post' => $postbit_classes['normal']); if ($topicinfo['id_layout']) { $this_start = isset($_REQUEST['perma']) ? 0 : (int) $_REQUEST['start']; if ((int) $topicinfo['id_layout'] & 0x80) { if ($this_start > 0) { array_unshift($messages, intval($topicinfo['id_first_msg'])); } $context['postbit_callbacks']['firstpost'] = $layout == 0 ? 'template_postbit_normal' : ($layout == 2 ? 'template_postbit_clean' : 'template_postbit_lean'); $context['postbit_callbacks']['post'] = $layout == 2 ? 'template_postbit_comment' : 'template_postbit_normal'; $context['postbit_template_class']['firstpost'] = $layout == 0 ? $postbit_classes['normal'] : ($layout == 2 ? $postbit_classes['article'] : $postbit_classes['lean']); $context['postbit_template_class']['post'] = $layout == 2 ? $postbit_classes['commentstyle'] : $postbit_classes['normal']; } elseif ($layout) { $context['postbit_callbacks']['firstpost'] = $layout == 0 || $this_start != 0 ? 'template_postbit_normal' : ($layout == 2 ? 'template_postbit_clean' : 'template_postbit_lean'); $context['postbit_callbacks']['post'] = $layout == 2 ? 'template_postbit_comment' : 'template_postbit_normal'; $context['postbit_template_class']['firstpost'] = $layout == 0 || $this_start != 0 ? $postbit_classes['normal'] : ($layout == 2 ? $postbit_classes['article'] : $postbit_classes['lean']); $context['postbit_template_class']['post'] = $layout == 2 ? $postbit_classes['commentstyle'] : $postbit_classes['normal']; } } // now we know which display template we need if (!isset($_REQUEST['perma'])) { EoS_Smarty::loadTemplate($layout > 1 ? 'topic/topic_page' : 'topic/topic'); } /* if($user_info['is_admin']) { EoS_Smarty::init(); if(!isset($_REQUEST['perma'])) EoS_Smarty::loadTemplate($layout > 1 ? 'topic_page' : 'topic'); } else { if(!isset($_REQUEST['perma'])) loadTemplate($layout > 1 ? 'DisplayPage' : 'Display'); loadTemplate('Postbit'); } */ // If there _are_ messages here... (probably an error otherwise :!) if (!empty($messages)) { // Fetch attachments. if (!empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) { $request = smf_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 = mysql_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(); } } mysql_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 (!isset($posters[$context['topic_starter_id']])) { $posters[] = $context['topic_starter_id']; } if (!empty($posters)) { loadMemberData($posters); } if (!isset($user_profile[$context['topic_starter_id']])) { $context['topicstarter']['name'] = $topicinfo['poster_name']; $context['topicstarter']['id'] = 0; $context['topicstarter']['group'] = $txt['guest_title']; $context['topicstarter']['link'] = $topicinfo['poster_name']; $context['topicstarter']['email'] = $topicinfo['poster_email']; $context['topicstarter']['show_email'] = showEmailAddress(true, 0); $context['topicstarter']['is_guest'] = true; $context['topicstarter']['avatar'] = array(); } else { loadMemberContext($context['topic_starter_id'], true); $context['topicstarter'] =& $memberContext[$context['topic_starter_id']]; } $context['topicstarter']['start_time'] = timeformat($topicinfo['first_post_time']); $sql_what = ' m.id_msg, m.icon, m.subject, m.poster_time, m.poster_ip, m.id_member, m.modified_time, m.modified_name, m.body, mc.body AS cached_body, m.smileys_enabled, m.poster_name, m.poster_email, m.approved, m.locked,' . (!empty($modSettings['karmaMode']) ? 'c.likes_count, c.like_status, c.updated AS like_updated, l.rtype AS liked,' : '0 AS likes_count, 0 AS like_status, 0 AS like_updated, 0 AS liked,') . ' m.id_msg_modified < {int:new_from} AS is_read'; $sql_from_tables = ' FROM {db_prefix}messages AS m'; $sql_from_joins = (!empty($modSettings['karmaMode']) ? ' LEFT JOIN {db_prefix}likes AS l ON (l.id_msg = m.id_msg AND l.ctype = 1 AND l.id_user = {int:id_user}) LEFT JOIN {db_prefix}like_cache AS c ON (c.id_msg = m.id_msg AND c.ctype = 1)' : '') . ' LEFT JOIN {db_prefix}messages_cache AS mc on mc.id_msg = m.id_msg AND mc.style = {int:style} AND mc.lang = {int:lang}'; $sql_array = array('message_list' => $messages, 'new_from' => $topicinfo['new_from'], 'style' => $user_info['smiley_set_id'], 'lang' => $user_info['language_id'], 'id_user' => $user_info['id']); HookAPI::callHook('display_messagerequest', array(&$sql_what, &$sql_from_tables, &$sql_from_joins, &$sql_array)); $messages_request = smf_db_query(' SELECT ' . $sql_what . ' ' . $sql_from_tables . $sql_from_joins . ' WHERE m.id_msg IN ({array_int:message_list}) ORDER BY m.id_msg' . (empty($options['view_newest_first']) ? '' : ' DESC'), $sql_array); // 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('&' => '&'))), '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'); } $context['can_add_tags'] = $context['user']['started'] && allowedTo('smftags_add') || allowedTo('smftags_manage'); $context['can_delete_tags'] = $context['user']['started'] && allowedTo('smftags_del') || allowedTo('smftags_manage'); $context['can_moderate_board'] = allowedTo('moderate_board'); $context['can_modify_any'] = allowedTo('modify_any'); $context['can_modify_replies'] = allowedTo('modify_replies'); $context['can_modify_own'] = allowedTo('modify_own'); $context['can_delete_any'] = allowedTo('delete_any'); $context['can_delete_replies'] = allowedTo('delete_replies'); $context['can_delete_own'] = allowedTo('delete_own'); $context['use_share'] = !$user_info['possibly_robot'] && allowedTo('use_share') && ($context['user']['is_guest'] || (empty($options['use_share_bar']) ? 1 : !$options['use_share_bar'])); $context['can_unapprove'] = $context['can_approve'] && !empty($modSettings['postmod_active']); $context['can_profile_view_any'] = allowedTo('profile_view_any'); $context['can_profile_view_own'] = allowedTo('profile_view_own'); $context['is_banned_from_topic'] = !$user_info['is_admin'] && !$context['can_moderate_forum'] && !$context['can_moderate_board'] && (!empty($context['topic_banned_members']) ? in_array($user_info['id'], $context['topic_banned_members']) : false); $context['banned_notice'] = $context['is_banned_from_topic'] ? $txt['topic_banned_notice'] : ''; // 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']); if ($context['is_banned_from_topic']) { $context['can_add_tags'] = $context['can_delete_tags'] = $context['can_modify_any'] = $context['can_modify_replies'] = $context['can_modify_own'] = $context['can_delete_any'] = $context['can_delete_replies'] = $context['can_delete_own'] = $context['can_lock'] = $context['can_sticky'] = $context['calendar_post'] = $context['can_add_poll'] = $context['can_remove_poll'] = $context['can_reply'] = $context['can_reply_unapproved'] = $context['can_quote'] = $context['can_remove_post'] = false; } // 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'] : ''; } // todo: drafts -> plugin $context['can_save_draft'] = false; //$context['can_reply'] && !$context['user']['is_guest'] && in_array('dr', $context['admin_features']) && !empty($options['use_drafts']) && allowedTo('drafts_allow'); $context['can_autosave_draft'] = false; //$context['can_save_draft'] && !empty($modSettings['enableAutoSaveDrafts']) && allowedTo('drafts_autosave_allow'); enqueueThemeScript('topic', 'scripts/topic.js', true); if ($context['can_autosave_draft']) { enqueueThemeScript('drafts', 'scripts/drafts.js', true); } $context['can_moderate_member'] = $context['can_issue_warning'] || $context['can_moderate_board']; $context['topic_has_banned_members_msg'] = $context['topic_banned_members_count'] > 0 && $context['can_moderate_board'] ? sprintf($txt['topic_has_bans_msg'], URL::parse('?action=moderate;area=topicbans;sa=bytopic;t=' . $topic)) : ''; if (EoS_Smarty::isActive()) { if (isset($context['poll'])) { $context['poll_buttons'] = array('vote' => array('test' => 'allow_return_vote', 'text' => 'poll_return_vote', 'image' => 'poll_options.gif', 'lang' => true, 'url' => $scripturl . '?topic=' . $context['current_topic'] . '.' . $context['start']), 'results' => array('test' => 'show_view_results_button', 'text' => 'poll_results', 'image' => 'poll_results.gif', '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.gif', 'lang' => true, 'url' => $scripturl . '?action=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.gif', '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.gif', '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.gif', 'lang' => true, 'custom' => 'onclick="return Eos_Confirm(\'\', \'' . $txt['poll_remove_warn'] . '\', $(this).attr(\'href\'));"', 'url' => $scripturl . '?action=removepoll;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id'])); } $context['normal_buttons'] = array('reply' => array('test' => 'can_reply', 'text' => 'reply', 'custom' => 'onclick="return oQuickReply.quote(0);" ', 'image' => 'reply.gif', 'lang' => true, 'url' => $scripturl . '?action=post;topic=' . $context['current_topic'] . '.' . $context['start'] . ';last_msg=' . $context['topic_last_message'], 'active' => true), 'add_poll' => array('test' => 'can_add_poll', 'text' => 'add_poll', 'image' => 'add_poll.gif', 'lang' => true, 'url' => $scripturl . '?action=editpoll;add;topic=' . $context['current_topic'] . '.' . $context['start']), 'mark_unread' => array('test' => 'can_mark_unread', 'text' => 'mark_unread', 'image' => 'markunread.gif', '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'])); HookAPI::callHook('integrate_display_buttons', array(&$context['normal_buttons'])); $remove_url = $scripturl . '?action=removetopic2;topic=' . $context['current_topic'] . '.0;' . $context['session_var'] . '=' . $context['session_id']; $context['mod_buttons'] = array('move' => array('test' => 'can_move', 'text' => 'move_topic', 'image' => 'admin_move.gif', 'lang' => true, 'url' => $scripturl . '?action=movetopic;topic=' . $context['current_topic'] . '.0'), 'delete' => array('test' => 'can_delete', 'text' => 'remove_topic', 'image' => 'admin_rem.gif', 'lang' => true, 'custom' => 'onclick="return Eos_Confirm(\'\',\'' . $txt['are_sure_remove_topic'] . '\',\'' . $remove_url . '\');"', 'url' => $remove_url), 'lock' => array('test' => 'can_lock', 'text' => empty($context['is_locked']) ? 'set_lock' : 'set_unlock', 'image' => 'admin_lock.gif', 'lang' => true, 'url' => $scripturl . '?action=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.gif', 'lang' => true, 'url' => $scripturl . '?action=sticky;topic=' . $context['current_topic'] . '.' . $context['start'] . ';' . $context['session_var'] . '=' . $context['session_id']), 'merge' => array('test' => 'can_merge', 'text' => 'merge', 'image' => 'merge.gif', '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.gif', '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']); } // Allow adding new mod buttons easily. HookAPI::callHook('integrate_mod_buttons', array(&$context['mod_buttons'])); $context['message_ids'] = $messages; $context['perma_request'] = isset($_REQUEST['perma']) ? true : false; $context['mod_buttons_style'] = array('id' => 'moderationbuttons_strip', 'class' => 'buttonlist'); $context['full_members_viewing_list'] = empty($context['view_members_list']) ? '0 ' . $txt['members'] : implode(', ', $context['view_members_list']) . (empty($context['view_num_hidden']) || $context['can_moderate_forum'] ? '' : ' (+ ' . $context['view_num_hidden'] . ' ' . $txt['hidden'] . ')'); } fetchNewsItems($board, $topic); HookAPI::callHook('display_general', array()); /* * $message is always available in templates as global variable * prepareDisplayContext() just repopulates it and is called from * the topic display template via $SUPPORT object callback. */ EoS_Smarty::getSmartyInstance()->assignByRef('message', $output); }
function ViewModlog() { global $txt, $modSettings, $context, $scripturl, $sourcedir, $user_info, $smcFunc, $settings; // Are we looking at the moderation log or the administration log. $context['log_type'] = isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'adminlog' ? 3 : 1; if ($context['log_type'] == 3) { isAllowedTo('admin_forum'); } // These change dependant on whether we are viewing the moderation or admin log. if ($context['log_type'] == 3 || $_REQUEST['action'] == 'admin') { $context['url_start'] = '?action=admin;area=logs;sa=' . ($context['log_type'] == 3 ? 'adminlog' : 'modlog') . ';type=' . $context['log_type']; } else { $context['url_start'] = '?action=moderate;area=modlog;type=' . $context['log_type']; } $context['can_delete'] = allowedTo('admin_forum'); loadLanguage('Modlog'); $context['page_title'] = $context['log_type'] == 3 ? $txt['modlog_admin_log'] : $txt['modlog_view']; // The number of entries to show per page of log file. $context['displaypage'] = 30; // Amount of hours that must pass before allowed to delete file. $context['hoursdisable'] = 24; // Handle deletion... if (isset($_POST['removeall']) && $context['can_delete']) { checkSession(); smf_db_query(' DELETE FROM {db_prefix}log_actions WHERE id_log = {int:moderate_log} AND log_time < {int:twenty_four_hours_wait}', array('twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600, 'moderate_log' => $context['log_type'])); } elseif (!empty($_POST['remove']) && isset($_POST['delete']) && $context['can_delete']) { checkSession(); smf_db_query(' DELETE FROM {db_prefix}log_actions WHERE id_log = {int:moderate_log} AND id_action IN ({array_string:delete_actions}) AND log_time < {int:twenty_four_hours_wait}', array('twenty_four_hours_wait' => time() - $context['hoursdisable'] * 3600, 'delete_actions' => array_unique($_POST['delete']), 'moderate_log' => $context['log_type'])); } // Do the column stuff! $sort_types = array('action' => 'lm.action', 'time' => 'lm.log_time', 'member' => 'mem.real_name', 'group' => 'mg.group_name', 'ip' => 'lm.ip'); // Setup the direction stuff... $context['order'] = isset($_REQUEST['sort']) && isset($sort_types[$_REQUEST['sort']]) ? $_REQUEST['sort'] : 'time'; // If we're coming from a search, get the variables. if (!empty($_REQUEST['params']) && empty($_REQUEST['is_search'])) { $search_params = base64_decode(strtr($_REQUEST['params'], array(' ' => '+'))); $search_params = @unserialize($search_params); } // This array houses all the valid search types. $searchTypes = array('action' => array('sql' => 'lm.action', 'label' => $txt['modlog_action']), 'member' => array('sql' => 'mem.real_name', 'label' => $txt['modlog_member']), 'group' => array('sql' => 'mg.group_name', 'label' => $txt['modlog_position']), 'ip' => array('sql' => 'lm.ip', 'label' => $txt['modlog_ip'])); if (!isset($search_params['string']) || !empty($_REQUEST['search']) && $search_params['string'] != $_REQUEST['search']) { $search_params_string = empty($_REQUEST['search']) ? '' : $_REQUEST['search']; } else { $search_params_string = $search_params['string']; } if (isset($_REQUEST['search_type']) || empty($search_params['type']) || !isset($searchTypes[$search_params['type']])) { $search_params_type = isset($_REQUEST['search_type']) && isset($searchTypes[$_REQUEST['search_type']]) ? $_REQUEST['search_type'] : (isset($searchTypes[$context['order']]) ? $context['order'] : 'member'); } else { $search_params_type = $search_params['type']; } $search_params_column = $searchTypes[$search_params_type]['sql']; $search_params = array('string' => $search_params_string, 'type' => $search_params_type); // Setup the search context. $context['search_params'] = empty($search_params['string']) ? '' : base64_encode(serialize($search_params)); $context['search'] = array('string' => htmlspecialchars($search_params['string']), 'type' => $search_params['type'], 'label' => $searchTypes[$search_params_type]['label']); // If they are searching by action, then we must do some manual intervention to search in their language! if ($search_params['type'] == 'action' && !empty($search_params['string'])) { // For the moment they can only search for ONE action! foreach ($txt as $key => $text) { if (substr($key, 0, 10) == 'modlog_ac_' && strpos($text, $search_params['string']) !== false) { $search_params['string'] = substr($key, 10); break; } } } require_once $sourcedir . '/lib/Subs-List.php'; // This is all the information required for a watched user listing. $listOptions = array('id' => 'moderation_log_list', 'title' => '<a href="' . $scripturl . '?action=helpadmin;help=' . ($context['log_type'] == 3 ? 'adminlog' : 'modlog') . '" onclick="return reqWin(this.href);" class="help"><strong>[' . $txt['help'] . '] </strong></a> ' . $txt['modlog_' . ($context['log_type'] == 3 ? 'admin' : 'moderation') . '_log'], 'width' => '100%', 'items_per_page' => $context['displaypage'], 'no_items_label' => $txt['modlog_' . ($context['log_type'] == 3 ? 'admin_log_' : '') . 'no_entries_found'], 'base_href' => $scripturl . $context['url_start'] . (!empty($context['search_params']) ? ';params=' . $context['search_params'] : ''), 'default_sort_col' => 'time', 'get_items' => array('function' => 'list_getModLogEntries', 'params' => array(!empty($search_params['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : '', array('sql_type' => $search_params_column, 'search_string' => $search_params['string']), $context['log_type'])), 'get_count' => array('function' => 'list_getModLogEntryCount', 'params' => array(!empty($search_params['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : '', array('sql_type' => $search_params_column, 'search_string' => $search_params['string']), $context['log_type'])), 'columns' => array('action' => array('header' => array('value' => $txt['modlog_action'], 'class' => 'lefttext first_th'), 'data' => array('db' => 'action_text', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.action', 'reverse' => 'lm.action DESC')), 'time' => array('header' => array('value' => $txt['modlog_date'], 'class' => 'lefttext'), 'data' => array('db' => 'time', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.log_time DESC', 'reverse' => 'lm.log_time')), 'moderator' => array('header' => array('value' => $txt['modlog_member'], 'class' => 'lefttext'), 'data' => array('db' => 'moderator_link', 'class' => 'smalltext'), 'sort' => array('default' => 'mem.real_name', 'reverse' => 'mem.real_name DESC')), 'position' => array('header' => array('value' => $txt['modlog_position'], 'class' => 'lefttext'), 'data' => array('db' => 'position', 'class' => 'smalltext'), 'sort' => array('default' => 'mg.group_name', 'reverse' => 'mg.group_name DESC')), 'ip' => array('header' => array('value' => $txt['modlog_ip'], 'class' => 'lefttext'), 'data' => array('db' => 'ip', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.ip', 'reverse' => 'lm.ip DESC')), 'delete' => array('header' => array('value' => '<input type="checkbox" name="all" class="input_check" onclick="invertAll(this, this.form);" />'), 'data' => array('function' => create_function('$entry', ' return \'<input type="checkbox" class="input_check" name="delete[]" value="\' . $entry[\'id\'] . \'"\' . ($entry[\'editable\'] ? \'\' : \' disabled="disabled"\') . \' />\'; '), 'style' => 'text-align: center;'))), 'form' => array('href' => $scripturl . $context['url_start'], 'include_sort' => true, 'include_start' => true, 'hidden_fields' => array($context['session_var'] => $context['session_id'], 'params' => $context['search_params'])), 'additional_rows' => array(array('position' => 'after_title', 'value' => $txt['modlog_' . ($context['log_type'] == 3 ? 'admin' : 'moderation') . '_log_desc'], 'class' => 'smalltext', 'style' => 'padding: 2ex;'), array('position' => 'below_table_data', 'value' => ' ' . $txt['modlog_search'] . ' (' . $txt['modlog_by'] . ': ' . $context['search']['label'] . '): <input type="text" name="search" size="18" value="' . $context['search']['string'] . '" class="input_text" /> <input type="submit" name="is_search" value="' . $txt['modlog_go'] . '" class="button_submit" /> ' . ($context['can_delete'] ? ' | <input type="submit" name="remove" value="' . $txt['modlog_remove'] . '" class="button_submit" /> <input type="submit" name="removeall" value="' . $txt['modlog_removeall'] . '" class="button_submit" />' : '')))); EoS_Smarty::loadTemplate('modcenter/modcenter_base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('modcenter_content_area', 'modcenter/modlog'); // Create the watched user list. createList($listOptions); //$context['sub_template'] = 'show_list'; $context['default_list'] = 'moderation_log_list'; }
/** * @param $mid = int message (or content) id * * handle the ajax request for rating a post. Also handles deletion of * * TODO: remove likes from the database when a user is deleted * TODO: make it work without AJAX and JavaScript */ public static function rateIt($mid) { global $context, $user_info, $sourcedir, $txt, $modSettings; $total = array(); $content_type = 1; // > post content type, we should define them elsewhere later when we have more than just this one if ((int) $mid > 0) { $uid = $user_info['id']; $remove_it = isset($_REQUEST['remove']) ? true : false; $repair = isset($_REQUEST['repair']) && $user_info['is_admin'] ? true : false; $is_xmlreq = $_REQUEST['action'] == 'xmlhttp' ? true : false; $update_mode = false; $like_type = isset($_REQUEST['r']) && (int) $_REQUEST['r'] > 0 ? $_REQUEST['r'] : '1'; $comment = isset($_REQUEST['comment']) ? strip_tags($_REQUEST['comment']) : ''; $rtypes = explode(',', $like_type); foreach ($rtypes as $rtype) { if (!isset($modSettings['ratings'][$rtype])) { AjaxErrorMsg($txt['unknown_rating_type']); } } if ($user_info['is_guest']) { AjaxErrorMsg($txt['no_like_for_guests']); } $request = smf_db_query('SELECT m.id_msg, m.id_member, m.id_board, m.id_topic, m.subject, l.id_msg AS like_message, l.rtype, l.id_user FROM {db_prefix}messages AS m LEFT JOIN {db_prefix}likes AS l ON (l.id_msg = m.id_msg AND l.ctype = {int:content_type} AND l.id_user = {int:id_user}) WHERE m.id_msg = {int:id_msg} LIMIT 1', array('content_type' => $content_type, 'id_msg' => $mid, 'id_user' => $uid)); $row = mysql_fetch_assoc($request); mysql_free_result($request); $like_owner = $row['id_user']; if ($row['id_user'] > 0 && !$remove_it && !$repair) { // duplicate like (but not when removing it) AjaxErrorMsg($txt['like_verify_error']); } $like_receiver = $row['id_member']; EoS_Smarty::loadTemplate('xml_blocks'); $context['template_functions'] = 'rating_response'; $context['ratings_output']['mid'] = $mid; /* * this is a debugging feature and allows the admin to repair * the likes for a post. * it may go away at a later time. */ if ($repair) { if (!$user_info['is_admin']) { obExit(false); } $total = self::updateForContent($mid); $output = ''; self::generateOutput($total['status'], $output, $mid, $row['id_user'] > 0 ? $row['rtype'] : 0); // fix like stats for the like_giver and like_receiver. This might be a very slow query, but // since this feature will most likely go away, right now I do not care. /* smf_db_query('UPDATE {db_prefix}members AS m SET m.likes_given = (SELECT COUNT(l.id_user) FROM {db_prefix}likes AS l WHERE l.id_user = m.id_member), m.likes_received = (SELECT COUNT(l1.id_receiver) FROM {db_prefix}likes AS l1 WHERE l1.id_receiver = m.id_member) WHERE m.id_member = {int:owner} OR m.id_member = {int:receiver}', array('owner' => $like_owner, 'receiver' => $like_receiver)); */ invalidateMemberData(array($like_owner, $like_receiver)); if ($is_xmlreq) { $context['ratings_output']['output'] = $output; $context['ratings_output']['likebar'] = ''; $context['postratings'] = json_encode($context['ratings_output']); return; } else { redirectexit(); } } if ($like_receiver == $uid) { AjaxErrorMsg($txt['cannot_like_own']); } if (!allowedTo('like_give', $row['id_board'])) { // no permission to give likes in this board AjaxErrorMsg($txt['like_no_permission']); } if ($remove_it && $row['id_user'] > 0) { // remove a rating if ($like_owner == $uid) { smf_db_query('DELETE FROM {db_prefix}likes WHERE id_msg = {int:id_msg} AND id_user = {int:id_user} AND ctype = {int:ctype}', array('id_msg' => $mid, 'id_user' => $uid, 'ctype' => $content_type)); if ($like_receiver) { smf_db_query('UPDATE {db_prefix}members SET likes_received = likes_received - 1 WHERE id_member = {int:id_member}', array('id_member' => $like_receiver)); } smf_db_query('UPDATE {db_prefix}members SET likes_given = likes_given - 1 WHERE id_member = {int:id_member}', array('id_member' => $uid)); // if we remove a like (unlike) a post, also delete the corresponding activity smf_db_query('DELETE a.*, n.* FROM {db_prefix}log_activities AS a LEFT JOIN {db_prefix}log_notifications AS n ON(n.id_act = a.id_act) WHERE a.id_member = {int:id_member} AND a.id_type = 1 AND a.id_content = {int:id_content}', array('id_member' => $uid, 'id_content' => $mid)); $context['ratings_output']['likebar'] = self::$rate_bar; } } else { /* store the rating */ global $memberContext; if ($like_receiver) { // we do have a member, but still allow to like posts made by guests loadMemberData($like_receiver); // but banned users shall not receive likes loadMemberContext($like_receiver); } if ($like_receiver && !$memberContext[$like_receiver]['is_banned'] || $like_receiver == 0) { // posts by guests can be liked smf_db_query('INSERT INTO {db_prefix}likes(id_msg, id_user, id_receiver, updated, ctype, rtype, comment) VALUES({int:id_message}, {int:id_user}, {int:id_receiver}, {int:updated}, {int:ctype}, {string:rtype}, {string:comment})', array('id_message' => $mid, 'id_user' => $uid, 'id_receiver' => $like_receiver, 'updated' => time(), 'ctype' => $content_type, 'rtype' => $like_type, 'comment' => $comment)); if ($like_receiver) { smf_db_query('UPDATE {db_prefix}members SET likes_received = likes_received + 1 WHERE id_member = {int:id_member}', array('id_member' => $like_receiver)); } smf_db_query('UPDATE {db_prefix}members SET likes_given = likes_given + 1 WHERE id_member = {int:uid}', array('uid' => $uid)); $update_mode = $like_type; if ($modSettings['astream_active']) { @(require_once $sourcedir . '/lib/Subs-Activities.php'); aStreamAdd($uid, ACT_LIKE, array('member_name' => $context['user']['name'], 'topic_title' => $row['subject'], 'rtype' => $like_type), $row['id_board'], $row['id_topic'], $mid, $like_receiver); } } else { AjaxErrorMsg($txt['like_cannot_like']); } $context['ratings_output']['likebar'] = '<a rel="nofollow" class="givelike" data-fn="remove" href="#" data-id="' . $mid . '">' . $txt['unlike_label'] . '</a>'; } if ($user_info['is_admin'] && self::$show_repair_link) { $context['ratings_output']['likebar'] .= ' <a rel="nofollow" class="givelike" data-fn="repair" href="#" data-id="' . $mid . '">Repair ratings</a>'; } $total = self::updateForContent($mid); $output = ''; self::generateOutput($total['status'], $output, $mid, $update_mode); $context['ratings_output']['output'] = $output; $context['postratings'] = json_encode($context['ratings_output']); } }
function EditPoll() { global $txt, $user_info, $context, $topic, $board, $smcFunc, $sourcedir, $scripturl; if (empty($topic)) { fatal_lang_error('no_access', false); } loadLanguage('Post'); EoS_Smarty::loadTemplate('topic/poll'); $context['can_moderate_poll'] = isset($_REQUEST['add']) ? 1 : allowedTo('moderate_board'); $context['start'] = (int) $_REQUEST['start']; $context['is_edit'] = isset($_REQUEST['add']) ? 0 : 1; // Check if a poll currently exists on this topic, and get the id, question and starter. $request = smf_db_query(' SELECT t.id_member_started, p.id_poll, p.question, p.hide_results, p.expire_time, p.max_votes, p.change_vote, m.subject, p.guest_vote, p.id_member AS poll_starter FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) WHERE t.id_topic = {int:current_topic} LIMIT 1', array('current_topic' => $topic)); // Assume the the topic exists, right? if (mysql_num_rows($request) == 0) { fatal_lang_error('no_board'); } // Get the poll information. $pollinfo = mysql_fetch_assoc($request); mysql_free_result($request); // If we are adding a new poll - make sure that there isn't already a poll there. if (!$context['is_edit'] && !empty($pollinfo['id_poll'])) { fatal_lang_error('poll_already_exists'); } elseif ($context['is_edit'] && empty($pollinfo['id_poll'])) { fatal_lang_error('poll_not_found'); } // Can you do this? if ($context['is_edit'] && !allowedTo('poll_edit_any')) { isAllowedTo('poll_edit_' . ($user_info['id'] == $pollinfo['id_member_started'] || $pollinfo['poll_starter'] != 0 && $user_info['id'] == $pollinfo['poll_starter'] ? 'own' : 'any')); } elseif (!$context['is_edit'] && !allowedTo('poll_add_any')) { isAllowedTo('poll_add_' . ($user_info['id'] == $pollinfo['id_member_started'] ? 'own' : 'any')); } // Do we enable guest voting? require_once $sourcedir . '/lib/Subs-Members.php'; $groupsAllowedVote = groupsAllowedTo('poll_vote', $board); // Want to make sure before you actually submit? Must be a lot of options, or something. if (isset($_POST['preview'])) { $question = commonAPI::htmlspecialchars($_POST['question']); // Basic theme info... $context['poll'] = array('id' => $pollinfo['id_poll'], 'question' => $question, 'hide_results' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed']), 'max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes'])); // Start at number one with no last id to speak of. $number = 1; $last_id = 0; // Get all the choices - if this is an edit. if ($context['is_edit']) { $request = smf_db_query(' SELECT label, votes, id_choice FROM {db_prefix}poll_choices WHERE id_poll = {int:id_poll}', array('id_poll' => $pollinfo['id_poll'])); $context['choices'] = array(); while ($row = mysql_fetch_assoc($request)) { // Get the highest id so we can add more without reusing. if ($row['id_choice'] >= $last_id) { $last_id = $row['id_choice'] + 1; } // They cleared this by either omitting it or emptying it. if (!isset($_POST['options'][$row['id_choice']]) || $_POST['options'][$row['id_choice']] == '') { continue; } censorText($row['label']); // Add the choice! $context['choices'][$row['id_choice']] = array('id' => $row['id_choice'], 'number' => $number++, 'votes' => $row['votes'], 'label' => $row['label'], 'is_last' => false); } mysql_free_result($request); } // Work out how many options we have, so we get the 'is_last' field right... $totalPostOptions = 0; foreach ($_POST['options'] as $id => $label) { if ($label != '') { $totalPostOptions++; } } $count = 1; // If an option exists, update it. If it is new, add it - but don't reuse ids! foreach ($_POST['options'] as $id => $label) { $label = commonAPI::htmlspecialchars($label); censorText($label); if (isset($context['choices'][$id])) { $context['choices'][$id]['label'] = $label; } elseif ($label != '') { $context['choices'][] = array('id' => $last_id++, 'number' => $number++, 'label' => $label, 'votes' => -1, 'is_last' => $count++ == $totalPostOptions && $totalPostOptions > 1 ? true : false); } } // Make sure we have two choices for sure! if ($totalPostOptions < 2) { // Need two? if ($totalPostOptions == 0) { $context['choices'][] = array('id' => $last_id++, 'number' => $number++, 'label' => '', 'votes' => -1, 'is_last' => false); } $poll_errors[] = 'poll_few'; } // Always show one extra box... $context['choices'][] = array('id' => $last_id++, 'number' => $number++, 'label' => '', 'votes' => -1, 'is_last' => true); if ($context['can_moderate_poll']) { $context['poll']['expiration'] = $_POST['poll_expire']; } // Check the question/option count for errors. if (trim($_POST['question']) == '' && empty($context['poll_error'])) { $poll_errors[] = 'no_question'; } // No check is needed, since nothing is really posted. checkSubmitOnce('free'); // Take a check for any errors... assuming we haven't already done so! if (!empty($poll_errors) && empty($context['poll_error'])) { loadLanguage('Errors'); $context['poll_error'] = array('messages' => array()); foreach ($poll_errors as $poll_error) { $context['poll_error'][$poll_error] = true; $context['poll_error']['messages'][] = $txt['error_' . $poll_error]; } } } else { // Basic theme info... $context['poll'] = array('id' => $pollinfo['id_poll'], 'question' => $pollinfo['question'], 'hide_results' => $pollinfo['hide_results'], 'max_votes' => $pollinfo['max_votes'], 'change_vote' => !empty($pollinfo['change_vote']), 'guest_vote' => !empty($pollinfo['guest_vote']), 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed'])); // Poll expiration time? $context['poll']['expiration'] = empty($pollinfo['expire_time']) || !allowedTo('moderate_board') ? '' : ceil($pollinfo['expire_time'] <= time() ? -1 : ($pollinfo['expire_time'] - time()) / (3600 * 24)); // Get all the choices - if this is an edit. if ($context['is_edit']) { $request = smf_db_query(' SELECT label, votes, id_choice FROM {db_prefix}poll_choices WHERE id_poll = {int:id_poll}', array('id_poll' => $pollinfo['id_poll'])); $context['choices'] = array(); $number = 1; while ($row = mysql_fetch_assoc($request)) { censorText($row['label']); $context['choices'][$row['id_choice']] = array('id' => $row['id_choice'], 'number' => $number++, 'votes' => $row['votes'], 'label' => $row['label'], 'is_last' => false); } mysql_free_result($request); $last_id = max(array_keys($context['choices'])) + 1; // Add an extra choice... $context['choices'][] = array('id' => $last_id, 'number' => $number, 'votes' => -1, 'label' => '', 'is_last' => true); } else { // Setup the default poll options. $context['poll'] = array('id' => 0, 'question' => '', 'hide_results' => 0, 'max_votes' => 1, 'change_vote' => 0, 'guest_vote' => 0, 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed']), 'expiration' => ''); // Make all five poll choices empty. $context['choices'] = array(array('id' => 0, 'number' => 1, 'votes' => -1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'votes' => -1, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'votes' => -1, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'votes' => -1, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'votes' => -1, 'label' => '', 'is_last' => true)); } } $context['page_title'] = $context['is_edit'] ? $txt['poll_edit'] : $txt['add_poll']; // Build the link tree. censorText($pollinfo['subject']); $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.0', 'name' => $pollinfo['subject']); $context['linktree'][] = array('name' => $context['page_title']); $context['poll_script'] = ' <script type="text/javascript"><!-- // --><![CDATA[ var pollOptionNum = 0; function addPollOption() { if (pollOptionNum == 0) { for (var i = 0; i < document.forms.postmodify.elements.length; i++) if (document.forms.postmodify.elements[i].id.substr(0, 8) == "options-") pollOptionNum++; } pollOptionNum++ setOuterHTML(document.getElementById("pollMoreOptions"), \'<li><label for="options-\' + pollOptionNum + \'" ' . (isset($context['poll_error']['no_question']) ? ' class="error"' : '') . '>' . $txt['option'] . ' \' + pollOptionNum + \'</label>: <input type="text" name="options[\' + (pollOptionNum - 1) + \']" id="options-\' + (pollOptionNum - 1) + \'" value="" size="80" maxlength="255" class="input_text" /></li><li id="pollMoreOptions"></li\'); } // ]]></script>'; // Register this form in the session variables. checkSubmitOnce('register'); }
function UnapprovedAttachments() { global $txt, $scripturl, $context, $user_info, $sourcedir, $backend_subdir; $context['page_title'] = $txt['mc_unapproved_attachments']; // Once again, permissions are king! $approve_boards = boardsAllowedTo('approve_posts'); if ($approve_boards == array(0)) { $approve_query = ''; } elseif (!empty($approve_boards)) { $approve_query = ' AND m.id_board IN (' . implode(',', $approve_boards) . ')'; } else { $approve_query = ' AND 0'; } // Get together the array of things to act on, if any. $attachments = array(); if (isset($_GET['approve'])) { $attachments[] = (int) $_GET['approve']; } elseif (isset($_GET['delete'])) { $attachments[] = (int) $_GET['delete']; } elseif (isset($_POST['item'])) { foreach ($_POST['item'] as $item) { $attachments[] = (int) $item; } } // Are we approving or deleting? if (isset($_GET['approve']) || isset($_POST['do']) && $_POST['do'] == 'approve') { $curAction = 'approve'; } elseif (isset($_GET['delete']) || isset($_POST['do']) && $_POST['do'] == 'delete') { $curAction = 'delete'; } // Something to do, let's do it! if (!empty($attachments) && isset($curAction)) { checkSession('request'); // This will be handy. require_once $sourcedir . '/lib/Subs-ManageAttachments.php'; // Confirm the attachments are eligible for changing! $request = smf_db_query(' SELECT a.id_attach FROM {db_prefix}attachments AS a INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) LEFT JOIN {db_prefix}boards AS b ON (m.id_board = b.id_board) WHERE a.id_attach IN ({array_int:attachments}) AND a.approved = {int:not_approved} AND a.attachment_type = {int:attachment_type} AND {query_see_board} ' . $approve_query, array('attachments' => $attachments, 'not_approved' => 0, 'attachment_type' => 0)); $attachments = array(); while ($row = mysql_fetch_assoc($request)) { $attachments[] = $row['id_attach']; } mysql_free_result($request); // Assuming it wasn't all like, proper illegal, we can do the approving. if (!empty($attachments)) { if ($curAction == 'approve') { ApproveAttachments($attachments); } else { removeAttachments(array('id_attach' => $attachments)); } } } // How many unapproved attachments in total? $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}attachments AS a INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) WHERE a.approved = {int:not_approved} AND a.attachment_type = {int:attachment_type} AND {query_see_board} ' . $approve_query, array('not_approved' => 0, 'attachment_type' => 0)); list($context['total_unapproved_attachments']) = mysql_fetch_row($request); mysql_free_result($request); $context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=attachmod;sa=attachments', $_GET['start'], $context['total_unapproved_attachments'], 10); $context['start'] = $_GET['start']; // Get all unapproved attachments. $request = smf_db_query(' SELECT a.id_attach, a.filename, a.size, m.id_msg, m.id_topic, m.id_board, m.subject, m.body, m.id_member, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, t.id_member_started, t.id_first_msg, b.name AS board_name, c.id_cat, c.name AS cat_name FROM {db_prefix}attachments AS a INNER JOIN {db_prefix}messages AS m ON (m.id_msg = a.id_msg) INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) WHERE a.approved = {int:not_approved} AND a.attachment_type = {int:attachment_type} AND {query_see_board} ' . $approve_query . ' LIMIT ' . $context['start'] . ', 10', array('not_approved' => 0, 'attachment_type' => 0)); $context['unapproved_items'] = array(); for ($i = 1; $row = mysql_fetch_assoc($request); $i++) { $context['unapproved_items'][] = array('id' => $row['id_attach'], 'alternate' => $i % 2, 'filename' => $row['filename'], 'size' => round($row['size'] / 1024, 2), 'time' => timeformat($row['poster_time']), 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'link' => $row['id_member'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name'], 'href' => $scripturl . '?action=profile;u=' . $row['id_member']), 'message' => array('id' => $row['id_msg'], 'subject' => $row['subject'], 'body' => parse_bbc($row['body']), 'time' => timeformat($row['poster_time']), 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg']), 'topic' => array('id' => $row['id_topic']), 'board' => array('id' => $row['id_board'], 'name' => $row['board_name']), 'category' => array('id' => $row['id_cat'], 'name' => $row['cat_name'])); } mysql_free_result($request); EoS_Smarty::loadTemplate('modcenter/modcenter_base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('modcenter_content_area', 'modcenter/unapproved_attachments'); // The ever popular approve button, with the massively unpopular delete. $context['approve_button'] = create_button('approve', 'approve'); $context['remove_button'] = create_button('remove_message', 'remove'); }
/** * @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'); }
function ob_sessrewrite($buffer) { global $scripturl, $modSettings, $context, $user_info, $txt, $time_start, $db_count; /* * tidy support as a debugging option to generate prettified output * and only do it for the admin when 'tidyup' is set in the request string (tidy can be slow) * pretty HTML output might help with debugging templates */ if (isset($_REQUEST['tidyup']) && !isset($_REQUEST['xml']) && class_exists('Tidy') && $user_info['is_admin']) { $tidy = new Tidy(); $tidy_config = array('indent' => true, 'output-html' => true, 'wrap' => 0, 'merge-divs' => false, 'merge-spans' => false); $tidy->parseString($buffer, $tidy_config, 'utf8'); $buffer = $tidy; } // If $scripturl is set to nothing, or the SID is not defined (SSI?) just quit. if ($scripturl == '' || !defined('SID')) { return $buffer; } // rewrite urls with PHPSESSID, but only if the session isn't cookied and NOT for spiders if (empty($_COOKIE) && SID != '' && empty($context['browser']['possibly_robot'])) { $buffer = preg_replace('/"' . preg_quote($scripturl, '/') . '(?!\\?' . preg_quote(SID, '/') . ')\\??/', '"' . $scripturl . '?' . SID . '&', $buffer); } elseif (isset($_GET['debug'])) { $buffer = preg_replace('/(?<!<link rel="canonical" href=)"' . preg_quote($scripturl, '/') . '\\??/', '"' . $scripturl . '?debug;', $buffer); } $now = microtime(); $context['load_time'] = round(array_sum(explode(' ', $now)) - array_sum(explode(' ', $time_start)), 3); $context['load_queries'] = $db_count; $context['template_benchmark_time'] = round(array_sum(explode(' ', $now)) - array_sum(explode(' ', $context['template_benchmark'])), 3); if (!empty($modSettings['simplesef_enable'])) { $buffer = isset($context['sef_full_rewrite']) ? SimpleSEF::ob_simplesef($buffer) : SimpleSEF::ob_simplesef_light($buffer); //$buffer .= SimpleSEF::$debug_info; } $_t = EoS_Smarty::isActive() ? 's template-smarty), ' : 's template), '; $buffer = str_replace('@%%__loadtime__%%@', $user_info['is_admin'] ? $context['load_time'] . 's CPU (' . $context['template_benchmark_time'] . $_t . $context['load_queries'] . ' ' . $txt['queries'] . SimpleSEF::getPerfData() : '', $buffer); if (isset($_REQUEST['xml'])) { $buffer = ltrim($buffer); } return $buffer; }