header('Location: ' . $base_config['baseurl'] . '/admin/maintenance'); return; } echo '<div class="forum_content">'; $first = true; $outid = 0; while (list($id, $sig) = $db->fetch_row($result)) { if ($first) { echo '<p style="border: 1px solid #000; margin-left:5%; margin-right:5%; padding:0px;"> <span style="width:' . $id / $user_count * 100 . '%; background-color: #39F; display:block; padding-left: 1px; padding-top: 1px; padding-bottom: 1px; margin-left:0px"> </span> </p> <h3>' . translate('reparsingsigs') . '</h3>'; $first = false; } echo '<p>' . translate('reparsingsig', $id) . '</p>'; $sig = BBCodeController::parse_msg($sig); $db->query('UPDATE `#^users` SET parsed_signature=\'' . $db->escape($sig) . '\' WHERE id=' . $id) or error('Failed to update post', __FILE__, __LINE__, $db->error()); $outid = $id; } echo '<p>' . translate('redirmsg', '?start=' . ($_GET['start'] + $per_page)) . '</p>'; echo '</div>'; header('Refresh: 1; url=' . $base_config['baseurl'] . '/admin/maintenance/reparse_sigs?start=' . ($_GET['start'] + $per_page)); return; case 'rebuildsearch': include FORUM_ROOT . '/app_resources/includes/search.php'; $per_page = 300; if (!isset($_GET['start'])) { $_GET['start'] = 0; $db->truncate('search_index'); } $result = $db->query('SELECT MAX(id) FROM `#^posts`') or error('Failed to find post count', __FILE__, __LINE__, $db->error());
static function error_check($text, &$errors) { global $futurebb_user, $futurebb_config; static $filter_data, $filter_domains; if (!$futurebb_user['g_post_links'] && preg_match('%\\[url.*?\\]%', $text)) { $errors[] = translate('nolinks'); } if (!$futurebb_user['g_post_images'] && preg_match('%\\[img.*?\\]%', $text)) { $errors[] = translate('noimgs'); } if (!isset($filter_data)) { $filter_data = explode('|', $futurebb_config['imghostrestriction']); } if (!$futurebb_user['g_mod_privs'] && !$futurebb_user['g_admin_privs'] && $filter_data[0] != 'none') { if (!isset($filter_domains)) { $filter_domains = explode("\n", $filter_data[1]); } preg_match_all('%\\[img\\](.*?)\\[/img\\]%', $text, $matches); foreach ($matches[1] as $url) { if (!preg_match('%^(ht|f)tps?://%', $url)) { $url = 'http://' . $url; } $parse = parse_url($url); $host = $parse['host']; if ($filter_data[0] == 'blacklist') { foreach ($filter_domains as $domain) { if (preg_match('%' . preg_quote($domain) . '$%', $host)) { $errors[] = translate('imgblacklisterror', $url, implode(', ', $filter_domains)); break; } } } else { if ($filter_data[0] == 'whitelist') { $ok = false; foreach ($filter_domains as $domain) { if (preg_match('%' . preg_quote($domain) . '$%', $host)) { $ok = true; } } if (!$ok) { $errors[] = translate('imgwhitelisterror', $url, implode(', ', $filter_domains)); } } } } } if (empty(self::$tags)) { self::$tags = array('b', 'i', 'u', 's', 'color', 'colour', 'url', 'img', 'quote', 'code', 'list', '\\*', 'table', 'tr', 'td', 'th'); } if (preg_match_all('%\\[(' . implode('|', self::$tags) . ')=(.*?)(\\[|\\])\\]%', $text, $matches)) { $errors[] = translate('bracketparam', $matches[1][0]); return; } //parsing rules $no_nest_tags = array('img'); $block_tags = array('quote', 'code', 'list', 'table', 'tr'); $inline_tags = array('b', 'i', 'u', 's', 'color', 'colour', 'url', 'img', '\\*', 'th', 'td'); $nest_only = array('table' => array('tr'), 'tr' => array('td', 'th'), 'list' => array('*')); //tags that can only have a specific set of subtags $nest_forbid = array('td' => array('td', 'th'), 'th' => array('td', 'th')); $no_body = array('table', 'tr', 'list'); //tags that can't have text inside them $bbcode_parts = preg_split('%(\\[[\\*a-zA-Z0-9-/]*?(?:=.*?)?\\])%', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); //this regular expression was copied from FluxBB. However, everything used to parse it is completely original //split the message into tags and check syntax $open_tags = array(); $last_key = 0; $quotes = 0; foreach ($bbcode_parts as $key => $val) { if (preg_match('%^\\[/(' . implode('|', self::$tags) . ')\\]$%', $val, $matches)) { //closing tag of some sort if ($last_key == 0) { $errors[] = translate('closenoopen', $matches[1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); return; } if ($open_tags[$last_key - 1] != 'code' && $matches[1] != $open_tags[$last_key - 1]) { //if it's not a [code] tag, ignore it $errors[] = translate('expectedfound', $open_tags[$last_key - 1], $matches[1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); return; } if (!($open_tags[$last_key - 1] == 'code' && $matches[1] != $open_tags[$last_key - 1])) { //close the tag in the tag stack if it's not a mismatch inside a [code] tag (like [code][/tr][/code]) if ($open_tags[$last_key - 1] == 'quote') { $quotes--; } unset($open_tags[$last_key - 1]); $last_key--; } } else { if (!($last_key > 0 && $open_tags[$last_key - 1] == 'code') && preg_match('%^\\[(' . implode('|', self::$tags) . ')(=.*?)?\\]$%', $val, $matches)) { //opening tag of some sort $open_tags[$last_key] = $matches[1]; //check if there are any block tags inside inline tags if ($last_key > 0 && in_array($open_tags[$last_key - 1], $inline_tags) && in_array($matches[1], $block_tags)) { $errors[] = translate('blockininline', $matches[1], $open_tags[$last_key - 1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); } //check for the tags that only allow specific tags directly inside them if ($last_key > 0 && array_key_exists($open_tags[$last_key - 1], $nest_only) && !in_array($open_tags[$last_key], $nest_only[$open_tags[$last_key - 1]])) { $errors[] = translate('specificnestingerror', $matches[1], $open_tags[$last_key - 1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); } if ($last_key > 0 && array_key_exists($open_tags[$last_key - 1], $nest_forbid) && in_array($open_tags[$last_key], $nest_forbid[$open_tags[$last_key - 1]])) { $errors[] = translate('specificnestingerror', $matches[1], $open_tags[$last_key - 1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); } //check if there is any bbcode inside a tag which can't nest if ($last_key > 0 && in_array($open_tags[$last_key - 1], $no_nest_tags)) { $errors[] = translate('nonesting', $open_tags[$last_key - 1]); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); } if ($open_tags[$last_key] == 'quote') { $quotes++; if ($quotes > $futurebb_config['max_quote_depth']) { $errors[] = translate('toomanynestedquotes', $futurebb_config['max_quote_depth']); $errors[] = self::highlight_error($text, $matches[0], $bbcode_parts, $key); } } $last_key++; } else { if ($last_key > 0) { //no tag, just text if (!preg_match('%^\\s+$%ms', $val) && in_array($open_tags[$last_key - 1], $no_body)) { $errors[] = translate('notextinsidetag', $open_tags[$last_key - 1]); $errors[] = self::highlight_error($text, $val, $bbcode_parts, $key); } } } } } if (sizeof($open_tags) > 0) { $location_notices = array(); foreach ($open_tags as &$val) { //find the last occurrence of this tag $reverse_parts = array_reverse($bbcode_parts); foreach ($reverse_parts as $partkey => $part) { if (strpos($part, '[' . $val) === 0) { $location_notices[] = self::highlight_error($text, $part, $bbcode_parts, sizeof($bbcode_parts) - $partkey - 1, 'tagwasopened', $val); break; } } //bold this so it goes on the error list $val = '<b>[' . $val . ']</b>'; } $errors[] = translate('tagsnotclosed', implode(', ', $open_tags)); $errors = array_merge($errors, $location_notices); } }
} $db->query('UPDATE `#^topics` SET subject=\'' . $db->escape($_POST['subject']) . '\',url=\'' . $db->escape($name) . '\' WHERE id=' . $cur_post['tid']) or error('Failed to update topic subject', __FILE__, __LINE__, $db->error()); $db->query('INSERT INTO `#^topics`(url,redirect_id) VALUES(\'' . $db->escape($cur_post['turl']) . '\',' . $cur_post['tid'] . ')') or error('Failed to create redirect topic', __FILE__, __LINE__, $db->error()); } update_search_index($pid, $_POST['content']); if (isset($_POST['silentedit']) && ($futurebb_user['g_mod_privs'] || $futurebb_user['g_admin_privs'])) { $last_edited_sql = ''; } else { $last_edited_sql = 'last_edited=' . time() . ',last_edited_by=' . $futurebb_user['id'] . ','; } $db->query('UPDATE `#^posts` SET content=\'' . $db->escape($_POST['content']) . '\',parsed_content=\'' . $db->escape(BBCodeController::parse_msg($_POST['content'], !isset($_POST['hidesmilies']))) . '\',' . $last_edited_sql . 'disable_smilies=' . intval(isset($_POST['hidesmilies'])) . ' WHERE id=' . $pid) or error('Failed to update post', __FILE__, __LINE__, $db->error()); redirect($base_config['baseurl'] . '/posts/' . $pid); return; } else { if (isset($_POST['preview']) && empty($errors)) { echo '<div class="quotebox preview">' . BBCodeController::parse_msg($_POST['content'], !isset($_POST['hidesmilies'])) . '</div>'; } else { echo '<p>' . translate('errordesc') . '<ul>'; foreach ($errors as $val) { echo '<li>' . $val . '</li>'; } echo '</ul></p>'; } } $content = $_POST['content']; } else { $content = $cur_post['content']; } ?> <form action="<?php echo $base_config['baseurl'];
} if (isset($_POST['form_sent'])) { $errors = array(); include FORUM_ROOT . '/app_resources/includes/parser.php'; if ($futurebb_config['enable_bbcode']) { BBCodeController::error_check($_POST['signature'], $errors); } if ($futurebb_config['sig_max_length'] && strlen($_POST['signature']) > $futurebb_config['sig_max_length']) { $errors[] = translate('sigtoolong', $futurebb_config['sig_max_length'], strlen($_POST['signature'])); } if ($futurebb_config['sig_max_lines'] && sizeof(explode("\n", $_POST['signature'])) > $futurebb_config['sig_max_length']) { $errors[] = translate('toomanysiglines', $futurebb_config['sig_max_lines'], sizeof(explode("\n", $_POST['signature']))); } if (empty($errors)) { $cur_user['signature'] = $_POST['signature']; $db->query('UPDATE `#^users` SET signature=\'' . $db->escape($_POST['signature']) . '\',parsed_signature=\'' . $db->escape(BBCodeController::parse_msg($_POST['signature'], $futurebb_config['enable_smilies'], false, $futurebb_config['enable_bbcode'])) . '\' WHERE id=' . $cur_user['id'], $futurebb_config['enable_bbcode']) or error('Failed to update sig', __FILE__, __LINE__, $db->error()); echo '</div></div>'; header('Refresh: 0'); return; } } echo '<h3>' . translate('changesig') . '</h3>'; if (!empty($errors)) { echo '<p>' . translate('errordesc') . '<ul><li>' . implode('</li><li>', $errors) . '</li></ul></p>'; } echo '<form action="' . $base_config['baseurl'] . '/users/' . htmlspecialchars($dirs[2]) . '/sig" method="post" enctype="multipart/form-data">'; if ($cur_user['signature'] != '') { echo '<h4>' . translate('currentsig') . '</h4><p class="quotebox"'; if ($futurebb_config['sig_max_height']) { echo ' style="max-height:' . $futurebb_config['sig_max_height'] . 'px; overflow:hidden"'; }
} } } } // Continue posting $db->query('UPDATE `#^topics` SET last_post=' . time() . ',last_post_id=' . $pid . ',num_replies=num_replies+1 WHERE id=' . $tid) or error('Failed to update topic info', __FILE__, __LINE__, $db->error()); $db->query('UPDATE `#^forums` SET last_post=' . time() . ',last_post_id=' . $pid . ($cur_topic['deleted'] ? '' : ',num_posts=num_posts+1') . ' WHERE id=' . $cur_topic['f_id']) or error('Failed to forum last post', __FILE__, __LINE__, $db->error()); $db->query('DELETE FROM `#^read_tracker` WHERE (forum_id=' . $cur_topic['f_id'] . ' OR topic_id=' . $tid . ') AND user_id<>' . $futurebb_user['id']) or error('Failed to update read tracker', __FILE__, __LINE__, $db->error()); $db->query('UPDATE `#^users` SET num_posts=num_posts+1 WHERE id=' . $futurebb_user['id']) or error('Failed to update number of posts', __FILE__, __LINE__, $db->error()); update_search_index($pid, $_POST['message']); ExtensionConfig::run_hooks('new_post', array('id' => $pid, 'topic' => $cur_topic['subject'], 'topic_url' => $cur_topic['url'], 'poster' => $futurebb_user['username'], 'message' => $_POST['message'], 'forum_url' => $cur_topic['forum_url'], 'forum' => $cur_topic['forum_name'])); redirect($base_config['baseurl'] . '/posts/' . $pid); return; } else { if (isset($_POST['preview']) && empty($errors)) { echo '<div class="quotebox preview">' . BBCodeController::parse_msg($_POST['message'], !isset($_POST['hidesmilies']), true, $futurebb_config['enable_bbcode']) . '</div>'; } } } } if (isset($errors) && !empty($errors)) { echo '<p>' . translate('errordesc') . '<ul>'; foreach ($errors as $val) { echo '<li>' . $val . '</li>'; } echo '</ul></p>'; } if (isset($_GET['quote'])) { $result = $db->query('SELECT p.content,u.username FROM `#^posts` AS p LEFT JOIN `#^users` AS u ON u.id=p.poster WHERE p.id=' . intval($_GET['quote'])) or error('Failed to get post to quote', __FILE__, __LINE__, $db->error()); if (!$db->num_rows($result)) { httperror(404);
static function LoadNotifications() { // Select notifications from the database and put them into the user variable global $futurebb_user, $db, $base_config, $futurebb_config; if ($futurebb_config['bbcode_privatemsg']) { include_once FORUM_ROOT . '/app_resources/includes/parser.php'; } $futurebb_user['notifications'] = array(); // The following is the standard format for the array containing user notifications // (string $type, int $send_time, string $contents) // type: warning, msg, notification // // Arguments for type 'warning': // issuer ID // Arguments for type 'msg': // sender ID // Arguments for type 'notification': // poster ID (contents = post ID where user was mentioned) $result = $db->query('SELECT id, type, send_time, read_time, contents, arguments FROM `#^notifications` WHERE user='******'id'] . ' ORDER BY send_time DESC LIMIT 100') or error('Failed to load user notifications', __FILE__, __LINE__, $db->error()); // Load out into array and translate where needed while ($notifs_raw = $db->fetch_assoc($result)) { $sender = ''; if ($notifs_raw['type'] == 'warning') { $contents_raw = translate('user_sent_warning', '<a href="' . $base_config['baseurl'] . '/users/' . htmlspecialchars($notifs_raw['arguments']) . '">' . htmlspecialchars($notifs_raw['arguments']) . '</a>') . '<br />'; if ($futurebb_config['bbcode_privatemsg']) { $contents_raw .= BBCodeController::parse_msg($notifs_raw['contents'], true, false, true); } else { $contents_raw .= htmlspecialchars($notifs_raw['contents']); } $sender = $notifs_raw['arguments']; } elseif ($notifs_raw['type'] == 'msg') { $contents_raw = translate('user_sent_msg', '<a href="' . $base_config['baseurl'] . '/users/' . htmlspecialchars($notifs_raw['arguments']) . '">' . htmlspecialchars($notifs_raw['arguments']) . '</a>') . '<br />'; if ($futurebb_config['bbcode_privatemsg']) { $contents_raw .= BBCodeController::parse_msg($notifs_raw['contents'], true, false, true); } else { $contents_raw .= htmlspecialchars($notifs_raw['contents']); } $sender = $notifs_raw['arguments']; } elseif ($notifs_raw['type'] == 'notification') { $parts = explode(',', $notifs_raw['arguments'], 2); $contents_raw = translate('user_mentioned_you', '<a href="' . $base_config['baseurl'] . '/users/' . htmlspecialchars($parts[0]) . '">' . htmlspecialchars($parts[0]) . '</a>') . '<a href="' . $base_config['baseurl'] . '/posts/' . $notifs_raw['contents'] . '">' . htmlspecialchars($parts[1]) . '</a>'; } else { $contents_raw = translate('couldnot_display_notif'); } $futurebb_user['notifications'][] = array('type' => $notifs_raw['type'], 'id' => $notifs_raw['id'], 'send_time' => $notifs_raw['send_time'], 'read_time' => $notifs_raw['read_time'], 'sender' => $sender, 'contents' => $contents_raw); } // Check for unread notifications $futurebb_user['notifications_count'] = $db->num_rows($db->query('SELECT type, send_time, contents FROM `#^notifications` WHERE user='******'id'] . ' AND read_time = 0')); }