/** * Find the ID of the "current" member * * @param boolean $fatal if the function ends in a fatal error in case of problems (default true) * @param boolean $reload_id if true the already set value is ignored (default false) * * @return mixed and integer if no error, false in case of problems if $fatal is false */ function currentMemberID($fatal = true, $reload_id = false) { global $user_info; static $memID; // If we already know who we're dealing with if (isset($memID) && !$reload_id) { return $memID; } // Did we get the user by name... if (isset($_REQUEST['user'])) { $memberResult = loadMemberData($_REQUEST['user'], true, 'profile'); } elseif (!empty($_REQUEST['u'])) { $memberResult = loadMemberData((int) $_REQUEST['u'], false, 'profile'); } else { $memberResult = loadMemberData($user_info['id'], false, 'profile'); } // Check if loadMemberData() has returned a valid result. if (!is_array($memberResult)) { // Members only... is_not_guest('', $fatal); if ($fatal) { fatal_lang_error('not_a_user', false); } else { return false; } } // If all went well, we have a valid member ID! list($memID) = $memberResult; return $memID; }
function ENotifyMain() { global $modSettings; // Guests can't have unread things, we don't know anything about them. is_not_guest(); // Update our unread replies log if (!empty($modSettings['enotify_replies'])) { ENotifyUpdateUnreadReplies(); } // Update our personal messages log if (!empty($modSettings['enotify_pms'])) { ENotifyUpdatePms(); } // Load up the notifications at last :) ENotifyLoad(); // Run our garbage collection randomly (setting 0.05% chance for it to run) $random = rand(1, 5000); if ($random == '1987') { ENotifyGarbageCollect(); } // Load the language and the template file. loadLanguage('ENotify'); loadTemplate('ENotify'); template_enotify_main(); // We use this to deactivate the SMF Wrapping Templates die; }
/** * Subaction handler - manages the action and delegates control to the proper * sub-action. * * What it does: * - It loads both the Themes and Settings language files. * - Checks the session by GET or POST to verify the sent data. * - Requires the user to not be a guest. * - Accessed via ?action=admin;area=theme. * * @see Action_Controller::action_index() */ public function action_index() { global $txt, $context; if (isset($_REQUEST['api'])) { return $this->action_index_api(); } // Load the important language files... loadLanguage('ManageThemes'); loadLanguage('Settings'); require_once SUBSDIR . '/Action.class.php'; // No guests in here. is_not_guest(); // Theme administration, removal, choice, or installation... $subActions = array('admin' => array($this, 'action_admin', 'permission' => 'admin_forum'), 'list' => array($this, 'action_list', 'permission' => 'admin_forum'), 'reset' => array($this, 'action_options', 'permission' => 'admin_forum'), 'options' => array($this, 'action_options', 'permission' => 'admin_forum'), 'install' => array($this, 'action_install', 'permission' => 'admin_forum'), 'remove' => array($this, 'action_remove', 'permission' => 'admin_forum'), 'pick' => array($this, 'action_pick'), 'edit' => array($this, 'action_edit', 'permission' => 'admin_forum'), 'copy' => array($this, 'action_copy', 'permission' => 'admin_forum'), 'themelist' => array($this, 'action_themelist', 'permission' => 'admin_forum'), 'browse' => array($this, 'action_browse', 'permission' => 'admin_forum')); // Action controller $action = new Action('manage_themes'); // @todo Layout Settings? if (!empty($context['admin_menu_name'])) { $context[$context['admin_menu_name']]['tab_data'] = array('title' => $txt['themeadmin_title'], 'description' => $txt['themeadmin_description'], 'tabs' => array('admin' => array('description' => $txt['themeadmin_admin_desc']), 'list' => array('description' => $txt['themeadmin_list_desc']), 'reset' => array('description' => $txt['themeadmin_reset_desc']), 'edit' => array('description' => $txt['themeadmin_edit_desc']), 'themelist' => array('description' => $txt['themeadmin_edit_desc']), 'browse' => array('description' => $txt['themeadmin_edit_desc']))); } // Follow the sa or just go to administration, call integrate_sa_manage_themes $subAction = $action->initialize($subActions, 'admin'); // Default the page title to Theme Administration by default. $context['page_title'] = $txt['themeadmin_title']; $context['sub_action'] = $subAction; // Go to the action, if you have permissions $action->dispatch($subAction); }
/** * This is the main function for markasread file. * * @see Action_Controller::action_index() */ public function action_index() { // These checks have been moved here. // Do NOT call the specific handlers directly. // Guests can't mark things. is_not_guest(); checkSession('get'); $redir = $this->_dispatch(); redirectexit($redir); }
/** * Marks a ticket unread. * * There are no permission checks made; other than that the user is who they claim to be. If a ticket is marked unread * but they can't see it anyway, the consequence is that the database gets lighter. * * Invoked through ?action=helpdesk;sa=unreadticket;ticket=x;sessvar=sessid before redirecting back to the main helpdesk page. * * @since 1.0 */ function shd_ticket_unread() { global $smcFunc, $user_info, $context; is_not_guest(); checkSession('get'); if (!empty($context['ticket_id'])) { call_integration_hook('shd_hook_markunread'); $result = shd_db_query('', ' DELETE FROM {db_prefix}helpdesk_log_read WHERE id_ticket = {int:current_ticket} AND id_member = {int:user}', array('current_ticket' => $context['ticket_id'], 'user' => $user_info['id'])); } redirectexit($context['shd_home'] . $context['shd_dept_link']); }
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... loadTemplate('Notify'); // Find out if they have notification set for this topic already. $request = $smcFunc['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'] = $smcFunc['db_num_rows']($request) != 0; $smcFunc['db_free_result']($request); // Set the template variables... $context['board_href'] = $scripturl . '?board=' . $board . '.' . $_REQUEST['start']; $context['start'] = $_REQUEST['start']; $context['page_title'] = $txt['notification']; $context['sub_template'] = 'notify_board'; return; } elseif ($_GET['sa'] == 'on') { checkSession('get'); // Turn notification on. (note this just blows smoke if it's already on.) $smcFunc['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. $smcFunc['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']); }
/** * Subaction handler - manages the action and delegates control to the proper * sub-action. * It loads both the Themes and Settings language files. * Checks the session by GET or POST to verify the sent data. * Requires the user not be a guest. (@todo what?) * Accessed via ?action=admin;area=theme. */ function ThemesMain() { global $txt, $context, $scripturl; // Load the important language files... loadLanguage('Themes'); loadLanguage('Settings'); // No funny business - guests only. is_not_guest(); // Default the page title to Theme Administration by default. $context['page_title'] = $txt['themeadmin_title']; // Theme administration, removal, choice, or installation... $subActions = array('admin' => 'ThemeAdmin', 'list' => 'ThemeList', 'reset' => 'SetThemeOptions', 'options' => 'SetThemeOptions', 'install' => 'ThemeInstall', 'remove' => 'RemoveTheme', 'pick' => 'PickTheme', 'edit' => 'EditTheme', 'copy' => 'CopyTemplate'); // @todo Layout Settings? if (!empty($context['admin_menu_name'])) { $context[$context['admin_menu_name']]['tab_data'] = array('title' => $txt['themeadmin_title'], 'help' => 'themes', 'description' => $txt['themeadmin_description'], 'tabs' => array('admin' => array('description' => $txt['themeadmin_admin_desc']), 'list' => array('description' => $txt['themeadmin_list_desc']), 'reset' => array('description' => $txt['themeadmin_reset_desc']), 'edit' => array('description' => $txt['themeadmin_edit_desc']))); } // Follow the sa or just go to administration. if (isset($_GET['sa']) && !empty($subActions[$_GET['sa']])) { $subActions[$_GET['sa']](); } else { $subActions['admin'](); } }
function UnreadTopics() { global $board, $txt, $scripturl, $db_prefix, $sourcedir; global $ID_MEMBER, $user_info, $context, $settings, $modSettings, $func; // Guests can't have unread things, we don't know anything about them. is_not_guest(); // Prefetching + lots of MySQL work = bad mojo. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { ob_end_clean(); header('HTTP/1.1 403 Forbidden'); die; } $context['showing_all_topics'] = isset($_GET['all']); if ($_REQUEST['action'] == 'unread') { $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit']; } else { $context['page_title'] = $txt['unread_replies']; } if ($context['showing_all_topics'] && !empty($context['load_average']) && !empty($modSettings['loadavg_allunread']) && $context['load_average'] >= $modSettings['loadavg_allunread']) { fatal_lang_error('loadavg_allunread_disabled', false); } elseif ($_REQUEST['action'] != 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unreadreplies']) && $context['load_average'] >= $modSettings['loadavg_unreadreplies']) { fatal_lang_error('loadavg_unreadreplies_disabled', false); } // Are we specifying any specific board? if (!empty($board)) { $query_this_board = 'ID_BOARD = ' . $board; $context['querystring_board_limits'] = ';board=' . $board . '.%d'; } elseif (!empty($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $i => $b) { $_REQUEST['boards'][$i] = (int) $b; } $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}\n\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $_REQUEST['boards']) . ")", __FILE__, __LINE__); $boards = array(); while ($row = mysql_fetch_assoc($request)) { $boards[] = $row['ID_BOARD']; } mysql_free_result($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')'; $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%d'; } elseif (!empty($_REQUEST['c'])) { $_REQUEST['c'] = explode(',', $_REQUEST['c']); foreach ($_REQUEST['c'] as $i => $c) { $_REQUEST['c'][$i] = (int) $c; } $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}\n\t\t\t\tAND b.ID_CAT IN (" . implode(', ', $_REQUEST['c']) . ")", __FILE__, __LINE__); $boards = array(); while ($row = mysql_fetch_assoc($request)) { $boards[] = $row['ID_BOARD']; } mysql_free_result($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')'; $context['querystring_board_limits'] = ';c=' . implode(',', $_REQUEST['c']) . ';start=%d'; } else { // Don't bother to show deleted posts! $request = db_query("\n\t\t\tSELECT b.ID_BOARD\n\t\t\tFROM {$db_prefix}boards AS b\n\t\t\tWHERE {$user_info['query_see_board']}" . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? "\n\t\t\t\tAND b.ID_BOARD != " . (int) $modSettings['recycle_board'] : ''), __FILE__, __LINE__); $boards = array(); while ($row = mysql_fetch_assoc($request)) { $boards[] = $row['ID_BOARD']; } mysql_free_result($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'ID_BOARD IN (' . implode(', ', $boards) . ')'; $context['querystring_board_limits'] = ';start=%d'; $context['no_board_limits'] = true; } $sort_methods = array('subject' => 'ms.subject', 'starter' => 'IFNULL(mems.realName, ms.posterName)', 'replies' => 't.numReplies', 'views' => 't.numViews', 'first_post' => 't.ID_TOPIC', 'last_post' => 't.ID_LAST_MSG'); // The default is the most logical: newest first. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'last_post'; $_REQUEST['sort'] = 't.ID_LAST_MSG'; $ascending = isset($_REQUEST['asc']); $context['querystring_sort_limits'] = $ascending ? ';asc' : ''; } else { $context['sort_by'] = $_REQUEST['sort']; $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']]; $ascending = !isset($_REQUEST['desc']); $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc'); } $context['sort_direction'] = $ascending ? 'up' : 'down'; if (!empty($_REQUEST['c']) && is_array($_REQUEST['c']) && count($_REQUEST['c']) == 1) { $request = db_query("\n\t\t\tSELECT name\n\t\t\tFROM {$db_prefix}categories\n\t\t\tWHERE ID_CAT = " . (int) $_REQUEST['c'][0] . "\n\t\t\tLIMIT 1", __FILE__, __LINE__); list($name) = mysql_fetch_row($request); mysql_free_result($request); $context['linktree'][] = array('url' => $scripturl . '#' . (int) $_REQUEST['c'][0], 'name' => $name); } $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $_REQUEST['action'] == 'unread' ? $txt['unread_topics_visit'] : $txt['unread_replies']); if ($context['showing_all_topics']) { $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $txt['unread_topics_all']); } else { $txt['unread_topics_visit_none'] = strtr($txt['unread_topics_visit_none'], array('?action=unread;all' => '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'])); } if (WIRELESS) { $context['sub_template'] = WIRELESS_PROTOCOL . '_recent'; } else { loadTemplate('Recent'); $context['sub_template'] = $_REQUEST['action'] == 'unread' ? 'unread' : 'replies'; } // Setup the default topic icons... for checking they exist and the like ;) $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless'); $context['icon_sources'] = array(); foreach ($stable_icons as $icon) { $context['icon_sources'][$icon] = 'images_url'; } $is_topics = $_REQUEST['action'] == 'unread'; // This part is the same for each query. $select_clause = ' ms.subject AS firstSubject, ms.posterTime AS firstPosterTime, ms.ID_TOPIC, t.ID_BOARD, b.name AS bname, t.numReplies, t.numViews, ms.ID_MEMBER AS ID_FIRST_MEMBER, ml.ID_MEMBER AS ID_LAST_MEMBER, ml.posterTime AS lastPosterTime, IFNULL(mems.realName, ms.posterName) AS firstPosterName, IFNULL(meml.realName, ml.posterName) AS lastPosterName, ml.subject AS lastSubject, ml.icon AS lastIcon, ms.icon AS firstIcon, t.ID_POLL, t.isSticky, t.locked, ml.modifiedTime AS lastModifiedTime, IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1 AS new_from, LEFT(ml.body, 384) AS lastBody, LEFT(ms.body, 384) AS firstBody, ml.smileysEnabled AS lastSmileys, ms.smileysEnabled AS firstSmileys, t.ID_FIRST_MSG, t.ID_LAST_MSG'; if ($context['showing_all_topics']) { if (!empty($board)) { $request = db_query("\n\t\t\t\tSELECT MIN(ID_MSG)\n\t\t\t\tFROM {$db_prefix}log_mark_read\n\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND ID_BOARD = {$board}", __FILE__, __LINE__); list($earliest_msg) = mysql_fetch_row($request); mysql_free_result($request); } else { $request = db_query("\n\t\t\t\tSELECT MIN(lmr.ID_MSG)\n\t\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = b.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE {$user_info['query_see_board']}", __FILE__, __LINE__); list($earliest_msg) = mysql_fetch_row($request); mysql_free_result($request); } // This is needed in case of topics marked unread. if (empty($earliest_msg)) { $earliest_msg = 0; } else { // Using caching, when possible, to ignore the below slow query. if (isset($_SESSION['cached_log_time']) && $_SESSION['cached_log_time'][0] + 45 > time()) { $earliest_msg2 = $_SESSION['cached_log_time'][1]; } else { // This query is pretty slow, but it's needed to ensure nothing crucial is ignored. $request = db_query("\n\t\t\t\t\tSELECT MIN(ID_MSG)\n\t\t\t\t\tFROM {$db_prefix}log_topics\n\t\t\t\t\tWHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__); list($earliest_msg2) = mysql_fetch_row($request); mysql_free_result($request); // In theory this could be zero, if the first ever post is unread, so fudge it ;) if ($earliest_msg2 == 0) { $earliest_msg2 = -1; } $_SESSION['cached_log_time'] = array(time(), $earliest_msg2); } $earliest_msg = min($earliest_msg2, $earliest_msg); } } // !!! Add modifiedTime in for logTime check? if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics']) { db_query("\n\t\t\tDROP TABLE IF EXISTS {$db_prefix}log_topics_unread", false, false); // Let's copy things out of the log_topics table, to reduce searching. $have_temp_table = db_query("\n\t\t\tCREATE TEMPORARY TABLE {$db_prefix}log_topics_unread (\n\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t)\n\t\t\tSELECT lt.ID_TOPIC, lt.ID_MSG\n\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}log_topics AS lt)\n\t\t\tWHERE lt.ID_TOPIC = t.ID_TOPIC\n\t\t\t\tAND lt.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\tAND t.{$query_this_board}" . (!empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : ''), false, false) !== false; } else { $have_temp_table = false; } if ($context['showing_all_topics'] && $have_temp_table) { $request = db_query("\n\t\t\tSELECT COUNT(*), MIN(t.ID_LAST_MSG)\n\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.{$query_this_board}" . ($context['showing_all_topics'] && !empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : "\n\t\t\t\tAND t.ID_LAST_MSG > {$_SESSION['ID_MSG_LAST_VISIT']}") . "\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true); $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics']; $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1); if ($num_topics == 0) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND t.{$query_this_board}\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\t\tAND t.ID_LAST_MSG >= {$min_message}\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__); } elseif ($is_topics) { $request = db_query("\n\t\t\tSELECT COUNT(*), MIN(t.ID_LAST_MSG)\n\t\t\tFROM {$db_prefix}topics AS t" . ($have_temp_table ? "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)" : "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})") . "\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.{$query_this_board}" . ($context['showing_all_topics'] && !empty($earliest_msg) ? "\n\t\t\t\tAND t.ID_LAST_MSG > {$earliest_msg}" : "\n\t\t\t\tAND t.ID_LAST_MSG > {$_SESSION['ID_MSG_LAST_VISIT']}") . "\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true); $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics']; $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1); if ($num_topics == 0) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)" . ($have_temp_table ? "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics_unread AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)" : "\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})") . "\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND t.{$query_this_board}\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\t\tAND t.ID_LAST_MSG >= {$min_message}\n\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < ml.ID_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__); } else { if ($modSettings['totalMessages'] > 100000) { db_query("\n\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}topics_posted_in", false, false); db_query("\n\t\t\t\tDROP TABLE IF EXISTS {$db_prefix}log_topics_posted_in", false, false); $sortKey_joins = array('ms.subject' => "\n\t\t\t\t\tINNER JOIN {$db_prefix}messages AS ms ON (ms.ID_MSG = t.ID_FIRST_MSG)", 'IFNULL(mems.realName, ms.posterName)' => "\n\t\t\t\t\tINNER JOIN {$db_prefix}messages AS ms ON (ms.ID_MSG = t.ID_FIRST_MSG)\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)"); // The main benefit of this temporary table is not that it's faster; it's that it avoids locks later. $have_temp_table = db_query("\n\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}topics_posted_in (\n\t\t\t\t\tID_TOPIC mediumint(8) unsigned NOT NULL default '0',\n\t\t\t\t\tID_BOARD smallint(5) unsigned NOT NULL default '0',\n\t\t\t\t\tID_LAST_MSG int(10) unsigned NOT NULL default '0',\n\t\t\t\t\tID_MSG int(10) unsigned NOT NULL default '0',\n\t\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t\t)\n\t\t\t\tSELECT t.ID_TOPIC, t.ID_BOARD, t.ID_LAST_MSG, IFNULL(lmr.ID_MSG, 0) AS ID_MSG" . (!in_array($_REQUEST['sort'], array('t.ID_LAST_MSG', 't.ID_TOPIC')) ? ", {$_REQUEST['sort']} AS sortKey" : '') . "\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})" . (isset($sortKey_joins[$_REQUEST['sort']]) ? $sortKey_joins[$_REQUEST['sort']] : '') . "\n\t\t\t\tWHERE m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND t.ID_TOPIC = m.ID_TOPIC" . (!empty($board) ? "\n\t\t\t\t\tAND t.ID_BOARD = {$board}" : '') . "\n\t\t\t\tGROUP BY m.ID_TOPIC", false, false) !== false; // If that worked, create a sample of the log_topics table too. if ($have_temp_table) { $have_temp_table = db_query("\n\t\t\t\t\tCREATE TEMPORARY TABLE {$db_prefix}log_topics_posted_in (\n\t\t\t\t\t\tPRIMARY KEY (ID_TOPIC)\n\t\t\t\t\t)\n\t\t\t\t\tSELECT lt.ID_TOPIC, lt.ID_MSG\n\t\t\t\t\tFROM ({$db_prefix}log_topics AS lt, {$db_prefix}topics_posted_in AS pi)\n\t\t\t\t\tWHERE lt.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\t\tAND lt.ID_TOPIC = pi.ID_TOPIC", false, false) !== false; } } if ($have_temp_table) { $request = db_query("\n\t\t\t\tSELECT COUNT(*)\n\t\t\t\tFROM ({$db_prefix}topics_posted_in AS pi)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics_posted_in AS lt ON (lt.ID_TOPIC = pi.ID_TOPIC)\n\t\t\t\tWHERE pi.{$query_this_board}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, pi.ID_MSG) < pi.ID_LAST_MSG", __FILE__, __LINE__); list($num_topics) = mysql_fetch_row($request); mysql_free_result($request); } else { $request = db_query("\n\t\t\t\tSELECT COUNT(DISTINCT t.ID_TOPIC), MIN(t.ID_LAST_MSG)\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m)\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE t.{$query_this_board}\n\t\t\t\t\tAND m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG", __FILE__, __LINE__); list($num_topics, $min_message) = mysql_fetch_row($request); mysql_free_result($request); } // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $modSettings['defaultMaxTopics'], true); $context['current_page'] = (int) $_REQUEST['start'] / $modSettings['defaultMaxTopics']; $context['links'] = array('first' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $modSettings['defaultMaxTopics'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $modSettings['defaultMaxTopics'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) * $modSettings['defaultMaxTopics']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $modSettings['defaultMaxTopics'] + 1, 'num_pages' => floor(($num_topics - 1) / $modSettings['defaultMaxTopics']) + 1); if ($num_topics == 0) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } if ($have_temp_table) { $request = db_query("\n\t\t\t\tSELECT t.ID_TOPIC\n\t\t\t\tFROM {$db_prefix}topics_posted_in AS t\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics_posted_in AS lt ON (lt.ID_TOPIC = t.ID_TOPIC)\n\t\t\t\tWHERE t.{$query_this_board}\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, t.ID_MSG) < t.ID_LAST_MSG\n\t\t\t\tORDER BY " . (in_array($_REQUEST['sort'], array('t.ID_LAST_MSG', 't.ID_TOPIC')) ? $_REQUEST['sort'] : 't.sortKey') . ($ascending ? '' : ' DESC') . "\n\t\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__); } else { $request = db_query("\n\t\t\t\tSELECT DISTINCT t.ID_TOPIC\n\t\t\t\tFROM ({$db_prefix}topics AS t, {$db_prefix}messages AS m" . (strpos($_REQUEST['sort'], 'ms.') === false ? '' : ", {$db_prefix}messages AS ms") . ')' . (strpos($_REQUEST['sort'], 'mems.') === false ? '' : "\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)") . "\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tWHERE m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND m.ID_MEMBER = {$ID_MEMBER}\n\t\t\t\t\tAND t.{$query_this_board}\n\t\t\t\t\tAND t.ID_LAST_MSG >= " . (int) $min_message . "\n\t\t\t\t\tAND IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) < t.ID_LAST_MSG" . (strpos($_REQUEST['sort'], 'ms.') !== false ? "\n\t\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG" : '') . "\n\t\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\t\tLIMIT {$_REQUEST['start']}, {$modSettings['defaultMaxTopics']}", __FILE__, __LINE__); } $topics = array(); while ($row = mysql_fetch_assoc($request)) { $topics[] = $row['ID_TOPIC']; } mysql_free_result($request); // Sanity... where have you gone? if (empty($topics)) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } $request = db_query("\n\t\t\tSELECT {$select_clause}\n\t\t\tFROM ({$db_prefix}messages AS ms, {$db_prefix}messages AS ml, {$db_prefix}topics AS t, {$db_prefix}boards AS b)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mems ON (mems.ID_MEMBER = ms.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}members AS meml ON (meml.ID_MEMBER = ml.ID_MEMBER)\n\t\t\t\tLEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tLEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = t.ID_BOARD AND lmr.ID_MEMBER = {$ID_MEMBER})\n\t\t\tWHERE t.ID_TOPIC IN (" . implode(', ', $topics) . ")\n\t\t\t\tAND t.ID_TOPIC = ms.ID_TOPIC\n\t\t\t\tAND b.ID_BOARD = t.ID_BOARD\n\t\t\t\tAND ms.ID_MSG = t.ID_FIRST_MSG\n\t\t\t\tAND ml.ID_MSG = t.ID_LAST_MSG\n\t\t\tORDER BY " . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . "\n\t\t\tLIMIT " . count($topics), __FILE__, __LINE__); } $context['topics'] = array(); $topic_ids = array(); while ($row = mysql_fetch_assoc($request)) { if ($row['ID_POLL'] > 0 && $modSettings['pollMode'] == '0') { continue; } $topic_ids[] = $row['ID_TOPIC']; // Clip the strings first because censoring is slow :/. (for some reason?) $row['firstBody'] = strip_tags(strtr(parse_bbc($row['firstBody'], $row['firstSmileys'], $row['ID_FIRST_MSG']), array('<br />' => ' '))); if ($func['strlen']($row['firstBody']) > 128) { $row['firstBody'] = $func['substr']($row['firstBody'], 0, 128) . '...'; } $row['lastBody'] = strip_tags(strtr(parse_bbc($row['lastBody'], $row['lastSmileys'], $row['ID_LAST_MSG']), array('<br />' => ' '))); if ($func['strlen']($row['lastBody']) > 128) { $row['lastBody'] = $func['substr']($row['lastBody'], 0, 128) . '...'; } // Do a bit of censoring... censorText($row['firstSubject']); censorText($row['firstBody']); // But don't do it twice, it can be a slow ordeal! if ($row['ID_FIRST_MSG'] == $row['ID_LAST_MSG']) { $row['lastSubject'] = $row['firstSubject']; $row['lastBody'] = $row['firstBody']; } else { censorText($row['lastSubject']); censorText($row['lastBody']); } // Decide how many pages the topic should have. $topic_length = $row['numReplies'] + 1; if ($topic_length > $modSettings['defaultMaxMessages']) { $tmppages = array(); $tmpa = 1; for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $modSettings['defaultMaxMessages']) { $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.' . $tmpb . ';topicseen">' . $tmpa . '</a>'; $tmpa++; } // Show links to all the pages? if (count($tmppages) <= 5) { $pages = '« ' . implode(' ', $tmppages); } else { $pages = '« ' . $tmppages[0] . ' ' . $tmppages[1] . ' ... ' . $tmppages[count($tmppages) - 2] . ' ' . $tmppages[count($tmppages) - 1]; } if (!empty($modSettings['enableAllMessages']) && $topic_length < $modSettings['enableAllMessages']) { $pages .= ' <a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;all">' . $txt[190] . '</a>'; } $pages .= ' »'; } else { $pages = ''; } // We need to check the topic icons exist... you can never be too sure! if (empty($modSettings['messageIconChecks_disable'])) { // First icon first... as you'd expect. if (!isset($context['icon_sources'][$row['firstIcon']])) { $context['icon_sources'][$row['firstIcon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['firstIcon'] . '.gif') ? 'images_url' : 'default_images_url'; } // Last icon... last... duh. if (!isset($context['icon_sources'][$row['lastIcon']])) { $context['icon_sources'][$row['lastIcon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['lastIcon'] . '.gif') ? 'images_url' : 'default_images_url'; } } // And build the array. $context['topics'][$row['ID_TOPIC']] = array('id' => $row['ID_TOPIC'], 'first_post' => array('id' => $row['ID_FIRST_MSG'], 'member' => array('name' => $row['firstPosterName'], 'id' => $row['ID_FIRST_MEMBER'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'], 'link' => !empty($row['ID_FIRST_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_FIRST_MEMBER'] . '" title="' . $txt[92] . ' ' . $row['firstPosterName'] . '">' . $row['firstPosterName'] . '</a>' : $row['firstPosterName']), 'time' => timeformat($row['firstPosterTime']), 'timestamp' => forum_time(true, $row['firstPosterTime']), 'subject' => $row['firstSubject'], 'preview' => $row['firstBody'], 'icon' => $row['firstIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['firstIcon']]] . '/post/' . $row['firstIcon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;topicseen', 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.0;topicseen">' . $row['firstSubject'] . '</a>'), 'last_post' => array('id' => $row['ID_LAST_MSG'], 'member' => array('name' => $row['lastPosterName'], 'id' => $row['ID_LAST_MEMBER'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_LAST_MEMBER'], 'link' => !empty($row['ID_LAST_MEMBER']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_LAST_MEMBER'] . '">' . $row['lastPosterName'] . '</a>' : $row['lastPosterName']), 'time' => timeformat($row['lastPosterTime']), 'timestamp' => forum_time(true, $row['lastPosterTime']), 'subject' => $row['lastSubject'], 'preview' => $row['lastBody'], 'icon' => $row['lastIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['lastIcon']]] . '/post/' . $row['lastIcon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['ID_LAST_MSG']) . ';topicseen#msg' . $row['ID_LAST_MSG'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['ID_LAST_MSG']) . ';topicseen#msg' . $row['ID_LAST_MSG'] . '">' . $row['lastSubject'] . '</a>'), 'new_from' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['new_from'] . ';topicseen#new', 'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen' . ($row['numReplies'] == 0 ? '' : 'new'), 'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . ($row['numReplies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen#msg' . $row['new_from'] . '">' . $row['firstSubject'] . '</a>', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['isSticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['ID_POLL'] > 0, 'is_hot' => $row['numReplies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['numReplies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'icon' => $row['firstIcon'], 'icon_url' => $settings[$context['icon_sources'][$row['firstIcon']]] . '/post/' . $row['firstIcon'] . '.gif', 'subject' => $row['firstSubject'], 'pages' => $pages, 'replies' => $row['numReplies'], 'views' => $row['numViews'], 'board' => array('id' => $row['ID_BOARD'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bname'] . '</a>')); determineTopicClass($context['topics'][$row['ID_TOPIC']]); } mysql_free_result($request); if ($is_topics && !empty($modSettings['enableParticipation']) && !empty($topic_ids)) { $result = db_query("\n\t\t\tSELECT ID_TOPIC\n\t\t\tFROM {$db_prefix}messages\n\t\t\tWHERE ID_TOPIC IN (" . implode(', ', $topic_ids) . ")\n\t\t\t\tAND ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { if (empty($context['topics'][$row['ID_TOPIC']]['is_posted_in'])) { $context['topics'][$row['ID_TOPIC']]['is_posted_in'] = true; $context['topics'][$row['ID_TOPIC']]['class'] = 'my_' . $context['topics'][$row['ID_TOPIC']]['class']; } } mysql_free_result($result); } $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); $context['topics_to_mark'] = implode('-', $topic_ids); }
function BuddyListToggle() { global $user_info; checkSession('get'); isAllowedTo('profile_identity_own'); is_not_guest(); if (empty($_REQUEST['u'])) { fatal_lang_error('no_access', false); } $_REQUEST['u'] = (int) $_REQUEST['u']; // Remove if it's already there... if (in_array($_REQUEST['u'], $user_info['buddies'])) { $user_info['buddies'] = array_diff($user_info['buddies'], array($_REQUEST['u'])); } elseif ($user_info['id'] != $_REQUEST['u']) { $user_info['buddies'][] = (int) $_REQUEST['u']; } // Update the settings. updateMemberData($user_info['id'], array('buddy_list' => implode(',', $user_info['buddies']))); // Redirect back to the profile redirectexit('action=profile;u=' . $_REQUEST['u']); }
function Post() { global $txt, $scripturl, $topic, $modSettings, $board; global $user_info, $sc, $board_info, $context, $settings; global $sourcedir, $options, $smcFunc, $language; loadLanguage('Post'); // You can't reply with a poll... hacker. if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) { unset($_REQUEST['poll']); } // Posting an event? $context['make_event'] = isset($_REQUEST['calendar']); $context['robot_no_index'] = true; // You must be posting to *some* board. if (empty($board) && !$context['make_event']) { fatal_lang_error('no_board', false); } require_once $sourcedir . '/Subs-Post.php'; if (isset($_REQUEST['xml'])) { $context['sub_template'] = 'post'; // Just in case of an earlier error... $context['preview_message'] = ''; $context['preview_subject'] = ''; } // No message is complete without a topic. if (empty($topic) && !empty($_REQUEST['msg'])) { $request = $smcFunc['db_query']('', ' SELECT id_topic FROM {db_prefix}messages WHERE id_msg = {int:msg}', array('msg' => (int) $_REQUEST['msg'])); if ($smcFunc['db_num_rows']($request) != 1) { unset($_REQUEST['msg'], $_POST['msg'], $_GET['msg']); } else { list($topic) = $smcFunc['db_fetch_row']($request); } $smcFunc['db_free_result']($request); } // Check if it's locked. It isn't locked if no topic is specified. if (!empty($topic)) { $request = $smcFunc['db_query']('', ' SELECT t.locked, IFNULL(ln.id_topic, 0) AS notify, t.is_sticky, t.id_poll, t.id_last_msg, mf.id_member, t.id_first_msg, mf.subject, CASE WHEN ml.poster_time > ml.modified_time THEN ml.poster_time ELSE ml.modified_time END AS last_post_time FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}log_notify AS ln ON (ln.id_topic = t.id_topic AND ln.id_member = {int:current_member}) LEFT JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) WHERE t.id_topic = {int:current_topic} LIMIT 1', array('current_member' => $user_info['id'], 'current_topic' => $topic)); list($locked, $context['notify'], $sticky, $pollID, $context['topic_last_message'], $id_member_poster, $id_first_msg, $first_subject, $lastPostTime) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // If this topic already has a poll, they sure can't add another. if (isset($_REQUEST['poll']) && $pollID > 0) { unset($_REQUEST['poll']); } if (empty($_REQUEST['msg'])) { if ($user_info['is_guest'] && !allowedTo('post_reply_any') && (!$modSettings['postmod_active'] || !allowedTo('post_unapproved_replies_any'))) { is_not_guest(); } // By default the reply will be approved... $context['becomes_approved'] = true; if ($id_member_poster != $user_info['id']) { if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_any') && !allowedTo('post_reply_any')) { $context['becomes_approved'] = false; } else { isAllowedTo('post_reply_any'); } } elseif (!allowedTo('post_reply_any')) { if ($modSettings['postmod_active'] && allowedTo('post_unapproved_replies_own') && !allowedTo('post_reply_own')) { $context['becomes_approved'] = false; } else { isAllowedTo('post_reply_own'); } } } else { $context['becomes_approved'] = true; } $context['can_lock'] = allowedTo('lock_any') || $user_info['id'] == $id_member_poster && allowedTo('lock_own'); $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']); $context['notify'] = !empty($context['notify']); $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky; } else { $context['becomes_approved'] = true; if (!$context['make_event'] || !empty($board)) { if ($modSettings['postmod_active'] && !allowedTo('post_new') && allowedTo('post_unapproved_topics')) { $context['becomes_approved'] = false; } else { isAllowedTo('post_new'); } } $locked = 0; // !!! These won't work if you're making an event. $context['can_lock'] = allowedTo(array('lock_any', 'lock_own')); $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']); $context['notify'] = !empty($context['notify']); $context['sticky'] = !empty($_REQUEST['sticky']); } // !!! These won't work if you're posting an event! $context['can_notify'] = allowedTo('mark_any_notify'); $context['can_move'] = allowedTo('move_any'); $context['move'] = !empty($_REQUEST['move']); $context['announce'] = !empty($_REQUEST['announce']); // You can only announce topics that will get approved... $context['can_announce'] = allowedTo('announce_topic') && $context['becomes_approved']; $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']); $context['can_quote'] = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); // Generally don't show the approval box... (Assume we want things approved) $context['show_approval'] = false; // An array to hold all the attachments for this topic. $context['current_attachments'] = array(); // Don't allow a post if it's locked and you aren't all powerful. if ($locked && !allowedTo('moderate_board')) { fatal_lang_error('topic_locked', false); } // Check the users permissions - is the user allowed to add or post a poll? if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') { // New topic, new poll. if (empty($topic)) { isAllowedTo('poll_post'); } elseif ($user_info['id'] == $id_member_poster && !allowedTo('poll_add_any')) { isAllowedTo('poll_add_own'); } else { isAllowedTo('poll_add_any'); } require_once $sourcedir . '/Subs-Members.php'; $allowedVoteGroups = groupsAllowedTo('poll_vote', $board); // Set up the poll options. $context['poll_options'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expire' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote']), 'guest_vote' => isset($_POST['poll_guest_vote']), 'guest_vote_enabled' => in_array(-1, $allowedVoteGroups['allowed'])); // Make all five poll choices empty. $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true)); } if ($context['make_event']) { // They might want to pick a board. if (!isset($context['current_board'])) { $context['current_board'] = 0; } // Start loading up the event info. $context['event'] = array(); $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : ''; $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1; $context['event']['new'] = $context['event']['id'] == -1; // Permissions check! isAllowedTo('calendar_post'); // Editing an event? (but NOT previewing!?) if (!$context['event']['new'] && !isset($_REQUEST['subject'])) { // If the user doesn't have permission to edit the post in this topic, redirect them. if ((empty($id_member_poster) || $id_member_poster != $user_info['id'] || !allowedTo('modify_own')) && !allowedTo('modify_any')) { require_once $sourcedir . '/Calendar.php'; return CalendarPost(); } // Get the current event information. $request = $smcFunc['db_query']('', ' SELECT id_member, title, MONTH(start_date) AS month, DAYOFMONTH(start_date) AS day, YEAR(start_date) AS year, (TO_DAYS(end_date) - TO_DAYS(start_date)) AS span FROM {db_prefix}calendar WHERE id_event = {int:id_event} LIMIT 1', array('id_event' => $context['event']['id'])); $row = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // Make sure the user is allowed to edit this event. if ($row['id_member'] != $user_info['id']) { isAllowedTo('calendar_edit_any'); } elseif (!allowedTo('calendar_edit_any')) { isAllowedTo('calendar_edit_own'); } $context['event']['month'] = $row['month']; $context['event']['day'] = $row['day']; $context['event']['year'] = $row['year']; $context['event']['title'] = $row['title']; $context['event']['span'] = $row['span'] + 1; } else { $today = getdate(); // You must have a month and year specified! if (!isset($_REQUEST['month'])) { $_REQUEST['month'] = $today['mon']; } if (!isset($_REQUEST['year'])) { $_REQUEST['year'] = $today['year']; } $context['event']['month'] = (int) $_REQUEST['month']; $context['event']['year'] = (int) $_REQUEST['year']; $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0); $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1; // Make sure the year and month are in the valid range. if ($context['event']['month'] < 1 || $context['event']['month'] > 12) { fatal_lang_error('invalid_month', false); } if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) { fatal_lang_error('invalid_year', false); } // Get a list of boards they can post in. $boards = boardsAllowedTo('post_new'); if (empty($boards)) { fatal_lang_error('cannot_post_new', 'user'); } // Load a list of boards for this event in the context. require_once $sourcedir . '/Subs-MessageIndex.php'; $boardListOptions = array('included_boards' => in_array(0, $boards) ? null : $boards, 'not_redirection' => true, 'use_permissions' => true, 'selected_board' => empty($context['current_board']) ? $modSettings['cal_defaultboard'] : $context['current_board']); $context['event']['categories'] = getBoardList($boardListOptions); } // Find the last day of the month. $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year'])); $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard']; } if (empty($context['post_errors'])) { $context['post_errors'] = array(); } // See if any new replies have come along. if (empty($_REQUEST['msg']) && !empty($topic)) { if (empty($options['no_new_reply_warning']) && isset($_REQUEST['last_msg']) && $context['topic_last_message'] > $_REQUEST['last_msg']) { $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}messages WHERE id_topic = {int:current_topic} AND id_msg > {int:last_msg}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' AND approved = {int:approved}') . ' LIMIT 1', array('current_topic' => $topic, 'last_msg' => (int) $_REQUEST['last_msg'], 'approved' => 1)); list($context['new_replies']) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); if (!empty($context['new_replies'])) { if ($context['new_replies'] == 1) { $txt['error_new_reply'] = isset($_GET['last_msg']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply']; } else { $txt['error_new_replies'] = sprintf(isset($_GET['last_msg']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $context['new_replies']); } // If they've come from the display page then we treat the error differently.... if (isset($_GET['last_msg'])) { $newRepliesError = $context['new_replies']; } else { $context['post_error'][$context['new_replies'] == 1 ? 'new_reply' : 'new_replies'] = true; } $modSettings['topicSummaryPosts'] = $context['new_replies'] > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts']; } } // Check whether this is a really old post being bumped... if (!empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) { $oldTopicError = true; } } // Get a response prefix (like 'Re:') in the default forum language. if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) { if ($language === $user_info['language']) { $context['response_prefix'] = $txt['response_prefix']; } else { loadLanguage('index', $language, false); $context['response_prefix'] = $txt['response_prefix']; loadLanguage('index'); } cache_put_data('response_prefix', $context['response_prefix'], 600); } // Previewing, modifying, or posting? if (isset($_REQUEST['message']) || !empty($context['post_error'])) { // Validate inputs. if (empty($context['post_error'])) { if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['subject'])) == '') { $context['post_error']['no_subject'] = true; } if (htmltrim__recursive(htmlspecialchars__recursive($_REQUEST['message'])) == '') { $context['post_error']['no_message'] = true; } if (!empty($modSettings['max_messageLength']) && $smcFunc['strlen']($_REQUEST['message']) > $modSettings['max_messageLength']) { $context['post_error']['long_message'] = true; } // Are you... a guest? if ($user_info['is_guest']) { $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']); $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']); // Validate the name and email. if (!isset($_REQUEST['guestname']) || trim(strtr($_REQUEST['guestname'], '_', ' ')) == '') { $context['post_error']['no_name'] = true; } elseif ($smcFunc['strlen']($_REQUEST['guestname']) > 25) { $context['post_error']['long_name'] = true; } else { require_once $sourcedir . '/Subs-Members.php'; if (isReservedName(htmlspecialchars($_REQUEST['guestname']), 0, true, false)) { $context['post_error']['bad_name'] = true; } } if (empty($modSettings['guest_post_no_email'])) { if (!isset($_REQUEST['email']) || $_REQUEST['email'] == '') { $context['post_error']['no_email'] = true; } elseif (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_REQUEST['email']) == 0) { $context['post_error']['bad_email'] = true; } } } // This is self explanatory - got any questions? if (isset($_REQUEST['question']) && trim($_REQUEST['question']) == '') { $context['post_error']['no_question'] = true; } // This means they didn't click Post and get an error. $really_previewing = true; } else { if (!isset($_REQUEST['subject'])) { $_REQUEST['subject'] = ''; } if (!isset($_REQUEST['message'])) { $_REQUEST['message'] = ''; } if (!isset($_REQUEST['icon'])) { $_REQUEST['icon'] = 'xx'; } // They are previewing if they asked to preview (i.e. came from quick reply). $really_previewing = !empty($_POST['preview']); } // In order to keep the approval status flowing through, we have to pass it through the form... $context['becomes_approved'] = empty($_REQUEST['not_approved']); $context['show_approval'] = isset($_REQUEST['approve']) ? $_REQUEST['approve'] ? 2 : 1 : 0; $context['can_announce'] &= $context['becomes_approved']; // Set up the inputs for the form. $form_subject = strtr($smcFunc['htmlspecialchars']($_REQUEST['subject']), array("\r" => '', "\n" => '', "\t" => '')); $form_message = $smcFunc['htmlspecialchars']($_REQUEST['message'], ENT_QUOTES); // Make sure the subject isn't too long - taking into account special characters. if ($smcFunc['strlen']($form_subject) > 100) { $form_subject = $smcFunc['substr']($form_subject, 0, 100); } // Have we inadvertently trimmed off the subject of useful information? if ($smcFunc['htmltrim']($form_subject) === '') { $context['post_error']['no_subject'] = true; } // Any errors occurred? if (!empty($context['post_error'])) { loadLanguage('Errors'); $context['error_type'] = 'minor'; $context['post_error']['messages'] = array(); foreach ($context['post_error'] as $post_error => $dummy) { if ($post_error == 'messages') { continue; } if ($post_error == 'long_message') { $txt['error_' . $post_error] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']); } $context['post_error']['messages'][] = $txt['error_' . $post_error]; // If it's not a minor error flag it as such. if (!in_array($post_error, array('new_reply', 'not_approved', 'new_replies', 'old_topic', 'need_qr_verification'))) { $context['error_type'] = 'serious'; } } } if (isset($_REQUEST['poll'])) { $context['question'] = isset($_REQUEST['question']) ? $smcFunc['htmlspecialchars'](trim($_REQUEST['question'])) : ''; $context['choices'] = array(); $choice_id = 0; $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive($_POST['options']); foreach ($_POST['options'] as $option) { if (trim($option) == '') { continue; } $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false); } if (count($context['choices']) < 2) { $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false); $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false); } $context['choices'][count($context['choices']) - 1]['is_last'] = true; } // Are you... a guest? if ($user_info['is_guest']) { $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']); $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']); $_REQUEST['guestname'] = htmlspecialchars($_REQUEST['guestname']); $context['name'] = $_REQUEST['guestname']; $_REQUEST['email'] = htmlspecialchars($_REQUEST['email']); $context['email'] = $_REQUEST['email']; $user_info['name'] = $_REQUEST['guestname']; } // Only show the preview stuff if they hit Preview. if ($really_previewing == true || isset($_REQUEST['xml'])) { // Set up the preview message and subject and censor them... $context['preview_message'] = $form_message; preparsecode($form_message, true); preparsecode($context['preview_message']); // Do all bulletin board code tags, with or without smileys. $context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1); if ($form_subject != '') { $context['preview_subject'] = $form_subject; censorText($context['preview_subject']); censorText($context['preview_message']); } else { $context['preview_subject'] = '<em>' . $txt['no_subject'] . '</em>'; } // Protect any CDATA blocks. if (isset($_REQUEST['xml'])) { $context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>')); } } // Set up the checkboxes. $context['notify'] = !empty($_REQUEST['notify']); $context['use_smileys'] = !isset($_REQUEST['ns']); $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx'; // Set the destination action for submission. $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : '') . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = isset($_REQUEST['msg']) ? $txt['save'] : $txt['post']; // Previewing an edit? if (isset($_REQUEST['msg']) && !empty($topic)) { // Get the existing message. $request = $smcFunc['db_query']('', ' SELECT m.id_member, m.modified_time, m.smileys_enabled, m.body, m.poster_name, m.poster_email, m.subject, m.icon, m.approved, IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach, a.approved AS attachment_approved, t.id_member_started AS id_member_poster, m.poster_time FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic}) LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type}) WHERE m.id_msg = {int:id_msg} AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg'])); // The message they were trying to edit was most likely deleted. // !!! Change this error message? if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('no_board', false); } $row = $smcFunc['db_fetch_assoc']($request); $attachment_stuff = array($row); while ($row2 = $smcFunc['db_fetch_assoc']($request)) { $attachment_stuff[] = $row2; } $smcFunc['db_free_result']($request); if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) { // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public. if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_own'); } } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_any'); } if (!empty($modSettings['attachmentEnable'])) { $request = $smcFunc['db_query']('', ' SELECT IFNULL(size, -1) AS filesize, filename, id_attach, approved FROM {db_prefix}attachments WHERE id_msg = {int:id_msg} AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['filesize'] <= 0) { continue; } $context['current_attachments'][] = array('name' => htmlspecialchars($row['filename']), 'id' => $row['id_attach'], 'approved' => $row['approved']); } $smcFunc['db_free_result']($request); } // Allow moderators to change names.... if (allowedTo('moderate_forum') && !empty($topic)) { $request = $smcFunc['db_query']('', ' SELECT id_member, poster_name, poster_email FROM {db_prefix}messages WHERE id_msg = {int:id_msg} AND id_topic = {int:current_topic} LIMIT 1', array('current_topic' => $topic, 'id_msg' => (int) $_REQUEST['msg'])); $row = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); if (empty($row['id_member'])) { $context['name'] = htmlspecialchars($row['poster_name']); $context['email'] = htmlspecialchars($row['poster_email']); } } } // No check is needed, since nothing is really posted. checkSubmitOnce('free'); } elseif (isset($_REQUEST['msg']) && !empty($topic)) { $_REQUEST['msg'] = (int) $_REQUEST['msg']; // Get the existing message. $request = $smcFunc['db_query']('', ' SELECT m.id_member, m.modified_time, m.smileys_enabled, m.body, m.poster_name, m.poster_email, m.subject, m.icon, m.approved, IFNULL(a.size, -1) AS filesize, a.filename, a.id_attach, a.approved AS attachment_approved, t.id_member_started AS id_member_poster, m.poster_time FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic}) LEFT JOIN {db_prefix}attachments AS a ON (a.id_msg = m.id_msg AND a.attachment_type = {int:attachment_type}) WHERE m.id_msg = {int:id_msg} AND m.id_topic = {int:current_topic}', array('current_topic' => $topic, 'attachment_type' => 0, 'id_msg' => $_REQUEST['msg'])); // The message they were trying to edit was most likely deleted. // !!! Change this error message? if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('no_board', false); } $row = $smcFunc['db_fetch_assoc']($request); $attachment_stuff = array($row); while ($row2 = $smcFunc['db_fetch_assoc']($request)) { $attachment_stuff[] = $row2; } $smcFunc['db_free_result']($request); if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) { // Give an extra five minutes over the disable time threshold, so they can type - assuming the post is public. if ($row['approved'] && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_own')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_own'); } } elseif ($row['id_member_poster'] == $user_info['id'] && !allowedTo('modify_any')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_any'); } // When was it last modified? if (!empty($row['modified_time'])) { $context['last_modified'] = timeformat($row['modified_time']); } // Get the stuff ready for the form. $form_subject = $row['subject']; $form_message = un_preparsecode($row['body']); censorText($form_message); censorText($form_subject); // Check the boxes that should be checked. $context['use_smileys'] = !empty($row['smileys_enabled']); $context['icon'] = $row['icon']; // Show an "approve" box if the user can approve it, and the message isn't approved. if (!$row['approved'] && !$context['show_approval']) { $context['show_approval'] = allowedTo('approve_posts'); } // Load up 'em attachments! foreach ($attachment_stuff as $attachment) { if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) { $context['current_attachments'][] = array('name' => htmlspecialchars($attachment['filename']), 'id' => $attachment['id_attach'], 'approved' => $attachment['attachment_approved']); } } // Allow moderators to change names.... if (allowedTo('moderate_forum') && empty($row['id_member'])) { $context['name'] = htmlspecialchars($row['poster_name']); $context['email'] = htmlspecialchars($row['poster_email']); } // Set the destinaton. $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = $txt['save']; } else { // By default.... $context['use_smileys'] = true; $context['icon'] = 'xx'; if ($user_info['is_guest']) { $context['name'] = isset($_SESSION['guest_name']) ? $_SESSION['guest_name'] : ''; $context['email'] = isset($_SESSION['guest_email']) ? $_SESSION['guest_email'] : ''; } $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = $txt['post']; // Posting a quoted reply? if (!empty($topic) && !empty($_REQUEST['quote'])) { // Make sure they _can_ quote this post, and if so get it. $request = $smcFunc['db_query']('', ' SELECT m.subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, m.body FROM {db_prefix}messages AS m 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}' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : ' AND m.approved = {int:is_approved}') . ' LIMIT 1', array('id_msg' => (int) $_REQUEST['quote'], 'is_approved' => 1)); if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('quoted_post_deleted', false); } list($form_subject, $mname, $mdate, $form_message) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Add 'Re: ' to the front of the quoted subject. if (trim($context['response_prefix']) != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) { $form_subject = $context['response_prefix'] . $form_subject; } // Censor the message and subject. censorText($form_message); censorText($form_subject); // But if it's in HTML world, turn them into htmlspecialchar's so they can be edited! if (strpos($form_message, '[html]') !== false) { $parts = preg_split('~(\\[/code\\]|\\[code(?:=[^\\]]+)?\\])~i', $form_message, -1, PREG_SPLIT_DELIM_CAPTURE); for ($i = 0, $n = count($parts); $i < $n; $i++) { // It goes 0 = outside, 1 = begin tag, 2 = inside, 3 = close tag, repeat. if ($i % 4 == 0) { $parts[$i] = preg_replace('~\\[html\\](.+?)\\[/html\\]~ise', '\'[html]\' . preg_replace(\'~<br\\s?/?' . '>~i\', \'<br /><br />\', \'$1\') . \'[/html]\'', $parts[$i]); } } $form_message = implode('', $parts); } $form_message = preg_replace('~<br ?/?' . '>~i', "\n", $form_message); // Remove any nested quotes, if necessary. if (!empty($modSettings['removeNestedQuotes'])) { $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message); } // Add a quote string on the front and end. $form_message = '[quote author=' . $mname . ' link=topic=' . $topic . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $mdate . ']' . "\n" . rtrim($form_message) . "\n" . '[/quote]'; } elseif (!empty($topic) && empty($_REQUEST['quote'])) { // Get the first message's subject. $form_subject = $first_subject; // Add 'Re: ' to the front of the subject. if (trim($context['response_prefix']) != '' && $form_subject != '' && $smcFunc['strpos']($form_subject, trim($context['response_prefix'])) !== 0) { $form_subject = $context['response_prefix'] . $form_subject; } // Censor the subject. censorText($form_subject); $form_message = ''; } else { $form_subject = isset($_GET['subject']) ? $_GET['subject'] : ''; $form_message = ''; } } // !!! This won't work if you're posting an event. if (allowedTo('post_attachment') || allowedTo('post_unapproved_attachments')) { if (empty($_SESSION['temp_attachments'])) { $_SESSION['temp_attachments'] = array(); } if (!empty($modSettings['currentAttachmentUploadDir'])) { if (!is_array($modSettings['attachmentUploadDir'])) { $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']); } // Just use the current path for temp files. $current_attach_dir = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; } else { $current_attach_dir = $modSettings['attachmentUploadDir']; } // If this isn't a new post, check the current attachments. if (isset($_REQUEST['msg'])) { $request = $smcFunc['db_query']('', ' SELECT COUNT(*), SUM(size) FROM {db_prefix}attachments WHERE id_msg = {int:id_msg} AND attachment_type = {int:attachment_type}', array('id_msg' => (int) $_REQUEST['msg'], 'attachment_type' => 0)); list($quantity, $total_size) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); } else { $quantity = 0; $total_size = 0; } $temp_start = 0; if (!empty($_SESSION['temp_attachments'])) { if ($context['current_action'] != 'post2' || !empty($_POST['from_qr'])) { $context['post_error']['messages'][] = $txt['error_temp_attachments']; $context['error_type'] = 'minor'; } foreach ($_SESSION['temp_attachments'] as $attachID => $name) { $temp_start++; if (preg_match('~^post_tmp_' . $user_info['id'] . '_\\d+$~', $attachID) == 0) { unset($_SESSION['temp_attachments'][$attachID]); continue; } if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) { $deleted_attachments = true; unset($_SESSION['temp_attachments'][$attachID]); @unlink($current_attach_dir . '/' . $attachID); continue; } $quantity++; $total_size += filesize($current_attach_dir . '/' . $attachID); $context['current_attachments'][] = array('name' => htmlspecialchars($name), 'id' => $attachID, 'approved' => 1); } } if (!empty($_POST['attach_del'])) { $del_temp = array(); foreach ($_POST['attach_del'] as $i => $dummy) { $del_temp[$i] = (int) $dummy; } foreach ($context['current_attachments'] as $k => $dummy) { if (!in_array($dummy['id'], $del_temp)) { $context['current_attachments'][$k]['unchecked'] = true; $deleted_attachments = !isset($deleted_attachments) || is_bool($deleted_attachments) ? 1 : $deleted_attachments + 1; $quantity--; } } } if (!empty($_FILES['attachment'])) { foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) { if ($_FILES['attachment']['name'][$n] == '') { continue; } if (!is_uploaded_file($_FILES['attachment']['tmp_name'][$n]) || @ini_get('open_basedir') == '' && !file_exists($_FILES['attachment']['tmp_name'][$n])) { fatal_lang_error('attach_timeout', 'critical'); } if (!empty($modSettings['attachmentSizeLimit']) && $_FILES['attachment']['size'][$n] > $modSettings['attachmentSizeLimit'] * 1024) { fatal_lang_error('file_too_big', false, array($modSettings['attachmentSizeLimit'])); } $quantity++; if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) { fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit'])); } $total_size += $_FILES['attachment']['size'][$n]; if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) { fatal_lang_error('file_too_big', false, array($modSettings['attachmentPostLimit'])); } if (!empty($modSettings['attachmentCheckExtensions'])) { if (!in_array(strtolower(substr(strrchr($_FILES['attachment']['name'][$n], '.'), 1)), explode(',', strtolower($modSettings['attachmentExtensions'])))) { fatal_error($_FILES['attachment']['name'][$n] . '.<br />' . $txt['cant_upload_type'] . ' ' . $modSettings['attachmentExtensions'] . '.', false); } } if (!empty($modSettings['attachmentDirSizeLimit'])) { // Make sure the directory isn't full. $dirSize = 0; $dir = @opendir($current_attach_dir) or fatal_lang_error('cant_access_upload_path', 'critical'); while ($file = readdir($dir)) { if ($file == '.' || $file == '..') { continue; } if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) { // Temp file is more than 5 hours old! if (filemtime($current_attach_dir . '/' . $file) < time() - 18000) { @unlink($current_attach_dir . '/' . $file); } continue; } $dirSize += filesize($current_attach_dir . '/' . $file); } closedir($dir); // Too big! Maybe you could zip it or something... if ($_FILES['attachment']['size'][$n] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) { fatal_lang_error('ran_out_of_space'); } } if (!is_writable($current_attach_dir)) { fatal_lang_error('attachments_no_write', 'critical'); } $attachID = 'post_tmp_' . $user_info['id'] . '_' . $temp_start++; $_SESSION['temp_attachments'][$attachID] = basename($_FILES['attachment']['name'][$n]); $context['current_attachments'][] = array('name' => htmlspecialchars(basename($_FILES['attachment']['name'][$n])), 'id' => $attachID, 'approved' => 1); $destName = $current_attach_dir . '/' . $attachID; if (!move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) { fatal_lang_error('attach_timeout', 'critical'); } @chmod($destName, 0644); } } } // If we are coming here to make a reply, and someone has already replied... make a special warning message. if (isset($newRepliesError)) { $context['post_error']['messages'][] = $newRepliesError == 1 ? $txt['error_new_reply'] : $txt['error_new_replies']; $context['error_type'] = 'minor'; } if (isset($oldTopicError)) { $context['post_error']['messages'][] = sprintf($txt['error_old_topic'], $modSettings['oldTopicDays']); $context['error_type'] = 'minor'; } // What are you doing? Posting a poll, modifying, previewing, new post, or reply... if (isset($_REQUEST['poll'])) { $context['page_title'] = $txt['new_poll']; } elseif ($context['make_event']) { $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar_post_event'] : $txt['calendar_edit']; } elseif (isset($_REQUEST['msg'])) { $context['page_title'] = $txt['modify_msg']; } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) { $context['page_title'] = $txt['preview'] . ' - ' . strip_tags($context['preview_subject']); } elseif (empty($topic)) { $context['page_title'] = $txt['start_new_topic']; } else { $context['page_title'] = $txt['post_reply']; } // Build the link tree. if (empty($topic)) { $context['linktree'][] = array('name' => '<em>' . $txt['start_new_topic'] . '</em>'); } else { $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav">' . $context['page_title'] . ' ( </strong></span>', 'extra_after' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><strong class="nav"> )</strong></span>'); } // Give wireless a linktree url to the post screen, so that they can switch to full version. if (WIRELESS) { $context['linktree'][count($context['linktree']) - 1]['url'] = $scripturl . '?action=post;' . (!empty($topic) ? 'topic=' . $topic : 'board=' . $board) . '.' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . (int) $_REQUEST['msg'] . ';' . $context['session_var'] . '=' . $context['session_id'] : ''); } // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments. // !!! This won't work if you're posting an event. $context['num_allowed_attachments'] = empty($modSettings['attachmentNumPerPostLimit']) ? 50 : min($modSettings['attachmentNumPerPostLimit'] - count($context['current_attachments']) + (isset($deleted_attachments) ? $deleted_attachments : 0), $modSettings['attachmentNumPerPostLimit']); $context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && (allowedTo('post_attachment') || $modSettings['postmod_active'] && allowedTo('post_unapproved_attachments')) && $context['num_allowed_attachments'] > 0; $context['can_post_attachment_unapproved'] = allowedTo('post_attachment'); $context['subject'] = addcslashes($form_subject, '"'); $context['message'] = str_replace(array('"', '<', '>', ' '), array('"', '<', '>', ' '), $form_message); // Needed for the editor and message icons. require_once $sourcedir . '/Subs-Editor.php'; // Now create the editor. $editorOptions = array('id' => 'message', 'value' => $context['message'], 'labels' => array('post_button' => $context['submit_label']), 'height' => '175px', 'width' => '100%', 'preview_type' => 2); create_control_richedit($editorOptions); // Store the ID. $context['post_box_name'] = $editorOptions['id']; $context['attached'] = ''; $context['make_poll'] = isset($_REQUEST['poll']); // Message icons - customized icons are off? $context['icons'] = getMessageIcons($board); if (!empty($context['icons'])) { $context['icons'][count($context['icons']) - 1]['is_last'] = true; } $context['icon_url'] = ''; for ($i = 0, $n = count($context['icons']); $i < $n; $i++) { $context['icons'][$i]['selected'] = $context['icon'] == $context['icons'][$i]['value']; if ($context['icons'][$i]['selected']) { $context['icon_url'] = $context['icons'][$i]['url']; } } if (empty($context['icon_url'])) { $context['icon_url'] = $settings[file_exists($settings['theme_dir'] . '/images/post/' . $context['icon'] . '.gif') ? 'images_url' : 'default_images_url'] . '/post/' . $context['icon'] . '.gif'; array_unshift($context['icons'], array('value' => $context['icon'], 'name' => $txt['current_icon'], 'url' => $context['icon_url'], 'is_last' => empty($context['icons']), 'selected' => true)); } if (!empty($topic) && !empty($modSettings['topicSummaryPosts'])) { getTopic(); } // If the user can post attachments prepare the warning labels. if ($context['can_post_attachment']) { $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', ')); $context['attachment_restrictions'] = array(); $attachmentRestrictionTypes = array('attachmentNumPerPostLimit', 'attachmentPostLimit', 'attachmentSizeLimit'); foreach ($attachmentRestrictionTypes as $type) { if (!empty($modSettings[$type])) { $context['attachment_restrictions'][] = sprintf($txt['attach_restrict_' . $type], $modSettings[$type]); } } } $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']); $context['show_additional_options'] = !empty($_POST['additional_options']) || !empty($_SESSION['temp_attachments']) || !empty($deleted_attachments); $context['is_new_topic'] = empty($topic); $context['is_new_post'] = !isset($_REQUEST['msg']); $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $id_first_msg; // Do we need to show the visual verification image? $context['require_verification'] = !$user_info['is_mod'] && !$user_info['is_admin'] && !empty($modSettings['posts_require_captcha']) && ($user_info['posts'] < $modSettings['posts_require_captcha'] || $user_info['is_guest'] && $modSettings['posts_require_captcha'] == -1); if ($context['require_verification']) { require_once $sourcedir . '/Subs-Editor.php'; $verificationOptions = array('id' => 'post'); $context['require_verification'] = create_control_verification($verificationOptions); $context['visual_verification_id'] = $verificationOptions['id']; } // If they came from quick reply, and have to enter verification details, give them some notice. if (!empty($_REQUEST['from_qr']) && !empty($context['require_verification'])) { $context['post_error']['messages'][] = $txt['enter_verification_details']; $context['error_type'] = 'minor'; } // WYSIWYG only works if BBC is enabled $modSettings['disable_wysiwyg'] = !empty($modSettings['disable_wysiwyg']) || empty($modSettings['enableBBC']); // Register this form in the session variables. checkSubmitOnce('register'); // Finally, load the template. if (WIRELESS && WIRELESS_PROTOCOL != 'wap') { $context['sub_template'] = WIRELESS_PROTOCOL . '_post'; } elseif (!isset($_REQUEST['xml'])) { loadTemplate('Post'); } }
* * * This program is distributed in the hope that it is and will be useful, but * * WITHOUT ANY WARRANTIES; without even any implied warranty of MERCHANTABILITY * * or FITNESS FOR A PARTICULAR PURPOSE. * * * * See the "license.txt" file for details of the Simple Machines license. * * The latest version can always be found at http://www.simplemachines.org. * **********************************************************************************/ $smfsite = 'http://www.simplemachines.org/smf'; if (!file_exists(dirname(__FILE__) . '/SSI.php')) { die('Please move this file to the main SMF directory and make sure SSI.php is part of that directory.'); } $sphinx_ver = '0.9.9'; require dirname(__FILE__) . '/SSI.php'; // Kick the guests. is_not_guest(); // Kick the non-admin if (!$user_info['is_admin']) { die('You need admin permission to use this tool.'); } if (!isset($_REQUEST['step'])) { step_0(); } else { $cur_step = 'step_' . (int) $_REQUEST['step']; $cur_step(); } function step_0() { global $txt; template_sphinx_config_above('Introduction'); echo '
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 action_get_message() { global $context, $smcFunc, $modSettings, $scripturl, $sourcedir, $user_info, $msg_id, $box_id, $user_profile, $memberContext; require_once 'include/PersonalMessage.php'; // No guests! is_not_guest(); // You're not supposed to be here at all, if you can't even read PMs. isAllowedTo('pm_read'); loadLanguage('PersonalMessage'); $request = $smcFunc['db_query']('', ' SELECT COUNT(*) AS num FROM {db_prefix}pm_recipients pr INNER JOIN {db_prefix}personal_messages AS pm ON (pr.id_pm = pm.id_pm) WHERE pm.id_pm = {int:id_message} and (pr.id_member = {int:id_member} or pm.id_member_from = {int:id_member})', array('id_message' => $msg_id, 'id_member' => $user_info['id'])); $permission = $smcFunc['db_fetch_assoc']($request); if (empty($permission) || $permission['num'] <= 0) { fatal_lang_error('no_access', false); } $request = $smcFunc['db_query']('', ' SELECT pm.id_member_from, pm.msgtime, pm.subject, pm.body, m.member_name, m.real_name FROM {db_prefix}personal_messages AS pm LEFT JOIN {db_prefix}members AS m ON (pm.id_member_from = m.id_member) WHERE pm.id_pm = {int:id_message} ' . ($box_id == 'sent' ? 'AND pm.id_member_from = {int:current_member} AND pm.deleted_by_sender = 0' : ''), array('id_message' => $msg_id, 'current_member' => $user_info['id'])); $pm = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); if (empty($pm)) { fatal_lang_error('no_access', false); } censorText($pm['subject']); censorText($pm['body']); $context['pm'] = array('id_member' => $pm['id_member_from'], 'username' => $pm['member_name'], 'name' => $pm['real_name'], 'time' => timeformat($pm['msgtime']), 'timestamp' => $pm['msgtime'], 'subject' => $pm['subject'], 'body' => mobiquo_parse_bbc($pm['body'], false, 'pm' . $msg_id), 'recipients' => array()); $request = $smcFunc['db_query']('', ' SELECT pmr.id_member, m.member_name, m.real_name FROM {db_prefix}pm_recipients AS pmr LEFT JOIN {db_prefix}members AS m ON (pmr.id_member = m.id_member) WHERE pmr.id_pm = {int:id_message} ' . ($box_id == 'inbox' ? 'AND ((pmr.id_member = {int:current_member} AND pmr.deleted = 0) OR (pmr.id_member != {int:current_member} AND pmr.bcc = 0))' : ''), array('id_message' => $msg_id, 'current_member' => $user_info['id'])); $no_member = true; while ($row = $smcFunc['db_fetch_assoc']($request)) { $context['pm']['recipients'][] = new xmlrpcval(array('user_id' => new xmlrpcval(basic_clean($row['id_member'])), 'username' => new xmlrpcval(basic_clean($row['real_name']), 'base64')), 'struct'); if ($no_member) { $display_member_id = $box_id == 'inbox' ? $pm['id_member_from'] : $row['id_member']; $no_member = false; } } $smcFunc['db_free_result']($request); loadMemberData($display_member_id); loadMemberContext($display_member_id); $context['pm']['member'] = $memberContext[$display_member_id]; if ($no_avatar) { fatal_lang_error('no_access', false); } // Mark this as read, if it is not already markMessages(array($msg_id)); }
function sp_shoutbox($parameters, $id, $return_parameters = false) { global $smcFunc, $context, $sourcedir, $modSettings, $user_info, $settings, $txt, $scripturl; $block_parameters = array('shoutbox' => array()); if ($return_parameters) { $shoutboxes = sportal_get_shoutbox(); $in_use = array(); $request = $smcFunc['db_query']('', ' SELECT id_block, value FROM {db_prefix}sp_parameters WHERE variable = {string:name}', array('name' => 'shoutbox')); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (empty($_REQUEST['block_id']) || $_REQUEST['block_id'] != $row['id_block']) { $in_use[] = $row['value']; } } $smcFunc['db_free_result']($request); foreach ($shoutboxes as $shoutbox) { if (!in_array($shoutbox['id'], $in_use)) { $block_parameters['shoutbox'][$shoutbox['id']] = $shoutbox['name']; } } if (empty($block_parameters['shoutbox'])) { fatal_error(allowedTo(array('sp_admin', 'sp_manage_shoutbox')) ? $txt['error_sp_no_shoutbox'] . '<br />' . sprintf($txt['error_sp_no_shoutbox_sp_moderator'], $scripturl . '?action=admin;area=portalshoutbox;sa=add') : $txt['error_sp_no_shoutbox_normaluser'], false); } return $block_parameters; } loadTemplate('PortalShoutbox'); loadLanguage('Post'); $shoutbox = sportal_get_shoutbox($parameters['shoutbox'], true, true); if (empty($shoutbox)) { echo ' ', $txt['error_sp_shoutbox_not_exist']; return; } if (!empty($_POST['new_shout']) && !empty($_POST['submit_shout']) && !empty($_POST['shoutbox_id']) && $_POST['shoutbox_id'] == $shoutbox['id']) { checkSession(); is_not_guest(); if (!($flood = sp_prevent_flood('spsbp', false))) { require_once $sourcedir . '/Subs-Post.php'; $_POST['new_shout'] = $smcFunc['htmlspecialchars'](trim($_POST['new_shout'])); preparsecode($_POST['new_shout']); if (!empty($_POST['new_shout'])) { sportal_create_shout($shoutbox, $_POST['new_shout']); } } else { $shoutbox['warning'] = $flood; } } $can_moderate = allowedTo('sp_admin') || allowedTo('sp_manage_shoutbox'); if (!$can_moderate && !empty($shoutbox['moderator_groups'])) { $can_moderate = count(array_intersect($user_info['groups'], $shoutbox['moderator_groups'])) > 0; } $shout_parameters = array('limit' => $shoutbox['num_show'], 'bbc' => $shoutbox['allowed_bbc'], 'reverse' => $shoutbox['reverse'], 'cache' => $shoutbox['caching'], 'can_moderate' => $can_moderate); $shoutbox['shouts'] = sportal_get_shouts($shoutbox['id'], $shout_parameters); $shoutbox['warning'] = parse_bbc($shoutbox['warning']); $context['can_shout'] = $context['user']['is_logged']; if ($context['can_shout']) { $settings['smileys_url'] = $modSettings['smileys_url'] . '/' . $user_info['smiley_set']; $shoutbox['smileys'] = array('normal' => array(), 'popup' => array()); if (empty($modSettings['smiley_enable'])) { $shoutbox['smileys']['normal'] = array(array('code' => ':)', 'filename' => 'smiley.gif', 'description' => $txt['icon_smiley']), array('code' => ';)', 'filename' => 'wink.gif', 'description' => $txt['icon_wink']), array('code' => ':D', 'filename' => 'cheesy.gif', 'description' => $txt['icon_cheesy']), array('code' => ';D', 'filename' => 'grin.gif', 'description' => $txt['icon_grin']), array('code' => '>:(', 'filename' => 'angry.gif', 'description' => $txt['icon_angry']), array('code' => ':(', 'filename' => 'sad.gif', 'description' => $txt['icon_sad']), array('code' => ':o', 'filename' => 'shocked.gif', 'description' => $txt['icon_shocked']), array('code' => '8)', 'filename' => 'cool.gif', 'description' => $txt['icon_cool']), array('code' => '???', 'filename' => 'huh.gif', 'description' => $txt['icon_huh']), array('code' => '::)', 'filename' => 'rolleyes.gif', 'description' => $txt['icon_rolleyes']), array('code' => ':P', 'filename' => 'tongue.gif', 'description' => $txt['icon_tongue']), array('code' => ':-[', 'filename' => 'embarrassed.gif', 'description' => $txt['icon_embarrassed']), array('code' => ':-X', 'filename' => 'lipsrsealed.gif', 'description' => $txt['icon_lips']), array('code' => ':-\\', 'filename' => 'undecided.gif', 'description' => $txt['icon_undecided']), array('code' => ':-*', 'filename' => 'kiss.gif', 'description' => $txt['icon_kiss']), array('code' => ':\'(', 'filename' => 'cry.gif', 'description' => $txt['icon_cry'])); } else { if (($temp = cache_get_data('shoutbox_smileys', 3600)) == null) { $request = $smcFunc['db_query']('', ' SELECT code, filename, description, smiley_row, hidden FROM {db_prefix}smileys WHERE hidden IN ({array_int:hidden}) ORDER BY smiley_row, smiley_order', array('hidden' => array(0, 2))); while ($row = $smcFunc['db_fetch_assoc']($request)) { $row['filename'] = htmlspecialchars($row['filename']); $row['description'] = htmlspecialchars($row['description']); $row['code'] = htmlspecialchars($row['code']); $shoutbox['smileys'][empty($row['hidden']) ? 'normal' : 'popup'][] = $row; } $smcFunc['db_free_result']($request); cache_put_data('shoutbox_smileys', $shoutbox['smileys'], 3600); } else { $shoutbox['smileys'] = $temp; } } foreach (array_keys($shoutbox['smileys']) as $location) { $n = count($shoutbox['smileys'][$location]); for ($i = 0; $i < $n; $i++) { $shoutbox['smileys'][$location][$i]['code'] = addslashes($shoutbox['smileys'][$location][$i]['code']); $shoutbox['smileys'][$location][$i]['js_description'] = addslashes($shoutbox['smileys'][$location][$i]['description']); } if (!empty($shoutbox['smileys'][$location])) { $shoutbox['smileys'][$location][$n - 1]['last'] = true; } } $shoutbox['bbc'] = array('bold' => array('code' => 'b', 'before' => '[b]', 'after' => '[/b]', 'description' => $txt['bold']), 'italicize' => array('code' => 'i', 'before' => '[i]', 'after' => '[/i]', 'description' => $txt['italic']), 'underline' => array('code' => 'u', 'before' => '[u]', 'after' => '[/u]', 'description' => $txt['underline']), 'strike' => array('code' => 's', 'before' => '[s]', 'after' => '[/s]', 'description' => $txt['strike']), 'pre' => array('code' => 'pre', 'before' => '[pre]', 'after' => '[/pre]', 'description' => $txt['preformatted']), 'flash' => array('code' => 'flash', 'before' => '[flash=200,200]', 'after' => '[/flash]', 'description' => $txt['flash']), 'img' => array('code' => 'img', 'before' => '[img]', 'after' => '[/img]', 'description' => $txt['image']), 'url' => array('code' => 'url', 'before' => '[url]', 'after' => '[/url]', 'description' => $txt['hyperlink']), 'email' => array('code' => 'email', 'before' => '[email]', 'after' => '[/email]', 'description' => $txt['insert_email']), 'ftp' => array('code' => 'ftp', 'before' => '[ftp]', 'after' => '[/ftp]', 'description' => $txt['ftp']), 'glow' => array('code' => 'glow', 'before' => '[glow=red,2,300]', 'after' => '[/glow]', 'description' => $txt['glow']), 'shadow' => array('code' => 'shadow', 'before' => '[shadow=red,left]', 'after' => '[/shadow]', 'description' => $txt['shadow']), 'sup' => array('code' => 'sup', 'before' => '[sup]', 'after' => '[/sup]', 'description' => $txt['superscript']), 'sub' => array('code' => 'sub', 'before' => '[sub]', 'after' => '[/sub]', 'description' => $txt['subscript']), 'tele' => array('code' => 'tt', 'before' => '[tt]', 'after' => '[/tt]', 'description' => $txt['teletype']), 'code' => array('code' => 'code', 'before' => '[code]', 'after' => '[/code]', 'description' => $txt['bbc_code']), 'quote' => array('code' => 'quote', 'before' => '[quote]', 'after' => '[/quote]', 'description' => $txt['bbc_quote'])); } template_shoutbox_embed($shoutbox); }
function isAllowedTo($permission, $boards = null) { global $user_info, $txt; static $heavy_permissions = array('admin_forum', 'manage_attachments', 'manage_smileys', 'manage_boards', 'edit_news', 'moderate_forum', 'manage_bans', 'manage_membergroups', 'manage_permissions'); // Make it an array, even if a string was passed. $permission = is_array($permission) ? $permission : array($permission); // Check the permission and return an error... if (!allowedTo($permission, $boards)) { // Pick the last array entry as the permission shown as the error. $error_permission = array_shift($permission); // If they are a guest, show a login. (because the error might be gone if they do!) if ($user_info['is_guest']) { loadLanguage('Errors'); is_not_guest($txt['cannot_' . $error_permission]); } // Clear the action because they aren't really doing that! $_GET['action'] = ''; $_GET['board'] = ''; $_GET['topic'] = ''; writeLog(true); fatal_lang_error('cannot_' . $error_permission, false); // Getting this far is a really big problem, but let's try our best to prevent any cases... trigger_error('Hacking attempt...', E_USER_ERROR); } // If you're doing something on behalf of some "heavy" permissions, validate your session. // (take out the heavy permissions, and if you can't do anything but those, you need a validated session.) if (!allowedTo(array_diff($permission, $heavy_permissions), $boards)) { validateSession(); } }
function MarkRead() { global $board, $topic, $user_info, $board_info, $modSettings, $smcFunc; // No Guests allowed! is_not_guest(); checkSession('get'); if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'all') { // Find all the boards this user can see. $result = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE {query_see_board}', array()); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($result)) { $boards[] = $row['id_board']; } $smcFunc['db_free_result']($result); if (!empty($boards)) { markBoardsRead($boards, isset($_REQUEST['unread'])); } $_SESSION['id_msg_last_visit'] = $modSettings['maxMsgID']; if (!empty($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'action=unread') !== false) { redirectexit('action=unread'); } if (isset($_SESSION['topicseen_cache'])) { $_SESSION['topicseen_cache'] = array(); } redirectexit(); } elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'unreadreplies') { // Make sure all the boards are integers! $topics = explode('-', $_REQUEST['topics']); $markRead = array(); foreach ($topics as $id_topic) { $markRead[] = array($modSettings['maxMsgID'], $user_info['id'], (int) $id_topic); } $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'), $markRead, array('id_member', 'id_topic')); if (isset($_SESSION['topicseen_cache'])) { $_SESSION['topicseen_cache'] = array(); } redirectexit('action=unreadreplies'); } elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'topic') { // First, let's figure out what the latest message is. $result = $smcFunc['db_query']('', ' SELECT id_first_msg, id_last_msg FROM {db_prefix}topics WHERE id_topic = {int:current_topic}', array('current_topic' => $topic)); $topicinfo = $smcFunc['db_fetch_assoc']($result); $smcFunc['db_free_result']($result); if (!empty($_GET['t'])) { // If they read the whole topic, go back to the beginning. if ($_GET['t'] >= $topicinfo['id_last_msg']) { $earlyMsg = 0; } elseif ($_GET['t'] <= $topicinfo['id_first_msg']) { $earlyMsg = 0; } else { $result = $smcFunc['db_query']('', ' SELECT MAX(id_msg) FROM {db_prefix}messages WHERE id_topic = {int:current_topic} AND id_msg >= {int:id_first_msg} AND id_msg < {int:topic_msg_id}', array('current_topic' => $topic, 'topic_msg_id' => (int) $_GET['t'], 'id_first_msg' => $topicinfo['id_first_msg'])); list($earlyMsg) = $smcFunc['db_fetch_row']($result); $smcFunc['db_free_result']($result); } } elseif ($_REQUEST['start'] == 0) { $earlyMsg = 0; } else { $result = $smcFunc['db_query']('', ' SELECT id_msg FROM {db_prefix}messages WHERE id_topic = {int:current_topic} ORDER BY id_msg LIMIT ' . (int) $_REQUEST['start'] . ', 1', array('current_topic' => $topic)); list($earlyMsg) = $smcFunc['db_fetch_row']($result); $smcFunc['db_free_result']($result); $earlyMsg--; } // Blam, unread! $smcFunc['db_insert']('replace', '{db_prefix}log_topics', array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'), array($earlyMsg, $user_info['id'], $topic), array('id_member', 'id_topic')); redirectexit('board=' . $board . '.0'); } else { $categories = array(); $boards = array(); if (isset($_REQUEST['c'])) { $_REQUEST['c'] = explode(',', $_REQUEST['c']); foreach ($_REQUEST['c'] as $c) { $categories[] = (int) $c; } } if (isset($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $b) { $boards[] = (int) $b; } } if (!empty($board)) { $boards[] = (int) $board; } if (isset($_REQUEST['children']) && !empty($boards)) { // They want to mark the entire tree starting with the boards specified // The easist thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them $request = $smcFunc['db_query']('', ' SELECT b.id_board, b.id_parent FROM {db_prefix}boards AS b WHERE {query_see_board} AND b.child_level > {int:no_parents} AND b.id_board NOT IN ({array_int:board_list}) ORDER BY child_level ASC ', array('no_parents' => 0, 'board_list' => $boards)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (in_array($row['id_parent'], $boards)) { $boards[] = $row['id_board']; } } $smcFunc['db_free_result']($request); } $clauses = array(); $clauseParameters = array(); if (!empty($categories)) { $clauses[] = 'id_cat IN ({array_int:category_list})'; $clauseParameters['category_list'] = $categories; } if (!empty($boards)) { $clauses[] = 'id_board IN ({array_int:board_list})'; $clauseParameters['board_list'] = $boards; } if (empty($clauses)) { redirectexit(); } $request = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE {query_see_board} AND b.' . implode(' OR b.', $clauses), array_merge($clauseParameters, array())); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $boards[] = $row['id_board']; } $smcFunc['db_free_result']($request); if (empty($boards)) { redirectexit(); } markBoardsRead($boards, isset($_REQUEST['unread'])); foreach ($boards as $b) { if (isset($_SESSION['topicseen_cache'][$b])) { $_SESSION['topicseen_cache'][$b] = array(); } } if (!isset($_REQUEST['unread'])) { // Find all the boards this user can see. $result = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE b.id_parent IN ({array_int:parent_list}) AND {query_see_board}', array('parent_list' => $boards)); if ($smcFunc['db_num_rows']($result) > 0) { $logBoardInserts = ''; while ($row = $smcFunc['db_fetch_assoc']($result)) { $logBoardInserts[] = array($modSettings['maxMsgID'], $user_info['id'], $row['id_board']); } $smcFunc['db_insert']('replace', '{db_prefix}log_boards', array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), $logBoardInserts, array('id_member', 'id_board')); } $smcFunc['db_free_result']($result); if (empty($board)) { redirectexit(); } else { redirectexit('board=' . $board . '.0'); } } else { if (empty($board_info['parent'])) { redirectexit(); } else { redirectexit('board=' . $board_info['parent'] . '.0'); } } } }
function MessageMain() { global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $db_prefix, $ID_MEMBER; // No guests! is_not_guest(); // You're not supposed to be here at all, if you can't even read PMs. isAllowedTo('pm_read'); // This file contains the basic functions for sending a PM. require_once $sourcedir . '/Subs-Post.php'; if (loadLanguage('PersonalMessage', '', false) === false) { loadLanguage('InstantMessage'); } if (WIRELESS) { $context['sub_template'] = WIRELESS_PROTOCOL . '_pm'; } else { if (loadTemplate('PersonalMessage', false) === false) { loadTemplate('InstantMessage'); } } // Load up the members maximum message capacity. if (!$user_info['is_admin']) { // !!! Why do we do this? It seems like if they have any limit we should use it. $request = db_query("\n\t\t\tSELECT MAX(maxMessages) AS topLimit, MIN(maxMessages) AS bottomLimit\n\t\t\tFROM {$db_prefix}membergroups\n\t\t\tWHERE ID_GROUP IN (" . implode(', ', $user_info['groups']) . ')', __FILE__, __LINE__); list($maxMessage, $minMessage) = mysql_fetch_row($request); mysql_free_result($request); $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage; } else { $context['message_limit'] = 0; } // Prepare the context for the capacity bar. if (!empty($context['message_limit'])) { $bar = $user_info['messages'] * 100 / $context['message_limit']; $context['limit_bar'] = array('messages' => $user_info['messages'], 'allowed' => $context['message_limit'], 'percent' => $bar, 'bar' => min(100, (int) $bar), 'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1))); } // We should probably cache this information for speed. $context['labels'] = $user_settings['messageLabels'] == '' ? array() : explode(',', $user_settings['messageLabels']); foreach ($context['labels'] as $k => $v) { $context['labels'][(int) $k] = array('id' => $k, 'name' => trim($v), 'messages' => 0, 'unread_messages' => 0); } $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0); // !!! The idea would be to cache this information in the members table, and invlidate it when they are sent messages. $result = db_query("\n\t\tSELECT labels, is_read, COUNT(*) AS num\n\t\tFROM {$db_prefix}pm_recipients\n\t\tWHERE ID_MEMBER = {$ID_MEMBER}\n\t\tGROUP BY labels, is_read", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { $this_labels = explode(',', $row['labels']); foreach ($this_labels as $this_label) { $context['labels'][(int) $this_label]['messages'] += $row['num']; if (!($row['is_read'] & 1)) { $context['labels'][(int) $this_label]['unread_messages'] += $row['num']; } } } mysql_free_result($result); // This determines if we have more labels than just the standard inbox. $context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0; // Some stuff for the labels... $context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][(int) $_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1; $context['current_label'] =& $context['labels'][(int) $context['current_label_id']]['name']; $context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'outbox' ? 'inbox' : 'outbox'; // This is convenient. Do you know how annoying it is to do this every time?! $context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : ''); // Build the linktree for all the actions... $context['linktree'][] = array('url' => $scripturl . '?action=pm', 'name' => $txt[144]); $subActions = array('addbuddy' => 'WirelessAddBuddy', 'manlabels' => 'ManageLabels', 'outbox' => 'MessageFolder', 'pmactions' => 'MessageActionsApply', 'prune' => 'MessagePrune', 'removeall' => 'MessageKillAllQuery', 'removeall2' => 'MessageKillAll', 'report' => 'ReportMessage', 'search' => 'MessageSearch', 'search2' => 'MessageSearch2', 'send' => 'MessagePost', 'send2' => 'MessagePost2'); if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) { MessageFolder(); } else { messageIndexBar($_REQUEST['sa']); $subActions[$_REQUEST['sa']](); } }
/** * Check for moderators and see if they have access to the board. * * What it does: * - sets up the $board_info array for current board information. * - if cache is enabled, the $board_info array is stored in cache. * - redirects to appropriate post if only message id is requested. * - is only used when inside a topic or board. * - determines the local moderators for the board. * - adds group id 3 if the user is a local moderator for the board they are in. * - prevents access if user is not in proper group nor a local moderator of the board. */ function loadBoard() { global $txt, $scripturl, $context, $modSettings; global $board_info, $board, $topic, $user_info; $db = database(); // Assume they are not a moderator. $user_info['is_mod'] = false; $context['user']['is_mod'] =& $user_info['is_mod']; // @since 1.0.5 - is_mod takes into account only local (board) moderators, // and not global moderators, is_moderator is meant to take into account both. $user_info['is_moderator'] = false; $context['user']['is_moderator'] =& $user_info['is_moderator']; // 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 = cache_get_data('msg_topic-' . $_REQUEST['msg'], 120)) === null) { require_once SUBSDIR . '/Messages.subs.php'; $topic = associatedTopic($_REQUEST['msg']); // So did it find anything? if ($topic !== false) { // Save save save. cache_put_data('msg_topic-' . $_REQUEST['msg'], $topic, 120); } } // Remember redirection is the key to avoiding fallout from your bosses. if (!empty($topic)) { redirectexit('topic=' . $topic . '.msg' . $_REQUEST['msg'] . '#msg' . $_REQUEST['msg']); } else { loadPermissions(); loadTheme(); 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)) { // @todo SLOW? if (!empty($topic)) { $temp = cache_get_data('topic_board-' . $topic, 120); } else { $temp = cache_get_data('board-' . $board, 120); } if (!empty($temp)) { $board_info = $temp; $board = $board_info['id']; } } if (empty($temp)) { $select_columns = array(); $select_tables = array(); // Wanna grab something more from the boards table or another table at all? call_integration_hook('integrate_load_board_query', array(&$select_columns, &$select_tables)); $request = $db->query('', ' SELECT c.id_cat, b.name AS bname, b.description, b.num_topics, b.member_groups, b.deny_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.unapproved_topics, b.unapproved_posts' . (!empty($topic) ? ', t.approved, t.id_member_started' : '') . (!empty($select_columns) ? ', ' . implode(', ', $select_columns) : '') . ' FROM {db_prefix}boards AS b' . (!empty($topic) ? ' INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})' : '') . (!empty($select_tables) ? ' ' . implode("\n\t\t\t\t", $select_tables) : '') . ' 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) ? $db->quote('{int:current_board}', array('current_board' => $board)) : 't.id_board')); // If there aren't any, skip. if ($db->num_rows($request) > 0) { $row = $db->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']), 'name' => $row['bname'], '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']); $board_info['deny_groups'] = $row['deny_member_groups'] == '' ? array() : explode(',', $row['deny_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 = $db->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')) { // Free the previous result $db->free_result($request); // @todo why is this using id_topic? // @todo Can this get cached? $request = $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']) = $db->fetch_row($request); } call_integration_hook('integrate_loaded_board', array(&$board_info, &$row)); if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] >= 3)) { // @todo SLOW? if (!empty($topic)) { cache_put_data('topic_board-' . $topic, $board_info, 120); } cache_put_data('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; } $db->free_result($request); } if (!empty($topic)) { $_GET['board'] = (int) $board; } if (!empty($board)) { // Now check if the user is a moderator. $user_info['is_mod'] = isset($board_info['moderators'][$user_info['id']]); $user_info['is_moderator'] = $user_info['is_mod'] || allowedTo('moderate_board'); if (count(array_intersect($user_info['groups'], $board_info['groups'])) == 0 && !$user_info['is_admin']) { $board_info['error'] = 'access'; } if (!empty($modSettings['deny_boards_access']) && count(array_intersect($user_info['groups'], $board_info['deny_groups'])) != 0 && !$user_info['is_admin']) { $board_info['error'] = 'access'; } // Build up the linktree. $context['linktree'] = array_merge($context['linktree'], array(array('url' => $scripturl . '#c' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name']))); } // Set the template contextual information. $context['user']['is_mod'] =& $user_info['is_mod']; $context['user']['is_moderator'] =& $user_info['is_moderator']; $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']) && (!empty($modSettings['deny_boards_access']) || $board_info['error'] != 'access' || !$user_info['is_moderator'])) { // The permissions and theme need loading, just to make sure everything goes smoothly. loadPermissions(); loadTheme(); $_GET['board'] = ''; $_GET['topic'] = ''; // The linktree should not give the game away mate! $context['linktree'] = array(array('url' => $scripturl, '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; } }
/** * Turn off/on unread replies subscription for a topic * Must be called with a topic specified in the URL. * The sub-action can be 'on', 'off', or nothing for what to do. * Requires the mark_any_notify permission. * Upon successful completion of action will direct user back to topic. * Accessed via ?action=unwatchtopic. */ public function action_unwatchtopic() { global $user_info, $topic, $modSettings; is_not_guest(); // our topic functions are here require_once SUBSDIR . '/Topic.subs.php'; // Let's do something only if the function is enabled if (!$user_info['is_guest'] && !empty($modSettings['enable_unwatch'])) { checkSession('get'); setTopicWatch($user_info['id'], $topic, $_GET['sa'] == 'on'); } // Back to the topic. redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); }
function sportal_shoutbox() { global $smcFunc, $context, $scripturl, $txt, $sourcedir, $user_info; $shoutbox_id = !empty($_REQUEST['shoutbox_id']) ? (int) $_REQUEST['shoutbox_id'] : 0; $request_time = !empty($_REQUEST['time']) ? (int) $_REQUEST['time'] : 0; $context['SPortal']['shoutbox'] = sportal_get_shoutbox($shoutbox_id, true, true); if (empty($context['SPortal']['shoutbox'])) { fatal_lang_error('error_sp_shoutbox_not_exist', false); } $context['SPortal']['shoutbox']['warning'] = parse_bbc($context['SPortal']['shoutbox']['warning']); $can_moderate = allowedTo('sp_admin') || allowedTo('sp_manage_shoutbox'); if (!$can_moderate && !empty($context['SPortal']['shoutbox']['moderator_groups'])) { $can_moderate = count(array_intersect($user_info['groups'], $context['SPortal']['shoutbox']['moderator_groups'])) > 0; } if (!empty($_REQUEST['shout'])) { checkSession('request'); is_not_guest(); if (!($flood = sp_prevent_flood('spsbp', false))) { require_once $sourcedir . '/Subs-Post.php'; $_REQUEST['shout'] = $smcFunc['htmlspecialchars'](trim($_REQUEST['shout'])); preparsecode($_REQUEST['shout']); if (!empty($_REQUEST['shout'])) { sportal_create_shout($context['SPortal']['shoutbox'], $_REQUEST['shout']); } } else { $context['SPortal']['shoutbox']['warning'] = $flood; } } if (!empty($_REQUEST['delete'])) { checkSession('request'); if (!$can_moderate) { fatal_lang_error('error_sp_cannot_shoutbox_moderate', false); } $_REQUEST['delete'] = (int) $_REQUEST['delete']; if (!empty($_REQUEST['delete'])) { sportal_delete_shout($shoutbox_id, $_REQUEST['delete']); } } loadTemplate('PortalShoutbox'); if (isset($_REQUEST['xml'])) { $shout_parameters = array('limit' => $context['SPortal']['shoutbox']['num_show'], 'bbc' => $context['SPortal']['shoutbox']['allowed_bbc'], 'reverse' => $context['SPortal']['shoutbox']['reverse'], 'cache' => $context['SPortal']['shoutbox']['caching'], 'can_moderate' => $can_moderate); $context['SPortal']['shouts'] = sportal_get_shouts($shoutbox_id, $shout_parameters); $context['sub_template'] = 'shoutbox_xml'; $context['SPortal']['updated'] = empty($context['SPortal']['shoutbox']['last_update']) || $context['SPortal']['shoutbox']['last_update'] > $request_time; return; } $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}sp_shouts WHERE id_shoutbox = {int:current}', array('current' => $shoutbox_id)); list($total_shouts) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $context['per_page'] = $context['SPortal']['shoutbox']['num_show']; $context['start'] = !empty($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0; $context['page_index'] = constructPageIndex($scripturl . '?action=portal;sa=shoutbox;shoutbox_id=' . $shoutbox_id, $context['start'], $total_shouts, $context['per_page']); $shout_parameters = array('start' => $context['start'], 'limit' => $context['per_page'], 'bbc' => $context['SPortal']['shoutbox']['allowed_bbc'], 'cache' => $context['SPortal']['shoutbox']['caching'], 'can_moderate' => $can_moderate); $context['SPortal']['shouts_history'] = sportal_get_shouts($shoutbox_id, $shout_parameters); $context['SPortal']['shoutbox_id'] = $shoutbox_id; $context['sub_template'] = 'shoutbox_all'; $context['page_title'] = $context['SPortal']['shoutbox']['name']; }
/** * Enforces a user having a given permission and returning to a fatal error message if not. * * All fatal-level SimpleDesk-specific permissions should be checked with this function. Any other permission check that is * not specifically SimpleDesk-related should use isAllowedTo instead. Note that this is a void function because should this * fail, SMF execution will be halted. * * Prior to 1.0, this function was in Subs-SimpleDesk.php * * @param mixed $permission A string or array of strings naming a permission or permissions that wish to be examined. * @param int $dept A number indicating a department that the user must the permission in, or 0 for not caring which department provided the user has that permission in at least one department. * @see shd_allowed_to() * @since 1.0 */ function shd_is_allowed_to($permission, $dept = 0) { global $user_info, $txt; $permission = is_array($permission) ? $permission : (array) $permission; if (!shd_allowed_to($permission, $dept)) { // Pick the last array entry as the permission shown as the error. $error_permission = array_shift($permission); // If they are a guest, show a login. (because the error might be gone if they do!) if ($user_info['is_guest']) { loadLanguage('Errors'); is_not_guest($txt['cannot_' . $error_permission]); } // Clear the action because they aren't really doing that! $_GET['action'] = ''; $_GET['board'] = ''; $_GET['topic'] = ''; writeLog(true); fatal_lang_error('cannot_' . $error_permission, false); // Getting this far is a really big problem, but let's try our best to prevent any cases... trigger_error('Hacking attempt...', E_USER_ERROR); } }
/** * Checks that few things are in order (in addition to permissions) for likes. */ private function prepare_like() { global $modSettings, $user_info, $txt; $check = true; // Valid request checkSession('get'); // If you're a guest or simply can't do this, we stop is_not_guest(); isAllowedTo('like_posts'); // Load up the helpers require_once SUBSDIR . '/Likes.subs.php'; // Maintain our log clearLikes(empty($modSettings['likeWaitTime']) ? 0 : $modSettings['likeWaitTime']); // Not a moderator/administrator then we do some checking if (!empty($modSettings['likeRestrictAdmins']) || !allowedTo('moderate_forum')) { // Find out if this user has done this recently... $check = lastLikeOn($user_info['id']); } // Past the post threshold? if (!$user_info['is_admin'] && !empty($modSettings['likeMinPosts']) && $user_info['posts'] < $modSettings['likeMinPosts']) { $check = false; } // If they have exceeded their limits, provide a message for the ajax response if ($check === false && $this->_api) { loadLanguage('Errors'); $wait = $modSettings['likeWaitTime'] > 60 ? round($modSettings['likeWaitTime'] / 60, 2) : $modSettings['likeWaitTime']; $error = sprintf($txt['like_wait_time'], $wait, $modSettings['likeWaitTime'] < 60 ? strtolower($txt['minutes']) : $txt['hours']); $this->_likes_response = array('result' => false, 'data' => $error); } return $check; }
function RateLink() { global $db_prefix, $ID_MEMBER, $txt; isAllowedTo('rate_links'); // Guests can't rate links? Cause how can we keep track??? is_not_guest(); // Get the link ID if (!empty($_REQUEST['id'])) { $id = (int) $_REQUEST['id']; } if (empty($id)) { fatal_error($txt['smflinks_nolinkselected']); } $dbresult = db_query("\n\tSELECT \n\t ID_LINK \n\tFROM {$db_prefix}links \n\tWHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__); $row = mysql_fetch_assoc($dbresult); if (empty($row['ID_LINK'])) { fatal_error($txt['smflinks_nolinkselected']); } // See if the user already rated the link. $dbresult = db_query("\n\tSELECT \n\t\tID_LINK, ID_MEMBER \n\tFROM {$db_prefix}links_rating \n\tWHERE ID_MEMBER = {$ID_MEMBER} AND ID_LINK = {$id}", __FILE__, __LINE__); if (db_affected_rows() != 0) { fatal_error($txt['smflinks_alreadyrated'], false); } mysql_free_result($dbresult); //Get the value of rating if (!empty($_REQUEST['value'])) { $value = (int) $_REQUEST['value']; } else { $value = 0; } //Check value if ($value == 0) { //Lower Ranking //Insert rating db_query("INSERT INTO {$db_prefix}links_rating\n\t\t\t\t(ID_LINK, ID_MEMBER,value)\n\t\t\tVALUES ({$id}, {$ID_MEMBER},0)", __FILE__, __LINE__); // Update main link rating db_query("UPDATE {$db_prefix}links\n\t\t\tSET rating = rating - 1 WHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__); } else { //Higher Ranking //Insert rating db_query("INSERT INTO {$db_prefix}links_rating\n\t\t\t\t(ID_LINK, ID_MEMBER,value)\n\t\t\tVALUES ({$id}, {$ID_MEMBER},1)", __FILE__, __LINE__); //Update main link rating db_query("UPDATE {$db_prefix}links\n\t\t\tSET rating = rating + 1 WHERE ID_LINK = {$id} LIMIT 1", __FILE__, __LINE__); } redirectexit('action=links'); }
function UnreadTopics() { global $board, $txt, $scripturl, $sourcedir; global $user_info, $context, $settings, $modSettings, $smcFunc, $options; // Guests can't have unread things, we don't know anything about them. is_not_guest(); // Prefetching + lots of MySQL work = bad mojo. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { ob_end_clean(); header('HTTP/1.1 403 Forbidden'); die; } $context['showing_all_topics'] = isset($_GET['all']); $context['start'] = (int) $_REQUEST['start']; $context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) && !WIRELESS ? $options['topics_per_page'] : $modSettings['defaultMaxTopics']; if ($_REQUEST['action'] == 'unread') { $context['page_title'] = $context['showing_all_topics'] ? $txt['unread_topics_all'] : $txt['unread_topics_visit']; } else { $context['page_title'] = $txt['unread_replies']; } if ($context['showing_all_topics'] && !empty($context['load_average']) && !empty($modSettings['loadavg_allunread']) && $context['load_average'] >= $modSettings['loadavg_allunread']) { fatal_lang_error('loadavg_allunread_disabled', false); } elseif ($_REQUEST['action'] != 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unreadreplies']) && $context['load_average'] >= $modSettings['loadavg_unreadreplies']) { fatal_lang_error('loadavg_unreadreplies_disabled', false); } elseif (!$context['showing_all_topics'] && $_REQUEST['action'] == 'unread' && !empty($context['load_average']) && !empty($modSettings['loadavg_unread']) && $context['load_average'] >= $modSettings['loadavg_unread']) { fatal_lang_error('loadavg_unread_disabled', false); } // Parameters for the main query. $query_parameters = array(); // Are we specifying any specific board? if (isset($_REQUEST['children']) && (!empty($board) || !empty($_REQUEST['boards']))) { $boards = array(); if (!empty($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $b) { $boards[] = (int) $b; } } if (!empty($board)) { $boards[] = (int) $board; } // The easiest thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them $request = $smcFunc['db_query']('', ' SELECT b.id_board, b.id_parent FROM {db_prefix}boards AS b WHERE {query_wanna_see_board} AND b.child_level > {int:no_child} AND b.id_board NOT IN ({array_int:boards}) ORDER BY child_level ASC ', array('no_child' => 0, 'boards' => $boards)); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (in_array($row['id_parent'], $boards)) { $boards[] = $row['id_board']; } } $smcFunc['db_free_result']($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'id_board IN ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%d'; } elseif (!empty($board)) { $query_this_board = 'id_board = {int:board}'; $query_parameters['board'] = $board; $context['querystring_board_limits'] = ';board=' . $board . '.%1$d'; } elseif (!empty($_REQUEST['boards'])) { $_REQUEST['boards'] = explode(',', $_REQUEST['boards']); foreach ($_REQUEST['boards'] as $i => $b) { $_REQUEST['boards'][$i] = (int) $b; } $request = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE {query_see_board} AND b.id_board IN ({array_int:board_list})', array('board_list' => $_REQUEST['boards'])); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $boards[] = $row['id_board']; } $smcFunc['db_free_result']($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'id_board IN ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';boards=' . implode(',', $boards) . ';start=%1$d'; } elseif (!empty($_REQUEST['c'])) { $_REQUEST['c'] = explode(',', $_REQUEST['c']); foreach ($_REQUEST['c'] as $i => $c) { $_REQUEST['c'][$i] = (int) $c; } $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board'; $request = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE ' . $user_info[$see_board] . ' AND b.id_cat IN ({array_int:id_cat})', array('id_cat' => $_REQUEST['c'])); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $boards[] = $row['id_board']; } $smcFunc['db_free_result']($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'id_board IN ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';c=' . implode(',', $_REQUEST['c']) . ';start=%1$d'; } else { $see_board = isset($_REQUEST['action']) && $_REQUEST['action'] == 'unreadreplies' ? 'query_see_board' : 'query_wanna_see_board'; // Don't bother to show deleted posts! $request = $smcFunc['db_query']('', ' SELECT b.id_board FROM {db_prefix}boards AS b WHERE ' . $user_info[$see_board] . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' AND b.id_board != {int:recycle_board}' : ''), array('recycle_board' => (int) $modSettings['recycle_board'])); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $boards[] = $row['id_board']; } $smcFunc['db_free_result']($request); if (empty($boards)) { fatal_lang_error('error_no_boards_selected'); } $query_this_board = 'id_board IN ({array_int:boards})'; $query_parameters['boards'] = $boards; $context['querystring_board_limits'] = ';start=%1$d'; $context['no_board_limits'] = true; } $sort_methods = array('subject' => 'ms.subject', 'starter' => 'IFNULL(mems.real_name, ms.poster_name)', 'replies' => 't.num_replies', 'views' => 't.num_views', 'first_post' => 't.id_topic', 'last_post' => 't.id_last_msg'); // The default is the most logical: newest first. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'last_post'; $_REQUEST['sort'] = 't.id_last_msg'; $ascending = isset($_REQUEST['asc']); $context['querystring_sort_limits'] = $ascending ? ';asc' : ''; } else { $context['sort_by'] = $_REQUEST['sort']; $_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']]; $ascending = !isset($_REQUEST['desc']); $context['querystring_sort_limits'] = ';sort=' . $context['sort_by'] . ($ascending ? '' : ';desc'); } $context['sort_direction'] = $ascending ? 'up' : 'down'; if (!empty($_REQUEST['c']) && is_array($_REQUEST['c']) && count($_REQUEST['c']) == 1) { $request = $smcFunc['db_query']('', ' SELECT name FROM {db_prefix}categories WHERE id_cat = {int:id_cat} LIMIT 1', array('id_cat' => (int) $_REQUEST['c'][0])); list($name) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $context['linktree'][] = array('url' => $scripturl . '#c' . (int) $_REQUEST['c'][0], 'name' => $name); } $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $_REQUEST['action'] == 'unread' ? $txt['unread_topics_visit'] : $txt['unread_replies']); if ($context['showing_all_topics']) { $context['linktree'][] = array('url' => $scripturl . '?action=' . $_REQUEST['action'] . ';all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'], 'name' => $txt['unread_topics_all']); } else { $txt['unread_topics_visit_none'] = strtr($txt['unread_topics_visit_none'], array('?action=unread;all' => '?action=unread;all' . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'])); } if (WIRELESS) { $context['sub_template'] = WIRELESS_PROTOCOL . '_recent'; } else { loadTemplate('Recent'); $context['sub_template'] = $_REQUEST['action'] == 'unread' ? 'unread' : 'replies'; } // Setup the default topic icons... for checking they exist and the like ;) $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless', 'clip'); $context['icon_sources'] = array(); foreach ($stable_icons as $icon) { $context['icon_sources'][$icon] = 'images_url'; } $is_topics = $_REQUEST['action'] == 'unread'; // This part is the same for each query. $select_clause = ' ms.subject AS first_subject, ms.poster_time AS first_poster_time, ms.id_topic, t.id_board, b.name AS bname, t.num_replies, t.num_views, ms.id_member AS id_first_member, ml.id_member AS id_last_member, ml.poster_time AS last_poster_time, IFNULL(mems.real_name, ms.poster_name) AS first_poster_name, IFNULL(meml.real_name, ml.poster_name) AS last_poster_name, ml.subject AS last_subject, ml.icon AS last_icon, ms.icon AS first_icon, t.id_poll, t.is_sticky, t.locked, ml.modified_time AS last_modified_time, IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1 AS new_from, SUBSTRING(ml.body, 1, 385) AS last_body, SUBSTRING(ms.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, ms.smileys_enabled AS first_smileys, t.id_first_msg, t.id_last_msg'; if ($context['showing_all_topics']) { if (!empty($board)) { $request = $smcFunc['db_query']('', ' SELECT MIN(id_msg) FROM {db_prefix}log_mark_read WHERE id_member = {int:current_member} AND id_board = {int:current_board}', array('current_board' => $board, 'current_member' => $user_info['id'])); list($earliest_msg) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); } else { $request = $smcFunc['db_query']('', ' SELECT MIN(lmr.id_msg) FROM {db_prefix}boards AS b LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = b.id_board AND lmr.id_member = {int:current_member}) WHERE {query_see_board}', array('current_member' => $user_info['id'])); list($earliest_msg) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); } // This is needed in case of topics marked unread. if (empty($earliest_msg)) { $earliest_msg = 0; } else { // Using caching, when possible, to ignore the below slow query. if (isset($_SESSION['cached_log_time']) && $_SESSION['cached_log_time'][0] + 45 > time()) { $earliest_msg2 = $_SESSION['cached_log_time'][1]; } else { // This query is pretty slow, but it's needed to ensure nothing crucial is ignored. $request = $smcFunc['db_query']('', ' SELECT MIN(id_msg) FROM {db_prefix}log_topics WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'])); list($earliest_msg2) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // In theory this could be zero, if the first ever post is unread, so fudge it ;) if ($earliest_msg2 == 0) { $earliest_msg2 = -1; } $_SESSION['cached_log_time'] = array(time(), $earliest_msg2); } $earliest_msg = min($earliest_msg2, $earliest_msg); } } // !!! Add modified_time in for log_time check? if ($modSettings['totalMessages'] > 100000 && $context['showing_all_topics']) { $smcFunc['db_query']('', ' DROP TABLE IF EXISTS {db_prefix}log_topics_unread', array()); // Let's copy things out of the log_topics table, to reduce searching. $have_temp_table = $smcFunc['db_query']('', ' CREATE TEMPORARY TABLE {db_prefix}log_topics_unread ( PRIMARY KEY (id_topic) ) SELECT lt.id_topic, lt.id_msg FROM {db_prefix}topics AS t INNER JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic) WHERE lt.id_member = {int:current_member} AND t.' . $query_this_board . (empty($earliest_msg) ? '' : ' AND t.id_last_msg > {int:earliest_msg}') . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1, 'db_error_skip' => true))) !== false; } else { $have_temp_table = false; } if ($context['showing_all_topics'] && $have_temp_table) { $request = $smcFunc['db_query']('', ' SELECT COUNT(*), MIN(t.id_last_msg) FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . (!empty($earliest_msg) ? ' AND t.id_last_msg > {int:earliest_msg}' : '') . ' AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'is_approved' => 1))); list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true); $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { // Mark the boards as read if there are no unread topics! require_once $sourcedir . '/Subs-Boards.php'; markBoardsRead(empty($boards) ? $board : $boards); $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%1$d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = $smcFunc['db_query']('substring', ' SELECT ' . $select_clause . ' FROM {db_prefix}messages AS ms INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}boards AS b ON (b.id_board = ms.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE b.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND ms.approved = {int:is_approved}' : '') . ' ORDER BY {raw:sort} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'sort' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } elseif ($is_topics) { $request = $smcFunc['db_query']('', ' SELECT COUNT(*), MIN(t.id_last_msg) FROM {db_prefix}topics AS t' . (!empty($have_temp_table) ? ' LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})') . ' LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ($context['showing_all_topics'] && !empty($earliest_msg) ? ' AND t.id_last_msg > {int:earliest_msg}' : (!$context['showing_all_topics'] && empty($_SESSION['first_login']) ? ' AND t.id_last_msg > {int:id_msg_last_visit}' : '')) . ' AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'earliest_msg' => !empty($earliest_msg) ? $earliest_msg : 0, 'id_msg_last_visit' => $_SESSION['id_msg_last_visit'], 'is_approved' => 1))); list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true); $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { // Is this an all topics query? if ($context['showing_all_topics']) { // Since there are no unread topics, mark the boards as read! require_once $sourcedir . '/Subs-Boards.php'; markBoardsRead(empty($boards) ? $board : $boards); } $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } else { $min_message = (int) $min_message; } $request = $smcFunc['db_query']('substring', ' SELECT ' . $select_clause . ' FROM {db_prefix}messages AS ms INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ms.id_topic AND t.id_first_msg = ms.id_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' . (!empty($have_temp_table) ? ' LEFT JOIN {db_prefix}log_topics_unread AS lt ON (lt.id_topic = t.id_topic)' : ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})') . ' LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < ml.id_msg' . ($modSettings['postmod_active'] ? ' AND ms.approved = {int:is_approved}' : '') . ' ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } else { if ($modSettings['totalMessages'] > 100000) { $smcFunc['db_query']('', ' DROP TABLE IF EXISTS {db_prefix}topics_posted_in', array()); $smcFunc['db_query']('', ' DROP TABLE IF EXISTS {db_prefix}log_topics_posted_in', array()); $sortKey_joins = array('ms.subject' => ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)', 'IFNULL(mems.real_name, ms.poster_name)' => ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)'); // The main benefit of this temporary table is not that it's faster; it's that it avoids locks later. $have_temp_table = $smcFunc['db_query']('', ' CREATE TEMPORARY TABLE {db_prefix}topics_posted_in ( id_topic mediumint(8) unsigned NOT NULL default {string:string_zero}, id_board smallint(5) unsigned NOT NULL default {string:string_zero}, id_last_msg int(10) unsigned NOT NULL default {string:string_zero}, id_msg int(10) unsigned NOT NULL default {string:string_zero}, PRIMARY KEY (id_topic) ) SELECT t.id_topic, t.id_board, t.id_last_msg, IFNULL(lmr.id_msg, 0) AS id_msg' . (!in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? ', ' . $_REQUEST['sort'] . ' AS sort_key' : '') . ' FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member})' . (isset($sortKey_joins[$_REQUEST['sort']]) ? $sortKey_joins[$_REQUEST['sort']] : '') . ' WHERE m.id_member = {int:current_member}' . (!empty($board) ? ' AND t.id_board = {int:current_board}' : '') . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : '') . ' GROUP BY m.id_topic', array('current_board' => $board, 'current_member' => $user_info['id'], 'is_approved' => 1, 'string_zero' => '0', 'db_error_skip' => true)) !== false; // If that worked, create a sample of the log_topics table too. if ($have_temp_table) { $have_temp_table = $smcFunc['db_query']('', ' CREATE TEMPORARY TABLE {db_prefix}log_topics_posted_in ( PRIMARY KEY (id_topic) ) SELECT lt.id_topic, lt.id_msg FROM {db_prefix}log_topics AS lt INNER JOIN {db_prefix}topics_posted_in AS pi ON (pi.id_topic = lt.id_topic) WHERE lt.id_member = {int:current_member}', array('current_member' => $user_info['id'], 'db_error_skip' => true)) !== false; } } if (!empty($have_temp_table)) { $request = $smcFunc['db_query']('', ' SELECT COUNT(*) FROM {db_prefix}topics_posted_in AS pi LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = pi.id_topic) WHERE pi.' . $query_this_board . ' AND IFNULL(lt.id_msg, pi.id_msg) < pi.id_last_msg', array_merge($query_parameters, array())); list($num_topics) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); } else { $request = $smcFunc['db_query']('unread_fetch_topic_count', ' SELECT COUNT(DISTINCT t.id_topic), MIN(t.id_last_msg) FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic) LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ' AND m.id_member = {int:current_member} AND IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0)) < t.id_last_msg' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved}' : ''), array_merge($query_parameters, array('current_member' => $user_info['id'], 'is_approved' => 1))); list($num_topics, $min_message) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); } // Make sure the starting place makes sense and construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=' . $_REQUEST['action'] . $context['querystring_board_limits'] . $context['querystring_sort_limits'], $_REQUEST['start'], $num_topics, $context['topics_per_page'], true); $context['current_page'] = (int) $_REQUEST['start'] / $context['topics_per_page']; $context['links'] = array('first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], 0) . $context['querystring_sort_limits'] : '', 'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] - $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'next' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], $_REQUEST['start'] + $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'last' => $_REQUEST['start'] + $context['topics_per_page'] < $num_topics ? $scripturl . '?action=' . $_REQUEST['action'] . ($context['showing_all_topics'] ? ';all' : '') . sprintf($context['querystring_board_limits'], floor(($num_topics - 1) / $context['topics_per_page']) * $context['topics_per_page']) . $context['querystring_sort_limits'] : '', 'up' => $scripturl); $context['page_info'] = array('current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1, 'num_pages' => floor(($num_topics - 1) / $context['topics_per_page']) + 1); if ($num_topics == 0) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } if (!empty($have_temp_table)) { $request = $smcFunc['db_query']('', ' SELECT t.id_topic FROM {db_prefix}topics_posted_in AS t LEFT JOIN {db_prefix}log_topics_posted_in AS lt ON (lt.id_topic = t.id_topic) WHERE t.' . $query_this_board . ' AND IFNULL(lt.id_msg, t.id_msg) < t.id_last_msg ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('order' => (in_array($_REQUEST['sort'], array('t.id_last_msg', 't.id_topic')) ? $_REQUEST['sort'] : 't.sort_key') . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page']))); } else { $request = $smcFunc['db_query']('unread_replies', ' SELECT DISTINCT t.id_topic FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_topic = t.id_topic AND m.id_member = {int:current_member})' . (strpos($_REQUEST['sort'], 'ms.') === false ? '' : ' INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)') . (strpos($_REQUEST['sort'], 'mems.') === false ? '' : ' LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member)') . ' LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.' . $query_this_board . ' AND t.id_last_msg >= {int:min_message} AND (IFNULL(lt.id_msg, IFNULL(lmr.id_msg, 0))) < t.id_last_msg AND t.approved = {int:is_approved} ORDER BY {raw:order} LIMIT {int:offset}, {int:limit}', array_merge($query_parameters, array('current_member' => $user_info['id'], 'min_message' => (int) $min_message, 'is_approved' => 1, 'order' => $_REQUEST['sort'] . ($ascending ? '' : ' DESC'), 'offset' => $_REQUEST['start'], 'limit' => $context['topics_per_page'], 'sort' => $_REQUEST['sort']))); } $topics = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $topics[] = $row['id_topic']; } $smcFunc['db_free_result']($request); // Sanity... where have you gone? if (empty($topics)) { $context['topics'] = array(); if ($context['querystring_board_limits'] == ';start=%d') { $context['querystring_board_limits'] = ''; } else { $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); } return; } $request = $smcFunc['db_query']('substring', ' SELECT ' . $select_clause . ' FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS ms ON (ms.id_topic = t.id_topic AND ms.id_msg = t.id_first_msg) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}members AS mems ON (mems.id_member = ms.id_member) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board AND lmr.id_member = {int:current_member}) WHERE t.id_topic IN ({array_int:topic_list}) ORDER BY ' . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . ' LIMIT ' . count($topics), array('current_member' => $user_info['id'], 'topic_list' => $topics)); } $context['topics'] = array(); $topic_ids = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') { continue; } $topic_ids[] = $row['id_topic']; if (!empty($settings['message_index_preview'])) { // Limit them to 128 characters - do this FIRST because it's a lot of wasted censoring otherwise. $row['first_body'] = strip_tags(strtr(parse_bbc($row['first_body'], $row['first_smileys'], $row['id_first_msg']), array('<br />' => ' '))); if ($smcFunc['strlen']($row['first_body']) > 128) { $row['first_body'] = $smcFunc['substr']($row['first_body'], 0, 128) . '...'; } $row['last_body'] = strip_tags(strtr(parse_bbc($row['last_body'], $row['last_smileys'], $row['id_last_msg']), array('<br />' => ' '))); if ($smcFunc['strlen']($row['last_body']) > 128) { $row['last_body'] = $smcFunc['substr']($row['last_body'], 0, 128) . '...'; } // Censor the subject and message preview. censorText($row['first_subject']); censorText($row['first_body']); // Don't censor them twice! if ($row['id_first_msg'] == $row['id_last_msg']) { $row['last_subject'] = $row['first_subject']; $row['last_body'] = $row['first_body']; } else { censorText($row['last_subject']); censorText($row['last_body']); } } else { $row['first_body'] = ''; $row['last_body'] = ''; censorText($row['first_subject']); if ($row['id_first_msg'] == $row['id_last_msg']) { $row['last_subject'] = $row['first_subject']; } else { censorText($row['last_subject']); } } // Decide how many pages the topic should have. $topic_length = $row['num_replies'] + 1; $messages_per_page = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages']; if ($topic_length > $messages_per_page) { $tmppages = array(); $tmpa = 1; for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $messages_per_page) { $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.' . $tmpb . ';topicseen">' . $tmpa . '</a>'; $tmpa++; } // Show links to all the pages? if (count($tmppages) <= 5) { $pages = '« ' . implode(' ', $tmppages); } else { $pages = '« ' . $tmppages[0] . ' ' . $tmppages[1] . ' ... ' . $tmppages[count($tmppages) - 2] . ' ' . $tmppages[count($tmppages) - 1]; } if (!empty($modSettings['enableAllMessages']) && $topic_length < $modSettings['enableAllMessages']) { $pages .= ' <a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;all">' . $txt['all'] . '</a>'; } $pages .= ' »'; } else { $pages = ''; } // We need to check the topic icons exist... you can never be too sure! if (empty($modSettings['messageIconChecks_disable'])) { // First icon first... as you'd expect. if (!isset($context['icon_sources'][$row['first_icon']])) { $context['icon_sources'][$row['first_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['first_icon'] . '.gif') ? 'images_url' : 'default_images_url'; } // Last icon... last... duh. if (!isset($context['icon_sources'][$row['last_icon']])) { $context['icon_sources'][$row['last_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['last_icon'] . '.gif') ? 'images_url' : 'default_images_url'; } } // And build the array. $context['topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('name' => $row['first_poster_name'], 'id' => $row['id_first_member'], 'href' => $scripturl . '?action=profile;u=' . $row['id_first_member'], 'link' => !empty($row['id_first_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_first_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_poster_name'] . '">' . $row['first_poster_name'] . '</a>' : $row['first_poster_name']), 'time' => timeformat($row['first_poster_time']), 'timestamp' => forum_time(true, $row['first_poster_time']), 'subject' => $row['first_subject'], 'preview' => $row['first_body'], 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0;topicseen', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;topicseen">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('name' => $row['last_poster_name'], 'id' => $row['id_last_member'], 'href' => $scripturl . '?action=profile;u=' . $row['id_last_member'], 'link' => !empty($row['id_last_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_last_member'] . '">' . $row['last_poster_name'] . '</a>' : $row['last_poster_name']), 'time' => timeformat($row['last_poster_time']), 'timestamp' => forum_time(true, $row['last_poster_time']), 'subject' => $row['last_subject'], 'preview' => $row['last_body'], 'icon' => $row['last_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.gif', 'href' => $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . ';topicseen#msg' . $row['id_last_msg'], 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . ';topicseen#msg' . $row['id_last_msg'] . '" rel="nofollow">' . $row['last_subject'] . '</a>'), 'new_from' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . ';topicseen#new', 'href' => $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen' . ($row['num_replies'] == 0 ? '' : 'new'), 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['new_from']) . ';topicseen#msg' . $row['new_from'] . '" rel="nofollow">' . $row['first_subject'] . '</a>', 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($row['is_sticky']), 'is_locked' => !empty($row['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0, 'is_hot' => $row['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $row['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'is_posted_in' => false, 'icon' => $row['first_icon'], 'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.gif', 'subject' => $row['first_subject'], 'pages' => $pages, 'replies' => comma_format($row['num_replies']), 'views' => comma_format($row['num_views']), 'board' => array('id' => $row['id_board'], 'name' => $row['bname'], 'href' => $scripturl . '?board=' . $row['id_board'] . '.0', 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['bname'] . '</a>')); determineTopicClass($context['topics'][$row['id_topic']]); } $smcFunc['db_free_result']($request); if ($is_topics && !empty($modSettings['enableParticipation']) && !empty($topic_ids)) { $result = $smcFunc['db_query']('', ' SELECT id_topic FROM {db_prefix}messages WHERE id_topic IN ({array_int:topic_list}) AND id_member = {int:current_member} GROUP BY id_topic LIMIT {int:limit}', array('current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'limit' => count($topic_ids))); while ($row = $smcFunc['db_fetch_assoc']($result)) { if (empty($context['topics'][$row['id_topic']]['is_posted_in'])) { $context['topics'][$row['id_topic']]['is_posted_in'] = true; $context['topics'][$row['id_topic']]['class'] = 'my_' . $context['topics'][$row['id_topic']]['class']; } } $smcFunc['db_free_result']($result); } $context['querystring_board_limits'] = sprintf($context['querystring_board_limits'], $_REQUEST['start']); $context['topics_to_mark'] = implode('-', $topic_ids); }
function ModifyKarma() { global $modSettings, $txt, $user_info, $topic, $smcFunc, $context; // If the mod is disabled, show an error. if (empty($modSettings['karmaMode'])) { fatal_lang_error('feature_disabled', true); } // If you're a guest or can't do this, blow you off... is_not_guest(); isAllowedTo('karma_edit'); checkSession('get'); // If you don't have enough posts, tough luck. // !!! Should this be dropped in favor of post group permissions? Should this apply to the member you are smiting/applauding? if (!$user_info['is_admin'] && $user_info['posts'] < $modSettings['karmaMinPosts']) { fatal_lang_error('not_enough_posts_karma', true, array($modSettings['karmaMinPosts'])); } // And you can't modify your own, punk! (use the profile if you need to.) if (empty($_REQUEST['uid']) || (int) $_REQUEST['uid'] == $user_info['id']) { fatal_lang_error('cant_change_own_karma', false); } // The user ID _must_ be a number, no matter what. $_REQUEST['uid'] = (int) $_REQUEST['uid']; // Applauding or smiting? $dir = $_REQUEST['sa'] != 'applaud' ? -1 : 1; // Delete any older items from the log. (karmaWaitTime is by hour.) smf_db_query(' DELETE FROM {db_prefix}log_karma WHERE {int:current_time} - log_time > {int:wait_time}', array('wait_time' => (int) ($modSettings['karmaWaitTime'] * 3600), 'current_time' => time())); // Start off with no change in karma. $action = 0; // Not an administrator... or one who is restricted as well. if (!empty($modSettings['karmaTimeRestrictAdmins']) || !allowedTo('moderate_forum')) { // Find out if this user has done this recently... $request = smf_db_query(' SELECT action FROM {db_prefix}log_karma WHERE id_target = {int:id_target} AND id_executor = {int:current_member} LIMIT 1', array('current_member' => $user_info['id'], 'id_target' => $_REQUEST['uid'])); if (mysql_num_rows($request) > 0) { list($action) = mysql_fetch_row($request); } mysql_free_result($request); } // They haven't, not before now, anyhow. if (empty($action) || empty($modSettings['karmaWaitTime'])) { // Put it in the log. smf_db_insert('replace', '{db_prefix}log_karma', array('action' => 'int', 'id_target' => 'int', 'id_executor' => 'int', 'log_time' => 'int'), array($dir, $_REQUEST['uid'], $user_info['id'], time()), array('id_target', 'id_executor')); // Change by one. updateMemberData($_REQUEST['uid'], array($dir == 1 ? 'karma_good' : 'karma_bad' => '+')); } else { // If you are gonna try to repeat.... don't allow it. if ($action == $dir) { fatal_lang_error('karma_wait_time', false, array($modSettings['karmaWaitTime'], $txt['hours'])); } // You decided to go back on your previous choice? smf_db_query(' UPDATE {db_prefix}log_karma SET action = {int:action}, log_time = {int:current_time} WHERE id_target = {int:id_target} AND id_executor = {int:current_member}', array('current_member' => $user_info['id'], 'action' => $dir, 'current_time' => time(), 'id_target' => $_REQUEST['uid'])); // It was recently changed the OTHER way... so... reverse it! if ($dir == 1) { updateMemberData($_REQUEST['uid'], array('karma_good' => '+', 'karma_bad' => '-')); } else { updateMemberData($_REQUEST['uid'], array('karma_bad' => '+', 'karma_good' => '-')); } } // Figure out where to go back to.... the topic? if (!empty($topic)) { redirectexit('topic=' . $topic . '.' . $_REQUEST['start'] . '#msg' . (int) $_REQUEST['m']); } elseif (isset($_REQUEST['f'])) { redirectexit('action=pm;f=' . $_REQUEST['f'] . ';start=' . $_REQUEST['start'] . (isset($_REQUEST['l']) ? ';l=' . (int) $_REQUEST['l'] : '') . (isset($_REQUEST['pm']) ? '#' . (int) $_REQUEST['pm'] : '')); } else { echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"', $context['right_to_left'] ? ' dir="rtl"' : '', '> <head> <title>...</title> <script type="text/javascript"><!-- // --><![CDATA[ history.go(-1); // ]]></script> </head> <body>«</body> </html>'; obExit(false); } }
function Post() { global $txt, $scripturl, $topic, $db_prefix, $modSettings, $board, $ID_MEMBER; global $user_info, $sc, $board_info, $context, $settings, $sourcedir; global $options, $func, $language; loadLanguage('Post'); $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new'); // You can't reply with a poll... hacker. if (isset($_REQUEST['poll']) && !empty($topic) && !isset($_REQUEST['msg'])) { unset($_REQUEST['poll']); } // Posting an event? $context['make_event'] = isset($_REQUEST['calendar']); // You must be posting to *some* board. if (empty($board) && !$context['make_event']) { fatal_lang_error('smf232', false); } require_once $sourcedir . '/Subs-Post.php'; if (isset($_REQUEST['xml'])) { $context['sub_template'] = 'post'; // Just in case of an earlier error... $context['preview_message'] = ''; $context['preview_subject'] = ''; } // Check if it's locked. It isn't locked if no topic is specified. if (!empty($topic)) { $request = db_query("\n\t\t\tSELECT\n\t\t\t\tt.locked, IFNULL(ln.ID_TOPIC, 0) AS notify, t.isSticky, t.ID_POLL, t.numReplies, mf.ID_MEMBER,\n\t\t\t\tt.ID_FIRST_MSG, mf.subject, GREATEST(ml.posterTime, ml.modifiedTime) AS lastPostTime\n\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\tLEFT JOIN {$db_prefix}log_notify AS ln ON (ln.ID_TOPIC = t.ID_TOPIC AND ln.ID_MEMBER = {$ID_MEMBER})\n\t\t\t\tLEFT JOIN {$db_prefix}messages AS mf ON (mf.ID_MSG = t.ID_FIRST_MSG)\n\t\t\t\tLEFT JOIN {$db_prefix}messages AS ml ON (ml.ID_MSG = t.ID_LAST_MSG)\n\t\t\tWHERE t.ID_TOPIC = {$topic}\n\t\t\tLIMIT 1", __FILE__, __LINE__); list($locked, $context['notify'], $sticky, $pollID, $context['num_replies'], $ID_MEMBER_POSTER, $ID_FIRST_MSG, $first_subject, $lastPostTime) = mysql_fetch_row($request); mysql_free_result($request); // If this topic already has a poll, they sure can't add another. if (isset($_REQUEST['poll']) && $pollID > 0) { unset($_REQUEST['poll']); } if (empty($_REQUEST['msg'])) { if ($user_info['is_guest'] && !allowedTo('post_reply_any')) { is_not_guest(); } if ($ID_MEMBER_POSTER != $ID_MEMBER) { isAllowedTo('post_reply_any'); } elseif (!allowedTo('post_reply_any')) { isAllowedTo('post_reply_own'); } } $context['can_lock'] = allowedTo('lock_any') || $ID_MEMBER == $ID_MEMBER_POSTER && allowedTo('lock_own'); $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']); $context['notify'] = !empty($context['notify']); $context['sticky'] = isset($_REQUEST['sticky']) ? !empty($_REQUEST['sticky']) : $sticky; } else { if ((!$context['make_event'] || !empty($board)) && (!isset($_REQUEST['poll']) || $modSettings['pollMode'] != '1')) { isAllowedTo('post_new'); } $locked = 0; // !!! These won't work if you're making an event. $context['can_lock'] = allowedTo(array('lock_any', 'lock_own')); $context['can_sticky'] = allowedTo('make_sticky') && !empty($modSettings['enableStickyTopics']); $context['notify'] = !empty($context['notify']); $context['sticky'] = !empty($_REQUEST['sticky']); } // !!! These won't work if you're posting an event! $context['can_notify'] = allowedTo('mark_any_notify'); $context['can_move'] = allowedTo('move_any'); $context['can_announce'] = allowedTo('announce_topic'); $context['locked'] = !empty($locked) || !empty($_REQUEST['lock']); // An array to hold all the attachments for this topic. $context['current_attachments'] = array(); // Don't allow a post if it's locked and you aren't all powerful. if ($locked && !allowedTo('moderate_board')) { fatal_lang_error(90, false); } // Check the users permissions - is the user allowed to add or post a poll? if (isset($_REQUEST['poll']) && $modSettings['pollMode'] == '1') { // New topic, new poll. if (empty($topic)) { isAllowedTo('poll_post'); } elseif ($ID_MEMBER == $ID_MEMBER_POSTER && !allowedTo('poll_add_any')) { isAllowedTo('poll_add_own'); } else { isAllowedTo('poll_add_any'); } // Set up the poll options. $context['poll_options'] = array('max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), 'hide' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], 'expire' => !isset($_POST['poll_expire']) ? '' : $_POST['poll_expire'], 'change_vote' => isset($_POST['poll_change_vote'])); // Make all five poll choices empty. $context['choices'] = array(array('id' => 0, 'number' => 1, 'label' => '', 'is_last' => false), array('id' => 1, 'number' => 2, 'label' => '', 'is_last' => false), array('id' => 2, 'number' => 3, 'label' => '', 'is_last' => false), array('id' => 3, 'number' => 4, 'label' => '', 'is_last' => false), array('id' => 4, 'number' => 5, 'label' => '', 'is_last' => true)); } if ($context['make_event']) { // They might want to pick a board. if (!isset($context['current_board'])) { $context['current_board'] = 0; } // Start loading up the event info. $context['event'] = array(); $context['event']['title'] = isset($_REQUEST['evtitle']) ? htmlspecialchars(stripslashes($_REQUEST['evtitle'])) : ''; $context['event']['id'] = isset($_REQUEST['eventid']) ? (int) $_REQUEST['eventid'] : -1; $context['event']['new'] = $context['event']['id'] == -1; // Permissions check! isAllowedTo('calendar_post'); // Editing an event? (but NOT previewing!?) if (!$context['event']['new'] && !isset($_REQUEST['subject'])) { // If the user doesn't have permission to edit the post in this topic, redirect them. if ($ID_MEMBER_POSTER != $ID_MEMBER || !allowedTo('modify_own') && !allowedTo('modify_any')) { require_once $sourcedir . '/Calendar.php'; return CalendarPost(); } // Get the current event information. $request = db_query("\n\t\t\t\tSELECT\n\t\t\t\t\tID_MEMBER, title, MONTH(startDate) AS month, DAYOFMONTH(startDate) AS day,\n\t\t\t\t\tYEAR(startDate) AS year, (TO_DAYS(endDate) - TO_DAYS(startDate)) AS span\n\t\t\t\tFROM {$db_prefix}calendar\n\t\t\t\tWHERE ID_EVENT = " . $context['event']['id'] . "\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); $row = mysql_fetch_assoc($request); mysql_free_result($request); // Make sure the user is allowed to edit this event. if ($row['ID_MEMBER'] != $ID_MEMBER) { isAllowedTo('calendar_edit_any'); } elseif (!allowedTo('calendar_edit_any')) { isAllowedTo('calendar_edit_own'); } $context['event']['month'] = $row['month']; $context['event']['day'] = $row['day']; $context['event']['year'] = $row['year']; $context['event']['title'] = $row['title']; $context['event']['span'] = $row['span'] + 1; } else { $today = getdate(); // You must have a month and year specified! if (!isset($_REQUEST['month'])) { $_REQUEST['month'] = $today['mon']; } if (!isset($_REQUEST['year'])) { $_REQUEST['year'] = $today['year']; } $context['event']['month'] = (int) $_REQUEST['month']; $context['event']['year'] = (int) $_REQUEST['year']; $context['event']['day'] = isset($_REQUEST['day']) ? $_REQUEST['day'] : ($_REQUEST['month'] == $today['mon'] ? $today['mday'] : 0); $context['event']['span'] = isset($_REQUEST['span']) ? $_REQUEST['span'] : 1; // Make sure the year and month are in the valid range. if ($context['event']['month'] < 1 || $context['event']['month'] > 12) { fatal_lang_error('calendar1', false); } if ($context['event']['year'] < $modSettings['cal_minyear'] || $context['event']['year'] > $modSettings['cal_maxyear']) { fatal_lang_error('calendar2', false); } // Get a list of boards they can post in. $boards = boardsAllowedTo('post_new'); if (empty($boards)) { fatal_lang_error('cannot_post_new'); } $request = db_query("\n\t\t\t\tSELECT c.name AS catName, c.ID_CAT, b.ID_BOARD, b.name AS boardName, b.childLevel\n\t\t\t\tFROM {$db_prefix}boards AS b\n\t\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\t\tWHERE {$user_info['query_see_board']}" . (in_array(0, $boards) ? '' : "\n\t\t\t\t\tAND b.ID_BOARD IN (" . implode(', ', $boards) . ")"), __FILE__, __LINE__); $context['event']['boards'] = array(); while ($row = mysql_fetch_assoc($request)) { $context['event']['boards'][] = array('id' => $row['ID_BOARD'], 'name' => $row['boardName'], 'childLevel' => $row['childLevel'], 'prefix' => str_repeat(' ', $row['childLevel'] * 3), 'cat' => array('id' => $row['ID_CAT'], 'name' => $row['catName'])); } mysql_free_result($request); } // Find the last day of the month. $context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year'])); $context['event']['board'] = !empty($board) ? $board : $modSettings['cal_defaultboard']; } if (empty($context['post_errors'])) { $context['post_errors'] = array(); } // See if any new replies have come along. if (empty($_REQUEST['msg']) && !empty($topic)) { if (empty($options['no_new_reply_warning']) && isset($_REQUEST['num_replies'])) { $newReplies = $context['num_replies'] > $_REQUEST['num_replies'] ? $context['num_replies'] - $_REQUEST['num_replies'] : 0; if (!empty($newReplies)) { if ($newReplies == 1) { $txt['error_new_reply'] = isset($_GET['num_replies']) ? $txt['error_new_reply_reading'] : $txt['error_new_reply']; } else { $txt['error_new_replies'] = sprintf(isset($_GET['num_replies']) ? $txt['error_new_replies_reading'] : $txt['error_new_replies'], $newReplies); } // If they've come from the display page then we treat the error differently.... if (isset($_GET['num_replies'])) { $newRepliesError = $newReplies; } else { $context['post_error'][$newReplies == 1 ? 'new_reply' : 'new_replies'] = true; } $modSettings['topicSummaryPosts'] = $newReplies > $modSettings['topicSummaryPosts'] ? max($modSettings['topicSummaryPosts'], 5) : $modSettings['topicSummaryPosts']; } } // Check whether this is a really old post being bumped... if (!empty($modSettings['oldTopicDays']) && $lastPostTime + $modSettings['oldTopicDays'] * 86400 < time() && empty($sticky) && !isset($_REQUEST['subject'])) { $oldTopicError = true; } } // Get a response prefix (like 'Re:') in the default forum language. if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix'))) { if ($language === $user_info['language']) { $context['response_prefix'] = $txt['response_prefix']; } else { loadLanguage('index', $language, false); $context['response_prefix'] = $txt['response_prefix']; loadLanguage('index'); } cache_put_data('response_prefix', $context['response_prefix'], 600); } // Previewing, modifying, or posting? if (isset($_REQUEST['message']) || !empty($context['post_error'])) { // Validate inputs. if (empty($context['post_error'])) { if ($func['htmltrim']($_REQUEST['subject']) == '') { $context['post_error']['no_subject'] = true; } if ($func['htmltrim']($_REQUEST['message']) == '') { $context['post_error']['no_message'] = true; } if (!empty($modSettings['max_messageLength']) && $func['strlen']($_REQUEST['message']) > $modSettings['max_messageLength']) { $context['post_error']['long_message'] = true; } // Are you... a guest? if ($user_info['is_guest']) { $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']); $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']); // Validate the name and email. if (!isset($_REQUEST['guestname']) || trim(strtr($_REQUEST['guestname'], '_', ' ')) == '') { $context['post_error']['no_name'] = true; } elseif ($func['strlen']($_REQUEST['guestname']) > 25) { $context['post_error']['long_name'] = true; } else { require_once $sourcedir . '/Subs-Members.php'; if (isReservedName(htmlspecialchars($_REQUEST['guestname']), 0, true, false)) { $context['post_error']['bad_name'] = true; } } if (empty($modSettings['guest_post_no_email'])) { if (!isset($_REQUEST['email']) || $_REQUEST['email'] == '') { $context['post_error']['no_email'] = true; } elseif (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_REQUEST['email'])) == 0) { $context['post_error']['bad_email'] = true; } } } // This is self explanatory - got any questions? if (isset($_REQUEST['question']) && trim($_REQUEST['question']) == '') { $context['post_error']['no_question'] = true; } // This means they didn't click Post and get an error. $really_previewing = true; } else { if (!isset($_REQUEST['subject'])) { $_REQUEST['subject'] = ''; } if (!isset($_REQUEST['message'])) { $_REQUEST['message'] = ''; } if (!isset($_REQUEST['icon'])) { $_REQUEST['icon'] = 'xx'; } $really_previewing = false; } // Set up the inputs for the form. $form_subject = strtr($func['htmlspecialchars'](stripslashes($_REQUEST['subject'])), array("\r" => '', "\n" => '', "\t" => '')); $form_message = $func['htmlspecialchars'](stripslashes($_REQUEST['message']), ENT_QUOTES); // Make sure the subject isn't too long - taking into account special characters. if ($func['strlen']($form_subject) > 100) { $form_subject = $func['substr']($form_subject, 0, 100); } // Have we inadvertently trimmed off the subject of useful information? if ($func['htmltrim']($form_subject) === '') { $context['post_error']['no_subject'] = true; } // Any errors occurred? if (!empty($context['post_error'])) { loadLanguage('Errors'); $context['error_type'] = 'minor'; $context['post_error']['messages'] = array(); foreach ($context['post_error'] as $post_error => $dummy) { if ($post_error == 'messages') { continue; } $context['post_error']['messages'][] = $txt['error_' . $post_error]; // If it's not a minor error flag it as such. if (!in_array($post_error, array('new_reply', 'new_replies', 'old_topic'))) { $context['error_type'] = 'serious'; } } } if (isset($_REQUEST['poll'])) { $context['question'] = isset($_REQUEST['question']) ? $func['htmlspecialchars'](stripslashes(trim($_REQUEST['question']))) : ''; $context['choices'] = array(); $choice_id = 0; $_POST['options'] = empty($_POST['options']) ? array() : htmlspecialchars__recursive(stripslashes__recursive($_POST['options'])); foreach ($_POST['options'] as $option) { if (trim($option) == '') { continue; } $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => $option, 'is_last' => false); } if (count($context['choices']) < 2) { $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false); $context['choices'][] = array('id' => $choice_id++, 'number' => $choice_id, 'label' => '', 'is_last' => false); } $context['choices'][count($context['choices']) - 1]['is_last'] = true; } // Are you... a guest? if ($user_info['is_guest']) { $_REQUEST['guestname'] = !isset($_REQUEST['guestname']) ? '' : trim($_REQUEST['guestname']); $_REQUEST['email'] = !isset($_REQUEST['email']) ? '' : trim($_REQUEST['email']); $_REQUEST['guestname'] = htmlspecialchars($_REQUEST['guestname']); $context['name'] = $_REQUEST['guestname']; $_REQUEST['email'] = htmlspecialchars($_REQUEST['email']); $context['email'] = $_REQUEST['email']; $user_info['name'] = $_REQUEST['guestname']; } // Only show the preview stuff if they hit Preview. if ($really_previewing == true || isset($_REQUEST['xml'])) { // Set up the preview message and subject and censor them... $context['preview_message'] = $form_message; preparsecode($form_message, true); preparsecode($context['preview_message']); // Do all bulletin board code tags, with or without smileys. $context['preview_message'] = parse_bbc($context['preview_message'], isset($_REQUEST['ns']) ? 0 : 1); if ($form_subject != '') { $context['preview_subject'] = $form_subject; censorText($context['preview_subject']); censorText($context['preview_message']); } else { $context['preview_subject'] = '<i>' . $txt[24] . '</i>'; } // Protect any CDATA blocks. if (isset($_REQUEST['xml'])) { $context['preview_message'] = strtr($context['preview_message'], array(']]>' => ']]]]><![CDATA[>')); } } // Set up the checkboxes. $context['notify'] = !empty($_REQUEST['notify']); $context['use_smileys'] = !isset($_REQUEST['ns']); $context['icon'] = isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : 'xx'; // Set the destination action for submission. $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['msg']) ? ';msg=' . $_REQUEST['msg'] . ';sesc=' . $sc : '') . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = isset($_REQUEST['msg']) ? $txt[10] : $txt[105]; // Previewing an edit? if (isset($_REQUEST['msg'])) { if (!empty($modSettings['attachmentEnable'])) { $request = db_query("\n\t\t\t\t\tSELECT IFNULL(size, -1) AS filesize, filename, ID_ATTACH\n\t\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\t\t AND attachmentType = 0", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { if ($row['filesize'] <= 0) { continue; } $context['current_attachments'][] = array('name' => $row['filename'], 'id' => $row['ID_ATTACH']); } mysql_free_result($request); } // Allow moderators to change names.... if (allowedTo('moderate_forum') && !empty($topic)) { $request = db_query("\n\t\t\t\t\tSELECT ID_MEMBER, posterName, posterEmail\n\t\t\t\t\tFROM {$db_prefix}messages\n\t\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\t\tAND ID_TOPIC = {$topic}\n\t\t\t\t\tLIMIT 1", __FILE__, __LINE__); $row = mysql_fetch_assoc($request); mysql_free_result($request); if (empty($row['ID_MEMBER'])) { $context['name'] = htmlspecialchars($row['posterName']); $context['email'] = htmlspecialchars($row['posterEmail']); } } } // No check is needed, since nothing is really posted. checkSubmitOnce('free'); } elseif (isset($_REQUEST['msg'])) { checkSession('get'); // Get the existing message. $request = db_query("\n\t\t\tSELECT\n\t\t\t\tm.ID_MEMBER, m.modifiedTime, m.smileysEnabled, m.body,\n\t\t\t\tm.posterName, m.posterEmail, m.subject, m.icon,\n\t\t\t\tIFNULL(a.size, -1) AS filesize, a.filename, a.ID_ATTACH,\n\t\t\t\tt.ID_MEMBER_STARTED AS ID_MEMBER_POSTER, m.posterTime\n\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\t\tLEFT JOIN {$db_prefix}attachments AS a ON (a.ID_MSG = m.ID_MSG AND a.attachmentType = 0)\n\t\t\tWHERE m.ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\tAND m.ID_TOPIC = {$topic}\n\t\t\t\tAND t.ID_TOPIC = {$topic}", __FILE__, __LINE__); // The message they were trying to edit was most likely deleted. // !!! Change this error message? if (mysql_num_rows($request) == 0) { fatal_lang_error('smf232', false); } $row = mysql_fetch_assoc($request); $attachment_stuff = array($row); while ($row2 = mysql_fetch_assoc($request)) { $attachment_stuff[] = $row2; } mysql_free_result($request); if ($row['ID_MEMBER'] == $ID_MEMBER && !allowedTo('modify_any')) { // Give an extra five minutes over the disable time threshold, so they can type. if (!empty($modSettings['edit_disable_time']) && $row['posterTime'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_own')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_own'); } } elseif ($row['ID_MEMBER_POSTER'] == $ID_MEMBER && !allowedTo('modify_any')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_any'); } // When was it last modified? if (!empty($row['modifiedTime'])) { $context['last_modified'] = timeformat($row['modifiedTime']); } // Get the stuff ready for the form. $form_subject = $row['subject']; $form_message = un_preparsecode($row['body']); censorText($form_message); censorText($form_subject); // Check the boxes that should be checked. $context['use_smileys'] = !empty($row['smileysEnabled']); $context['icon'] = $row['icon']; // Load up 'em attachments! foreach ($attachment_stuff as $attachment) { if ($attachment['filesize'] >= 0 && !empty($modSettings['attachmentEnable'])) { $context['current_attachments'][] = array('name' => $attachment['filename'], 'id' => $attachment['ID_ATTACH']); } } // Allow moderators to change names.... if (allowedTo('moderate_forum') && empty($row['ID_MEMBER'])) { $context['name'] = htmlspecialchars($row['posterName']); $context['email'] = htmlspecialchars($row['posterEmail']); } // Set the destinaton. $context['destination'] = 'post2;start=' . $_REQUEST['start'] . ';msg=' . $_REQUEST['msg'] . ';sesc=' . $sc . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = $txt[10]; } else { // By default.... $context['use_smileys'] = true; $context['icon'] = 'xx'; if ($user_info['is_guest']) { $context['name'] = ''; $context['email'] = ''; } $context['destination'] = 'post2;start=' . $_REQUEST['start'] . (isset($_REQUEST['poll']) ? ';poll' : ''); $context['submit_label'] = $txt[105]; // Posting a quoted reply? if (!empty($topic) && !empty($_REQUEST['quote'])) { checkSession('get'); // Make sure they _can_ quote this post, and if so get it. $request = db_query("\n\t\t\t\tSELECT m.subject, IFNULL(mem.realName, m.posterName) AS posterName, m.posterTime, m.body\n\t\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b)\n\t\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER)\n\t\t\t\tWHERE m.ID_MSG = " . (int) $_REQUEST['quote'] . "\n\t\t\t\t\tAND b.ID_BOARD = m.ID_BOARD\n\t\t\t\t\tAND {$user_info['query_see_board']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { fatal_lang_error('quoted_post_deleted', false); } list($form_subject, $mname, $mdate, $form_message) = mysql_fetch_row($request); mysql_free_result($request); // Add 'Re: ' to the front of the quoted subject. if (trim($context['response_prefix']) != '' && $func['strpos']($form_subject, trim($context['response_prefix'])) !== 0) { $form_subject = $context['response_prefix'] . $form_subject; } // Censor the message and subject. censorText($form_message); censorText($form_subject); $form_message = preg_replace('~<br(?: /)?' . '>~i', "\n", $form_message); // Remove any nested quotes, if necessary. if (!empty($modSettings['removeNestedQuotes'])) { $form_message = preg_replace(array('~\\n?\\[quote.*?\\].+?\\[/quote\\]\\n?~is', '~^\\n~', '~\\[/quote\\]~'), '', $form_message); } // Add a quote string on the front and end. $form_message = '[quote author=' . $mname . ' link=topic=' . $topic . '.msg' . (int) $_REQUEST['quote'] . '#msg' . (int) $_REQUEST['quote'] . ' date=' . $mdate . ']' . "\n" . $form_message . "\n" . '[/quote]'; } elseif (!empty($topic) && empty($_REQUEST['quote'])) { // Get the first message's subject. $form_subject = $first_subject; // Add 'Re: ' to the front of the subject. if (trim($context['response_prefix']) != '' && $form_subject != '' && $func['strpos']($form_subject, trim($context['response_prefix'])) !== 0) { $form_subject = $context['response_prefix'] . $form_subject; } // Censor the subject. censorText($form_subject); $form_message = ''; } else { $form_subject = isset($_GET['subject']) ? $_GET['subject'] : ''; $form_message = ''; } } // !!! This won't work if you're posting an event. if (allowedTo('post_attachment')) { if (empty($_SESSION['temp_attachments'])) { $_SESSION['temp_attachments'] = array(); } // If this isn't a new post, check the current attachments. if (isset($_REQUEST['msg'])) { $request = db_query("\n\t\t\t\tSELECT COUNT(*), SUM(size)\n\t\t\t\tFROM {$db_prefix}attachments\n\t\t\t\tWHERE ID_MSG = " . (int) $_REQUEST['msg'] . "\n\t\t\t\t\tAND attachmentType = 0", __FILE__, __LINE__); list($quantity, $total_size) = mysql_fetch_row($request); mysql_free_result($request); } else { $quantity = 0; $total_size = 0; } $temp_start = 0; if (!empty($_SESSION['temp_attachments'])) { foreach ($_SESSION['temp_attachments'] as $attachID => $name) { $temp_start++; if (preg_match('~^post_tmp_' . $ID_MEMBER . '_\\d+$~', $attachID) == 0) { unset($_SESSION['temp_attachments'][$attachID]); continue; } if (!empty($_POST['attach_del']) && !in_array($attachID, $_POST['attach_del'])) { $deleted_attachments = true; unset($_SESSION['temp_attachments'][$attachID]); @unlink($modSettings['attachmentUploadDir'] . '/' . $attachID); continue; } $quantity++; $total_size += filesize($modSettings['attachmentUploadDir'] . '/' . $attachID); $context['current_attachments'][] = array('name' => getAttachmentFilename($name, false, true), 'id' => $attachID); } } if (!empty($_POST['attach_del'])) { $del_temp = array(); foreach ($_POST['attach_del'] as $i => $dummy) { $del_temp[$i] = (int) $dummy; } foreach ($context['current_attachments'] as $k => $dummy) { if (!in_array($dummy['id'], $del_temp)) { $context['current_attachments'][$k]['unchecked'] = true; $deleted_attachments = !isset($deleted_attachments) || is_bool($deleted_attachments) ? 1 : $deleted_attachments + 1; $quantity--; } } } if (!empty($_FILES['attachment'])) { foreach ($_FILES['attachment']['tmp_name'] as $n => $dummy) { if ($_FILES['attachment']['name'][$n] == '') { continue; } if (!is_uploaded_file($_FILES['attachment']['tmp_name'][$n]) || @ini_get('open_basedir') == '' && !file_exists($_FILES['attachment']['tmp_name'][$n])) { fatal_lang_error('smf124'); } if (!empty($modSettings['attachmentSizeLimit']) && $_FILES['attachment']['size'][$n] > $modSettings['attachmentSizeLimit'] * 1024) { fatal_lang_error('smf122', false, array($modSettings['attachmentSizeLimit'])); } $quantity++; if (!empty($modSettings['attachmentNumPerPostLimit']) && $quantity > $modSettings['attachmentNumPerPostLimit']) { fatal_lang_error('attachments_limit_per_post', false, array($modSettings['attachmentNumPerPostLimit'])); } $total_size += $_FILES['attachment']['size'][$n]; if (!empty($modSettings['attachmentPostLimit']) && $total_size > $modSettings['attachmentPostLimit'] * 1024) { fatal_lang_error('smf122', false, array($modSettings['attachmentPostLimit'])); } if (!empty($modSettings['attachmentCheckExtensions'])) { if (!in_array(strtolower(substr(strrchr($_FILES['attachment']['name'][$n], '.'), 1)), explode(',', strtolower($modSettings['attachmentExtensions'])))) { fatal_error($_FILES['attachment']['name'][$n] . '.<br />' . $txt['smf123'] . ' ' . $modSettings['attachmentExtensions'] . '.', false); } } if (!empty($modSettings['attachmentDirSizeLimit'])) { // Make sure the directory isn't full. $dirSize = 0; $dir = @opendir($modSettings['attachmentUploadDir']) or fatal_lang_error('smf115b'); while ($file = readdir($dir)) { if (substr($file, 0, -1) == '.') { continue; } if (preg_match('~^post_tmp_\\d+_\\d+$~', $file) != 0) { // Temp file is more than 5 hours old! if (filemtime($modSettings['attachmentUploadDir'] . '/' . $file) < time() - 18000) { @unlink($modSettings['attachmentUploadDir'] . '/' . $file); } continue; } $dirSize += filesize($modSettings['attachmentUploadDir'] . '/' . $file); } closedir($dir); // Too big! Maybe you could zip it or something... if ($_FILES['attachment']['size'][$n] + $dirSize > $modSettings['attachmentDirSizeLimit'] * 1024) { fatal_lang_error('smf126'); } } if (!is_writable($modSettings['attachmentUploadDir'])) { fatal_lang_error('attachments_no_write'); } $attachID = 'post_tmp_' . $ID_MEMBER . '_' . $temp_start++; $_SESSION['temp_attachments'][$attachID] = stripslashes(basename($_FILES['attachment']['name'][$n])); $context['current_attachments'][] = array('name' => basename(stripslashes($_FILES['attachment']['name'][$n])), 'id' => $attachID); $destName = $modSettings['attachmentUploadDir'] . '/' . $attachID; if (!move_uploaded_file($_FILES['attachment']['tmp_name'][$n], $destName)) { fatal_lang_error('smf124'); } @chmod($destName, 0644); } } } // If we are coming here to make a reply, and someone has already replied... make a special warning message. if (isset($newRepliesError)) { $context['post_error']['messages'][] = $newRepliesError == 1 ? $txt['error_new_reply'] : $txt['error_new_replies']; $context['error_type'] = 'minor'; } if (isset($oldTopicError)) { $context['post_error']['messages'][] = $txt['error_old_topic']; $context['error_type'] = 'minor'; } // What are you doing? Posting a poll, modifying, previewing, new post, or reply... if (isset($_REQUEST['poll'])) { $context['page_title'] = $txt['smf20']; } elseif ($context['make_event']) { $context['page_title'] = $context['event']['id'] == -1 ? $txt['calendar23'] : $txt['calendar20']; } elseif (isset($_REQUEST['msg'])) { $context['page_title'] = $txt[66]; } elseif (isset($_REQUEST['subject'], $context['preview_subject'])) { $context['page_title'] = $txt[507] . ' - ' . strip_tags($context['preview_subject']); } elseif (empty($topic)) { $context['page_title'] = $txt[33]; } else { $context['page_title'] = $txt[25]; } // Build the link tree. if (empty($topic)) { $context['linktree'][] = array('name' => '<i>' . $txt[33] . '</i>'); } else { $context['linktree'][] = array('url' => $scripturl . '?topic=' . $topic . '.' . $_REQUEST['start'], 'name' => $form_subject, 'extra_before' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><b class="nav">' . $context['page_title'] . ' ( </b></span>', 'extra_after' => '<span' . ($settings['linktree_inline'] ? ' class="smalltext"' : '') . '><b class="nav"> )</b></span>'); } // If they've unchecked an attachment, they may still want to attach that many more files, but don't allow more than num_allowed_attachments. // !!! This won't work if you're posting an event. $context['num_allowed_attachments'] = min($modSettings['attachmentNumPerPostLimit'] - count($context['current_attachments']) + (isset($deleted_attachments) ? $deleted_attachments : 0), $modSettings['attachmentNumPerPostLimit']); $context['can_post_attachment'] = !empty($modSettings['attachmentEnable']) && $modSettings['attachmentEnable'] == 1 && allowedTo('post_attachment') && $context['num_allowed_attachments'] > 0; $context['subject'] = addcslashes($form_subject, '"'); $context['message'] = str_replace(array('"', '<', '>', ' '), array('"', '<', '>', ' '), $form_message); $context['attached'] = ''; $context['allowed_extensions'] = strtr($modSettings['attachmentExtensions'], array(',' => ', ')); $context['make_poll'] = isset($_REQUEST['poll']); // Message icons - customized icons are off? if (empty($modSettings['messageIcons_enable'])) { $context['icons'] = array(array('value' => 'xx', 'name' => $txt[281]), array('value' => 'thumbup', 'name' => $txt[282]), array('value' => 'thumbdown', 'name' => $txt[283]), array('value' => 'exclamation', 'name' => $txt[284]), array('value' => 'question', 'name' => $txt[285]), array('value' => 'lamp', 'name' => $txt[286]), array('value' => 'smiley', 'name' => $txt[287]), array('value' => 'angry', 'name' => $txt[288]), array('value' => 'cheesy', 'name' => $txt[289]), array('value' => 'grin', 'name' => $txt[293]), array('value' => 'sad', 'name' => $txt[291]), array('value' => 'wink', 'name' => $txt[292])); foreach ($context['icons'] as $k => $dummy) { $context['icons'][$k]['url'] = $settings['images_url'] . '/post/' . $dummy['value'] . '.gif'; $context['icons'][$k]['is_last'] = false; } $context['icon_url'] = $settings['images_url'] . '/post/' . $context['icon'] . '.gif'; } else { // Regardless of what *should* exist, let's do this properly. $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless'); $context['icon_sources'] = array(); foreach ($stable_icons as $icon) { $context['icon_sources'][$icon] = 'images_url'; } // Array for all icons that need to revert to the default theme! $context['javascript_icons'] = array(); if (($temp = cache_get_data('posting_icons-' . $board, 480)) == null) { $request = db_query("\n\t\t\t\tSELECT title, filename\n\t\t\t\tFROM {$db_prefix}message_icons\n\t\t\t\tWHERE ID_BOARD IN (0, {$board})", __FILE__, __LINE__); $icon_data = array(); while ($row = mysql_fetch_assoc($request)) { $icon_data[] = $row; } mysql_free_result($request); cache_put_data('posting_icons-' . $board, $icon_data, 480); } else { $icon_data = $temp; } $context['icons'] = array(); foreach ($icon_data as $icon) { if (!isset($context['icon_sources'][$icon['filename']])) { $context['icon_sources'][$icon['filename']] = file_exists($settings['theme_dir'] . '/images/post/' . $icon['filename'] . '.gif') ? 'images_url' : 'default_images_url'; } // If the icon exists only in the default theme, ensure the javascript popup respects this. if ($context['icon_sources'][$icon['filename']] == 'default_images_url') { $context['javascript_icons'][] = $icon['filename']; } $context['icons'][] = array('value' => $icon['filename'], 'name' => $icon['title'], 'url' => $settings[$context['icon_sources'][$icon['filename']]] . '/post/' . $icon['filename'] . '.gif', 'is_last' => false); } $context['icon_url'] = $settings[isset($context['icon_sources'][$context['icon']]) ? $context['icon_sources'][$context['icon']] : 'images_url'] . '/post/' . $context['icon'] . '.gif'; } if (!empty($context['icons'])) { $context['icons'][count($context['icons']) - 1]['is_last'] = true; } $found = false; for ($i = 0, $n = count($context['icons']); $i < $n; $i++) { $context['icons'][$i]['selected'] = $context['icon'] == $context['icons'][$i]['value']; if ($context['icons'][$i]['selected']) { $found = true; } } if (!$found) { array_unshift($context['icons'], array('value' => $context['icon'], 'name' => $txt['current_icon'], 'url' => $context['icon_url'], 'is_last' => empty($context['icons']), 'selected' => true)); } if (!empty($topic)) { getTopic(); } $context['back_to_topic'] = isset($_REQUEST['goback']) || isset($_REQUEST['msg']) && !isset($_REQUEST['subject']); $context['show_additional_options'] = !empty($_POST['additional_options']) || !empty($_SESSION['temp_attachments']) || !empty($deleted_attachments); $context['is_new_topic'] = empty($topic); $context['is_new_post'] = !isset($_REQUEST['msg']); $context['is_first_post'] = $context['is_new_topic'] || isset($_REQUEST['msg']) && $_REQUEST['msg'] == $ID_FIRST_MSG; // Register this form in the session variables. checkSubmitOnce('register'); // Finally, load the template. if (WIRELESS) { $context['sub_template'] = WIRELESS_PROTOCOL . '_post'; } elseif (!isset($_REQUEST['xml'])) { loadTemplate('Post'); } }
/** * This helps organize things... * @todo this should be a simple dispatcher.... */ function MessageMain() { global $txt, $scripturl, $sourcedir, $context, $user_info, $user_settings, $smcFunc, $modSettings; // No guests! is_not_guest(); // You're not supposed to be here at all, if you can't even read PMs. isAllowedTo('pm_read'); // This file contains the basic functions for sending a PM. require_once $sourcedir . '/Subs-Post.php'; loadLanguage('PersonalMessage+Drafts'); if (WIRELESS && WIRELESS_PROTOCOL == 'wap') { fatal_lang_error('wireless_error_notyet', false); } elseif (WIRELESS) { $context['sub_template'] = WIRELESS_PROTOCOL . '_pm'; } elseif (!isset($_REQUEST['xml'])) { loadTemplate('PersonalMessage'); } // Load up the members maximum message capacity. if ($user_info['is_admin']) { $context['message_limit'] = 0; } elseif (($context['message_limit'] = cache_get_data('msgLimit:' . $user_info['id'], 360)) === null) { // @todo Why do we do this? It seems like if they have any limit we should use it. $request = $smcFunc['db_query']('', ' SELECT MAX(max_messages) AS top_limit, MIN(max_messages) AS bottom_limit FROM {db_prefix}membergroups WHERE id_group IN ({array_int:users_groups})', array('users_groups' => $user_info['groups'])); list($maxMessage, $minMessage) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $context['message_limit'] = $minMessage == 0 ? 0 : $maxMessage; // Save us doing it again! cache_put_data('msgLimit:' . $user_info['id'], $context['message_limit'], 360); } // Prepare the context for the capacity bar. if (!empty($context['message_limit'])) { $bar = $user_info['messages'] * 100 / $context['message_limit']; $context['limit_bar'] = array('messages' => $user_info['messages'], 'allowed' => $context['message_limit'], 'percent' => $bar, 'bar' => min(100, (int) $bar), 'text' => sprintf($txt['pm_currently_using'], $user_info['messages'], round($bar, 1))); } // a previous message was sent successfully? show a small indication. if (isset($_GET['done']) && $_GET['done'] == 'sent') { $context['pm_sent'] = true; } // Now we have the labels, and assuming we have unsorted mail, apply our rules! if ($user_settings['new_pm']) { $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']); foreach ($context['labels'] as $id_label => $label_name) { $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0); } $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0); ApplyRules(); updateMemberData($user_info['id'], array('new_pm' => 0)); $smcFunc['db_query']('', ' UPDATE {db_prefix}pm_recipients SET is_new = {int:not_new} WHERE id_member = {int:current_member}', array('current_member' => $user_info['id'], 'not_new' => 0)); } // Load the label data. if ($user_settings['new_pm'] || ($context['labels'] = cache_get_data('labelCounts:' . $user_info['id'], 720)) === null) { $context['labels'] = $user_settings['message_labels'] == '' ? array() : explode(',', $user_settings['message_labels']); foreach ($context['labels'] as $id_label => $label_name) { $context['labels'][(int) $id_label] = array('id' => $id_label, 'name' => trim($label_name), 'messages' => 0, 'unread_messages' => 0); } $context['labels'][-1] = array('id' => -1, 'name' => $txt['pm_msg_label_inbox'], 'messages' => 0, 'unread_messages' => 0); // Looks like we need to reseek! $result = $smcFunc['db_query']('', ' SELECT labels, is_read, COUNT(*) AS num FROM {db_prefix}pm_recipients WHERE id_member = {int:current_member} AND deleted = {int:not_deleted} GROUP BY labels, is_read', array('current_member' => $user_info['id'], 'not_deleted' => 0)); while ($row = $smcFunc['db_fetch_assoc']($result)) { $this_labels = explode(',', $row['labels']); foreach ($this_labels as $this_label) { $context['labels'][(int) $this_label]['messages'] += $row['num']; if (!($row['is_read'] & 1)) { $context['labels'][(int) $this_label]['unread_messages'] += $row['num']; } } } $smcFunc['db_free_result']($result); // Store it please! cache_put_data('labelCounts:' . $user_info['id'], $context['labels'], 720); } // This determines if we have more labels than just the standard inbox. $context['currently_using_labels'] = count($context['labels']) > 1 ? 1 : 0; // Some stuff for the labels... $context['current_label_id'] = isset($_REQUEST['l']) && isset($context['labels'][(int) $_REQUEST['l']]) ? (int) $_REQUEST['l'] : -1; $context['current_label'] =& $context['labels'][(int) $context['current_label_id']]['name']; $context['folder'] = !isset($_REQUEST['f']) || $_REQUEST['f'] != 'sent' ? 'inbox' : 'sent'; // This is convenient. Do you know how annoying it is to do this every time?! $context['current_label_redirect'] = 'action=pm;f=' . $context['folder'] . (isset($_GET['start']) ? ';start=' . $_GET['start'] : '') . (isset($_REQUEST['l']) ? ';l=' . $_REQUEST['l'] : ''); $context['can_issue_warning'] = in_array('w', $context['admin_features']) && allowedTo('issue_warning') && $modSettings['warning_settings'][0] == 1; // Build the linktree for all the actions... $context['linktree'][] = array('url' => $scripturl . '?action=pm', 'name' => $txt['personal_messages']); // Preferences... $context['display_mode'] = WIRELESS ? 0 : $user_settings['pm_prefs'] & 3; $subActions = array('addbuddy' => 'WirelessAddBuddy', 'manlabels' => 'ManageLabels', 'manrules' => 'ManageRules', 'pmactions' => 'MessageActionsApply', 'prune' => 'MessagePrune', 'removeall' => 'MessageKillAllQuery', 'removeall2' => 'MessageKillAll', 'report' => 'ReportMessage', 'search' => 'MessageSearch', 'search2' => 'MessageSearch2', 'send' => 'MessagePost', 'send2' => 'MessagePost2', 'settings' => 'MessageSettings', 'showpmdrafts' => 'MessageDrafts'); if (!isset($_REQUEST['sa']) || !isset($subActions[$_REQUEST['sa']])) { MessageFolder(); } else { if (!isset($_REQUEST['xml'])) { messageIndexBar($_REQUEST['sa']); } $subActions[$_REQUEST['sa']](); } }
function AddPictureComment() { global $txt, $context, $smcFunc, $sourcedir, $scripturl, $modSettings, $language; $memID = $context['member']['id']; // Guests are not allowed to comment. is_not_guest(); if (empty($_POST['comment'])) { fatal_error($txt['Maximum_comment_field'], false); } // Integration with AEVA mod (Thanks Nao 尚 ;)) if (isset($modSettings['aeva_enable']) && file_exists($sourcedir . '/Subs-Aeva.php')) { @(include_once $sourcedir . '/Subs-Aeva.php'); if (function_exists('aeva_onposting')) { $_POST['comment'] = aeva_onposting($_POST['comment']); } } checkSession('post'); // Only buddies can post comments? if (isset($context['member']['options']['comments_budd_only']) && $context['member']['options']['comments_budd_only'] == 1) { if (!is_buddy($memID, $context['user']['id']) && !allowedTo('edit_Maximum_Maximum_any')) { fatal_error($txt['Maximum_comments_buddies_only'], false); } } $request = $smcFunc['db_insert']('normal', '{db_prefix}picture_comments', array('id_member' => 'int', 'comment' => 'text', 'time' => 'int', 'comment_picture_id' => 'int'), array('id_member' => $context['user']['id'], 'title' => htmlspecialchars($_POST['comment']), 'time' => time(), 'comment_picture_id' => (int) $_GET['comment']), array('id_comment')); // Should we notify the user? if (@$context['member']['options']['comments_notif_disable'] != 1 && $context['user']['id'] != $memID) { $request = $smcFunc['db_query']('', ' SELECT lngfile FROM {db_prefix}members WHERE id_member = {int:id_member}', array('id_member' => $memID)); list($user_language) = $smcFunc['db_fetch_row']($request); loadLanguage('Maximumprofile', empty($user_language) || empty($modSettings['userLanguage']) ? $language : $user_language, false); require_once $sourcedir . '/Subs-Post.php'; sendpm(array('to' => array($memID), 'bcc' => array()), sprintf($txt['Maximum_notif_piccom_subject'], $context['user']['name']), sprintf($txt['Maximum_notif_piccom_body'], $context['user']['name'], $scripturl . '?action=profile;area=pictures;view=' . (int) $_GET['comment']), false, array('id' => 0, 'name' => $txt['Maximum_notif_com_user'], 'username' => $txt['Maximum_notif_com_user'])); } redirectexit('action=profile;area=pictures;u=' . $memID . ';view=' . (int) $_GET['comment']); }
function loadBoard() { global $txt, $db_prefix, $scripturl, $context, $modSettings; global $board_info, $board, $topic, $ID_MEMBER, $user_info; // 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(); // Load this board only if the 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 = cache_get_data('topic_board-' . $topic, 120); } else { $temp = cache_get_data('board-' . $board, 120); } if (!empty($temp)) { $board_info = $temp; $board = $board_info['id']; } } if (empty($temp)) { $request = db_query("\n\t\t\tSELECT\n\t\t\t\tc.ID_CAT, b.name AS bname, b.description, b.numTopics, b.memberGroups,\n\t\t\t\tb.ID_PARENT, c.name AS cname, IFNULL(mem.ID_MEMBER, 0) AS ID_MODERATOR,\n\t\t\t\tmem.realName" . (!empty($topic) ? ", b.ID_BOARD" : '') . ", b.childLevel,\n\t\t\t\tb.ID_THEME, b.override_theme, b.permission_mode, b.countPosts\n\t\t\tFROM ({$db_prefix}boards AS b" . (!empty($topic) ? ", {$db_prefix}topics AS t" : '') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT)\n\t\t\t\tLEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = " . (empty($topic) ? $board : 't.ID_BOARD') . ")\n\t\t\t\tLEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = mods.ID_MEMBER)\n\t\t\tWHERE b.ID_BOARD = " . (empty($topic) ? $board : "t.ID_BOARD\n\t\t\t\tAND t.ID_TOPIC = {$topic}"), __FILE__, __LINE__); // 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']), 'name' => $row['bname'], 'description' => $row['description'], 'num_topics' => $row['numTopics'], 'parent_boards' => getBoardParents($row['ID_PARENT']), 'parent' => $row['ID_PARENT'], 'child_level' => $row['childLevel'], 'theme' => $row['ID_THEME'], 'override_theme' => !empty($row['override_theme']), 'use_local_permissions' => !empty($modSettings['permission_enable_by_board']) && $row['permission_mode'] == 1, 'permission_mode' => empty($modSettings['permission_enable_by_board']) ? empty($row['permission_mode']) ? 'normal' : ($row['permission_mode'] == 2 ? 'no_polls' : ($row['permission_mode'] == 3 ? 'reply_only' : 'read_only')) : 'normal', 'posts_count' => empty($row['countPosts'])); // Load the membergroups allowed, and check permissions. $board_info['groups'] = $row['memberGroups'] == '' ? array() : explode(',', $row['memberGroups']); do { if (!empty($row['ID_MODERATOR'])) { $board_info['moderators'][$row['ID_MODERATOR']] = array('id' => $row['ID_MODERATOR'], 'name' => $row['realName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MODERATOR'] . '" title="' . $txt[62] . '">' . $row['realName'] . '</a>'); } } while ($row = mysql_fetch_assoc($request)); if (!empty($modSettings['cache_enable']) && (empty($topic) || $modSettings['cache_enable'] == 3)) { // !!! SLOW? if (!empty($topic)) { cache_put_data('topic_board-' . $topic, $board_info, 120); } cache_put_data('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 (!empty($board)) { // Now check if the user is a moderator. $user_info['is_mod'] = isset($board_info['moderators'][$ID_MEMBER]); 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'], array(array('url' => $scripturl . '#' . $board_info['cat']['id'], 'name' => $board_info['cat']['name'])), array_reverse($board_info['parent_boards']), array(array('url' => $scripturl . '?board=' . $board . '.0', 'name' => $board_info['name']))); } // 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(); $_GET['board'] = ''; $_GET['topic'] = ''; // If it's a prefetching agent, just make clear they're not allowed. if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { 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; } }
/** * Creates a list of mentions for the user * Allows them to mark them read or unread * Can sort the various forms of mentions, likes or @mentions */ public function action_list() { global $context, $txt, $scripturl; // Only registered members can be mentioned is_not_guest(); require_once SUBSDIR . '/Mentions.subs.php'; require_once SUBSDIR . '/GenericList.class.php'; loadLanguage('Mentions'); $this->_buildUrl(); $list_options = array('id' => 'list_mentions', 'title' => empty($this->_all) ? $txt['my_unread_mentions'] : $txt['my_mentions'], 'items_per_page' => $this->_items_per_page, 'base_href' => $scripturl . '?action=mentions;sa=list' . $this->_url_param, 'default_sort_col' => $this->_default_sort, 'default_sort_dir' => 'default', 'no_items_label' => $this->_all ? $txt['no_mentions_yet'] : $txt['no_new_mentions'], 'get_items' => array('function' => array($this, 'list_loadMentions'), 'params' => array($this->_all, $this->_type)), 'get_count' => array('function' => array($this, 'list_getMentionCount'), 'params' => array($this->_all, $this->_type)), 'columns' => array('id_member_from' => array('header' => array('value' => $txt['mentions_from']), 'data' => array('function' => create_function('$row', ' global $settings, $scripturl; if (isset($settings[\'mentions\'][\'mentioner_template\'])) return str_replace( array( \'{avatar_img}\', \'{mem_url}\', \'{mem_name}\', ), array( $row[\'avatar\'][\'image\'], !empty($row[\'id_member_from\']) ? $scripturl . \'?action=profile;u=\' . $row[\'id_member_from\'] : \'\', $row[\'mentioner\'], ), $settings[\'mentions\'][\'mentioner_template\']); ')), 'sort' => array('default' => 'mtn.id_member_from', 'reverse' => 'mtn.id_member_from DESC')), 'type' => array('header' => array('value' => $txt['mentions_what']), 'data' => array('db' => 'message'), 'sort' => array('default' => 'mtn.mention_type', 'reverse' => 'mtn.mention_type DESC')), 'log_time' => array('header' => array('value' => $txt['mentions_when'], 'class' => 'mention_log_time'), 'data' => array('db' => 'log_time', 'timeformat' => 'html_time', 'class' => 'mention_log_time'), 'sort' => array('default' => 'mtn.log_time DESC', 'reverse' => 'mtn.log_time')), 'action' => array('header' => array('value' => $txt['mentions_action'], 'class' => 'listaction'), 'data' => array('function' => create_function('$row', ' global $txt, $settings, $context; $opts = \'\'; if (empty($row[\'status\'])) $opts = \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=read;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'mentions_markread\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/mark_read.png" alt="*" /></a> \'; else $opts = \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=unread;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'mentions_markunread\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/mark_unread.png" alt="*" /></a> \'; return $opts . \'<a href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=delete;item=\' . $row[\'id_mention\'] . \';\' . $context[\'session_var\'] . \'=\' . $context[\'session_id\'] . \';"><img title="\' . $txt[\'delete\'] . \'" src="\' . $settings[\'images_url\'] . \'/icons/delete.png" alt="*" /></a>\'; '), 'class' => 'listaction'))), 'list_menu' => array('show_on' => 'top', 'links' => array(array('href' => $scripturl . '?action=mentions' . (!empty($this->_all) ? ';all' : ''), 'is_selected' => empty($this->_type), 'label' => $txt['mentions_type_all']))), 'additional_rows' => array(array('position' => 'top_of_list', 'value' => '<a class="floatright linkbutton" href="' . $scripturl . '?action=mentions' . (!empty($this->_all) ? '' : ';all') . str_replace(';all', '', $this->_url_param) . '">' . (!empty($this->_all) ? $txt['mentions_unread'] : $txt['mentions_all']) . '</a>'), array('position' => 'bottom_of_list', 'value' => '<a class="floatright linkbutton" href="' . $scripturl . '?action=mentions;sa=updatestatus;mark=readall' . str_replace(';all', '', $this->_url_param) . ';' . $context['session_var'] . '=' . $context['session_id'] . '">' . $txt['mentions_mark_all_read'] . '</a>'))); foreach ($this->_known_mentions as $key => $mention) { if (!empty($mention['enabled'])) { $list_options['list_menu']['links'][] = array('href' => $scripturl . '?action=mentions;type=' . $key . (!empty($this->_all) ? ';all' : ''), 'is_selected' => $this->_type === $key, 'label' => $txt['mentions_type_' . $key]); $this->_callbacks[$key] = $mention['callback']; } } createList($list_options); $context['page_title'] = $txt['my_mentions'] . (!empty($this->_page) ? ' - ' . sprintf($txt['my_mentions_pages'], $this->_page) : ''); $context['linktree'][] = array('url' => $scripturl . '?action=mentions', 'name' => $txt['my_mentions']); if (!empty($this->_type)) { $context['linktree'][] = array('url' => $scripturl . '?action=mentions;type=' . $this->_type, 'name' => $txt['mentions_type_' . $this->_type]); } }