function getLastPost() { global $scripturl, $modSettings, $board; // Find it by the board - better to order by board than sort the entire messages table. $request = smf_db_query(' SELECT ml.poster_time, ml.subject, ml.id_topic, ml.poster_name, ml.body, ml.id_msg, b.id_board, ml.smileys_enabled FROM {db_prefix}boards AS b INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = b.id_last_msg) WHERE {query_wanna_see_board}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' AND b.id_board != {int:recycle_board}' : '') . ' AND ml.approved = {int:is_approved} ORDER BY b.id_msg_updated DESC LIMIT 1', array('recycle_board' => $modSettings['recycle_board'], 'is_approved' => 1)); if (mysql_num_rows($request) == 0) { return array(); } $row = mysql_fetch_assoc($request); mysql_free_result($request); $board = $row['id_board']; // Censor the subject and post... censorText($row['subject']); censorText($row['body']); $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled']), array('<br />' => ' '))); parse_bbc_stage2($row['body'], $row['id_msg']); if (commonAPI::strlen($row['body']) > 128) { $row['body'] = commonAPI::substr($row['body'], 0, 128) . '...'; } // Send the data. return array('topic' => $row['id_topic'], 'subject' => $row['subject'], 'short_subject' => shorten_subject($row['subject'], 35), 'preview' => $row['body'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.new;topicseen#new', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.new;topicseen#new">' . $row['subject'] . '</a>'); }
function EditHoliday() { global $txt, $context, $scripturl, $smcFunc; loadAdminTemplate('ManageCalendar'); $context['is_new'] = !isset($_REQUEST['holiday']); $context['page_title'] = $context['is_new'] ? $txt['holidays_add'] : $txt['holidays_edit']; $context['sub_template'] = 'edit_holiday'; // Cast this for safety... if (isset($_REQUEST['holiday'])) { $_REQUEST['holiday'] = (int) $_REQUEST['holiday']; } // Submitting? if (isset($_POST[$context['session_var']]) && (isset($_REQUEST['delete']) || $_REQUEST['title'] != '')) { checkSession(); // Not too long good sir? $_REQUEST['title'] = commonAPI::substr($_REQUEST['title'], 0, 60); $_REQUEST['holiday'] = isset($_REQUEST['holiday']) ? (int) $_REQUEST['holiday'] : 0; if (isset($_REQUEST['delete'])) { smf_db_query(' DELETE FROM {db_prefix}calendar_holidays WHERE id_holiday = {int:selected_holiday}', array('selected_holiday' => $_REQUEST['holiday'])); } else { $date = strftime($_REQUEST['year'] <= 4 ? '0004-%m-%d' : '%Y-%m-%d', mktime(0, 0, 0, $_REQUEST['month'], $_REQUEST['day'], $_REQUEST['year'])); if (isset($_REQUEST['edit'])) { smf_db_query(' UPDATE {db_prefix}calendar_holidays SET event_date = {date:holiday_date}, title = {string:holiday_title} WHERE id_holiday = {int:selected_holiday}', array('holiday_date' => $date, 'selected_holiday' => $_REQUEST['holiday'], 'holiday_title' => $_REQUEST['title'])); } else { smf_db_insert('', '{db_prefix}calendar_holidays', array('event_date' => 'date', 'title' => 'string-60'), array($date, $_REQUEST['title']), array('id_holiday')); } } updateSettings(array('calendar_updated' => time())); redirectexit('action=admin;area=managecalendar;sa=holidays'); } // Default states... if ($context['is_new']) { $context['holiday'] = array('id' => 0, 'day' => date('d'), 'month' => date('m'), 'year' => '0000', 'title' => ''); } else { $request = smf_db_query(' SELECT id_holiday, YEAR(event_date) AS year, MONTH(event_date) AS month, DAYOFMONTH(event_date) AS day, title FROM {db_prefix}calendar_holidays WHERE id_holiday = {int:selected_holiday} LIMIT 1', array('selected_holiday' => $_REQUEST['holiday'])); while ($row = mysql_fetch_assoc($request)) { $context['holiday'] = array('id' => $row['id_holiday'], 'day' => $row['day'], 'month' => $row['month'], 'year' => $row['year'] <= 4 ? 0 : $row['year'], 'title' => $row['title']); } mysql_free_result($request); } // Last day for the drop down? $context['holiday']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['holiday']['month'] == 12 ? 1 : $context['holiday']['month'] + 1, 0, $context['holiday']['month'] == 12 ? $context['holiday']['year'] + 1 : $context['holiday']['year'])); }
function getLastPosts($latestPostOptions) { global $scripturl, $txt, $user_info, $modSettings, $smcFunc, $context; // Find all the posts. Newer ones will have higher IDs. (assuming the last 20 * number are accessable...) // !!!SLOW This query is now slow, NEEDS to be fixed. Maybe break into two? $request = smf_db_query(' SELECT m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, b.name, m1.subject AS first_subject, IFNULL(mem.real_name, m.poster_name) AS poster_name, t.id_board, b.name AS board_name, SUBSTRING(m.body, 1, 385) AS body, m.smileys_enabled FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE m.id_msg >= {int:likely_max_msg}' . (!empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0 ? ' AND b.id_board != {int:recycle_board}' : '') . ' AND {query_wanna_see_board}' . ($modSettings['postmod_active'] ? ' AND t.approved = {int:is_approved} AND m.approved = {int:is_approved}' : '') . ' ORDER BY m.id_msg DESC LIMIT ' . $latestPostOptions['number_posts'], array('likely_max_msg' => max(0, $modSettings['maxMsgID'] - 50 * $latestPostOptions['number_posts']), 'recycle_board' => $modSettings['recycle_board'], 'is_approved' => 1)); $posts = array(); while ($row = mysql_fetch_assoc($request)) { // Censor the subject and post for the preview ;). censorText($row['subject']); censorText($row['body']); $row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']), array('<br />' => ' '))); if (commonAPI::strlen($row['body']) > 128) { $row['body'] = commonAPI::substr($row['body'], 0, 128) . '...'; } $bhref = URL::board($row['id_board'], $row['board_name'], 0, true); $mhref = URL::user($row['id_member'], $row['poster_name']); $thref = URL::topic($row['id_topic'], $row['first_subject'], 0, false, '.msg' . $row['id_msg'], ';topicseen#msg' . $row['id_msg']); // Build the array. $posts[] = array('board' => array('id' => $row['id_board'], 'name' => $row['board_name'], 'href' => $bhref, 'link' => '<a href="' . $bhref . '">' . $row['board_name'] . '</a>'), 'topic' => $row['id_topic'], 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => empty($row['id_member']) ? '' : $mhref, 'link' => empty($row['id_member']) ? $row['poster_name'] : '<a href="' . $mhref . '">' . $row['poster_name'] . '</a>'), 'subject' => $row['subject'], 'short_subject' => shorten_subject($row['subject'], 35), 'preview' => $row['body'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'raw_timestamp' => $row['poster_time'], 'href' => $thref, 'link' => '<a href="' . $thref . '" rel="nofollow">' . $row['first_subject'] . '</a>'); } mysql_free_result($request); return $posts; }
function ssi_boardNews($board = null, $limit = null, $start = null, $length = null, $output_method = 'echo') { global $scripturl, $db_prefix, $txt, $settings, $modSettings, $context; global $smcFunc; loadLanguage('Stats'); // Must be integers.... if ($limit === null) { $limit = isset($_GET['limit']) ? (int) $_GET['limit'] : 5; } else { $limit = (int) $limit; } if ($start === null) { $start = isset($_GET['start']) ? (int) $_GET['start'] : 0; } else { $start = (int) $start; } if ($board !== null) { $board = (int) $board; } elseif (isset($_GET['board'])) { $board = (int) $_GET['board']; } if ($length === null) { $length = isset($_GET['length']) ? (int) $_GET['length'] : 0; } else { $length = (int) $length; } $limit = max(0, $limit); $start = max(0, $start); // Make sure guests can see this board. $request = $smcFunc['db_query']('', ' SELECT id_board FROM {db_prefix}boards WHERE ' . ($board === null ? '' : 'id_board = {int:current_board} AND ') . 'FIND_IN_SET(-1, member_groups) LIMIT 1', array('current_board' => $board)); if ($smcFunc['db_num_rows']($request) == 0) { if ($output_method == 'echo') { die($txt['ssi_no_guests']); } else { return array(); } } list($board) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); // Load the message icons - the usual suspects. $stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless'); $icon_sources = array(); foreach ($stable_icons as $icon) { $icon_sources[$icon] = 'images_url'; } // Find the post ids. $request = $smcFunc['db_query']('', ' SELECT id_first_msg FROM {db_prefix}topics WHERE id_board = {int:current_board}' . ($modSettings['postmod_active'] ? ' AND approved = {int:is_approved}' : '') . ' ORDER BY id_first_msg DESC LIMIT ' . $start . ', ' . $limit, array('current_board' => $board, 'is_approved' => 1)); $posts = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $posts[] = $row['id_first_msg']; } $smcFunc['db_free_result']($request); if (empty($posts)) { return array(); } // Find the posts. $request = $smcFunc['db_query']('', ' SELECT m.icon, m.subject, m.body, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time, t.num_replies, t.id_topic, m.id_member, m.smileys_enabled, m.id_msg, t.locked, t.id_last_msg FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) WHERE t.id_first_msg IN ({array_int:post_list}) ORDER BY t.id_first_msg DESC LIMIT ' . count($posts), array('post_list' => $posts)); $return = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { // If we want to limit the length of the post. if (!empty($length) && commonAPI::strlen($row['body']) > $length) { $row['body'] = commonAPI::substr($row['body'], 0, $length); // The first space or line break. (<br />, etc.) $cutoff = max(strrpos($row['body'], ' '), strrpos($row['body'], '<')); if ($cutoff !== false) { $row['body'] = commonAPI::substr($row['body'], 0, $cutoff); } $row['body'] .= '...'; } $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); // Check that this message icon is there... if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']])) { $icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url'; } censorText($row['subject']); censorText($row['body']); $return[] = array('id' => $row['id_topic'], 'message_id' => $row['id_msg'], 'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" alt="' . $row['icon'] . '" />', 'subject' => $row['subject'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'body' => $row['body'], 'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['num_replies'] . ' ' . ($row['num_replies'] == 1 ? $txt['ssi_comment'] : $txt['ssi_comments']) . '</a>', 'replies' => $row['num_replies'], 'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'], 'comment_link' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';last_msg=' . $row['id_last_msg'] . '">' . $txt['ssi_write_comment'] . '</a>', 'new_comment' => !empty($row['locked']) ? '' : '<a href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . '">' . $txt['ssi_write_comment'] . '</a>', 'poster' => array('id' => $row['id_member'], 'name' => $row['poster_name'], 'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '', 'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name']), 'locked' => !empty($row['locked']), 'is_last' => false); } $smcFunc['db_free_result']($request); if (empty($return)) { return $return; } $return[count($return) - 1]['is_last'] = true; if ($output_method != 'echo') { return $return; } foreach ($return as $news) { echo ' <div class="news_item"> <h3 class="news_header"> ', $news['icon'], ' <a href="', $news['href'], '">', $news['subject'], '</a> </h3> <div class="news_timestamp">', $news['time'], ' ', $txt['by'], ' ', $news['poster']['link'], '</div> <div class="news_body" style="padding: 2ex 0;">', $news['body'], '</div> ', $news['link'], $news['locked'] ? '' : ' | ' . $news['comment_link'], ' </div>'; if (!$news['is_last']) { echo ' <hr />'; } } }
function MoveTopic2() { global $txt, $board, $topic, $scripturl, $sourcedir, $modSettings, $context; global $board, $language, $user_info, $smcFunc; if (empty($topic)) { fatal_lang_error('no_access', false); } // You can't choose to have a redirection topic and use an empty reason. if (isset($_POST['postRedirect']) && (!isset($_POST['reason']) || trim($_POST['reason']) == '')) { fatal_lang_error('movetopic_no_reason', false); } // Make sure this form hasn't been submitted before. checkSubmitOnce('check'); $request = smf_db_query(' SELECT id_member_started, id_first_msg, approved FROM {db_prefix}topics WHERE id_topic = {int:current_topic} LIMIT 1', array('current_topic' => $topic)); list($id_member_started, $id_first_msg, $context['is_approved']) = mysql_fetch_row($request); mysql_free_result($request); // Can they see it? if (!$context['is_approved']) { isAllowedTo('approve_posts'); } // Can they move topics on this board? if (!allowedTo('move_any')) { if ($id_member_started == $user_info['id']) { isAllowedTo('move_own'); $boards = array_merge(boardsAllowedTo('move_own'), boardsAllowedTo('move_any')); } else { isAllowedTo('move_any'); } } else { $boards = boardsAllowedTo('move_any'); } // If this topic isn't approved don't let them move it if they can't approve it! if ($modSettings['postmod_active'] && !$context['is_approved'] && !allowedTo('approve_posts')) { // Only allow them to move it to other boards they can't approve it in. $can_approve = boardsAllowedTo('approve_posts'); $boards = array_intersect($boards, $can_approve); } checkSession(); require_once $sourcedir . '/lib/Subs-Post.php'; // The destination board must be numeric. $_POST['toboard'] = (int) $_POST['toboard']; // Make sure they can see the board they are trying to move to (and get whether posts count in the target board). $request = smf_db_query(' SELECT b.count_posts, b.name, m.subject FROM {db_prefix}boards AS b INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic}) INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) WHERE {query_see_board} AND b.id_board = {int:to_board} AND b.redirect = {string:blank_redirect} LIMIT 1', array('current_topic' => $topic, 'to_board' => $_POST['toboard'], 'blank_redirect' => '')); if (mysql_num_rows($request) == 0) { fatal_lang_error('no_board'); } list($pcounter, $board_name, $subject) = mysql_fetch_row($request); mysql_free_result($request); // Remember this for later. $_SESSION['move_to_topic'] = $_POST['toboard']; // Rename the topic... if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '') { $_POST['custom_subject'] = strtr(commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => '')); // Keep checking the length. if (commonAPI::strlen($_POST['custom_subject']) > 100) { $_POST['custom_subject'] = commonAPI::substr($_POST['custom_subject'], 0, 100); } // If it's still valid move onwards and upwards. if ($_POST['custom_subject'] != '') { if (isset($_POST['enforce_subject'])) { // Get a response prefix, but in the forum's default language. if (!isset($context['response_prefix']) && !($context['response_prefix'] = CacheAPI::getCache('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'); } CacheAPI::putCache('response_prefix', $context['response_prefix'], 600); } smf_db_query(' UPDATE {db_prefix}messages SET subject = {string:subject} WHERE id_topic = {int:current_topic}', array('current_topic' => $topic, 'subject' => $context['response_prefix'] . $_POST['custom_subject'])); } smf_db_query(' UPDATE {db_prefix}messages SET subject = {string:custom_subject} WHERE id_msg = {int:id_first_msg}', array('id_first_msg' => $id_first_msg, 'custom_subject' => $_POST['custom_subject'])); // Fix the subject cache. updateStats('subject', $topic, $_POST['custom_subject']); } } // Create a link to this in the old board. //!!! Does this make sense if the topic was unapproved before? I'd just about say so. if (isset($_POST['postRedirect'])) { // Should be in the boardwide language. if ($user_info['language'] != $language) { loadLanguage('index', $language); } $_POST['reason'] = commonAPI::htmlspecialchars($_POST['reason'], ENT_QUOTES); preparsecode($_POST['reason']); // Add a URL onto the message. $_POST['reason'] = strtr($_POST['reason'], array($txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]', $txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]')); $msgOptions = array('subject' => $txt['moved'] . ': ' . $subject, 'body' => $_POST['reason'], 'icon' => 'moved', 'smileys_enabled' => 1); $topicOptions = array('board' => $board, 'lock_mode' => 1, 'mark_as_read' => true, 'topic_prefix' => 0, 'topic_layout' => 0); $posterOptions = array('id' => $user_info['id'], 'update_post_count' => empty($pcounter)); createPost($msgOptions, $topicOptions, $posterOptions); } $request = smf_db_query(' SELECT count_posts FROM {db_prefix}boards WHERE id_board = {int:current_board} LIMIT 1', array('current_board' => $board)); list($pcounter_from) = mysql_fetch_row($request); mysql_free_result($request); if ($pcounter_from != $pcounter) { $request = smf_db_query(' SELECT id_member FROM {db_prefix}messages WHERE id_topic = {int:current_topic} AND approved = {int:is_approved}', array('current_topic' => $topic, 'is_approved' => 1)); $posters = array(); while ($row = mysql_fetch_assoc($request)) { if (!isset($posters[$row['id_member']])) { $posters[$row['id_member']] = 0; } $posters[$row['id_member']]++; } mysql_free_result($request); foreach ($posters as $id_member => $posts) { // The board we're moving from counted posts, but not to. if (empty($pcounter_from)) { updateMemberData($id_member, array('posts' => 'posts - ' . $posts)); } else { updateMemberData($id_member, array('posts' => 'posts + ' . $posts)); } } } // Do the move (includes statistics update needed for the redirect topic). moveTopics($topic, $_POST['toboard']); // Log that they moved this topic. if (!allowedTo('move_own') || $id_member_started != $user_info['id']) { logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $_POST['toboard'])); } // Notify people that this topic has been moved? sendNotifications($topic, 'move'); // Why not go back to the original board in case they want to keep moving? if (!isset($_REQUEST['goback'])) { redirectexit('board=' . $board . '.0'); } else { redirectexit('topic=' . $topic . '.0'); } }
function MLAll() { global $txt, $scripturl, $user_info; global $modSettings, $context, $smcFunc; // The chunk size for the cached index. $cache_step_size = 500; // Only use caching if: // 1. there are at least 2k members, // 2. the default sorting method (real_name) is being used, // 3. the page shown is high enough to make a DB filesort unprofitable. $use_cache = $modSettings['totalMembers'] > 2000 && (!isset($_REQUEST['sort']) || $_REQUEST['sort'] === 'real_name') && isset($_REQUEST['start']) && $_REQUEST['start'] > $cache_step_size; if ($use_cache) { // Maybe there's something cached already. if (!empty($modSettings['memberlist_cache'])) { $memberlist_cache = @unserialize($modSettings['memberlist_cache']); } // The chunk size for the cached index. $cache_step_size = 500; // Only update the cache if something changed or no cache existed yet. if (empty($memberlist_cache) || empty($modSettings['memberlist_updated']) || $memberlist_cache['last_update'] < $modSettings['memberlist_updated']) { $request = smf_db_query(' SELECT real_name FROM {db_prefix}members WHERE is_activated = {int:is_activated} ORDER BY real_name', array('is_activated' => 1)); $memberlist_cache = array('last_update' => time(), 'num_members' => mysql_num_rows($request), 'index' => array()); for ($i = 0, $n = mysql_num_rows($request); $i < $n; $i += $cache_step_size) { mysql_data_seek($request, $i); list($memberlist_cache['index'][$i]) = mysql_fetch_row($request); } mysql_data_seek($request, $memberlist_cache['num_members'] - 1); list($memberlist_cache['index'][$i]) = mysql_fetch_row($request); mysql_free_result($request); // Now we've got the cache...store it. updateSettings(array('memberlist_cache' => serialize($memberlist_cache))); } $context['num_members'] = $memberlist_cache['num_members']; } else { $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}members WHERE is_activated = {int:is_activated}', array('is_activated' => 1)); list($context['num_members']) = mysql_fetch_row($request); mysql_free_result($request); } // Set defaults for sort (real_name) and start. (0) if (!isset($_REQUEST['sort']) || !isset($context['columns'][$_REQUEST['sort']])) { $_REQUEST['sort'] = 'real_name'; } if (!is_numeric($_REQUEST['start'])) { if (preg_match('~^[^\'\\\\/]~u', commonAPI::strtolower($_REQUEST['start']), $match) === 0) { fatal_error('Hacker?', false); } $_REQUEST['start'] = $match[0]; $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}members WHERE LOWER(SUBSTRING(real_name, 1, 1)) < {string:first_letter} AND is_activated = {int:is_activated}', array('is_activated' => 1, 'first_letter' => $_REQUEST['start'])); list($_REQUEST['start']) = mysql_fetch_row($request); mysql_free_result($request); } $context['letter_links'] = ''; for ($i = 97; $i < 123; $i++) { $context['letter_links'] .= '<a href="' . $scripturl . '?action=mlist;sa=all;start=' . chr($i) . '#letter' . chr($i) . '">' . strtoupper(chr($i)) . '</a> '; } // Sort out the column information. foreach ($context['columns'] as $col => $column_details) { $context['columns'][$col]['href'] = $scripturl . '?action=mlist;sort=' . $col . ';start=0'; if (!isset($_REQUEST['desc']) && $col == $_REQUEST['sort'] || $col != $_REQUEST['sort'] && !empty($column_details['default_sort_rev'])) { $context['columns'][$col]['href'] .= ';desc'; } $context['columns'][$col]['link'] = '<a href="' . $context['columns'][$col]['href'] . '" rel="nofollow">' . $context['columns'][$col]['label'] . '</a>'; $context['columns'][$col]['selected'] = $_REQUEST['sort'] == $col; } $context['sort_by'] = $_REQUEST['sort']; $context['sort_direction'] = !isset($_REQUEST['desc']) ? 'up' : 'down'; // Construct the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=mlist;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['num_members'], $modSettings['defaultMaxMembers']); // Send the data to the template. $context['start'] = $_REQUEST['start'] + 1; $context['end'] = min($_REQUEST['start'] + $modSettings['defaultMaxMembers'], $context['num_members']); $context['can_moderate_forum'] = allowedTo('moderate_forum'); $context['page_title'] = sprintf($txt['viewing_members'], $context['start'], $context['end']); $context['linktree'][] = array('url' => $scripturl . '?action=mlist;sort=' . $_REQUEST['sort'] . ';start=' . $_REQUEST['start'], 'name' => &$context['page_title'], 'extra_after' => ' (' . sprintf($txt['of_total_members'], $context['num_members']) . ')'); // List out the different sorting methods... $sort_methods = array('is_online' => array('down' => allowedTo('moderate_forum') ? 'IFNULL(lo.log_time, 1) ASC, real_name ASC' : 'IF(mem.show_online, IFNULL(lo.log_time, 1), 1) ASC, real_name ASC', 'up' => allowedTo('moderate_forum') ? 'IFNULL(lo.log_time, 1) DESC, real_name DESC' : 'IF(mem.show_online, IFNULL(lo.log_time, 1), 1) DESC, real_name DESC'), 'real_name' => array('down' => 'mem.real_name DESC', 'up' => 'mem.real_name ASC'), 'email_address' => array('down' => allowedTo('moderate_forum') ? 'mem.email_address DESC' : 'mem.hide_email DESC, mem.email_address DESC', 'up' => allowedTo('moderate_forum') ? 'mem.email_address ASC' : 'mem.hide_email ASC, mem.email_address ASC'), 'registered' => array('down' => 'mem.date_registered DESC', 'up' => 'mem.date_registered ASC'), 'id_group' => array('down' => 'IFNULL(mg.group_name, 1=1) DESC, mg.group_name DESC', 'up' => 'IFNULL(mg.group_name, 1=1) ASC, mg.group_name ASC'), 'posts' => array('down' => 'mem.posts DESC', 'up' => 'mem.posts ASC')); $limit = $_REQUEST['start']; $query_parameters = array('regular_id_group' => 0, 'is_activated' => 1, 'sort' => $sort_methods[$_REQUEST['sort']][$context['sort_direction']]); // Using cache allows to narrow down the list to be retrieved. if ($use_cache && $_REQUEST['sort'] === 'real_name' && !isset($_REQUEST['desc'])) { $first_offset = $_REQUEST['start'] - $_REQUEST['start'] % $cache_step_size; $second_offset = ceil(($_REQUEST['start'] + $modSettings['defaultMaxMembers']) / $cache_step_size) * $cache_step_size; $where = 'mem.real_name BETWEEN {string:real_name_low} AND {string:real_name_high}'; $query_parameters['real_name_low'] = $memberlist_cache['index'][$first_offset]; $query_parameters['real_name_high'] = $memberlist_cache['index'][$second_offset]; $limit -= $first_offset; } elseif ($use_cache && $_REQUEST['sort'] === 'real_name') { $first_offset = floor(($memberlist_cache['num_members'] - $modSettings['defaultMaxMembers'] - $_REQUEST['start']) / $cache_step_size) * $cache_step_size; if ($first_offset < 0) { $first_offset = 0; } $second_offset = ceil(($memberlist_cache['num_members'] - $_REQUEST['start']) / $cache_step_size) * $cache_step_size; $where = 'mem.real_name BETWEEN {string:real_name_low} AND {string:real_name_high}'; $query_parameters['real_name_low'] = $memberlist_cache['index'][$first_offset]; $query_parameters['real_name_high'] = $memberlist_cache['index'][$second_offset]; $limit = $second_offset - ($memberlist_cache['num_members'] - $_REQUEST['start']) - ($second_offset > $memberlist_cache['num_members'] ? $cache_step_size - $memberlist_cache['num_members'] % $cache_step_size : 0); } // Select the members from the database. $request = smf_db_query(' SELECT mem.id_member FROM {db_prefix}members AS mem' . ($_REQUEST['sort'] === 'is_online' ? ' LEFT JOIN {db_prefix}log_online AS lo ON (lo.id_member = mem.id_member)' : '') . ($_REQUEST['sort'] === 'id_group' ? ' LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:regular_id_group} THEN mem.id_post_group ELSE mem.id_group END)' : '') . ' WHERE mem.is_activated = {int:is_activated}' . (empty($where) ? '' : ' AND ' . $where) . ' ORDER BY {raw:sort} LIMIT ' . $limit . ', ' . $modSettings['defaultMaxMembers'], $query_parameters); printMemberListRows($request); mysql_free_result($request); // Add anchors at the start of each letter. if ($_REQUEST['sort'] == 'real_name') { $last_letter = ''; foreach ($context['members'] as $i => $dummy) { $this_letter = commonAPI::strtolower(commonAPI::substr($context['members'][$i]['name'], 0, 1)); if ($this_letter != $last_letter && preg_match('~[a-z]~', $this_letter) === 1) { $context['members'][$i]['sort_letter'] = htmlspecialchars($this_letter); $last_letter = $this_letter; } } } }
function EditCustomProfiles() { global $txt, $scripturl, $context, $settings, $sc, $smcFunc; // Sort out the context! $context['fid'] = isset($_GET['fid']) ? (int) $_GET['fid'] : 0; $context[$context['admin_menu_name']]['current_subsection'] = 'profile'; $context['page_title'] = $context['fid'] ? $txt['custom_edit_title'] : $txt['custom_add_title']; $context['sub_template'] = 'edit_profile_field'; // Load the profile language for section names. loadLanguage('Profile'); if ($context['fid']) { $request = smf_db_query(' SELECT id_field, col_name, field_name, field_desc, field_type, field_length, field_options, show_reg, show_display, show_profile, private, active, default_value, can_search, bbc, mask, enclose, placement FROM {db_prefix}custom_fields WHERE id_field = {int:current_field}', array('current_field' => $context['fid'])); $context['field'] = array(); while ($row = mysql_fetch_assoc($request)) { if ($row['field_type'] == 'textarea') { @(list($rows, $cols) = @explode(',', $row['default_value'])); } else { $rows = 3; $cols = 30; } $context['field'] = array('name' => $row['field_name'], 'desc' => $row['field_desc'], 'colname' => $row['col_name'], 'profile_area' => $row['show_profile'], 'reg' => $row['show_reg'], 'display' => $row['show_display'], 'type' => $row['field_type'], 'max_length' => $row['field_length'], 'rows' => $rows, 'cols' => $cols, 'bbc' => $row['bbc'] ? true : false, 'default_check' => $row['field_type'] == 'check' && $row['default_value'] ? true : false, 'default_select' => $row['field_type'] == 'select' || $row['field_type'] == 'radio' ? $row['default_value'] : '', 'options' => strlen($row['field_options']) > 1 ? explode(',', $row['field_options']) : array('', '', ''), 'active' => $row['active'], 'private' => $row['private'], 'can_search' => $row['can_search'], 'mask' => $row['mask'], 'regex' => substr($row['mask'], 0, 5) == 'regex' ? substr($row['mask'], 5) : '', 'enclose' => $row['enclose'], 'placement' => $row['placement']); } mysql_free_result($request); } // Setup the default values as needed. if (empty($context['field'])) { $context['field'] = array('name' => '', 'colname' => '???', 'desc' => '', 'profile_area' => 'forumprofile', 'reg' => false, 'display' => false, 'type' => 'text', 'max_length' => 255, 'rows' => 4, 'cols' => 30, 'bbc' => false, 'default_check' => false, 'default_select' => '', 'options' => array('', '', ''), 'active' => true, 'private' => false, 'can_search' => false, 'mask' => 'nohtml', 'regex' => '', 'enclose' => '', 'placement' => 0); } // Are we saving? if (isset($_POST['save'])) { checkSession(); // Everyone needs a name - even the (bracket) unknown... if (trim($_POST['field_name']) == '') { fatal_lang_error('custom_option_need_name'); } $_POST['field_name'] = commonAPI::htmlspecialchars($_POST['field_name']); $_POST['field_desc'] = commonAPI::htmlspecialchars($_POST['field_desc']); // Checkboxes... $show_reg = isset($_POST['reg']) ? (int) $_POST['reg'] : 0; $show_display = isset($_POST['display']) ? 1 : 0; $bbc = isset($_POST['bbc']) ? 1 : 0; $show_profile = $_POST['profile_area']; $active = isset($_POST['active']) ? 1 : 0; $private = isset($_POST['private']) ? (int) $_POST['private'] : 0; $can_search = isset($_POST['can_search']) ? 1 : 0; // Some masking stuff... $mask = isset($_POST['mask']) ? $_POST['mask'] : ''; if ($mask == 'regex' && isset($_POST['regex'])) { $mask .= $_POST['regex']; } $field_length = isset($_POST['max_length']) ? (int) $_POST['max_length'] : 255; $enclose = isset($_POST['enclose']) ? $_POST['enclose'] : ''; $placement = isset($_POST['placement']) ? (int) $_POST['placement'] : 0; // Select options? $field_options = ''; $newOptions = array(); $default = isset($_POST['default_check']) && $_POST['field_type'] == 'check' ? 1 : ''; if (!empty($_POST['select_option']) && ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio')) { foreach ($_POST['select_option'] as $k => $v) { // Clean, clean, clean... $v = commonAPI::htmlspecialchars($v); $v = strtr($v, array(',' => '')); // Nada, zip, etc... if (trim($v) == '') { continue; } // Otherwise, save it boy. $field_options .= $v . ','; // This is just for working out what happened with old options... $newOptions[$k] = $v; // Is it default? if (isset($_POST['default_select']) && $_POST['default_select'] == $k) { $default = $v; } } $field_options = substr($field_options, 0, -1); } // Text area has default has dimensions if ($_POST['field_type'] == 'textarea') { $default = (int) $_POST['rows'] . ',' . (int) $_POST['cols']; } // Come up with the unique name? if (empty($context['fid'])) { $colname = commonAPI::substr(strtr($_POST['field_name'], array(' ' => '')), 0, 6); preg_match('~([\\w\\d_-]+)~', $colname, $matches); // If there is nothing to the name, then let's start out own - for foreign languages etc. if (isset($matches[1])) { $colname = $initial_colname = 'cust_' . strtolower($matches[1]); } else { $colname = $initial_colname = 'cust_' . mt_rand(1, 999); } // Make sure this is unique. // !!! This may not be the most efficient way to do this. $unique = false; for ($i = 0; !$unique && $i < 9; $i++) { $request = smf_db_query(' SELECT id_field FROM {db_prefix}custom_fields WHERE col_name = {string:current_column}', array('current_column' => $colname)); if (mysql_num_rows($request) == 0) { $unique = true; } else { $colname = $initial_colname . $i; } mysql_free_result($request); } // Still not a unique colum name? Leave it up to the user, then. if (!$unique) { fatal_lang_error('custom_option_not_unique'); } } else { // Anything going to check or select is pointless keeping - as is anything coming from check! if ($_POST['field_type'] == 'check' && $context['field']['type'] != 'check' || ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') && $context['field']['type'] != 'select' && $context['field']['type'] != 'radio' || $context['field']['type'] == 'check' && $_POST['field_type'] != 'check') { smf_db_query(' DELETE FROM {db_prefix}themes WHERE variable = {string:current_column} AND id_member > {int:no_member}', array('no_member' => 0, 'current_column' => $context['field']['colname'])); } elseif ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') { $optionChanges = array(); $takenKeys = array(); // Work out what's changed! foreach ($context['field']['options'] as $k => $option) { if (trim($option) == '') { continue; } // Still exists? if (in_array($option, $newOptions)) { $takenKeys[] = $k; continue; } } // Finally - have we renamed it - or is it really gone? foreach ($optionChanges as $k => $option) { // Just been renamed? if (!in_array($k, $takenKeys) && !empty($newOptions[$k])) { smf_db_query(' UPDATE {db_prefix}themes SET value = {string:new_value} WHERE variable = {string:current_column} AND value = {string:old_value} AND id_member > {int:no_member}', array('no_member' => 0, 'new_value' => $newOptions[$k], 'current_column' => $context['field']['colname'], 'old_value' => $option)); } } } //!!! Maybe we should adjust based on new text length limits? } // Do the insertion/updates. if ($context['fid']) { smf_db_query(' UPDATE {db_prefix}custom_fields SET field_name = {string:field_name}, field_desc = {string:field_desc}, field_type = {string:field_type}, field_length = {int:field_length}, field_options = {string:field_options}, show_reg = {int:show_reg}, show_display = {int:show_display}, show_profile = {string:show_profile}, private = {int:private}, active = {int:active}, default_value = {string:default_value}, can_search = {int:can_search}, bbc = {int:bbc}, mask = {string:mask}, enclose = {string:enclose}, placement = {int:placement} WHERE id_field = {int:current_field}', array('field_length' => $field_length, 'show_reg' => $show_reg, 'show_display' => $show_display, 'private' => $private, 'active' => $active, 'can_search' => $can_search, 'bbc' => $bbc, 'current_field' => $context['fid'], 'field_name' => $_POST['field_name'], 'field_desc' => $_POST['field_desc'], 'field_type' => $_POST['field_type'], 'field_options' => $field_options, 'show_profile' => $show_profile, 'default_value' => $default, 'mask' => $mask, 'enclose' => $enclose, 'placement' => $placement)); // Just clean up any old selects - these are a pain! if (($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') && !empty($newOptions)) { smf_db_query(' DELETE FROM {db_prefix}themes WHERE variable = {string:current_column} AND value NOT IN ({array_string:new_option_values}) AND id_member > {int:no_member}', array('no_member' => 0, 'new_option_values' => $newOptions, 'current_column' => $context['field']['colname'])); } } else { smf_db_insert('', '{db_prefix}custom_fields', array('col_name' => 'string', 'field_name' => 'string', 'field_desc' => 'string', 'field_type' => 'string', 'field_length' => 'string', 'field_options' => 'string', 'show_reg' => 'int', 'show_display' => 'int', 'show_profile' => 'string', 'private' => 'int', 'active' => 'int', 'default_value' => 'string', 'can_search' => 'int', 'bbc' => 'int', 'mask' => 'string', 'enclose' => 'string', 'placement' => 'int'), array($colname, $_POST['field_name'], $_POST['field_desc'], $_POST['field_type'], $field_length, $field_options, $show_reg, $show_display, $show_profile, $private, $active, $default, $can_search, $bbc, $mask, $enclose, $placement), array('id_field')); } // As there's currently no option to priorize certain fields over others, let's order them alphabetically. smf_db_query(' ALTER TABLE {db_prefix}custom_fields ORDER BY field_name', array('db_error_skip' => true)); } elseif (isset($_POST['delete']) && $context['field']['colname']) { checkSession(); // Delete the user data first. smf_db_query(' DELETE FROM {db_prefix}themes WHERE variable = {string:current_column} AND id_member > {int:no_member}', array('no_member' => 0, 'current_column' => $context['field']['colname'])); // Finally - the field itself is gone! smf_db_query(' DELETE FROM {db_prefix}custom_fields WHERE id_field = {int:current_field}', array('current_field' => $context['fid'])); } // Rebuild display cache etc. if (isset($_POST['delete']) || isset($_POST['save'])) { checkSession(); $request = smf_db_query(' SELECT col_name, field_name, field_type, bbc, enclose, placement FROM {db_prefix}custom_fields WHERE show_display = {int:is_displayed} AND active = {int:active} AND private != {int:not_owner_only} AND private != {int:not_admin_only}', array('is_displayed' => 1, 'active' => 1, 'not_owner_only' => 2, 'not_admin_only' => 3)); $fields = array(); while ($row = mysql_fetch_assoc($request)) { $fields[] = array('colname' => strtr($row['col_name'], array('|' => '', ';' => '')), 'title' => strtr($row['field_name'], array('|' => '', ';' => '')), 'type' => $row['field_type'], 'bbc' => $row['bbc'] ? '1' : '0', 'placement' => !empty($row['placement']) ? $row['placement'] : '0', 'enclose' => !empty($row['enclose']) ? $row['enclose'] : ''); } mysql_free_result($request); updateSettings(array('displayFields' => serialize($fields))); redirectexit('action=admin;area=featuresettings;sa=profile'); } }
function template_show_month_grid($grid_name) { global $context, $settings, $options, $txt, $scripturl, $modSettings, $smcFunc; if (!isset($context['calendar_grid_' . $grid_name])) { return false; } $calendar_data =& $context['calendar_grid_' . $grid_name]; $colspan = !empty($calendar_data['show_week_links']) ? 8 : 7; if (empty($calendar_data['disable_title'])) { echo ' <div class="cat_bar2"> <h3 class="centertext" style="font-size: ', $calendar_data['size'] == 'large' ? 'medium' : 'small', ';">'; if (empty($calendar_data['previous_calendar']['disabled']) && $calendar_data['show_next_prev']) { echo ' <span class="floatleft"><a href="', $calendar_data['previous_calendar']['href'], '">«</a></span>'; } if (empty($calendar_data['next_calendar']['disabled']) && $calendar_data['show_next_prev']) { echo ' <span class="floatright"><a href="', $calendar_data['next_calendar']['href'], '">»</a></span>'; } if ($calendar_data['show_next_prev']) { echo ' ', $txt['months_titles'][$calendar_data['current_month']], ' ', $calendar_data['current_year']; } else { echo ' <a href="', $scripturl, '?action=calendar;year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], '">', $txt['months_titles'][$calendar_data['current_month']], ' ', $calendar_data['current_year'], '</a>'; } echo ' </h3> </div>'; } echo ' <table class="calendar_table">'; // Show each day of the week. if (empty($calendar_data['disable_day_titles'])) { echo ' <tr>'; if (!empty($calendar_data['show_week_links'])) { echo ' <th class="glass"> </th>'; } foreach ($calendar_data['week_days'] as $day) { echo ' <th class="glass days" scope="col" ', $calendar_data['size'] == 'small' ? 'style="font-size: x-small;"' : '', '>', !empty($calendar_data['short_day_titles']) ? commonAPI::substr($txt['days'][$day], 0, 1) : $txt['days'][$day], '</th>'; } echo ' </tr>'; } /* Each week in weeks contains the following: days (a list of days), number (week # in the year.) */ foreach ($calendar_data['weeks'] as $week) { echo ' <tr>'; if (!empty($calendar_data['show_week_links'])) { echo ' <td class="weeks orange_container"> <a href="', $scripturl, '?action=calendar;viewweek;year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $week['days'][0]['day'], '">»</a> </td>'; } /* Every day has the following: day (# in month), is_today (is this day *today*?), is_first_day (first day of the week?), holidays, events, birthdays. (last three are lists.) */ foreach ($week['days'] as $day) { // If this is today, make it a different color and show a border. echo ' <td style="height: ', $calendar_data['size'] == 'small' ? '20' : '100', 'px; padding: 2px;', $calendar_data['size'] == 'small' ? 'font-size: x-small;' : '', '" class="', $day['is_today'] ? 'red_container' : 'blue_container', ' days">'; // Skip it if it should be blank - it's not a day if it has no number. if (!empty($day['day'])) { // Should the day number be a link? if (!empty($modSettings['cal_daysaslink']) && $context['can_post']) { echo ' <a href="', $scripturl, '?action=calendar;sa=post;month=', $calendar_data['current_month'], ';year=', $calendar_data['current_year'], ';day=', $day['day'], ';', $context['session_var'], '=', $context['session_id'], '">', $day['day'], '</a>'; } else { echo ' ', $day['day']; } // Is this the first day of the week? (and are we showing week numbers?) if ($day['is_first_day'] && $calendar_data['size'] != 'small') { echo '<span class="smalltext"> - <a href="', $scripturl, '?action=calendar;viewweek;year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $day['day'], '">', $txt['calendar_week'], ' ', $week['number'], '</a></span>'; } // Are there any holidays? if (!empty($day['holidays'])) { echo ' <div class="smalltext holiday">', $txt['calendar_prompt'], ' ', implode(', ', $day['holidays']), '</div>'; } // Show any birthdays... if (!empty($day['birthdays'])) { echo ' <div class="smalltext"> <span class="birthday">', $txt['birthdays'], '</span>'; /* Each of the birthdays has: id, name (person), age (if they have one set?), and is_last. (last in list?) */ $use_js_hide = empty($context['show_all_birthdays']) && count($day['birthdays']) > 15; $count = 0; foreach ($day['birthdays'] as $member) { echo ' <a href="', $scripturl, '?action=profile;u=', $member['id'], '">', $member['name'], isset($member['age']) ? ' (' . $member['age'] . ')' : '', '</a>', $member['is_last'] || $count == 10 && $use_js_hide ? '' : ', '; // Stop at ten? if ($count == 10 && $use_js_hide) { echo '<span class="hidelink" id="bdhidelink_', $day['day'], '">...<br /><a href="', $scripturl, '?action=calendar;month=', $calendar_data['current_month'], ';year=', $calendar_data['current_year'], ';showbd" onclick="document.getElementById(\'bdhide_', $day['day'], '\').style.display = \'\'; document.getElementById(\'bdhidelink_', $day['day'], '\').style.display = \'none\'; return false;">(', sprintf($txt['calendar_click_all'], count($day['birthdays'])), ')</a></span><span id="bdhide_', $day['day'], '" style="display: none;">, '; } $count++; } if ($use_js_hide) { echo ' </span>'; } echo ' </div>'; } // Any special posted events? if (!empty($day['events'])) { echo ' <div class="smalltext"> <span class="event">', $txt['events'], '</span>'; /* The events are made up of: title, href, is_last, can_edit (are they allowed to?), and modify_href. */ foreach ($day['events'] as $event) { // If they can edit the event, show a star they can click on.... if ($event['can_edit']) { echo ' <a class="modify_event" href="', $event['modify_href'], '"><img src="' . $settings['images_url'] . '/icons/modify_small.gif" alt="*" /></a>'; } echo ' ', $event['link'], $event['is_last'] ? '' : ', '; } echo ' </div>'; } } echo ' </td>'; } echo ' </tr>'; } echo ' </table>'; }
function RegisterCheckUsername() { global $sourcedir, $context, $txt; // This is XML! loadTemplate('Xml'); $context['sub_template'] = 'check_username'; $context['checked_username'] = isset($_GET['username']) ? $_GET['username'] : ''; $context['valid_username'] = true; // Clean it up like mother would. $context['checked_username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : "Â ") . ']+~u', ' ', $context['checked_username']); if (commonAPI::strlen($context['checked_username']) > 25) { $context['checked_username'] = commonAPI::htmltrim(commonAPI::substr($context['checked_username'], 0, 25)); } // Only these characters are permitted. if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $context['checked_username'])) != 0 || $context['checked_username'] == '_' || $context['checked_username'] == '|' || strpos($context['checked_username'], '[code') !== false || strpos($context['checked_username'], '[/code') !== false) { $context['valid_username'] = false; } if (stristr($context['checked_username'], $txt['guest_title']) !== false) { $context['valid_username'] = false; } if (trim($context['checked_username']) == '') { $context['valid_username'] = false; } else { require_once $sourcedir . '/lib/Subs-Members.php'; $context['valid_username'] &= isReservedName($context['checked_username'], 0, false, false) ? 0 : 1; } }
function prepareSearchContext($reset = false) { global $txt, $modSettings, $scripturl, $user_info, $sourcedir; global $memberContext, $context, $options, $messages_request; global $boards_can, $participants, $output; // Remember which message this is. (ie. reply #83) static $counter = null; if ($counter == null || $reset) { $counter = $_REQUEST['start'] + 1; } // If the query returned false, bail. if ($messages_request == false) { return false; } // Start from the beginning... if ($reset) { return @mysql_data_seek($messages_request, 0); } // Attempt to get the next message. $message = mysql_fetch_assoc($messages_request); if (!$message) { return false; } // Can't have an empty subject can we? $message['subject'] = $message['subject'] != '' ? $message['subject'] : $txt['no_subject']; $message['first_subject'] = $message['first_subject'] != '' ? $message['first_subject'] : $txt['no_subject']; $message['last_subject'] = $message['last_subject'] != '' ? $message['last_subject'] : $txt['no_subject']; // If it couldn't load, or the user was a guest.... someday may be done with a guest table. if (!loadMemberContext($message['id_member'])) { // Notice this information isn't used anywhere else.... *cough guest table cough*. $memberContext[$message['id_member']]['name'] = $message['poster_name']; $memberContext[$message['id_member']]['id'] = 0; $memberContext[$message['id_member']]['group'] = $txt['guest_title']; $memberContext[$message['id_member']]['link'] = $message['poster_name']; $memberContext[$message['id_member']]['email'] = $message['poster_email']; } $memberContext[$message['id_member']]['ip'] = $message['poster_ip']; // Do the censor thang... censorText($message['body']); censorText($message['subject']); censorText($message['first_subject']); censorText($message['last_subject']); // Shorten this message if necessary. if ($context['compact']) { // Set the number of characters before and after the searched keyword. $charLimit = 50; $message['body'] = strtr($message['body'], array("\n" => ' ', '<br />' => "\n")); $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); $message['body'] = strip_tags(strtr($message['body'], array('</div>' => '<br />', '</li>' => '<br />')), '<br>'); if (commonAPI::strlen($message['body']) > $charLimit) { if (empty($context['key_words'])) { $message['body'] = commonAPI::substr($message['body'], 0, $charLimit) . '<strong>...</strong>'; } else { $matchString = ''; $force_partial_word = false; foreach ($context['key_words'] as $keyword) { $keyword = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~e', 'commonAPI::entity_fix(\'\\1\')', strtr($keyword, array('\\\'' => '\'', '&' => '&'))); if (preg_match('~[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]$~', $keyword) != 0 || preg_match('~^[\'\\.,/@%&;:(){}\\[\\]_\\-+\\\\]~', $keyword) != 0) { $force_partial_word = true; } $matchString .= strtr(preg_quote($keyword, '/'), array('\\*' => '.+?')) . '|'; } $matchString = substr($matchString, 0, -1); $message['body'] = un_htmlspecialchars(strtr($message['body'], array(' ' => ' ', '<br />' => "\n", '[' => '[', ']' => ']', ':' => ':', '@' => '@'))); if (empty($modSettings['search_method']) || $force_partial_word) { preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?|^)(' . $matchString . ')(.{0,' . $charLimit . '}[\\s\\W]|[^\\s\\W]{' . $charLimit . '})/isu', $message['body'], $matches); } else { preg_match_all('/([^\\s\\W]{' . $charLimit . '}[\\s\\W]|[\\s\\W].{0,' . $charLimit . '}?[\\s\\W]|^)(' . $matchString . ')([\\s\\W].{0,' . $charLimit . '}[\\s\\W]|[\\s\\W][^\\s\\W]{' . $charLimit . '})/isu', $message['body'], $matches); } $message['body'] = ''; foreach ($matches[0] as $index => $match) { $match = strtr(htmlspecialchars($match, ENT_QUOTES), array("\n" => ' ')); $message['body'] .= '<strong>......</strong> ' . $match . ' <strong>......</strong>'; } } // Re-fix the international characters. $message['body'] = preg_replace('~&#(\\d{1,7}|x[0-9a-fA-F]{1,6});~e', 'commonAPI::entity_fix(\'\\1\')', $message['body']); } } else { // Run BBC interpreter on the message. $message['body'] = parse_bbc($message['body'], $message['smileys_enabled'], $message['id_msg']); } // Make sure we don't end up with a practically empty message body. $message['body'] = preg_replace('~^(?: )+$~', '', $message['body']); // Do we have quote tag enabled? $quote_enabled = empty($modSettings['disabledBBC']) || !in_array('quote', explode(',', $modSettings['disabledBBC'])); $href = URL::topic($message['id_topic'], $message['first_subject'], 0); $mhref = URL::user($message['first_member_id'], $message['first_member_name']); $lhref = URL::topic($message['id_topic'], $message['last_subject'], 0, $message['num_replies'] == 0 ? true : false, $message['num_replies'] == 0 ? '' : '.msg' . $message['last_msg'], $message['num_replies'] == 0 ? '' : '#msg' . $message['last_msg']); $lmhref = URL::user($message['last_member_id'], $message['last_member_name']); $bhref = URL::board($message['id_board'], $message['board_name'], 0, true); $output = array_merge($context['topics'][$message['id_msg']], array('id' => $message['id_topic'], 'is_sticky' => !empty($modSettings['enableStickyTopics']) && !empty($message['is_sticky']), 'is_locked' => !empty($message['locked']), 'is_poll' => $modSettings['pollMode'] == '1' && $message['id_poll'] > 0, 'is_hot' => $message['num_replies'] >= $modSettings['hotTopicPosts'], 'is_very_hot' => $message['num_replies'] >= $modSettings['hotTopicVeryPosts'], 'posted_in' => !empty($participants[$message['id_topic']]), 'views' => $message['num_views'], 'replies' => $message['num_replies'], 'can_reply' => in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any']), 'can_quote' => (in_array($message['id_board'], $boards_can['post_reply_any']) || in_array(0, $boards_can['post_reply_any'])) && $quote_enabled, 'can_mark_notify' => in_array($message['id_board'], $boards_can['mark_any_notify']) || in_array(0, $boards_can['mark_any_notify']) && !$context['user']['is_guest'], 'first_post' => array('id' => $message['first_msg'], 'time' => timeformat($message['first_poster_time']), 'timestamp' => forum_time(true, $message['first_poster_time']), 'subject' => $message['first_subject'], 'href' => $href, 'link' => '<a href="' . $href . '">' . $message['first_subject'] . '</a>', 'icon' => $message['first_icon'], 'icon_url' => getPostIcon($message['first_icon']), 'member' => array('id' => $message['first_member_id'], 'name' => $message['first_member_name'], 'href' => !empty($message['first_member_id']) ? $mhref : '', 'link' => !empty($message['first_member_id']) ? '<a href="' . $mhref . '" title="' . $txt['profile_of'] . ' ' . $message['first_member_name'] . '">' . $message['first_member_name'] . '</a>' : $message['first_member_name'])), 'last_post' => array('id' => $message['last_msg'], 'time' => timeformat($message['last_poster_time']), 'timestamp' => forum_time(true, $message['last_poster_time']), 'subject' => $message['last_subject'], 'href' => $lhref, 'link' => '<a href="' . $lhref . '">' . $message['last_subject'] . '</a>', 'icon' => $message['last_icon'], 'icon_url' => getPostIcon($message['last_icon']), 'member' => array('id' => $message['last_member_id'], 'name' => $message['last_member_name'], 'href' => !empty($message['last_member_id']) ? $lmhref : '', 'link' => !empty($message['last_member_id']) ? '<a href="' . $lmhref . '" title="' . $txt['profile_of'] . ' ' . $message['last_member_name'] . '">' . $message['last_member_name'] . '</a>' : $message['last_member_name'])), 'board' => array('id' => $message['id_board'], 'name' => $message['board_name'], 'href' => $bhref, 'link' => '<a href="' . $bhref . '">' . $message['board_name'] . '</a>'), 'category' => array('id' => $message['id_cat'], 'name' => $message['cat_name'], 'href' => $scripturl . '#c' . $message['id_cat'], 'link' => '<a href="' . $scripturl . '#c' . $message['id_cat'] . '">' . $message['cat_name'] . '</a>'))); determineTopicClass($output); if ($output['posted_in']) { $output['class'] = 'my_' . $output['class']; } $body_highlighted = $message['body']; $subject_highlighted = $message['subject']; if (!empty($options['display_quick_mod'])) { $started = $output['first_post']['member']['id'] == $user_info['id']; $output['quick_mod'] = array('lock' => in_array(0, $boards_can['lock_any']) || in_array($output['board']['id'], $boards_can['lock_any']) || $started && (in_array(0, $boards_can['lock_own']) || in_array($output['board']['id'], $boards_can['lock_own'])), 'sticky' => (in_array(0, $boards_can['make_sticky']) || in_array($output['board']['id'], $boards_can['make_sticky'])) && !empty($modSettings['enableStickyTopics']), 'move' => in_array(0, $boards_can['move_any']) || in_array($output['board']['id'], $boards_can['move_any']) || $started && (in_array(0, $boards_can['move_own']) || in_array($output['board']['id'], $boards_can['move_own'])), 'remove' => in_array(0, $boards_can['remove_any']) || in_array($output['board']['id'], $boards_can['remove_any']) || $started && (in_array(0, $boards_can['remove_own']) || in_array($output['board']['id'], $boards_can['remove_own']))); $context['can_lock'] |= $output['quick_mod']['lock']; $context['can_sticky'] |= $output['quick_mod']['sticky']; $context['can_move'] |= $output['quick_mod']['move']; $context['can_remove'] |= $output['quick_mod']['remove']; $context['can_merge'] |= in_array($output['board']['id'], $boards_can['merge_any']); // If we've found a message we can move, and we don't already have it, load the destinations. if ($options['display_quick_mod'] && !isset($context['move_to_boards']) && $context['can_move']) { require_once $sourcedir . '/lib/Subs-MessageIndex.php'; $boardListOptions = array('use_permissions' => true, 'not_redirection' => true, 'selected_board' => empty($_SESSION['move_to_topic']) ? null : $_SESSION['move_to_topic']); $context['move_to_boards'] = getBoardList($boardListOptions); } } foreach ($context['key_words'] as $query) { // Fix the international characters in the keyword too. $query = strtr(commonAPI::htmlspecialchars($query), array('\\\'' => '\'')); $body_highlighted = preg_replace('/((<[^>]*)|' . preg_quote(strtr($query, array('\'' => ''')), '/') . ')/ieu', "'\$2' == '\$1' ? stripslashes('\$1') : '<strong class=\"highlight\">\$1</strong>'", $body_highlighted); $subject_highlighted = preg_replace('/(' . preg_quote($query, '/') . ')/iu', '<strong class="highlight">$1</strong>', $subject_highlighted); } $mhref = URL::topic($message['id_topic'], $message['subject'], 0, false, '.msg' . $message['id_msg'], '#msg' . $message['id_msg']); $output['matches'][] = array('id' => $message['id_msg'], 'attachment' => loadAttachmentContext($message['id_msg']), 'alternate' => $counter % 2, 'member' => &$memberContext[$message['id_member']], 'icon' => $message['icon'], 'icon_url' => getPostIcon($message['icon']), 'subject' => $message['subject'], 'subject_highlighted' => $subject_highlighted, 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'counter' => $counter, 'modified' => array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'name' => $message['modified_name']), 'body' => $body_highlighted, 'body_highlighted' => $body_highlighted, 'start' => 'msg' . $message['id_msg'], 'href' => $mhref, 'link' => '<a href="' . $mhref . '">' . $message['subject'] . '</a>'); $counter++; return $output; }
function prepareTopicArray($topic_ids) { global $scripturl, $txt, $db_prefix, $modSettings, $options, $context; global $user_info, $board_info, $settings, $smcFunc; // Setup the default topic icons... $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'; } if (empty($topic_ids)) { return false; } $context['messages_per_page'] = commonAPI::getMessagesPerPage(); $result = smf_db_query(' SELECT t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board, ' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from, t.id_last_msg, t.approved, t.unapproved_posts, ml.poster_time AS last_poster_time, ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon, ml.poster_name AS last_member_name, ml.id_member AS last_id_member, IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg, mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon, mf.poster_name AS first_member_name, mf.id_member AS first_id_member, IFNULL(memf.real_name, mf.poster_name) AS first_display_name, SUBSTRING(ml.body, 1, 385) AS last_body, SUBSTRING(mf.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys, b.id_board, b.name As board_name FROM {db_prefix}topics AS t INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg) INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member) LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : ' 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}) AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')', array('current_member' => $user_info['id'], 'topic_list' => $topic_ids, 'is_approved' => 1)); // Stolen from SMF while ($row = mysql_fetch_assoc($result)) { if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0') { continue; } 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 (commonAPI::strlen($row['first_body']) > 128) { $row['first_body'] = commonAPI::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 (commonAPI::strlen($row['last_body']) > 128) { $row['last_body'] = commonAPI::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; if ($topic_length > $context['messages_per_page']) { $tmppages = array(); $tmpa = 1; for ($tmpb = 0; $tmpb < $topic_length; $tmpb += $context['messages_per_page']) { $tmppages[] = '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.' . $tmpb . '">' . $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... if (empty($modSettings['messageIconChecks_disable'])) { 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'; } 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'; } } else { if (!isset($context['icon_sources'][$row['first_icon']])) { $context['icon_sources'][$row['first_icon']] = 'images_url'; } if (!isset($context['icon_sources'][$row['last_icon']])) { $context['icon_sources'][$row['last_icon']] = 'images_url'; } } $context['related_topics'][$row['id_topic']] = array('id' => $row['id_topic'], 'board' => array('id' => $row['id_board'], 'name' => $row['board_name'], 'link' => '<a href="' . $scripturl . '?board=' . $row['id_board'] . '.0">' . $row['board_name'] . '</a>', 'can_approve_posts' => in_array(0, $context['can_approve_posts_boards']) || in_array($row['id_board'], $context['can_approve_posts_boards'])), 'first_post' => array('id' => $row['id_first_msg'], 'member' => array('username' => $row['first_member_name'], 'name' => $row['first_display_name'], 'id' => $row['first_id_member'], 'href' => !empty($row['first_id_member']) ? $scripturl . '?action=profile;u=' . $row['first_id_member'] : '', 'link' => !empty($row['first_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['first_id_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '">' . $row['first_display_name'] . '</a>' : $row['first_display_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', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['first_subject'] . '</a>'), 'last_post' => array('id' => $row['id_last_msg'], 'member' => array('username' => $row['last_member_name'], 'name' => $row['last_display_name'], 'id' => $row['last_id_member'], 'href' => !empty($row['last_id_member']) ? $scripturl . '?action=profile;u=' . $row['last_id_member'] : '', 'link' => !empty($row['last_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['last_id_member'] . '">' . $row['last_display_name'] . '</a>' : $row['last_display_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']) . '#new', 'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_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'], 'new' => $row['new_from'] <= $row['id_msg_modified'], 'new_from' => $row['new_from'], 'newtime' => $row['new_from'], 'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new', 'pages' => $pages, 'replies' => $row['num_replies'], 'views' => $row['num_views'], 'approved' => $row['approved'], 'unapproved_posts' => $row['unapproved_posts']); determineTopicClass($context['related_topics'][$row['id_topic']]); } mysql_free_result($result); }
function MergeExecute($topics = array()) { global $user_info, $txt, $context, $scripturl, $sourcedir; global $smcFunc, $language, $modSettings; // Check the session. checkSession('request'); // Handle URLs from MergeIndex. if (!empty($_GET['from']) && !empty($_GET['to'])) { $topics = array((int) $_GET['from'], (int) $_GET['to']); } // If we came from a form, the topic IDs came by post. if (!empty($_POST['topics']) && is_array($_POST['topics'])) { $topics = $_POST['topics']; } // There's nothing to merge with just one topic... if (empty($topics) || !is_array($topics) || count($topics) == 1) { fatal_lang_error('merge_need_more_topics'); } // Make sure every topic is numeric, or some nasty things could be done with the DB. foreach ($topics as $id => $topic) { $topics[$id] = (int) $topic; } // Joy of all joys, make sure they're not pi**ing about with unapproved topics they can't see :P if ($modSettings['postmod_active']) { $can_approve_boards = boardsAllowedTo('approve_posts'); } // Get info about the topics and polls that will be merged. $request = smf_db_query(' SELECT t.id_topic, t.id_board, t.id_poll, t.num_views, t.is_sticky, t.approved, t.num_replies, t.unapproved_posts, m1.subject, m1.poster_time AS time_started, IFNULL(mem1.id_member, 0) AS id_member_started, IFNULL(mem1.real_name, m1.poster_name) AS name_started, m2.poster_time AS time_updated, IFNULL(mem2.id_member, 0) AS id_member_updated, IFNULL(mem2.real_name, m2.poster_name) AS name_updated FROM {db_prefix}topics AS t INNER JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg) INNER JOIN {db_prefix}messages AS m2 ON (m2.id_msg = t.id_last_msg) LEFT JOIN {db_prefix}members AS mem1 ON (mem1.id_member = m1.id_member) LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = m2.id_member) WHERE t.id_topic IN ({array_int:topic_list}) ORDER BY t.id_first_msg LIMIT ' . count($topics), array('topic_list' => $topics)); if (mysql_num_rows($request) < 2) { fatal_lang_error('no_topic_id'); } $num_views = 0; $is_sticky = 0; $boardTotals = array(); $boards = array(); $polls = array(); while ($row = mysql_fetch_assoc($request)) { // Make a note for the board counts... if (!isset($boardTotals[$row['id_board']])) { $boardTotals[$row['id_board']] = array('posts' => 0, 'topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0); } // We can't see unapproved topics here? if ($modSettings['postmod_active'] && !$row['approved'] && $can_approve_boards != array(0) && in_array($row['id_board'], $can_approve_boards)) { continue; } elseif (!$row['approved']) { $boardTotals[$row['id_board']]['unapproved_topics']++; } else { $boardTotals[$row['id_board']]['topics']++; } $boardTotals[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts']; $boardTotals[$row['id_board']]['posts'] += $row['num_replies'] + ($row['approved'] ? 1 : 0); $topic_data[$row['id_topic']] = array('id' => $row['id_topic'], 'board' => $row['id_board'], 'poll' => $row['id_poll'], 'num_views' => $row['num_views'], 'subject' => $row['subject'], 'started' => array('time' => timeformat($row['time_started']), 'timestamp' => forum_time(true, $row['time_started']), 'href' => empty($row['id_member_started']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_started'], 'link' => empty($row['id_member_started']) ? $row['name_started'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_started'] . '">' . $row['name_started'] . '</a>'), 'updated' => array('time' => timeformat($row['time_updated']), 'timestamp' => forum_time(true, $row['time_updated']), 'href' => empty($row['id_member_updated']) ? '' : $scripturl . '?action=profile;u=' . $row['id_member_updated'], 'link' => empty($row['id_member_updated']) ? $row['name_updated'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member_updated'] . '">' . $row['name_updated'] . '</a>')); $num_views += $row['num_views']; $boards[] = $row['id_board']; // If there's no poll, id_poll == 0... if ($row['id_poll'] > 0) { $polls[] = $row['id_poll']; } // Store the id_topic with the lowest id_first_msg. if (empty($firstTopic)) { $firstTopic = $row['id_topic']; } $is_sticky = max($is_sticky, $row['is_sticky']); } mysql_free_result($request); // If we didn't get any topics then they've been messing with unapproved stuff. if (empty($topic_data)) { fatal_lang_error('no_topic_id'); } $boards = array_values(array_unique($boards)); // The parameters of MergeExecute were set, so this must've been an internal call. if (!empty($topics)) { isAllowedTo('merge_any', $boards); loadTemplate('SplitTopics'); } // Get the boards a user is allowed to merge in. $merge_boards = boardsAllowedTo('merge_any'); if (empty($merge_boards)) { fatal_lang_error('cannot_merge_any', 'user'); } // Make sure they can see all boards.... $request = smf_db_query(' SELECT b.id_board FROM {db_prefix}boards AS b WHERE b.id_board IN ({array_int:boards}) AND {query_see_board}' . (!in_array(0, $merge_boards) ? ' AND b.id_board IN ({array_int:merge_boards})' : '') . ' LIMIT ' . count($boards), array('boards' => $boards, 'merge_boards' => $merge_boards)); // If the number of boards that's in the output isn't exactly the same as we've put in there, you're in trouble. if (mysql_num_rows($request) != count($boards)) { fatal_lang_error('no_board'); } mysql_free_result($request); if (empty($_REQUEST['sa']) || $_REQUEST['sa'] == 'options') { if (count($polls) > 1) { $request = smf_db_query(' SELECT t.id_topic, t.id_poll, m.subject, p.question FROM {db_prefix}polls AS p INNER JOIN {db_prefix}topics AS t ON (t.id_poll = p.id_poll) INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) WHERE p.id_poll IN ({array_int:polls}) LIMIT ' . count($polls), array('polls' => $polls)); while ($row = mysql_fetch_assoc($request)) { $context['polls'][] = array('id' => $row['id_poll'], 'topic' => array('id' => $row['id_topic'], 'subject' => $row['subject']), 'question' => $row['question'], 'selected' => $row['id_topic'] == $firstTopic); } mysql_free_result($request); } if (count($boards) > 1) { $request = smf_db_query(' SELECT id_board, name FROM {db_prefix}boards WHERE id_board IN ({array_int:boards}) ORDER BY name LIMIT ' . count($boards), array('boards' => $boards)); while ($row = mysql_fetch_assoc($request)) { $context['boards'][] = array('id' => $row['id_board'], 'name' => $row['name'], 'selected' => $row['id_board'] == $topic_data[$firstTopic]['board']); } mysql_free_result($request); } $context['topics'] = $topic_data; foreach ($topic_data as $id => $topic) { $context['topics'][$id]['selected'] = $topic['id'] == $firstTopic; } $context['page_title'] = $txt['merge']; $context['sub_template'] = 'merge_extra_options'; return; } // Determine target board. $target_board = count($boards) > 1 ? (int) $_REQUEST['board'] : $boards[0]; if (!in_array($target_board, $boards)) { fatal_lang_error('no_board'); } // Determine which poll will survive and which polls won't. $target_poll = count($polls) > 1 ? (int) $_POST['poll'] : (count($polls) == 1 ? $polls[0] : 0); if ($target_poll > 0 && !in_array($target_poll, $polls)) { fatal_lang_error('no_access', false); } $deleted_polls = empty($target_poll) ? $polls : array_diff($polls, array($target_poll)); // Determine the subject of the newly merged topic - was a custom subject specified? if (empty($_POST['subject']) && isset($_POST['custom_subject']) && $_POST['custom_subject'] != '') { $target_subject = strtr(commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => '')); // Keep checking the length. if (commonAPI::strlen($target_subject) > 100) { $target_subject = commonAPI::substr($target_subject, 0, 100); } // Nothing left - odd but pick the first topics subject. if ($target_subject == '') { $target_subject = $topic_data[$firstTopic]['subject']; } } elseif (!empty($topic_data[(int) $_POST['subject']]['subject'])) { $target_subject = $topic_data[(int) $_POST['subject']]['subject']; } else { $target_subject = $topic_data[$firstTopic]['subject']; } // Get the first and last message and the number of messages.... $request = smf_db_query(' SELECT approved, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg, COUNT(*) AS message_count FROM {db_prefix}messages WHERE id_topic IN ({array_int:topics}) GROUP BY approved ORDER BY approved DESC', array('topics' => $topics)); $topic_approved = 1; while ($row = mysql_fetch_assoc($request)) { // If this is approved, or is fully unapproved. if ($row['approved'] || !isset($first_msg)) { $first_msg = $row['first_msg']; $last_msg = $row['last_msg']; if ($row['approved']) { $num_replies = $row['message_count'] - 1; $num_unapproved = 0; } else { $topic_approved = 0; $num_replies = 0; $num_unapproved = $row['message_count']; } } else { // If this has a lower first_msg then the first post is not approved and hence the number of replies was wrong! if ($first_msg > $row['first_msg']) { $first_msg = $row['first_msg']; $num_replies++; $topic_approved = 0; } $num_unapproved = $row['message_count']; } } mysql_free_result($request); // Ensure we have a board stat for the target board. if (!isset($boardTotals[$target_board])) { $boardTotals[$target_board] = array('posts' => 0, 'topics' => 0, 'unapproved_posts' => 0, 'unapproved_topics' => 0); } // Fix the topic count stuff depending on what the new one counts as. if ($topic_approved) { $boardTotals[$target_board]['topics']--; } else { $boardTotals[$target_board]['unapproved_topics']--; } $boardTotals[$target_board]['unapproved_posts'] -= $num_unapproved; $boardTotals[$target_board]['posts'] -= $topic_approved ? $num_replies + 1 : $num_replies; // Get the member ID of the first and last message. $request = smf_db_query(' SELECT id_member FROM {db_prefix}messages WHERE id_msg IN ({int:first_msg}, {int:last_msg}) ORDER BY id_msg LIMIT 2', array('first_msg' => $first_msg, 'last_msg' => $last_msg)); list($member_started) = mysql_fetch_row($request); list($member_updated) = mysql_fetch_row($request); // First and last message are the same, so only row was returned. if ($member_updated === NULL) { $member_updated = $member_started; } mysql_free_result($request); // Assign the first topic ID to be the merged topic. $id_topic = min($topics); // Delete the remaining topics. $deleted_topics = array_diff($topics, array($id_topic)); smf_db_query(' DELETE FROM {db_prefix}topics WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics)); smf_db_query(' DELETE FROM {db_prefix}log_search_subjects WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics)); // Asssign the properties of the newly merged topic. smf_db_query(' UPDATE {db_prefix}topics SET id_board = {int:id_board}, id_member_started = {int:id_member_started}, id_member_updated = {int:id_member_updated}, id_first_msg = {int:id_first_msg}, id_last_msg = {int:id_last_msg}, id_poll = {int:id_poll}, num_replies = {int:num_replies}, unapproved_posts = {int:unapproved_posts}, num_views = {int:num_views}, is_sticky = {int:is_sticky}, approved = {int:approved} WHERE id_topic = {int:id_topic}', array('id_board' => $target_board, 'is_sticky' => $is_sticky, 'approved' => $topic_approved, 'id_topic' => $id_topic, 'id_member_started' => $member_started, 'id_member_updated' => $member_updated, 'id_first_msg' => $first_msg, 'id_last_msg' => $last_msg, 'id_poll' => $target_poll, 'num_replies' => $num_replies, 'unapproved_posts' => $num_unapproved, 'num_views' => $num_views)); // Grab the response prefix (like 'Re: ') in the default forum language. if (!isset($context['response_prefix']) && !($context['response_prefix'] = CacheAPI::getCache('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'); } CacheAPI::putCache('response_prefix', $context['response_prefix'], 600); } // Change the topic IDs of all messages that will be merged. Also adjust subjects if 'enforce subject' was checked. smf_db_query(' UPDATE {db_prefix}messages SET id_topic = {int:id_topic}, id_board = {int:target_board}' . (empty($_POST['enforce_subject']) ? '' : ', subject = {string:subject}') . ' WHERE id_topic IN ({array_int:topic_list})', array('topic_list' => $topics, 'id_topic' => $id_topic, 'target_board' => $target_board, 'subject' => $context['response_prefix'] . $target_subject)); // Any reported posts should reflect the new board. smf_db_query(' UPDATE {db_prefix}log_reported SET id_topic = {int:id_topic}, id_board = {int:target_board} WHERE id_topic IN ({array_int:topics_list})', array('topics_list' => $topics, 'id_topic' => $id_topic, 'target_board' => $target_board)); // Change the subject of the first message... smf_db_query(' UPDATE {db_prefix}messages SET subject = {string:target_subject} WHERE id_msg = {int:first_msg}', array('first_msg' => $first_msg, 'target_subject' => $target_subject)); // Adjust all calendar events to point to the new topic. smf_db_query(' UPDATE {db_prefix}calendar SET id_topic = {int:id_topic}, id_board = {int:target_board} WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics, 'id_topic' => $id_topic, 'target_board' => $target_board)); // Merge log topic entries. $request = smf_db_query(' SELECT id_member, MIN(id_msg) AS new_id_msg FROM {db_prefix}log_topics WHERE id_topic IN ({array_int:topics}) GROUP BY id_member', array('topics' => $topics)); if (mysql_num_rows($request) > 0) { $replaceEntries = array(); while ($row = mysql_fetch_assoc($request)) { $replaceEntries[] = array($row['id_member'], $id_topic, $row['new_id_msg']); } smf_db_insert('replace', '{db_prefix}log_topics', array('id_member' => 'int', 'id_topic' => 'int', 'id_msg' => 'int'), $replaceEntries, array('id_member', 'id_topic')); unset($replaceEntries); // Get rid of the old log entries. smf_db_query(' DELETE FROM {db_prefix}log_topics WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics)); } mysql_free_result($request); // Merge topic notifications. $notifications = isset($_POST['notifications']) && is_array($_POST['notifications']) ? array_intersect($topics, $_POST['notifications']) : array(); if (!empty($notifications)) { $request = smf_db_query(' SELECT id_member, MAX(sent) AS sent FROM {db_prefix}log_notify WHERE id_topic IN ({array_int:topics_list}) GROUP BY id_member', array('topics_list' => $notifications)); if (mysql_num_rows($request) > 0) { $replaceEntries = array(); while ($row = mysql_fetch_assoc($request)) { $replaceEntries[] = array($row['id_member'], $id_topic, 0, $row['sent']); } smf_db_insert('replace', '{db_prefix}log_notify', array('id_member' => 'int', 'id_topic' => 'int', 'id_board' => 'int', 'sent' => 'int'), $replaceEntries, array('id_member', 'id_topic', 'id_board')); unset($replaceEntries); smf_db_query(' DELETE FROM {db_prefix}log_topics WHERE id_topic IN ({array_int:deleted_topics})', array('deleted_topics' => $deleted_topics)); } mysql_free_result($request); } // Get rid of the redundant polls. if (!empty($deleted_polls)) { smf_db_query(' DELETE FROM {db_prefix}polls WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls)); smf_db_query(' DELETE FROM {db_prefix}poll_choices WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls)); smf_db_query(' DELETE FROM {db_prefix}log_polls WHERE id_poll IN ({array_int:deleted_polls})', array('deleted_polls' => $deleted_polls)); } // Cycle through each board... foreach ($boardTotals as $id_board => $stats) { smf_db_query(' UPDATE {db_prefix}boards SET num_topics = CASE WHEN {int:topics} > num_topics THEN 0 ELSE num_topics - {int:topics} END, unapproved_topics = CASE WHEN {int:unapproved_topics} > unapproved_topics THEN 0 ELSE unapproved_topics - {int:unapproved_topics} END, num_posts = CASE WHEN {int:posts} > num_posts THEN 0 ELSE num_posts - {int:posts} END, unapproved_posts = CASE WHEN {int:unapproved_posts} > unapproved_posts THEN 0 ELSE unapproved_posts - {int:unapproved_posts} END WHERE id_board = {int:id_board}', array('id_board' => $id_board, 'topics' => $stats['topics'], 'unapproved_topics' => $stats['unapproved_topics'], 'posts' => $stats['posts'], 'unapproved_posts' => $stats['unapproved_posts'])); } // Determine the board the final topic resides in $request = smf_db_query(' SELECT id_board FROM {db_prefix}topics WHERE id_topic = {int:id_topic} LIMIT 1', array('id_topic' => $id_topic)); list($id_board) = mysql_fetch_row($request); mysql_free_result($request); require_once $sourcedir . '/lib/Subs-Post.php'; // Update all the statistics. updateStats('topic'); updateStats('subject', $id_topic, $target_subject); updateLastMessages($boards); logAction('merge', array('topic' => $id_topic, 'board' => $id_board)); // Notify people that these topics have been merged? sendNotifications($id_topic, 'merge'); // Send them to the all done page. redirectexit('action=mergetopics;sa=done;to=' . $id_topic . ';targetboard=' . $target_board); }
function ManageLabels() { global $txt, $context, $user_info, $scripturl, $smcFunc; EoS_Smarty::loadTemplate('pm/base'); EoS_Smarty::getConfigInstance()->registerHookTemplate('pm_content_area', 'pm/manage_labels'); // Build the link tree elements... $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=manlabels', 'name' => $txt['pm_manage_labels']); $context['page_title'] = $txt['pm_manage_labels']; $context['sub_template'] = 'labels'; $the_labels = array(); // Add all existing labels to the array to save, slashing them as necessary... foreach ($context['labels'] as $label) { if ($label['id'] != -1) { $the_labels[$label['id']] = $label['name']; } } if (isset($_POST[$context['session_var']])) { checkSession('post'); // This will be for updating messages. $message_changes = array(); $new_labels = array(); $rule_changes = array(); // Will most likely need this. LoadRules(); // Adding a new label? if (isset($_POST['add'])) { $_POST['label'] = strtr(commonAPI::htmlspecialchars(trim($_POST['label'])), array(',' => ',')); if (commonAPI::strlen($_POST['label']) > 30) { $_POST['label'] = commonAPI::substr($_POST['label'], 0, 30); } if ($_POST['label'] != '') { $the_labels[] = $_POST['label']; } } elseif (isset($_POST['delete'], $_POST['delete_label'])) { $i = 0; foreach ($the_labels as $id => $name) { if (isset($_POST['delete_label'][$id])) { unset($the_labels[$id]); $message_changes[$id] = true; } else { $new_labels[$id] = $i++; } } } elseif (isset($_POST['save']) && !empty($_POST['label_name'])) { $i = 0; foreach ($the_labels as $id => $name) { if ($id == -1) { continue; } elseif (isset($_POST['label_name'][$id])) { $_POST['label_name'][$id] = trim(strtr(commonAPI::htmlspecialchars($_POST['label_name'][$id]), array(',' => ','))); if (commonAPI::strlen($_POST['label_name'][$id]) > 30) { $_POST['label_name'][$id] = commonAPI::substr($_POST['label_name'][$id], 0, 30); } if ($_POST['label_name'][$id] != '') { $the_labels[(int) $id] = $_POST['label_name'][$id]; $new_labels[$id] = $i++; } else { unset($the_labels[(int) $id]); $message_changes[(int) $id] = true; } } else { $new_labels[$id] = $i++; } } } // Save the label status. updateMemberData($user_info['id'], array('message_labels' => implode(',', $the_labels))); // Update all the messages currently with any label changes in them! if (!empty($message_changes)) { $searchArray = array_keys($message_changes); if (!empty($new_labels)) { for ($i = max($searchArray) + 1, $n = max(array_keys($new_labels)); $i <= $n; $i++) { $searchArray[] = $i; } } // Now find the messages to change. $request = smf_db_query(' SELECT id_pm, labels FROM {db_prefix}pm_recipients WHERE FIND_IN_SET({raw:find_label_implode}, labels) != 0 AND id_member = {int:current_member}', array('current_member' => $user_info['id'], 'find_label_implode' => '\'' . implode('\', labels) != 0 OR FIND_IN_SET(\'', $searchArray) . '\'')); while ($row = mysql_fetch_assoc($request)) { // Do the long task of updating them... $toChange = explode(',', $row['labels']); foreach ($toChange as $key => $value) { if (in_array($value, $searchArray)) { if (isset($new_labels[$value])) { $toChange[$key] = $new_labels[$value]; } else { unset($toChange[$key]); } } } if (empty($toChange)) { $toChange[] = '-1'; } // Update the message. smf_db_query(' UPDATE {db_prefix}pm_recipients SET labels = {string:new_labels} WHERE id_pm = {int:id_pm} AND id_member = {int:current_member}', array('current_member' => $user_info['id'], 'id_pm' => $row['id_pm'], 'new_labels' => implode(',', array_unique($toChange)))); } mysql_free_result($request); // Now do the same the rules - check through each rule. foreach ($context['rules'] as $k => $rule) { // Each action... foreach ($rule['actions'] as $k2 => $action) { if ($action['t'] != 'lab' || !in_array($action['v'], $searchArray)) { continue; } $rule_changes[] = $rule['id']; // If we're here we have a label which is either changed or gone... if (isset($new_labels[$action['v']])) { $context['rules'][$k]['actions'][$k2]['v'] = $new_labels[$action['v']]; } else { unset($context['rules'][$k]['actions'][$k2]); } } } } // If we have rules to change do so now. if (!empty($rule_changes)) { $rule_changes = array_unique($rule_changes); // Update/delete as appropriate. foreach ($rule_changes as $k => $id) { if (!empty($context['rules'][$id]['actions'])) { smf_db_query(' UPDATE {db_prefix}pm_rules SET actions = {string:actions} WHERE id_rule = {int:id_rule} AND id_member = {int:current_member}', array('current_member' => $user_info['id'], 'id_rule' => $id, 'actions' => serialize($context['rules'][$id]['actions']))); unset($rule_changes[$k]); } } // Anything left here means it's lost all actions... if (!empty($rule_changes)) { smf_db_query(' DELETE FROM {db_prefix}pm_rules WHERE id_rule IN ({array_int:rule_list}) AND id_member = {int:current_member}', array('current_member' => $user_info['id'], 'rule_list' => $rule_changes)); } } // Make sure we're not caching this! CacheAPI::putCache('labelCounts:' . $user_info['id'], null, 720); // To make the changes appear right away, redirect. redirectexit('action=pm;sa=manlabels'); } }
function validateEventPost() { global $modSettings, $txt, $sourcedir, $smcFunc; if (!isset($_POST['deleteevent'])) { // No month? No year? if (!isset($_POST['month'])) { fatal_lang_error('event_month_missing', false); } if (!isset($_POST['year'])) { fatal_lang_error('event_year_missing', false); } // Check the month and year... if ($_POST['month'] < 1 || $_POST['month'] > 12) { fatal_lang_error('invalid_month', false); } if ($_POST['year'] < $modSettings['cal_minyear'] || $_POST['year'] > $modSettings['cal_maxyear']) { fatal_lang_error('invalid_year', false); } } // Make sure they're allowed to post... isAllowedTo('calendar_post'); if (isset($_POST['span'])) { // Make sure it's turned on and not some fool trying to trick it. if (empty($modSettings['cal_allowspan'])) { fatal_lang_error('no_span', false); } if ($_POST['span'] < 1 || $_POST['span'] > $modSettings['cal_maxspan']) { fatal_lang_error('invalid_days_numb', false); } } // There is no need to validate the following values if we are just deleting the event. if (!isset($_POST['deleteevent'])) { // No day? if (!isset($_POST['day'])) { fatal_lang_error('event_day_missing', false); } if (!isset($_POST['evtitle']) && !isset($_POST['subject'])) { fatal_lang_error('event_title_missing', false); } elseif (!isset($_POST['evtitle'])) { $_POST['evtitle'] = $_POST['subject']; } // Bad day? if (!checkdate($_POST['month'], $_POST['day'], $_POST['year'])) { fatal_lang_error('invalid_date', false); } // No title? if (commonAPI::htmltrim($_POST['evtitle']) === '') { fatal_lang_error('no_event_title', false); } if (commonAPI::strlen($_POST['evtitle']) > 30) { $_POST['evtitle'] = commonAPI::substr($_POST['evtitle'], 0, 30); } $_POST['evtitle'] = str_replace(';', '', $_POST['evtitle']); } }
function JavaScriptModify() { global $sourcedir, $modSettings, $board, $topic, $txt; global $user_info, $context, $language; // We have to have a topic! if (empty($topic)) { obExit(false); } checkSession('get'); require_once $sourcedir . '/lib/Subs-Post.php'; // Assume the first message if no message ID was given. $request = smf_db_query(' SELECT t.locked, t.num_replies, t.id_member_started, t.id_first_msg, m.id_msg, m.id_member, m.poster_time, m.subject, m.smileys_enabled, m.body, m.icon, m.modified_time, m.modified_name, m.approved, ba.id_topic AS banned_from_topic FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic}) LEFT JOIN {db_prefix}topicbans AS ba ON (ba.id_topic = {int:current_topic} AND ba.id_member = {int:current_member}) WHERE m.id_msg = {raw:id_msg} AND m.id_topic = {int:current_topic}' . (allowedTo('approve_posts') ? '' : (!$modSettings['postmod_active'] ? ' AND (m.id_member != {int:guest_id} AND m.id_member = {int:current_member})' : ' AND (m.approved = {int:is_approved} OR (m.id_member != {int:guest_id} AND m.id_member = {int:current_member}))')), array('current_member' => $user_info['id'], 'current_topic' => $topic, 'id_msg' => empty($_REQUEST['msg']) ? 't.id_first_msg' : (int) $_REQUEST['msg'], 'is_approved' => 1, 'guest_id' => 0)); if (mysql_num_rows($request) == 0) { fatal_lang_error('no_board', false); } $row = mysql_fetch_assoc($request); mysql_free_result($request); // Change either body or subject requires permissions to modify messages. if (isset($_POST['message']) || isset($_POST['subject']) || isset($_REQUEST['icon'])) { if (!empty($row['locked'])) { isAllowedTo('moderate_board'); } if ($row['id_member'] == $user_info['id'] && !allowedTo('modify_any')) { if ((!$modSettings['postmod_active'] || $row['approved']) && !empty($modSettings['edit_disable_time']) && $row['poster_time'] + ($modSettings['edit_disable_time'] + 5) * 60 < time()) { fatal_lang_error('modify_post_time_passed', false); } elseif ($row['id_member_started'] == $user_info['id'] && !allowedTo('modify_own')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_own'); } } elseif ($row['id_member_started'] == $user_info['id'] && !allowedTo('modify_any')) { isAllowedTo('modify_replies'); } else { isAllowedTo('modify_any'); } // check topic bans if ($row['banned_from_topic'] != 0 && !$user_info['is_admin'] && !allowedTo('moderate_board') && !allowedTo('moderate_forum')) { fatal_lang_error('banned_from_topic'); } // Only log this action if it wasn't your message. $moderationAction = $row['id_member'] != $user_info['id']; } $post_errors = array(); if (isset($_POST['subject']) && commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['subject'])) !== '') { $_POST['subject'] = strtr(commonAPI::htmlspecialchars($_POST['subject']), array("\r" => '', "\n" => '', "\t" => '')); // Maximum number of characters. if (commonAPI::strlen($_POST['subject']) > 100) { $_POST['subject'] = commonAPI::substr($_POST['subject'], 0, 100); } } elseif (isset($_POST['subject'])) { $post_errors[] = 'no_subject'; unset($_POST['subject']); } if (isset($_POST['message'])) { if (commonAPI::htmltrim(commonAPI::htmlspecialchars($_POST['message'])) === '') { $post_errors[] = 'no_message'; unset($_POST['message']); } elseif (!empty($modSettings['max_messageLength']) && commonAPI::strlen($_POST['message']) > $modSettings['max_messageLength']) { $post_errors[] = 'long_message'; unset($_POST['message']); } else { $_POST['message'] = commonAPI::htmlspecialchars($_POST['message'], ENT_QUOTES); preparsecode($_POST['message']); if (commonAPI::htmltrim(strip_tags(parse_bbc($_POST['message'], false), '<img>')) === '') { $post_errors[] = 'no_message'; unset($_POST['message']); } } } if (isset($_POST['lock'])) { if (!allowedTo(array('lock_any', 'lock_own')) || !allowedTo('lock_any') && $user_info['id'] != $row['id_member']) { unset($_POST['lock']); } elseif (!allowedTo('lock_any')) { if ($row['locked'] == 1) { unset($_POST['lock']); } else { $_POST['lock'] = empty($_POST['lock']) ? 0 : 2; } } elseif (!empty($row['locked']) && !empty($_POST['lock']) || $_POST['lock'] == $row['locked']) { unset($_POST['lock']); } else { $_POST['lock'] = empty($_POST['lock']) ? 0 : 1; } } if (isset($_POST['sticky']) && !allowedTo('make_sticky')) { unset($_POST['sticky']); } if (empty($post_errors)) { $msgOptions = array('id' => $row['id_msg'], 'subject' => isset($_POST['subject']) ? $_POST['subject'] : null, 'body' => isset($_POST['message']) ? $_POST['message'] : null, 'icon' => isset($_REQUEST['icon']) ? preg_replace('~[\\./\\\\*\':"<>]~', '', $_REQUEST['icon']) : null, 'id_owner' => $row['id_member']); $topicOptions = array('id' => $topic, 'board' => $board, 'lock_mode' => isset($_POST['lock']) ? (int) $_POST['lock'] : null, 'sticky_mode' => isset($_POST['sticky']) && !empty($modSettings['enableStickyTopics']) ? (int) $_POST['sticky'] : null, 'mark_as_read' => true); $posterOptions = array(); // Only consider marking as editing if they have edited the subject, message or icon. if (isset($_POST['subject']) && $_POST['subject'] != $row['subject'] || isset($_POST['message']) && $_POST['message'] != $row['body'] || isset($_REQUEST['icon']) && $_REQUEST['icon'] != $row['icon']) { // And even then only if the time has passed... if (time() - $row['poster_time'] > $modSettings['edit_wait_time'] || $user_info['id'] != $row['id_member']) { $msgOptions['modify_time'] = time(); $msgOptions['modify_name'] = $user_info['name']; } } else { $moderationAction = false; } modifyPost($msgOptions, $topicOptions, $posterOptions); // If we didn't change anything this time but had before put back the old info. if (!isset($msgOptions['modify_time']) && !empty($row['modified_time'])) { $msgOptions['modify_time'] = $row['modified_time']; $msgOptions['modify_name'] = $row['modified_name']; } // Changing the first subject updates other subjects to 'Re: new_subject'. if (isset($_POST['subject']) && isset($_REQUEST['change_all_subjects']) && $row['id_first_msg'] == $row['id_msg'] && !empty($row['num_replies']) && (allowedTo('modify_any') || $row['id_member_started'] == $user_info['id'] && allowedTo('modify_replies'))) { // Get the proper (default language) response prefix first. if (!isset($context['response_prefix']) && !($context['response_prefix'] = CacheAPI::getCache('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'); } CacheAPI::putCache('response_prefix', $context['response_prefix'], 600); } smf_db_query(' UPDATE {db_prefix}messages SET subject = {string:subject} WHERE id_topic = {int:current_topic} AND id_msg != {int:id_first_msg}', array('current_topic' => $topic, 'id_first_msg' => $row['id_first_msg'], 'subject' => $context['response_prefix'] . $_POST['subject'])); } if (!empty($moderationAction)) { logAction('modify', array('topic' => $topic, 'message' => $row['id_msg'], 'member' => $row['id_member'], 'board' => $board)); } } if (isset($_REQUEST['xml'])) { $context['sub_template'] = 'modifydone'; if (empty($post_errors) && isset($msgOptions['subject']) && isset($msgOptions['body'])) { $context['message'] = array('id' => $row['id_msg'], 'modified' => array('time' => isset($msgOptions['modify_time']) ? timeformat($msgOptions['modify_time']) : '', 'timestamp' => isset($msgOptions['modify_time']) ? forum_time(true, $msgOptions['modify_time']) : 0, 'name' => isset($msgOptions['modify_time']) ? $msgOptions['modify_name'] : ''), 'subject' => $msgOptions['subject'], 'first_in_topic' => $row['id_msg'] == $row['id_first_msg'], 'body' => strtr($msgOptions['body'], array(']]>' => ']]]]><![CDATA[>'))); censorText($context['message']['subject']); censorText($context['message']['body']); $cache_key = isset($msgOptions['modify_time']) ? $row['id_msg'] . '|' . $msgOptions['modify_time'] : $row['id_msg']; $context['message']['body'] = parse_bbc($context['message']['body'], $row['smileys_enabled'], $cache_key); parse_bbc_stage2($context['message']['body']); } elseif (empty($post_errors)) { $context['sub_template'] = 'modifytopicdone'; $context['message'] = array('id' => $row['id_msg'], 'icon' => isset($_REQUEST['icon']) ? $_REQUEST['icon'] : '', 'modified' => array('time' => isset($msgOptions['modify_time']) ? timeformat($msgOptions['modify_time']) : '', 'timestamp' => isset($msgOptions['modify_time']) ? forum_time(true, $msgOptions['modify_time']) : 0, 'name' => isset($msgOptions['modify_time']) ? $msgOptions['modify_name'] : ''), 'subject' => isset($msgOptions['subject']) ? $msgOptions['subject'] : ''); censorText($context['message']['subject']); } else { $context['message'] = array('id' => $row['id_msg'], 'errors' => array(), 'error_in_subject' => in_array('no_subject', $post_errors), 'error_in_body' => in_array('no_message', $post_errors) || in_array('long_message', $post_errors)); loadLanguage('Errors'); foreach ($post_errors as $post_error) { if ($post_error == 'long_message') { $context['message']['errors'][] = sprintf($txt['error_' . $post_error], $modSettings['max_messageLength']); } else { $context['message']['errors'][] = $txt['error_' . $post_error]; } } } } else { obExit(false); } }
function profileValidateSignature(&$value) { global $sourcedir, $modSettings, $smcFunc, $txt; require_once $sourcedir . '/lib/Subs-Post.php'; // Admins can do whatever they hell they want! if (!allowedTo('admin_forum')) { if (!allowedTo('profile_signature')) { $_POST['signature'] = $value = ''; return false; } // Load all the signature limits. list($sig_limits, $sig_bbc) = explode(':', $modSettings['signature_settings']); $sig_limits = explode(',', $sig_limits); $disabledTags = !empty($sig_bbc) ? explode(',', $sig_bbc) : array(); $unparsed_signature = strtr(un_htmlspecialchars($value), array("\r" => '', ''' => '\'')); // Too long? if (!empty($sig_limits[1]) && commonAPI::strlen($unparsed_signature) > $sig_limits[1]) { $_POST['signature'] = trim(htmlspecialchars(commonAPI::substr($unparsed_signature, 0, $sig_limits[1]), ENT_QUOTES)); $txt['profile_error_signature_max_length'] = sprintf($txt['profile_error_signature_max_length'], $sig_limits[1]); return 'signature_max_length'; } // Too many lines? if (!empty($sig_limits[2]) && substr_count($unparsed_signature, "\n") >= $sig_limits[2]) { $txt['profile_error_signature_max_lines'] = sprintf($txt['profile_error_signature_max_lines'], $sig_limits[2]); return 'signature_max_lines'; } // Too many images?! if (!empty($sig_limits[3]) && substr_count(strtolower($unparsed_signature), '[img') + substr_count(strtolower($unparsed_signature), '<img') > $sig_limits[3]) { $txt['profile_error_signature_max_image_count'] = sprintf($txt['profile_error_signature_max_image_count'], $sig_limits[3]); return 'signature_max_image_count'; } // What about too many smileys! $smiley_parsed = $unparsed_signature; parsesmileys($smiley_parsed); $smiley_count = substr_count(strtolower($smiley_parsed), '<img') - substr_count(strtolower($unparsed_signature), '<img'); if (!empty($sig_limits[4]) && $sig_limits[4] == -1 && $smiley_count > 0) { return 'signature_allow_smileys'; } elseif (!empty($sig_limits[4]) && $sig_limits[4] > 0 && $smiley_count > $sig_limits[4]) { $txt['profile_error_signature_max_smileys'] = sprintf($txt['profile_error_signature_max_smileys'], $sig_limits[4]); return 'signature_max_smileys'; } // Maybe we are abusing font sizes? if (!empty($sig_limits[7]) && preg_match_all('~\\[size=([\\d\\.]+)?(px|pt|em|x-large|larger)~i', $unparsed_signature, $matches) !== false && isset($matches[2])) { foreach ($matches[1] as $ind => $size) { $limit_broke = 0; // Attempt to allow all sizes of abuse, so to speak. if ($matches[2][$ind] == 'px' && $size > $sig_limits[7]) { $limit_broke = $sig_limits[7] . 'px'; } elseif ($matches[2][$ind] == 'pt' && $size > $sig_limits[7] * 0.75) { $limit_broke = (int) $sig_limits[7] * 0.75 . 'pt'; } elseif ($matches[2][$ind] == 'em' && $size > (double) $sig_limits[7] / 16) { $limit_broke = (double) $sig_limits[7] / 16 . 'em'; } elseif ($matches[2][$ind] != 'px' && $matches[2][$ind] != 'pt' && $matches[2][$ind] != 'em' && $sig_limits[7] < 18) { $limit_broke = 'large'; } if ($limit_broke) { $txt['profile_error_signature_max_font_size'] = sprintf($txt['profile_error_signature_max_font_size'], $limit_broke); return 'signature_max_font_size'; } } } // The difficult one - image sizes! Don't error on this - just fix it. if (!empty($sig_limits[5]) || !empty($sig_limits[6])) { // Get all BBC tags... preg_match_all('~\\[img(\\s+width=([\\d]+))?(\\s+height=([\\d]+))?(\\s+width=([\\d]+))?\\s*\\](?:<br />)*([^<">]+?)(?:<br />)*\\[/img\\]~i', $unparsed_signature, $matches); // ... and all HTML ones. preg_match_all('~<img\\s+src=(?:")?((?:http://|ftp://|https://|ftps://).+?)(?:")?(?:\\s+alt=(?:")?(.*?)(?:")?)?(?:\\s?/)?>~i', $unparsed_signature, $matches2, PREG_PATTERN_ORDER); // And stick the HTML in the BBC. if (!empty($matches2)) { foreach ($matches2[0] as $ind => $dummy) { $matches[0][] = $matches2[0][$ind]; $matches[1][] = ''; $matches[2][] = ''; $matches[3][] = ''; $matches[4][] = ''; $matches[5][] = ''; $matches[6][] = ''; $matches[7][] = $matches2[1][$ind]; } } $replaces = array(); // Try to find all the images! if (!empty($matches)) { foreach ($matches[0] as $key => $image) { $width = -1; $height = -1; // Does it have predefined restraints? Width first. if ($matches[6][$key]) { $matches[2][$key] = $matches[6][$key]; } if ($matches[2][$key] && $sig_limits[5] && $matches[2][$key] > $sig_limits[5]) { $width = $sig_limits[5]; $matches[4][$key] = $matches[4][$key] * ($width / $matches[2][$key]); } elseif ($matches[2][$key]) { $width = $matches[2][$key]; } // ... and height. if ($matches[4][$key] && $sig_limits[6] && $matches[4][$key] > $sig_limits[6]) { $height = $sig_limits[6]; if ($width != -1) { $width = $width * ($height / $matches[4][$key]); } } elseif ($matches[4][$key]) { $height = $matches[4][$key]; } // If the dimensions are still not fixed - we need to check the actual image. if ($width == -1 && $sig_limits[5] || $height == -1 && $sig_limits[6]) { $sizes = url_image_size($matches[7][$key]); if (is_array($sizes)) { // Too wide? if ($sizes[0] > $sig_limits[5] && $sig_limits[5]) { $width = $sig_limits[5]; $sizes[1] = $sizes[1] * ($width / $sizes[0]); } // Too high? if ($sizes[1] > $sig_limits[6] && $sig_limits[6]) { $height = $sig_limits[6]; if ($width == -1) { $width = $sizes[0]; } $width = $width * ($height / $sizes[1]); } elseif ($width != -1) { $height = $sizes[1]; } } } // Did we come up with some changes? If so remake the string. if ($width != -1 || $height != -1) { $replaces[$image] = '[img' . ($width != -1 ? ' width=' . round($width) : '') . ($height != -1 ? ' height=' . round($height) : '') . ']' . $matches[7][$key] . '[/img]'; } } if (!empty($replaces)) { $value = str_replace(array_keys($replaces), array_values($replaces), $value); } } } // Any disabled BBC? $disabledSigBBC = implode('|', $disabledTags); if (!empty($disabledSigBBC)) { if (preg_match('~\\[(' . $disabledSigBBC . ')~i', $unparsed_signature, $matches) !== false && isset($matches[1])) { $disabledTags = array_unique($disabledTags); $txt['profile_error_signature_disabled_bbc'] = sprintf($txt['profile_error_signature_disabled_bbc'], implode(', ', $disabledTags)); return 'signature_disabled_bbc'; } } } preparsecode($value); return true; }
function getXmlRecent($xml_format) { global $user_info, $scripturl, $modSettings, $board; global $query_this_board, $smcFunc, $settings, $context; $done = false; $loops = 0; while (!$done) { $optimize_msg = implode(' AND ', $context['optimize_msg']); $request = smf_db_query(' SELECT m.id_msg FROM {db_prefix}messages AS m INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board) INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) WHERE ' . $query_this_board . (empty($optimize_msg) ? '' : ' AND {raw:optimize_msg}') . (empty($board) ? '' : ' AND m.id_board = {int:current_board}') . ($modSettings['postmod_active'] ? ' AND m.approved = {int:is_approved}' : '') . ' ORDER BY m.id_msg DESC LIMIT {int:limit}', array('limit' => $_GET['limit'], 'current_board' => $board, 'is_approved' => 1, 'optimize_msg' => $optimize_msg)); // If we don't have $_GET['limit'] results, try again with an unoptimized version covering all rows. if ($loops < 2 && mysql_num_rows($request) < $_GET['limit']) { mysql_free_result($request); if (empty($_REQUEST['boards']) && empty($board)) { unset($context['optimize_msg']['lowest']); } else { $context['optimize_msg']['lowest'] = $loops ? 'm.id_msg >= t.id_first_msg' : 'm.id_msg >= (t.id_last_msg - t.id_first_msg) / 2'; } $loops++; } else { $done = true; } } $messages = array(); while ($row = mysql_fetch_assoc($request)) { $messages[] = $row['id_msg']; } mysql_free_result($request); if (empty($messages)) { return array(); } // Find the most recent posts this user can see. $request = smf_db_query(' SELECT m.smileys_enabled, m.poster_time, m.id_msg, m.subject, m.body, m.id_topic, t.id_board, b.name AS bname, t.num_replies, m.id_member, m.icon, mf.id_member AS id_first_member, IFNULL(mem.real_name, m.poster_name) AS poster_name, mf.subject AS first_subject, IFNULL(memf.real_name, mf.poster_name) AS first_poster_name, mem.hide_email, IFNULL(mem.email_address, m.poster_email) AS poster_email, m.modified_time FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg) INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member) WHERE m.id_msg IN ({array_int:message_list}) ' . (empty($board) ? '' : 'AND t.id_board = {int:current_board}') . ' ORDER BY m.id_msg DESC LIMIT {int:limit}', array('limit' => $_GET['limit'], 'current_board' => $board, 'message_list' => $messages)); $data = array(); while ($row = mysql_fetch_assoc($request)) { // Limit the length of the message, if the option is set. if (!empty($modSettings['xmlnews_maxlen']) && commonAPI::strlen(str_replace('<br />', "\n", $row['body'])) > $modSettings['xmlnews_maxlen']) { $row['body'] = strtr(commonAPI::substr(str_replace('<br />', "\n", $row['body']), 0, $modSettings['xmlnews_maxlen'] - 3), array("\n" => '<br />')) . '...'; } $row['body'] = parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']); censorText($row['body']); censorText($row['subject']); // Doesn't work as well as news, but it kinda does.. if ($xml_format == 'rss' || $xml_format == 'rss2') { $data[] = array('title' => $row['subject'], 'link' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'description' => cdata_parse($row['body']), 'author' => in_array(showEmailAddress(!empty($row['hide_email']), $row['id_member']), array('yes', 'yes_permission_override')) ? $row['poster_email'] : null, 'category' => cdata_parse($row['bname']), 'comments' => $scripturl . '?action=post;topic=' . $row['id_topic'] . '.0', 'pubDate' => gmdate('D, d M Y H:i:s \\G\\M\\T', $row['poster_time']), 'guid' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg']); } elseif ($xml_format == 'rdf') { $data[] = array('title' => $row['subject'], 'link' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'description' => cdata_parse($row['body'])); } elseif ($xml_format == 'atom') { $data[] = array('title' => $row['subject'], 'link' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'summary' => cdata_parse($row['body']), 'category' => array('term' => $row['id_board'], 'label' => cdata_parse($row['bname'])), 'author' => array('name' => $row['poster_name'], 'email' => in_array(showEmailAddress(!empty($row['hide_email']), $row['id_member']), array('yes', 'yes_permission_override')) ? $row['poster_email'] : null, 'uri' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : ''), 'published' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', $row['poster_time']), 'updated' => gmstrftime('%Y-%m-%dT%H:%M:%SZ', empty($row['modified_time']) ? $row['poster_time'] : $row['modified_time']), 'id' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'], 'icon' => $settings['images_url'] . '/icons/' . $row['icon'] . '.gif'); } else { $data[] = array('time' => htmlspecialchars(strip_tags(timeformat($row['poster_time']))), 'id' => $row['id_msg'], 'subject' => cdata_parse($row['subject']), 'body' => cdata_parse($row['body']), 'starter' => array('name' => cdata_parse($row['first_poster_name']), 'id' => $row['id_first_member'], 'link' => !empty($row['id_first_member']) ? $scripturl . '?action=profile;u=' . $row['id_first_member'] : ''), 'poster' => array('name' => cdata_parse($row['poster_name']), 'id' => $row['id_member'], 'link' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : ''), 'topic' => array('subject' => cdata_parse($row['first_subject']), 'id' => $row['id_topic'], 'link' => $scripturl . '?topic=' . $row['id_topic'] . '.new#new'), 'board' => array('name' => cdata_parse($row['bname']), 'id' => $row['id_board'], 'link' => $scripturl . '?board=' . $row['id_board'] . '.0'), 'link' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg']); } } mysql_free_result($request); return $data; }
function TopicPeek() { global $context; global $user_info, $board, $memberContext, $txt; $is_xmlreq = $_REQUEST['action'] == 'xmlhttp' ? true : false; if (isset($_REQUEST['t'])) { $tid = intval($_REQUEST['t']); } else { $tid = 0; } if (!$is_xmlreq) { redirectexit(); } // this action is XMLHttp - only if ($tid) { global $memberContext; EoS_Smarty::loadTemplate('topic/preview'); loadLanguage('index'); loadLanguage('Errors'); $result = smf_db_query(' SELECT b.*, t.id_topic, t.id_board, t.id_first_msg, t.id_last_msg, m.id_member AS member_started, m1.id_member AS member_lastpost, m.subject AS first_subject, m.poster_name AS starter_name, m1.subject AS last_subject, m1.poster_name AS last_name, m.body as first_body, m1.body AS last_body, ' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from, m.poster_time AS first_time, m1.poster_time AS last_time FROM {db_prefix}topics AS t 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}) LEFT JOIN {db_prefix}boards AS b ON b.id_board = t.id_board LEFT JOIN {db_prefix}messages AS m ON m.id_msg = t.id_first_msg LEFT JOIN {db_prefix}messages AS m1 ON m1.id_msg = t.id_last_msg WHERE t.id_topic = {int:topic_id} AND {query_see_board} LIMIT 1', array('topic_id' => $tid, 'current_member' => $user_info['id'], 'current_board' => $board)); $row = mysql_fetch_assoc($result); mysql_free_result($result); if (!$row) { AjaxErrorMsg($txt['topic_gone'], $txt['error_occured']); } else { $m = array(); $m[0] = $row['member_started']; if ($row['id_first_msg'] != $row['id_last_msg'] && $row['member_lastpost']) { $m[1] = $row['member_lastpost']; } loadMemberData($m); loadMemberContext($m[0]); $context['member_started'] =& $memberContext[$row['member_started']]; if (isset($m[1])) { loadMemberContext($m[1]); $context['member_lastpost'] =& $memberContext[$row['member_lastpost']]; } else { $context['member_lastpost'] = null; } $context['preview'] =& $row; // truncate, censor and parse bbc $_b = commonAPI::substr($context['preview']['first_body'], 0, 300) . '...'; censorText($_b); $context['preview']['first_body'] = parse_bbc($_b, false); $context['preview']['first_time'] = timeformat($row['first_time']); if ($context['member_lastpost']) { $_b = commonAPI::substr($context['preview']['last_body'], 0, 600) . '...'; censorText($_b); $context['preview']['last_body'] = parse_bbc($_b, false); $context['preview']['last_time'] = timeformat($row['last_time']); } } } }
function getBoardIndex($boardIndexOptions) { global $smcFunc, $scripturl, $user_info, $modSettings, $txt; global $settings, $context; // For performance, track the latest post while going through the boards. if (!empty($boardIndexOptions['set_latest_post'])) { $latest_post = array('timestamp' => 0, 'ref' => 0); } // Find all boards and categories, as well as related information. This will be sorted by the natural order of boards and categories, which we control. $result_boards = smf_db_query(' SELECT' . ($boardIndexOptions['include_categories'] ? ' c.id_cat, c.name AS cat_name, c.description AS cat_desc,' : '') . ' b.id_board, b.name AS board_name, b.description, b.redirect, b.icon AS boardicon, CASE WHEN b.redirect != {string:blank_string} THEN 1 ELSE 0 END AS is_redirect, b.num_posts, b.num_topics, b.unapproved_posts, b.unapproved_topics, b.id_parent, b.allow_topics, IFNULL(m.poster_time, 0) AS poster_time, IFNULL(mem.member_name, m.poster_name) AS poster_name, m.subject, m1.subject AS first_subject, m.id_topic, t.id_first_msg AS id_first_msg, t.id_prefix, m1.icon AS icon, IFNULL(mem.real_name, m.poster_name) AS real_name, p.name as topic_prefix, ' . ($user_info['is_guest'] ? ' 1 AS is_read, 0 AS new_from,' : ' (IFNULL(lb.id_msg, 0) >= b.id_msg_updated) AS is_read, IFNULL(lb.id_msg, -1) + 1 AS new_from,' . ($boardIndexOptions['include_categories'] ? ' c.can_collapse, IFNULL(cc.id_member, 0) AS is_collapsed,' : '')) . ' IFNULL(mem.id_member, 0) AS id_member, m.id_msg, IFNULL(mods_mem.id_member, 0) AS id_moderator, mods_mem.real_name AS mod_real_name FROM {db_prefix}boards AS b' . ($boardIndexOptions['include_categories'] ? ' LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)' : '') . ' LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = b.id_last_msg) LEFT JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic) LEFT JOIN {db_prefix}prefixes AS p ON (p.id_prefix = t.id_prefix) LEFT JOIN {db_prefix}messages AS m1 ON (m1.id_msg = t.id_first_msg) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)' . ($user_info['is_guest'] ? '' : ' LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})' . ($boardIndexOptions['include_categories'] ? ' LEFT JOIN {db_prefix}collapsed_categories AS cc ON (cc.id_cat = c.id_cat AND cc.id_member = {int:current_member})' : '')) . ' LEFT JOIN {db_prefix}moderators AS mods ON (mods.id_board = b.id_board) LEFT JOIN {db_prefix}members AS mods_mem ON (mods_mem.id_member = mods.id_member) WHERE {query_see_board}' . (empty($boardIndexOptions['countChildPosts']) ? empty($boardIndexOptions['base_level']) ? '' : ' AND b.child_level >= {int:child_level}' : ' AND b.child_level BETWEEN ' . $boardIndexOptions['base_level'] . ' AND ' . ($boardIndexOptions['base_level'] + 1)), array('current_member' => $user_info['id'], 'child_level' => $boardIndexOptions['base_level'], 'blank_string' => '')); // Start with an empty array. if ($boardIndexOptions['include_categories']) { $categories = array(); } else { $this_category = array(); } $total_ignored_boards = 0; // Run through the categories and boards (or only boards).... while ($row_board = mysql_fetch_assoc($result_boards)) { // Perhaps we are ignoring this board? $ignoreThisBoard = in_array($row_board['id_board'], $user_info['ignoreboards']); $total_ignored_boards += $ignoreThisBoard ? 1 : 0; $row_board['is_read'] = !empty($row_board['is_read']) || $ignoreThisBoard ? '1' : '0'; if ($boardIndexOptions['include_categories']) { // Haven't set this category yet. if (empty($categories[$row_board['id_cat']])) { $categories[$row_board['id_cat']] = array('id' => $row_board['id_cat'], 'name' => $row_board['cat_name'], 'desc' => $row_board['cat_desc'], 'is_collapsed' => isset($row_board['can_collapse']) && $row_board['can_collapse'] == 1 && $row_board['is_collapsed'] > 0, 'can_collapse' => isset($row_board['can_collapse']) && $row_board['can_collapse'] == 1, 'collapse_href' => isset($row_board['can_collapse']) ? $scripturl . '?action=collapse;c=' . $row_board['id_cat'] . ';sa=' . ($row_board['is_collapsed'] > 0 ? 'expand;' : 'collapse;') . $context['session_var'] . '=' . $context['session_id'] . '#c' . $row_board['id_cat'] : '', 'collapse_image' => isset($row_board['can_collapse']) ? '<img class="clipsrc ' . ($row_board['is_collapsed'] ? ' _expand' : '_collapse') . '" src="' . $settings['images_url'] . '/clipsrc.png" alt="-" />' : '', 'href' => $scripturl . '#c' . $row_board['id_cat'], 'boards' => array(), 'is_root' => $row_board['cat_name'][0] === '!' ? true : false, 'new' => false); $categories[$row_board['id_cat']]['link'] = '<a id="c' . $row_board['id_cat'] . '"></a>' . ($categories[$row_board['id_cat']]['can_collapse'] ? '<a href="' . $categories[$row_board['id_cat']]['collapse_href'] . '">' . $row_board['cat_name'] . '</a>' : $row_board['cat_name']); } // If this board has new posts in it (and isn't the recycle bin!) then the category is new. if (empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $row_board['id_board']) { $categories[$row_board['id_cat']]['new'] |= empty($row_board['is_read']) && $row_board['poster_name'] != ''; } // Avoid showing category unread link where it only has redirection boards. $categories[$row_board['id_cat']]['show_unread'] = !empty($categories[$row_board['id_cat']]['show_unread']) ? 1 : !$row_board['is_redirect']; // Collapsed category - don't do any of this. //if ($categories[$row_board['id_cat']]['is_collapsed']) // continue; // Let's save some typing. Climbing the array might be slower, anyhow. $this_category =& $categories[$row_board['id_cat']]['boards']; } // This is a parent board. if ($row_board['id_parent'] == $boardIndexOptions['parent_id']) { // Is this a new board, or just another moderator? if (!isset($this_category[$row_board['id_board']])) { // Not a child. $isChild = false; $href = URL::board($row_board['id_board'], $row_board['board_name'], 0, false); $this_category[$row_board['id_board']] = array('new' => empty($row_board['is_read']), 'id' => $row_board['id_board'], 'name' => $row_board['board_name'], 'description' => $row_board['description'], 'moderators' => array(), 'link_moderators' => array(), 'children' => array(), 'link_children' => array(), 'children_new' => false, 'topics' => $row_board['num_topics'], 'posts' => $row_board['num_posts'], 'is_redirect' => $row_board['is_redirect'], 'is_page' => !empty($row_board['redirect']) && $row_board['redirect'][0] === '%' && intval(substr($row_board['redirect'], 1)) > 0, 'redirect' => $row_board['redirect'], 'boardicon' => $row_board['boardicon'], 'unapproved_topics' => $row_board['unapproved_topics'], 'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'], 'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])), 'href' => $href, 'link' => '<a href="' . $href . '">' . $row_board['board_name'] . '</a>', 'act_as_cat' => $row_board['allow_topics'] ? false : true, 'ignored' => $ignoreThisBoard); $this_category[$row_board['id_board']]['page_link'] = $this_category[$row_board['id_board']]['is_page'] ? URL::topic(intval(substr($this_category[$row_board['id_board']]['redirect'], 1)), $this_category[$row_board['id_board']]['name'], 0) : ''; } if (!empty($row_board['id_moderator'])) { $this_category[$row_board['id_board']]['moderators'][$row_board['id_moderator']] = array('id' => $row_board['id_moderator'], 'name' => $row_board['mod_real_name'], 'href' => $scripturl . '?action=profile;u=' . $row_board['id_moderator'], 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row_board['id_moderator'] . '" title="' . $txt['board_moderator'] . '">' . $row_board['mod_real_name'] . '</a>'); $this_category[$row_board['id_board']]['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row_board['id_moderator'] . '" title="' . $txt['board_moderator'] . '">' . $row_board['mod_real_name'] . '</a>'; } } elseif (isset($this_category[$row_board['id_parent']]['children']) && !isset($this_category[$row_board['id_parent']]['children'][$row_board['id_board']])) { // A valid child! $isChild = true; $href = URL::board($row_board['id_board'], $row_board['board_name'], 0, false); $this_category[$row_board['id_parent']]['children'][$row_board['id_board']] = array('id' => $row_board['id_board'], 'name' => $row_board['board_name'], 'description' => $row_board['description'], 'short_description' => !empty($row_board['description']) ? $modSettings['child_board_desc_shortened'] ? '(' . commonAPI::substr($row_board['description'], 0, $modSettings['child_board_desc_shortened']) . '...)' : '(' . $row_board['description'] . ')' : '', 'new' => empty($row_board['is_read']) && $row_board['poster_name'] != '', 'topics' => $row_board['num_topics'], 'posts' => $row_board['num_posts'], 'is_redirect' => $row_board['is_redirect'], 'is_page' => !empty($row_board['redirect']) && $row_board['redirect'][0] === '%' && intval(substr($row_board['redirect'], 1)) > 0, 'redirect' => $row_board['redirect'], 'boardicon' => $row_board['boardicon'], 'unapproved_topics' => $row_board['unapproved_topics'], 'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'], 'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])), 'href' => $href, 'link' => '<a href="' . $href . '">' . $row_board['board_name'] . '</a>', 'act_as_cat' => $row_board['allow_topics'] ? false : true, 'ignored' => $ignoreThisBoard); $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['page_link'] = $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['is_page'] ? URL::topic(intval(substr($this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['redirect'], 1)), $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['name'], 0) : ''; // Counting child board posts is... slow :/. if (!empty($boardIndexOptions['countChildPosts']) && !$row_board['is_redirect']) { $this_category[$row_board['id_parent']]['posts'] += $row_board['num_posts']; $this_category[$row_board['id_parent']]['topics'] += $row_board['num_topics']; } // Does this board contain new boards? $this_category[$row_board['id_parent']]['children_new'] |= empty($row_board['is_read']); // This is easier to use in many cases for the theme.... $this_category[$row_board['id_parent']]['link_children'][] =& $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['link']; } elseif (!empty($boardIndexOptions['countChildPosts'])) { if (!isset($parent_map)) { $parent_map = array(); } if (!isset($parent_map[$row_board['id_parent']])) { foreach ($this_category as $id => $board) { if (!isset($board['children'][$row_board['id_parent']])) { continue; } $parent_map[$row_board['id_parent']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['id_parent']]); $parent_map[$row_board['id_board']] = array(&$this_category[$id], &$this_category[$id]['children'][$row_board['id_parent']]); break; } } if (isset($parent_map[$row_board['id_parent']]) && !$row_board['is_redirect']) { $parent_map[$row_board['id_parent']][0]['posts'] += $row_board['num_posts']; $parent_map[$row_board['id_parent']][0]['topics'] += $row_board['num_topics']; $parent_map[$row_board['id_parent']][1]['posts'] += $row_board['num_posts']; $parent_map[$row_board['id_parent']][1]['topics'] += $row_board['num_topics']; continue; } continue; } else { continue; } // Prepare the subject, and make sure it's not too long. censorText($row_board['subject']); $mhref = $row_board['poster_name'] != '' && !empty($row_board['id_member']) ? URL::user($row_board['id_member'], $row_board['real_name']) : ''; $this_last_post = array('id' => $row_board['id_msg'], 'time' => $row_board['poster_time'] > 0 ? timeformat($row_board['poster_time']) : $txt['not_applicable'], 'timestamp' => forum_time(true, $row_board['poster_time']), 'member' => array('id' => $row_board['id_member'], 'username' => $row_board['poster_name'] != '' ? $row_board['poster_name'] : $txt['not_applicable'], 'name' => $row_board['real_name'], 'href' => $mhref, 'link' => $row_board['poster_name'] != '' ? !empty($row_board['id_member']) ? '<a onclick="getMcard(' . $row_board['id_member'] . ', $(this));return(false);" href="' . $mhref . '">' . $row_board['real_name'] . '</a>' : $row_board['real_name'] : $txt['not_applicable']), 'start' => 'msg' . $row_board['new_from'], 'topic' => $row_board['id_topic'], 'prefix' => !empty($row_board['topic_prefix']) ? html_entity_decode($row_board['topic_prefix']) . ' ' : ''); $row_board['short_subject'] = shorten_subject($row_board['subject'], 50); $this_last_post['subject'] = $row_board['short_subject']; $this_first_post = array('id' => $row_board['id_first_msg'], 'icon' => $row_board['icon'], 'icon_url' => getPostIcon($row_board['icon'])); // Provide the href and link. if ($row_board['subject'] != '') { $this_last_post['href'] = URL::topic($row_board['id_topic'], $row_board['first_subject'], 0, false, '.msg' . ($user_info['is_guest'] ? $row_board['id_msg'] : $row_board['new_from']), '#new'); if (empty($row_board['is_read'])) { $this_last_post['href'] = URL::addParam($this_last_post['href'], 'boardseen'); } //$this_last_post['href'] = $scripturl . '?topic=' . $row_board['id_topic'] . '.msg' . ($user_info['is_guest'] ? $row_board['id_msg'] : $row_board['new_from']) . (empty($row_board['is_read']) ? ';boardseen' : '') . '#new'; $this_last_post['link'] = '<a rel="nofollow" href="' . $this_last_post['href'] . '" title="' . $row_board['subject'] . '">' . $row_board['short_subject'] . '</a>'; $this_last_post['topichref'] = URL::topic($row_board['id_topic'], $row_board['first_subject'], 0); // $scripturl . '?topic=' . $row_board['id_topic']; $this_last_post['topiclink'] = '<a href="' . $this_last_post['topichref'] . '" title="' . $row_board['first_subject'] . '">' . $row_board['short_subject'] . '</a>'; } else { $this_last_post['href'] = ''; $this_last_post['link'] = $txt['not_applicable']; $this_last_post['topiclink'] = $txt['not_applicable']; } // Set the last post in the parent board. if ($row_board['id_parent'] == $boardIndexOptions['parent_id'] || $isChild && !empty($row_board['poster_time']) && $this_category[$row_board['id_parent']]['last_post']['timestamp'] < forum_time(true, $row_board['poster_time'])) { $this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['last_post'] = $this_last_post; $this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['first_post'] = $this_first_post; } // Just in the child...? if ($isChild) { $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['last_post'] = $this_last_post; $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['first_post'] = $this_first_post; // If there are no posts in this board, it really can't be new... $this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['new'] &= $row_board['poster_name'] != ''; } elseif ($row_board['poster_name'] == '') { $this_category[$row_board['id_board']]['new'] = false; } // Determine a global most recent topic. if (!empty($boardIndexOptions['set_latest_post']) && !empty($row_board['poster_time']) && $row_board['poster_time'] > $latest_post['timestamp'] && !$ignoreThisBoard) { $latest_post = array('timestamp' => $row_board['poster_time'], 'ref' => &$this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['last_post']); } } mysql_free_result($result_boards); // By now we should know the most recent post...if we wanna know it that is. if (!empty($boardIndexOptions['set_latest_post']) && !empty($latest_post['ref'])) { $context['latest_post'] = $latest_post['ref']; } $hidden_boards = $visible_boards = 0; $context['hidden_boards']['id'] = $context['hidden_boards']['is_collapsed'] = 0; // only run this if we actually have some boards on the ignore list to save cycles. if ($total_ignored_boards) { if ($boardIndexOptions['include_categories']) { foreach ($categories as &$cat) { $hidden_boards += hideIgnoredBoards($cat['boards']); } } else { if (count($this_category)) { $hidden_boards += hideIgnoredBoards($this_category); } } $context['hidden_boards']['notice'] = $txt[$hidden_boards > 1 ? 'hidden_boards_notice_many' : 'hidden_boards_notice_one']; $context['hidden_boards']['setup_notice'] = sprintf($txt['hidden_boards_setup_notice'], $scripturl . '?action=profile;area=ignoreboards'); } $context['hidden_boards']['hidden_count'] = $hidden_boards; $context['hidden_boards']['visible_count'] = $visible_boards; return $boardIndexOptions['include_categories'] ? $categories : $this_category; }
function shorten_subject($subject, $len) { // It was already short enough! if (commonAPI::strlen($subject) <= $len) { return $subject; } // Shorten it by the length it was too long, and strip off junk from the end. return commonAPI::substr($subject, 0, $len) . '...'; }