/** * Redirect the browser to a different page. * * @param string|integer $url * * The URL to redirect to, in case $url is a string. * * In case an integer is used, then this is treated as one of * the PHORUM_*_URL constants for building a Phorum URL. The API * call phorum_api_url() will be called to build the URL using * the $url value and any other arguments that are provided to * the function call. After building the URL, the browser is * redirected to that URL. */ function phorum_api_redirect($url) { // Handle building of a Phorum URL in case an integer value was // provided as the URL. if (is_integer($url)) { $argv = func_get_args(); $url = call_user_func_array('phorum_api_url', $argv); } // Some browsers strip the anchor from the URL in case we redirect // from a POSTed page :-/. So here we wrap the redirect, // to work around that problem. Instead of redirecting directly, // we do a GET request to Phorum's redirect.php script, which we // send the URL to redirect to in a request parameter. Then, the // redirect.php script will handle the actual redirect. if (count($_POST) && strstr($url, "#")) { $url = phorum_api_url(PHORUM_REDIRECT_URL, 'phorum_redirect_to=' . urlencode($url)); } // Check for response splitting and valid http(s) URLs. if (preg_match("/\\s/", $url) || !preg_match("!^https?://!i", $url)) { $url = phorum_api_url(PHORUM_INDEX_URL); } // An ugly IIS-hack to avoid crashing IIS servers. if (isset($_SERVER['SERVER_SOFTWARE']) && stristr($_SERVER['SERVER_SOFTWARE'], "Microsoft-IIS")) { $qurl = htmlspecialchars($url); $jurl = addslashes($url); print "<html><head><title>Redirecting ...</title>\n <script type=\"text/javascript\">\n //<![CDATA[\n document.location.href='{$jurl}'\n //]]>\n </script>\n <meta http-equiv=\"refresh\"\n content=\"0; URL={$qurl}\">\n </head>\n <body><a href=\"{$qurl}\">Redirecting ...</a></body>\n </html>"; } else { header("Location: {$url}"); } exit(0); }
function phorum_mod_smileys_editor_tool_plugin() { $PHORUM = $GLOBALS['PHORUM']; $lang = $PHORUM["DATA"]["LANG"]["mod_smileys"]; // Register the smiley tool button for the message body. if (!empty($PHORUM['mod_smileys']['smileys_tool_enabled'])) { editor_tools_register_tool('smiley', $lang['smiley'], "./mods/smileys/icon.gif", "editor_tools_handle_smiley()", NULL, NULL, 'body'); } // Register the smiley tool button for the message subject. if (!empty($PHORUM['mod_smileys']['subjectsmileys_tool_enabled'])) { editor_tools_register_tool('subjectsmiley', $lang['subjectsmiley'], "./mods/smileys/icon.gif", "editor_tools_handle_subjectsmiley()", NULL, NULL, 'subject'); } $description = isset($lang['smileys help']) ? $lang['smileys help'] : 'smileys help'; // Register the smileys help page. editor_tools_register_help($description, phorum_api_url(PHORUM_ADDON_URL, 'module=smileys', 'action=help')); }
/** * This function implements the JavaScript output adapter for the Feed API. * * @param array $messages * An array of messages to include in the feed. * * @param array $forums * An array of related forums. * * @param string $url * The URL that points to the feed's target. * * @param string $title * The title to use for the feed. * * @param string $description * The description to use for the feed. * * @param bool $replies * Whether or not this is a feed that includes reply messages. * If not, then it will only contain thread starter messages. * * @return array * An array containing two elements: * - The generated feed data (JavaScript code) * - The Content-Type header to use for the feed. */ function phorum_api_feed_js($messages, $forums, $url, $title, $description, $replies) { global $PHORUM; $feed = array('title' => $title, 'description' => $description, 'modified' => phorum_api_format_date($PHORUM['short_date'], time())); // Lookup the plain text usernames for the authenticated authors. $users = $messages['users']; unset($messages['users']); unset($users[0]); $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT); foreach ($messages as $message) { $author = !empty($users[$message['user_id']]) ? $users[$message['user_id']] : $message['author']; // Created date. $fmt = $PHORUM['short_date']; $created = phorum_api_format_date($fmt, $message['datestamp']); // Updated date. if ($message['parent_id']) { if (!empty($message['meta']['edit_date'])) { $modified = $message['meta']['edit_date']; } else { $modified = $message['datestamp']; } } else { $modified = $message['modifystamp']; } $modified = phorum_api_format_date($fmt, $modified); $url = htmlspecialchars(phorum_api_url(PHORUM_FOREIGN_READ_URL, $message['forum_id'], $message['thread'], $message['message_id'])); $item = array('title' => strip_tags($message['subject']), 'author' => $author, 'category' => $forums[$message['forum_id']]['name'], 'created' => $created, 'modified' => $modified, 'url' => $url, 'description' => $message['body']); if ($message["thread_count"]) { $replies = $message["thread_count"] - 1; $item["replies"] = $replies; } $feed["items"][] = $item; } // this is where we convert the array into js $buffer = 'phorum_feed = ' . phorum_api_json_encode($feed); return array($buffer, 'text/javascript'); }
function phorum_pm_format($messages) { global $PHORUM; // Reformat message so it looks like a forum message (so we can run it // through phorum_api_message_format()) and do some PM specific formatting. foreach ($messages as $id => $message) { // The formatting code expects a message id. $messages[$id]["message_id"] = $id; // Read URLs need a folder id, so we only create that URL if // one's available. if (isset($message['pm_folder_id'])) { $folder_id = $message['pm_folder_id'] ? $message['pm_folder_id'] : $message['special_folder']; $messages[$id]["URL"]["READ"] = phorum_api_url(PHORUM_PM_URL, "page=read", "folder_id={$folder_id}", "pm_id={$id}"); } // The datestamp is only available for already posted messages. if (isset($message['datestamp'])) { $messages[$id]["raw_date"] = $message["datestamp"]; $messages[$id]["date"] = phorum_api_format_date($PHORUM["short_date_time"], $message["datestamp"]); } if (isset($message['meta']) && !is_array($message['meta'])) { $messages[$id]['meta'] = unserialize($message['meta']); } $messages[$id]["body"] = isset($message["message"]) ? $message["message"] : ""; $messages[$id]["email"] = ""; $messages[$id]["URL"]["PROFILE"] = phorum_api_url(PHORUM_PROFILE_URL, $message["user_id"]); $messages[$id]["recipient_count"] = 0; $messages[$id]["receive_count"] = 0; if (isset($message["recipients"]) && is_array($message["recipients"])) { $receive_count = 0; foreach ($message["recipients"] as $rcpt_id => $rcpt) { if (!empty($rcpt["read_flag"])) { $receive_count++; } if (!isset($rcpt["display_name"])) { $messages[$id]["recipients"][$rcpt_id]["display_name"] = $PHORUM["DATA"]["LANG"]["AnonymousUser"]; } else { $messages[$id]["recipients"][$rcpt_id]["display_name"] = empty($PHORUM["custom_display_name"]) ? htmlspecialchars($rcpt["display_name"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]) : $rcpt["display_name"]; $messages[$id]["recipients"][$rcpt_id]["URL"]["PROFILE"] = phorum_api_url(PHORUM_PROFILE_URL, $rcpt_id); } } $messages[$id]["recipient_count"] = count($message["recipients"]); $messages[$id]["receive_count"] = $receive_count; } } // Run the messages through the standard formatting code. $messages = phorum_api_format_messages($messages); // Reformat message back to a private message. foreach ($messages as $id => $message) { $messages[$id]["message"] = $message["body"]; unset($messages[$id]["body"]); } return $messages; }
<?php if (!defined('PHORUM') || phorum_page !== 'moderation') { return; } $PHORUM['DATA']['HEADING'] = $PHORUM['DATA']['LANG']['Moderate'] . ': ' . $PHORUM['DATA']['LANG']['SplitThread']; $PHORUM['DATA']['BREADCRUMBS'][] = array('URL' => NULL, 'TEXT' => $PHORUM['DATA']['HEADING'], 'TYPE' => 'split'); $PHORUM['DATA']['URL']["ACTION"] = phorum_api_url(PHORUM_MODERATION_ACTION_URL); $message = $PHORUM['DB']->get_message($msgthd_id); $new_subject = preg_replace('/^Re:\\s*/', '', $message['subject']); $PHORUM['DATA']["FORM"]["forum_id"] = $PHORUM["forum_id"]; $PHORUM['DATA']["FORM"]["thread_id"] = $message["thread"]; $PHORUM['DATA']["FORM"]["message_id"] = $msgthd_id; $PHORUM['DATA']["FORM"]["message_subject"] = htmlspecialchars($message["subject"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $PHORUM['DATA']["FORM"]["new_message_subject"] = htmlspecialchars($new_subject, ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $PHORUM['DATA']["FORM"]["mod_step"] = PHORUM_DO_THREAD_SPLIT; $template = "split_form";
/** * Generate the URLs that are used on most pages. */ function phorum_build_common_urls() { global $PHORUM; $GLOBALS["PHORUM"]["DATA"]["URL"]["BASE"] = phorum_api_url(PHORUM_BASE_URL); $GLOBALS["PHORUM"]["DATA"]["URL"]["HTTP_PATH"] = $PHORUM['http_path']; $GLOBALS["PHORUM"]["DATA"]["URL"]["LIST"] = phorum_api_url(PHORUM_LIST_URL); // These links are only needed in forums, not in folders. if (isset($PHORUM['folder_flag']) && !$PHORUM['folder_flag']) { $GLOBALS["PHORUM"]["DATA"]["URL"]["POST"] = phorum_api_url(PHORUM_POSTING_URL); $GLOBALS["PHORUM"]["DATA"]["URL"]["SUBSCRIBE"] = phorum_api_url(PHORUM_SUBSCRIBE_URL); } $GLOBALS["PHORUM"]["DATA"]["URL"]["SEARCH"] = phorum_api_url(PHORUM_SEARCH_URL); // Find the id for the index. $index_id = -1; // A folder where we usually don't show the index-link but on // additional pages like search and login it is shown. if ($PHORUM['folder_flag'] && phorum_page != 'index' && ($PHORUM['forum_id'] == 0 || $PHORUM['vroot'] == $PHORUM['forum_id'])) { $index_id = $PHORUM['forum_id']; // Either a folder where the link should be shown (not vroot or root) // or an active forum where the link should be shown. } elseif ($PHORUM['folder_flag'] && ($PHORUM['forum_id'] != 0 && $PHORUM['vroot'] != $PHORUM['forum_id']) || !$PHORUM['folder_flag'] && $PHORUM['active']) { // Go to root or vroot. if (isset($PHORUM["index_style"]) && $PHORUM["index_style"] == PHORUM_INDEX_FLAT) { // vroot is either 0 (root) or another id $index_id = $PHORUM["vroot"]; // Go to the parent folder. } else { $index_id = $PHORUM["parent_id"]; } } if ($index_id > -1) { // check if its the full root, avoid adding an id in this case (SE-optimized ;)) if (!empty($index_id)) { $GLOBALS["PHORUM"]["DATA"]["URL"]["INDEX"] = phorum_api_url(PHORUM_INDEX_URL, $index_id); } else { $GLOBALS["PHORUM"]["DATA"]["URL"]["INDEX"] = phorum_api_url(PHORUM_INDEX_URL); } } // these urls depend on the login-status of a user if ($GLOBALS["PHORUM"]["DATA"]["LOGGEDIN"]) { $GLOBALS["PHORUM"]["DATA"]["URL"]["LOGINOUT"] = phorum_api_url(PHORUM_LOGIN_URL, "logout=1"); $GLOBALS["PHORUM"]["DATA"]["URL"]["REGISTERPROFILE"] = phorum_api_url(PHORUM_CONTROLCENTER_URL); $GLOBALS["PHORUM"]["DATA"]["URL"]["VIEWPROFILE"] = phorum_api_url(PHORUM_PROFILE_URL, $PHORUM['user']['user_id']); $GLOBALS["PHORUM"]["DATA"]["URL"]["PM"] = phorum_api_url(PHORUM_PM_URL); } else { $GLOBALS["PHORUM"]["DATA"]["URL"]["LOGINOUT"] = phorum_api_url(PHORUM_LOGIN_URL); $GLOBALS["PHORUM"]["DATA"]["URL"]["REGISTERPROFILE"] = phorum_api_url(PHORUM_REGISTER_URL); } }
// the admin. If they aren't then either set a message with a login link // (when running as include) or redirect to the login page. } elseif ($PHORUM["DATA"]["LOGGEDIN"] && !$PHORUM["DATA"]["FULLY_LOGGEDIN"]) { if (isset($PHORUM["postingargs"]["as_include"])) { // Generate the URL to return to after logging in. $args = array(PHORUM_REPLY_URL, $PHORUM["args"][1]); if (isset($PHORUM["args"][2])) { $args[] = $PHORUM["args"][2]; } if (isset($PHORUM["args"]["quote"])) { $args[] = "quote=1"; } phorum_api_url; // Make sure the URL API layer code is loaded. $redir = urlencode(call_user_func_array('phorum_api_url', $args)); $url = phorum_api_url(PHORUM_LOGIN_URL, "redir={$redir}"); $PHORUM["DATA"]["URL"]["CLICKHERE"] = $url; $PHORUM["DATA"]["CLICKHEREMSG"] = $PHORUM["DATA"]["LANG"]["ClickHereToLogin"]; $PHORUM["DATA"]["OKMSG"] = '<a name="REPLY"></a>' . $PHORUM["DATA"]["LANG"]["NoPost"] . ' ' . $PHORUM["DATA"]["LANG"]["PeriodicLogin"]; $PHORUM["posting_template"] = "message"; return; } else { // Generate the URL to return to after logging in. $args = array(PHORUM_POSTING_URL); if (isset($PHORUM["args"][1])) { $args[] = $PHORUM["args"][1]; } if (isset($PHORUM["args"][2])) { $args[] = $PHORUM["args"][2]; } if (isset($PHORUM["args"]["quote"])) {
$checkvar = 1; // Get the threads $rows = array(); // get the thread set started $rows = $PHORUM['DB']->get_unapproved_list($forum, $showwaiting, $moddays); // loop through and read all the data in. foreach ($rows as $key => $row) { $numunapproved++; $rows[$key]['forumname'] = $foruminfo[$forum]['name']; $rows[$key]['checkvar'] = $checkvar; if ($checkvar) { $checkvar = 0; } $rows[$key]['forum_id'] = $forum; $rows[$key]["URL"]["READ"] = phorum_api_url(PHORUM_FOREIGN_READ_URL, $forum, $row["thread"], $row['message_id']); // we need to fake the forum_id here $PHORUM["forum_id"] = $forum; $rows[$key]["URL"]["APPROVE_MESSAGE"] = phorum_api_url(PHORUM_MODERATION_URL, PHORUM_APPROVE_MESSAGE, $row["message_id"], "prepost=1", "old_forum=" . $oldforum, "onlyunapproved=" . $showwaiting, "moddays=" . $moddays); $rows[$key]["URL"]["APPROVE_TREE"] = phorum_api_url(PHORUM_MODERATION_URL, PHORUM_APPROVE_MESSAGE_TREE, $row["message_id"], "prepost=1", "old_forum=" . $oldforum, "onlyunapproved=" . $showwaiting, "moddays=" . $moddays); $rows[$key]["URL"]["DELETE"] = phorum_api_url(PHORUM_MODERATION_URL, PHORUM_DELETE_TREE, $row["message_id"], "prepost=1", "old_forum=" . $oldforum, "onlyunapproved=" . $showwaiting, "moddays=" . $moddays); $PHORUM["forum_id"] = $oldforum; $rows[$key]["raw_short_datestamp"] = $row["datestamp"]; $rows[$key]["short_datestamp"] = phorum_api_format_date($PHORUM["short_date_time"], $row["datestamp"]); } $rows = phorum_api_format_messages($rows); $PHORUM['DATA']['PREPOST'] = array_merge($PHORUM['DATA']['PREPOST'], $rows); } if (!$numunapproved) { $PHORUM["DATA"]["UNAPPROVEDMESSAGE"] = $PHORUM["DATA"]["LANG"]["NoUnapprovedMessages"]; } $template = "cc_prepost";
function phorum_mod_bbcode_editor_tool_plugin() { global $PHORUM; $lang = $PHORUM['DATA']['LANG']['mod_bbcode']; $nr_of_enabled_tags = 0; $enabled = isset($PHORUM['mod_bbcode']['enabled']) ? $PHORUM['mod_bbcode']['enabled'] : array(); $builtin = $PHORUM['MOD_BBCODE']['BUILTIN']; // Register the tool buttons. foreach ($PHORUM['mod_bbcode_parser']['taginfo'] as $id => $taginfo) { // Skip tool if no editor tools button is implemented. if (!$taginfo[BBCODE_INFO_HASEDITORTOOL]) { continue; } // Check if the editor tool should be shown. If not, then skip // to the next tag. If there are no settings saved yet for the // module, then use the settings from the builtin tag list. if (isset($enabled[$id]) && $enabled[$id] != 2 || !isset($PHORUM['mod_bbcode']['enabled'][$id]) && isset($builtin[$id]) && $builtin[$id][BBCODE_INFO_DEFAULTSTATE] != 2) { continue; } // Keep track of the number of enabled tags. $nr_of_enabled_tags++; // Determine the description to use for the tool. If we can find // a description in the language strings, then we use that one. // Otherwise, we simply fall back to the less descriptive feature id. $description = isset($lang[$id]) ? $lang[$id] : $id; // Register the tool button with the Editor Tools module. editor_tools_register_tool($id, $description, "./mods/bbcode/icons/{$id}.gif", "editor_tools_handle_{$id}()"); } // Register the bbcode help page, unless no tags were enabled at all. if ($nr_of_enabled_tags > 0) { $description = isset($lang['bbcode help']) ? $lang['bbcode help'] : 'BBcode help'; editor_tools_register_help($description, phorum_api_url(PHORUM_ADDON_URL, 'module=bbcode', 'action=help')); } // Make language strings available for the editor tools javascript code. editor_tools_register_translations($lang); }
} // if the option to build a dropdown list is enabled, build the list of members that could be added if ($PHORUM["enable_dropdown_userlist"]) { $userlist = phorum_api_user_list(PHORUM_GET_ACTIVE); $PHORUM["DATA"]["NEWMEMBERS"] = array(); foreach ($userlist as $userid => $userinfo) { if (!in_array($userid, $usersingroup)) { $userinfo["username"] = htmlspecialchars($userinfo["username"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $userinfo["display_name"] = htmlspecialchars($userinfo["display_name"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $PHORUM["DATA"]["NEWMEMBERS"][] = $userinfo; } } } } else { $PHORUM["DATA"]["GROUPS"] = array(); $groups = phorum_api_user_check_group_access(PHORUM_USER_GROUP_MODERATOR, PHORUM_ACCESS_LIST); // Turn the groups into a group id => group name mapping. foreach ($groups as $id => $group) { $groups[$id] = $group['name']; } // put these things in order so the user can read them asort($groups); foreach ($groups as $groupid => $groupname) { // get the group members who are unapproved, so we can count them $members = $PHORUM['DB']->get_group_members($groupid, PHORUM_USER_GROUP_UNAPPROVED); $full_members = $PHORUM['DB']->get_group_members($groupid); $PHORUM["DATA"]["GROUPS"][] = array("id" => $groupid, "name" => $groupname, "unapproved" => count($members), "members" => count($full_members), "URL" => array("VIEW" => phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_GROUP_MODERATION, "group=" . $groupid), "UNAPPROVED" => phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_GROUP_MODERATION, "group=" . $groupid, "filter=" . PHORUM_USER_GROUP_UNAPPROVED))); } } $PHORUM["DATA"]['POST_VARS'] .= "<input type=\"hidden\" name=\"group\" value=\"{$group_id}\" />\n"; $template = "cc_groupmod";
if (substr($var, 0, 7) == "detach:") { $do_detach = substr($var, 7); } } // Check if the user uploads an attachment. We remove file uploads // with no name set, because that simply means the user did not select // a file to upload. Not an error condition in this case. foreach ($_FILES as $key => $val) { if (!isset($val["name"]) || $val["name"] == "") { unset($_FILES[$key]); } } $do_attach = count($_FILES) ? true : false; // Set all our URL's phorum_build_common_urls(); $PHORUM["DATA"]["URL"]["ACTION"] = phorum_api_url(PHORUM_POSTING_ACTION_URL); // Keep track of errors. $PHORUM["DATA"]["ERROR"] = null; // Do things that are specific for first time or followup requests. if ($initial) { include './include/posting/request_first.php'; } else { include './include/posting/request_followup.php'; } // Store the posting mode in the form parameters, so we can remember // the mode throughout the editing cycle (for example to be able to // create page titles which match the editing mode). $PHORUM["DATA"]["MODE"] = $mode; // Set the page title, description and breadcrumbs accordingly switch ($mode) { case "post":
/** * Collect the data that is used for the feed and pass this information * on to the requested output adapter. * * @param string $adapter * The output adapter to use. The adapters that are available are: * - rss * - atom * - html * - js * * @param integer $source_type * The type of source. This is one of: * - {@link PHORUM_FEED_VROOT} * - {@link PHORUM_FEED_FORUM} * - {@link PHORUM_FEED_THREAD} * * @param integer $id * This parameter has a different meaning for each $source_type: * - For {@link PHORUM_FEED_VROOT}: the forum_id of the (v)root. * - For {@link PHORUM_FEED_FORUM}: the forum_id of the forum. * - For {@link PHORUM_FEED_THREAD}: the message_id of the thread. * * @param integer $count * The number of messages to include in the feed. * * @param boolean $replies * TRUE to include reply messages in the feed, FALSE otherwise. * This parameter is forced to TRUE for {@link PHORUM_FEED_THREAD}. */ function phorum_api_feed($adapter, $source_type, $id, $count, $replies) { global $PHORUM; settype($id, 'int'); settype($count, 'int'); settype($source_type, 'int'); $replies = $replies ? 1 : 0; $adapter = basename($adapter); if (!preg_match('/^[a-z][\\w_]*$/', $adapter)) { trigger_error('phorum_api_feed(): Illegal feed adapter name ' . '"' . htmlspecialchars($adapter) . '" used', E_USER_ERROR); } if (!file_exists(PHORUM_PATH . '/include/api/feed/' . $adapter . '.php')) { trigger_error('phorum_api_feed(): Unknown feed adapter ' . '"' . htmlspecialchars($adapter) . '" used', E_USER_ERROR); } // ---------------------------------------------------------------------- // Prepare the data for the requested feed type // ---------------------------------------------------------------------- // Prepare data for handling a vroot feed. if ($source_type === PHORUM_FEED_VROOT) { $forums = phorum_api_forums_by_vroot($id); $thread_id = NULL; $forum_ids = array_keys($forums); $cache_part = implode(',', array_keys($forums)); } elseif ($source_type === PHORUM_FEED_FORUM) { if ($PHORUM['forum_id'] == $id) { $forum = $PHORUM; // contains all required data already } else { $forum = phorum_api_forums_by_forum_id($id); if (empty($forum)) { trigger_error("phorum_api_feed(): Forum for forum_id \"{$id}\" not found.", E_USER_ERROR); } } $forums = array($id => $forum); $thread_id = NULL; $forum_ids = array_keys($forums); $cache_part = $forum['forum_id']; } elseif ($source_type === PHORUM_FEED_THREAD) { // When a feed for a thread is requested, we always include the // reply messages for that thread in the feed. $replies = 1; // Retrieve the thread starter message. $thread = $PHORUM['DB']->get_message($id); if (empty($thread)) { trigger_error("phorum_api_feed(): Thread for message_id \"{$id}\" not found.", E_USER_ERROR); } if (!empty($thread['parent_id'])) { trigger_error("phorum_api_feed(): Message for message_id \"{$id}\" is not " . "the start message of a thread.", E_USER_ERROR); } $thread_id = $id; $forum_ids = NULL; $cache_part = $id; } else { trigger_error("phorum_api_feed(): Illegal value \"{$source_type}\" used " . "for parameter \$source_type.", E_USER_ERROR); } // ---------------------------------------------------------------------- // Retrieve the data for the requested feed // ---------------------------------------------------------------------- $data = NULL; $content_type = NULL; // Try to retrieve the data from cache. if (!empty($PHORUM['cache_rss'])) { // Build the cache key that uniquely identifies the requested feed. $cache_key = $PHORUM['user']['user_id'] . '|' . $adapter . '|' . $source_type . '|' . $cache_part . '|' . $replies . '|' . $count; $cache = phorum_api_cache_get('feed', $cache_key); if (!empty($cache)) { list($data, $content_type) = $cache; } } // No data from cache. Load the recent threads / messages // directly from the database and generate the feed data. if (empty($data)) { // ---------------------------------------------------------------- // Retrieve the messages to show // ---------------------------------------------------------------- $messages = $PHORUM['DB']->get_recent_messages($count, 0, $forum_ids, $thread_id, $replies ? LIST_RECENT_MESSAGES : LIST_RECENT_THREADS); // Temporarily, remove the user list from the messages array. $users = $messages['users']; unset($messages['users']); // Apply the "read" hook(s) to the messages. if (isset($PHORUM['hooks']['read'])) { $messages = phorum_api_hook('read', $messages); } // Apply formatting to the messages. $messages = phorum_api_format_messages($messages); // Put the array of users back in the messages array. $messages['users'] = $users; // ---------------------------------------------------------------- // Setup the feed URL, title and description based on // the type of feed that was requested. // ---------------------------------------------------------------- if ($source_type === PHORUM_FEED_VROOT) { $feed_url = phorum_api_url(PHORUM_INDEX_URL); $feed_title = strip_tags($PHORUM['DATA']['TITLE']); $feed_description = !empty($PHORUM['description']) ? $PHORUM['description'] : ''; } if ($source_type === PHORUM_FEED_FORUM) { $feed_url = phorum_api_url(PHORUM_LIST_URL); /** * @todo The formatting of the forum base feed data should * be based on the data in $forum and not the common.php * $PHORUM contents. This is left as is for now, because * the wrong data will only be shown for threads that * were moved to a different forum. */ $feed_title = strip_tags($PHORUM['DATA']['TITLE'] . ' - ' . $PHORUM['DATA']['NAME']); $feed_description = strip_tags($PHORUM['DATA']['DESCRIPTION']); } if ($source_type === PHORUM_FEED_THREAD) { // Retrieve the information for the forum to which the thread // belongs. Normally, this should be in $PHORUM already, but // let's make sure that the caller is using the correct forum id // in the URL here (since the thread might have been moved to // a different forum). $forum_id = $thread['forum_id']; if ($PHORUM['forum_id'] == $forum_id) { $forum = $PHORUM; // contains all required data already } else { $forum = phorum_api_forums_by_forum_id($forum_id); if (empty($forum)) { trigger_error("phorum_api_feed(): Forum for forum_id \"{$id}\" not found.", E_USER_ERROR); } } $forums = array($forum_id => $forum); $feed_url = phorum_api_url(PHORUM_FOREIGN_READ_URL, $thread['forum_id'], $thread_id, $thread_id); $feed_title = strip_tags($thread['subject']); $feed_description = strip_tags($thread['body']); } // ---------------------------------------------------------------- // All data has been collected. Now the feed is generated. // ---------------------------------------------------------------- require_once PHORUM_PATH . '/include/api/feed/' . $adapter . '.php'; $adapter_function = 'phorum_api_feed_' . $adapter; list($data, $content_type) = $adapter_function($messages, $forums, $feed_url, $feed_title, $feed_description, $replies); // Store the feed data in the cache for future use. if (!empty($PHORUM['cache_rss'])) { phorum_api_cache_put('feed', $cache_key, array($data, $content_type, 600)); } } // ---------------------------------------------------------------------- // Output the feed data to the client // ---------------------------------------------------------------------- header("Content-Type: {$content_type}"); print $data; /* * [hook] * feed_sent * * [description] * This hook is called whenever the feed has been sent to the client * (regardless of the cache setting). This can be used to add internal * server side tracking code. * * [category] * Feed * * [when] * Feed sent to the client * * [input] * None * * [output] * None * * [example] * <hookcode> * function phorum_mod_foo_feed_after () * { * # E.g. do server side tracking * @file_get_contents('your tracking service'); * } * </hookcode> */ phorum_api_hook('feed_sent'); // Exit explicitly here, for not giving back control to portable and // embedded Phorum setups. exit(0); }
$forum_info = phorum_get_forum_info(2); $forum_matches = array(); foreach ($forum_info as $id => $name) { $forum_matches[htmlspecialchars($name)] = "message.forum_id = {$id}"; } $ruledefs = array("body" => array("label" => "Message body", "matches" => array("contains" => "message.body = *QUERY*", "does not contain" => "message.body != *QUERY*"), "queryfield" => "string"), "subject" => array("label" => "Message subject", "matches" => array("is" => "message.subject = QUERY", "is not" => "message.subject != QUERY", "contains" => "message.subject = *QUERY*", "does not contain" => "message.subject != *QUERY*"), "queryfield" => "string"), "date" => array("label" => "Message date", "matches" => array("posted on" => "function:prepare_filter_date", "posted on or before" => "function:prepare_filter_date", "posted before" => "function:prepare_filter_date", "posted after" => "function:prepare_filter_date", "posted on or after" => "function:prepare_filter_date"), "prepare_filter_date" => "message.datestamp", "queryfield" => "date"), "status" => array("label" => "Message status", "matches" => array("approved" => "message.status = " . PHORUM_STATUS_APPROVED, "waiting for approval (on hold)" => "message.status = " . PHORUM_STATUS_HOLD, "disapproved by moderator" => "message.status = " . PHORUM_STATUS_HIDDEN, "hidden (on hold or disapproved)" => "message.status != " . PHORUM_STATUS_APPROVED)), "messagetype" => array("label" => "Message type", "matches" => array("thread starting messages" => "message.parent_id = 0", "reply messages" => "message.parent_id != 0")), "forum" => array("label" => "Forum", "matches" => $forum_matches), "author" => array("label" => "Author name", "matches" => array("is" => "message.author = QUERY", "is not" => "message.author != QUERY", "contains" => "message.author = *QUERY*", "does not contain" => "message.author != *QUERY*", "starts with" => "message.author = QUERY*", "does not start with" => "message.author != QUERY*", "ends with" => "message.author = *QUERY", "does not end with" => "message.author != QUERY*"), "queryfield" => "string"), "username" => array("label" => "Author username", "matches" => array("is" => "user.username = QUERY", "is not" => "user.username != QUERY", "contains" => "user.username = *QUERY*", "does not contain" => "user.username != *QUERY*", "starts with" => "user.username = QUERY*", "does not start with" => "user.username != QUERY*", "ends with" => "user.username = *QUERY", "does not end with" => "user.username != *QUERY"), "queryfield" => "string"), "user_id" => array("label" => "Author user id", "matches" => array("is" => "message.user_id = QUERY", "is not" => "message.user_id != QUERY"), "queryfield" => "string"), "authortype" => array("label" => "Author type", "matches" => array("registered user" => "message.user_id != 0", "anonymous user" => "message.user_id = 0", "moderator" => "message.moderator_post = 1", "administrator" => "user.admin = 1", "active user" => "user.active = " . PHORUM_USER_ACTIVE, "deactivated user" => "user.active = " . PHORUM_USER_INACTIVE)), "ipaddress" => array("label" => "Author IP/hostname", "matches" => array("is" => "message.ip = QUERY", "is not" => "message.ip != QUERY", "starts with" => "message.ip = QUERY*", "does not start with" => "message.ip != QUERY*", "ends with" => "message.ip = *QUERY", "does not end with" => "message.ip != *QUERY"), "queryfield" => "string"), "threadstate" => array("label" => "Thread status", "matches" => array("open for posting" => "thread.closed = 0", "closed for posting" => "thread.closed = 1")), "threadlastpost" => array("label" => "Thread last post", "matches" => array("posted on or before" => "function:prepare_filter_date", "posted before" => "function:prepare_filter_date", "posted after" => "function:prepare_filter_date", "posted on or after" => "function:prepare_filter_date"), "prepare_filter_date" => "thread.modifystamp", "queryfield" => "date")); // ---------------------------------------------------------------------- // Handle a posted form // ---------------------------------------------------------------------- $messages = null; // selected messages (based on a filter) $filters = array(); // active filters $filtermode = "and"; // active filter mode (and / or) $read_url_template = phorum_api_url(PHORUM_FOREIGN_READ_URL, '%forum_id%', '%thread_id%', '%message_id%'); // If there are messages to delete in the post data, then delete them // from the database. $delete_count = 0; if (isset($_POST["deletemessage"]) && is_array($_POST["deletemessage"])) { $msgids = array_keys($_POST["deletemessage"]); $msgs = $PHORUM['DB']->get_message($msgids, "message_id", true); $deleted_messages = array(); foreach ($msgs as $msg) { // if the message was already deleted, skip it if (isset($delete_messages[$msg["message_id"]])) { continue; } $PHORUM["forum_id"] = $msg["forum_id"]; $delmode = $msg["parent_id"] == 0 ? PHORUM_DELETE_TREE : PHORUM_DELETE_MESSAGE; // A hook to allow modules to implement extra or different
/** * This function implements the RSS output adapter for the Feed API. * * @param array $messages * An array of messages to include in the feed. * * @param array $forums * An array of related forums. * * @param string $url * The URL that points to the feed's target. * * @param string $title * The title to use for the feed. * * @param string $description * The description to use for the feed. * * @param bool $replies * Whether or not this is a feed that includes reply messages. * If not, then it will only contain thread starter messages. * * @return array * An array containing two elements: * - The generated feed data (RSS XML). * - The Content-Type header to use for the feed. */ function phorum_api_feed_rss($messages, $forums, $url, $title, $description, $replies) { global $PHORUM; $hcharset = $PHORUM['DATA']['HCHARSET']; $url = htmlspecialchars($url, ENT_COMPAT, $hcharset); $title = htmlspecialchars($title, ENT_COMPAT, $hcharset); $description = htmlspecialchars($description, ENT_COMPAT, $hcharset); $builddate = htmlspecialchars(date('r'), ENT_COMPAT, $hcharset); $generator = htmlspecialchars('Phorum ' . PHORUM, ENT_COMPAT, $hcharset); $buffer = "<?xml version=\"1.0\" encoding=\"{$PHORUM['DATA']['CHARSET']}\"?>\n"; $buffer .= "<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n"; $buffer .= " <channel>\n"; $buffer .= " <title>{$title}</title>\n"; $buffer .= " <description>{$description}</description>\n"; $buffer .= " <link>{$url}</link>\n"; $buffer .= " <lastBuildDate>{$builddate}</lastBuildDate>\n"; $buffer .= " <generator>{$generator}</generator>\n"; // Lookup the plain text usernames for the authenticated authors. $users = $messages['users']; unset($messages['users']); unset($users[0]); $users = phorum_api_user_get_display_name($users, '', PHORUM_FLAG_PLAINTEXT); foreach ($messages as $message) { // Include information about the number of replies to threads. $title = strip_tags($message['subject']); if (!$replies) { $lang = $PHORUM['DATA']['LANG']; switch ($message['thread_count']) { case 1: $title .= " ({$lang['noreplies']})"; break; case 2: $title .= " (1 {$lang['reply']})"; break; default: $replies = $message['thread_count'] - 1; $title .= " ({$replies} {$lang['replies']})"; } $date = date('r', $message['modifystamp']); } else { $date = date('r', $message['datestamp']); } // Generate the URL for reading the message. $url = htmlspecialchars(phorum_api_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message["message_id"])); // The forum in which the message is stored is used as the category. $category = htmlspecialchars($forums[$message['forum_id']]['name'], ENT_COMPAT, $hcharset); // Format the author. $author = !empty($users[$message['user_id']]) ? $users[$message['user_id']] : $message['author']; $author = htmlspecialchars($author, ENT_COMPAT, $hcharset); // Strip unprintable characters from the message body. $body = strtr($message['body'], "\v\f" . "", "????????????????????????????"); $buffer .= " <item>\n"; $buffer .= " <guid>{$url}</guid>\n"; $buffer .= " <title>{$title}</title>\n"; $buffer .= " <link>{$url}</link>\n"; $buffer .= " <description><![CDATA[{$body}]]></description>\n"; $buffer .= " <dc:creator>{$author}</dc:creator>\n"; $buffer .= " <category>{$category}</category>\n"; $buffer .= " <pubDate>{$date}</pubDate>\n"; $buffer .= " </item>\n"; } $buffer .= " </channel>\n"; $buffer .= "</rss>\n"; return array($buffer, 'application/xml'); }
// the mark all read URL. phorum_api_redirect(PHORUM_INDEX_URL, (int) $PHORUM['forum_id']); } // Somehow we arrived at a forum instead of a folder. // Redirect the user to the message list for that forum. if (!empty($PHORUM["forum_id"]) && $PHORUM["folder_flag"] == 0) { phorum_api_redirect(PHORUM_LIST_URL); } // Setup the "mark all read" URL. if ($PHORUM["DATA"]["LOGGEDIN"]) { $PHORUM["DATA"]["URL"]["MARKVROOTREAD"] = phorum_api_url(PHORUM_INDEX_URL, $PHORUM["forum_id"], "markallread"); } // Setup the syndication feed URLs for this folder. $PHORUM['DATA']['FEEDS'] = array(); if (!empty($PHORUM['use_rss'])) { // Add the feed for new threads. $PHORUM['DATA']['FEEDS'][] = array('URL' => phorum_api_url(PHORUM_FEED_URL, $PHORUM['vroot'], 'type=' . $PHORUM['default_feed']), 'TITLE' => $PHORUM['DATA']['FEED'] . ' (' . strtolower($PHORUM['DATA']['LANG']['Threads']) . ')'); // Add the feed for new threads and their replies. $PHORUM['DATA']['FEEDS'][] = array('URL' => phorum_api_url(PHORUM_FEED_URL, $PHORUM['vroot'], 'replies=1', 'type=' . $PHORUM['default_feed']), 'TITLE' => $PHORUM['DATA']['FEED'] . ' (' . strtolower($PHORUM['DATA']['LANG']['Threads'] . ' + ' . $PHORUM['DATA']['LANG']['replies']) . ')'); } // From here on we differentiate the code per index style that we use. switch ($PHORUM['index_style']) { case PHORUM_INDEX_FLAT: require_once './include/index/flat.php'; break; case PHORUM_INDEX_DIRECTORY: default: // Should not happen require_once './include/index/directory.php'; break; }
$userdata["active"] = PHORUM_USER_PENDING_EMAIL; } elseif ($user["active"] == PHORUM_USER_PENDING_MOD) { $userdata["active"] = PHORUM_USER_ACTIVE; // send reg approved message $maildata["mailsubject"] = $PHORUM["DATA"]["LANG"]["RegApprovedSubject"]; $maildata["mailmessage"] = wordwrap($PHORUM["DATA"]["LANG"]["RegApprovedEmailBody"], 72); phorum_api_mail(array($user["email"]), $maildata); } } $userdata["user_id"] = $user_id; // only save it if something was changed if (isset($userdata['active'])) { phorum_api_user_save($userdata); } } } if (empty($users)) { $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["NoUnapprovedUsers"]; } else { // get a fresh list to update any changes $users = $PHORUM['DB']->user_get_unapproved(); // XSS prevention. foreach ($users as $id => $user) { $users[$id]["username"] = htmlspecialchars($user["username"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $users[$id]["email"] = htmlspecialchars($user["email"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); } $PHORUM["DATA"]["USERS"] = $users; $PHORUM["DATA"]["ACTION"] = phorum_api_url(PHORUM_CONTROLCENTER_ACTION_URL); $PHORUM["DATA"]["FORUM_ID"] = $PHORUM["forum_id"]; $template = "cc_users"; }
/** * This function can be used to build a tree structure for the available * folders and forums. * * @param mixed $vroot * The vroot for which to build the forums tree (0 (zero) to * use the main root folder) or NULL to use the current (v)root. * * @param int $flags * If the {@link PHORUM_FLAG_INCLUDE_INACTIVE} flag is set, then * inactive forums and folders will be included in the tree. * If the {@link PHORUM_FLAG_INCLUDE_EMPTY_FOLDERS} flag is set, then * empty folders will be included in the tree. By default, empty folders * will be taken out of the tree. * * @return array * An array containing arrays that describe nodes in the tree. * The nodes are in the order in which they would appear in an expanded * tree, moving from top to bottom. An "indent" field is added to each * node array to tell at what indention level the node lives. */ function phorum_api_forums_tree($vroot = NULL, $flags = 0) { global $PHORUM; if ($vroot === NULL) { $vroot = isset($PHORUM['vroot']) ? $PHORUM['vroot'] : 0; } else { settype($vroot, 'int'); } // Get the information for the root. $root = phorum_api_forums_by_forum_id($vroot, $flags); if (!$root) { trigger_error("phorum_api_forums_tree(): vroot {$vroot} does not exist", E_USER_ERROR); return NULL; } if ($root['vroot'] != $root['forum_id']) { trigger_error("phorum_api_forums_tree(): vroot {$vroot} is not a vroot folder", E_USER_ERROR); return NULL; } // Temporarily witch to the vroot for which we are building a tree. $orig_vroot = isset($PHORUM['vroot']) ? $PHORUM['vroot'] : 0; $PHORUM['vroot'] = $vroot; // Check what forums the current user can read in that vroot. $allowed_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, PHORUM_ACCESS_LIST); // Load the data for those forums. $forums = phorum_api_forums_by_forum_id($allowed_forums, $flags); // Sort the forums in a tree structure. // First pass: build a parent / child relationship structure. $tmp_forums = array(); foreach ($forums as $forum_id => $forum) { $tmp_forums[$forum_id]['forum_id'] = $forum_id; $tmp_forums[$forum_id]['parent'] = $forum['parent_id']; if (empty($forums[$forum["parent_id"]]["childcount"])) { $tmp_forums[$forum["parent_id"]]["children"] = array($forum_id); $forums[$forum["parent_id"]]["childcount"] = 1; } else { $tmp_forums[$forum["parent_id"]]["children"][] = $forum_id; $forums[$forum["parent_id"]]["childcount"]++; } } // Second pass: sort the folders and forums in their tree order. $order = array(); $stack = array(); $seen = array(); $curr_id = $vroot; while (count($tmp_forums)) { // Add the current element to the tree order array. Do not add it // in case we've already seen it (we move down and back up the tree // during processing, so we could see an element twice // while doing that). if ($curr_id != 0 && empty($seen[$curr_id])) { $order[$curr_id] = $forums[$curr_id]; $seen[$curr_id] = true; } // Push the current element on the tree walking stack // to move down the tree. array_push($stack, $curr_id); // Get the current element's data. $data = $tmp_forums[$curr_id]; // If there are no children (anymore), then move back up the the tree. if (empty($data["children"])) { unset($tmp_forums[$curr_id]); array_pop($stack); $curr_id = array_pop($stack); } else { $curr_id = array_shift($tmp_forums[$curr_id]["children"]); } if (!is_numeric($curr_id)) { break; } } $tree = array(); foreach ($order as $forum) { if ($forum["folder_flag"]) { // Skip empty folders, if we didn't request them if (empty($forums[$forum['forum_id']]['childcount']) && !($flags & PHORUM_FLAG_INCLUDE_EMPTY_FOLDERS)) { continue; } $url = phorum_api_url(PHORUM_INDEX_URL, $forum["forum_id"]); } else { $url = phorum_api_url(PHORUM_LIST_URL, $forum["forum_id"]); } // Add the indent level for the node. $indent = count($forum["forum_path"]) - 2; if ($indent < 0) { $indent = 0; } $forum['indent'] = $indent; // Some entries that are added to the forum array to be backward // compatible with the deprecated phorum_build_forum_list() function. $forum['stripped_name'] = strip_tags($forum['name']); $forum['indent_spaces'] = str_repeat(' ', $indent); $forum['url'] = $url; $forum['path'] = $forum['forum_path']; $tree[$forum["forum_id"]] = $forum; } return $tree; }
<?php if (!defined("PHORUM")) { return; } phorum_build_common_urls(); $PHORUM['DATA']['HEADING'] = 'Ajax layer example page'; $PHORUM['DATA']['HTML_DESCRIPTION'] = 'This page demonstrates some features of ' . 'the Phorum Ajax layer.'; include phorum_api_template('header'); $clientjs = phorum_api_url(PHORUM_AJAX_URL, 'client'); ?> <script type="text/javascript"> var viewer; function helloworld() { Phorum.Ajax.call({ "call" : "helloworld", "cache_id" : "helloworld", "onSuccess" : function (data) { viewer.innerHTML = 'Server returned: ' + data; }, "onFailure" : function (error) { alert("Error: " + error); } }); } function checkpm() { var id = document.getElementById('checkpm_user_id').value; Phorum.Ajax.call({
foreach ($_POST["delete"] as $file_id) { if (phorum_api_file_check_delete_access($file_id)) { phorum_api_file_delete($file_id); } } } // ---------------------------------------------------------------------- // Display the files for the current user. // ---------------------------------------------------------------------- $files = $PHORUM['DB']->get_user_file_list($PHORUM["user"]["user_id"]); $total_size = 0; foreach ($files as $key => $file) { $files[$key]["filesize"] = phorum_api_format_filesize($file["filesize"]); $files[$key]["raw_dateadded"] = $file["add_datetime"]; $files[$key]["dateadded"] = phorum_api_format_date($PHORUM["short_date_time"], $file["add_datetime"]); $files[$key]["url"] = phorum_api_url(PHORUM_FILE_URL, "file={$key}", "filename=" . urlencode($file['filename'])); $total_size += $file["filesize"]; } $template = "cc_files"; if ($PHORUM["max_file_size"]) { $PHORUM["DATA"]["FILE_SIZE_LIMIT"] = $PHORUM["DATA"]["LANG"]["FileSizeLimits"] . ' ' . phorum_api_format_filesize($PHORUM["max_file_size"] * 1024); } if ($PHORUM["file_types"]) { $PHORUM["DATA"]["FILE_TYPE_LIMIT"] = $PHORUM["DATA"]["LANG"]["FileTypeLimits"]; } if ($PHORUM["file_space_quota"]) { $PHORUM["DATA"]["FILE_QUOTA_LIMIT"] = $PHORUM["DATA"]["LANG"]["FileQuotaLimits"] . ' ' . phorum_api_format_filesize($PHORUM["file_space_quota"] * 1024); } foreach ($files as $id => $file) { $files[$id]['filename'] = htmlspecialchars($file['filename'], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); }
} $this_version['colored_body'] = phorum_api_format_censor($this_version['colored_body']); // only happens in first loop if ($prev_subject == -1) { $prev_subject = $message["subject"]; } // subject diffs if (isset($diff_info['diff_subject']) && !empty($diff_info['diff_subject'])) { $colored_subject = phorum_api_diff_unpatch_color($prev_subject, $diff_info['diff_subject']); $prev_subject = phorum_api_diff_unpatch($prev_subject, $diff_info['diff_subject']); $colored_subject = htmlspecialchars($colored_subject, ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $colored_subject = str_replace(array("[phorum addition]", "[phorum removal]", "[/phorum addition]", "[/phorum removal]"), array("<span class=\"addition\">", "<span class=\"removal\">", "</span>", "</span>"), $colored_subject); $colored_subject = nl2br($colored_subject); $this_version["colored_subject"] = $colored_subject; } elseif (!isset($diff_info['diff_subject'])) { $this_version['colored_subject'] = nl2br($prev_subject); } else { $this_version["colored_subject"] = nl2br($prev_subject); } $this_version['colored_subject'] = phorum_api_format_censor($this_version['colored_subject']); // no nl2br for subject //$this_version["colored_subject"] = nl2br($this_version["colored_subject"]); $message_hist[] = $this_version; } $PHORUM["DATA"]["HEADING"] = $PHORUM["DATA"]["LANG"]["ChangeHistory"]; // unset default description $PHORUM["DATA"]["DESCRIPTION"] = ""; $PHORUM["DATA"]["MESSAGE"]["subject"] = htmlspecialchars($message["subject"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $PHORUM["DATA"]["MESSAGE"]["URL"]["READ"] = phorum_api_url(PHORUM_READ_URL, $message["thread"], $message_id); $PHORUM["DATA"]["CHANGES"] = $message_hist; phorum_api_output("changes");
* } * $PHORUM['DB']->update_settings(array( * "mod_foo" => $PHORUM["mod_foo"] * )); * * return $msgthd_ids; * } * </hookcode> */ if (isset($PHORUM["hooks"]["delete"])) { phorum_api_hook("delete", array($msgthd_id)); } $PHORUM['DATA']['OKMSG'] = "1 " . $PHORUM["DATA"]['LANG']['MsgDeletedOk']; if (isset($PHORUM['args']['old_forum']) && !empty($PHORUM['args']['old_forum'])) { $PHORUM['forum_id'] = (int) $PHORUM['args']['old_forum']; } // Determine where to redirect to after the delete operation. // // When we're coming from the message moderation interface in // the control center, then redirect back to there. if (isset($PHORUM['args']["prepost"])) { $PHORUM['DATA']["URL"]["REDIRECT"] = phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_UNAPPROVED); } else { // If we did not delete the thread starter, then redirect // back to the parent of the deleted message. if ($message['parent_id']) { $PHORUM['DATA']['URL']['REDIRECT'] = phorum_api_url(PHORUM_READ_URL, $message['thread'], $message['parent_id']); } else { $PHORUM['DATA']['URL']['REDIRECT'] = $PHORUM['DATA']['URL']['LIST']; } }
phorum_api_mail($mail_users, $mail_data); $PHORUM["DATA"]["URL"]["REDIRECT"] = phorum_api_url(PHORUM_FOREIGN_READ_URL, $message["forum_id"], $message["thread"], $message['message_id']); $PHORUM["DATA"]["BACKMSG"] = $PHORUM["DATA"]["LANG"]["BackToThread"]; $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["ReportPostSuccess"]; $template = "message"; $report = true; } } else { $PHORUM["DATA"]["ReportPostMessage"] = $PHORUM["DATA"]["LANG"]['ReportPostNotAllowed']; } } // format message list($message) = phorum_api_format_messages(array($message)); $PHORUM["DATA"]["PostSubject"] = $message["subject"]; $PHORUM["DATA"]["PostAuthor"] = $message["author"]; $PHORUM["DATA"]["PostBody"] = $message["body"]; $PHORUM["DATA"]["raw_PostDate"] = $message["datestamp"]; $PHORUM["DATA"]["PostDate"] = phorum_api_format_date($PHORUM["short_date_time"], $message["datestamp"]); $PHORUM["DATA"]["ReportURL"] = phorum_api_url(PHORUM_REPORT_URL, $message_id); // if the report was not successfully sent, keep whatever explanation they gave already if (isset($_POST["explanation"]) && !$report) { $PHORUM["DATA"]["explanation"] = $_POST["explanation"]; } else { $PHORUM["DATA"]["explanation"] = ""; } } else { $PHORUM["DATA"]["ERROR"] = $PHORUM['DATA']['LANG']['MessageNotFound']; $template = 'message'; } $PHORUM['DATA']['BREADCRUMBS'][] = array('URL' => '', 'TEXT' => $PHORUM['DATA']['LANG']['Report'], 'TYPE' => 'report'); phorum_api_output($template);
* $pm_message = preg_replace( * "%message_subject%", * $data[0]["subject"], * $PHORUM["DATA"]["LANG"]["mod_foo"]["MessageApprovedBody"] * ); * $PHORUM['DB']->pm_send( * $PHORUM["DATA"]["LANG"]["mod_foo"]["MessageApprovedSubject"], * $pm_message, * $data[0]["user_id"] * ); * * return $data; * * } * </hookcode> */ if (isset($PHORUM["hooks"]["after_approve"])) { phorum_api_hook("after_approve", array($old_message, PHORUM_APPROVE_MESSAGE)); } if ($old_message['status'] != PHORUM_STATUS_HIDDEN) { phorum_api_mail_message_notify($old_message); } if (isset($PHORUM['args']['old_forum']) && is_numeric($PHORUM['args']['old_forum'])) { $PHORUM['forum_id'] = (int) $PHORUM['args']['old_forum']; } if (isset($PHORUM['args']["prepost"])) { $PHORUM['DATA']["URL"]["REDIRECT"] = phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_UNAPPROVED); } else { $PHORUM['DATA']["URL"]["REDIRECT"] = $PHORUM["DATA"]["URL"]["LIST"]; } $invalidate_message_cache[] = array("message_id" => $msgthd_id, "forum_id" => $PHORUM["forum_id"]);
/** * This function handles preparing message data for use in the templates. * * @param array $messages * An array of messages that have to be formatted. * Each message is an array on its own, containing the message data. * * @param array $author_specs * By default, the formatting function will create author info * data, based on the fields "user_id", "author" and "email". * This will create $messages["URL"]["PROFILE"] if needed (either pointing * to a user profile for registered users or the email address of * anonymous users that left an email address in the forum) and will * do formatting on the "author" field. * * By providing extra $author_specs, this formatting can be done on * more author fields. This argument should be an array, containing * arrays with five fields: * * - the name of the field that contains a user_id * - the name of the field that contains the name of the author * - the name of the field that contains the email address * (can be NULL if none available) * - the name of the field to store the author name in * - the name of the URL field to store the profile/email link in * * For the default author field handling like described above, * this array would be: * * array("user_id", "author", "email", "author", "PROFILE"); * * @return data - The formatted messages. */ function phorum_api_format_messages($messages, $author_specs = NULL) { global $PHORUM; // Prepare author specs. if ($author_specs === NULL) { $author_specs = array(); } $author_specs[] = array("user_id", "author", "email", "author", "PROFILE"); // Prepare censoring replacements. list($censor_search, $censor_replace) = phorum_api_format_censor_compile(); // Prepare the profile URL template. This is used to prevent // having to call the phorum_api_url() function over and over again. $profile_url_template = phorum_api_url(PHORUM_PROFILE_URL, '%spec_data%'); // A special <br> tag to keep track of breaks that are added by phorum. $phorum_br = '<phorum break>'; // Apply Phorum's formatting rules to all messages. foreach ($messages as $id => $message) { // Normally, the message_id must be set, since we should be handling // message data. It might not be set however, because sometimes // the message formatting is called using some fake message data // for formatting something else than a message. if (!isset($message['message_id'])) { $messages[$id]['message_id'] = $message['message_id'] = $id; } // ----------------------------------------------------------------- // Message body // ----------------------------------------------------------------- if (isset($message['body']) && $message['body'] != '') { $body = $message["body"]; // Convert legacy <...> URLs into bare URLs. $body = preg_replace("/<(\n (?:http|https|ftp):\\/\\/\n [a-z0-9;\\/\\?:@=\\&\$\\-_\\.\\+!*'\\(\\),~%]+?\n )>/xi", "\$1", $body); // Escape special HTML characters. $escaped_body = htmlspecialchars($body, ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); // When there is a charset mismatch between the database // and the language file, then bodies might get crippled // because of the htmlspecialchars() call. Here we try to // correct this issue. It's not perfect, but we do what // we can ... if ($escaped_body == '') { if (function_exists("iconv")) { // We are gonna guess and see if we get lucky. $escaped_body = iconv("ISO-8859-1", $PHORUM["DATA"]["HCHARSET"], $body); } else { // We let htmlspecialchars use its defaults. $escaped_body = htmlspecialchars($body); } } $body = $escaped_body; // Replace newlines with $phorum_br temporarily. // This way the mods know what breaks were added by // Phorum and what breaks by the user. $body = str_replace("\n", "{$phorum_br}\n", $body); // Censor bad words in the body. if ($censor_search !== NULL) { $body = preg_replace($censor_search, $censor_replace, $body); } $messages[$id]['body'] = $body; } // ----------------------------------------------------------------- // Message subject // ----------------------------------------------------------------- // Censor bad words in the subject. if (isset($message['subject']) && $censor_search !== NULL) { $messages[$id]['subject'] = preg_replace($censor_search, $censor_replace, $message['subject']); } // Escape special HTML characters. if (isset($message['subject'])) { $messages[$id]['subject'] = htmlspecialchars($messages[$id]['subject'], ENT_COMPAT, $PHORUM['DATA']['HCHARSET']); } // ----------------------------------------------------------------- // Message author // ----------------------------------------------------------------- // Escape special HTML characters in the email address. if (isset($message['email'])) { $messages[$id]['email'] = htmlspecialchars($message['email'], ENT_COMPAT, $PHORUM['DATA']['HCHARSET']); } // Do author formatting for all provided author fields. foreach ($author_specs as $spec) { // Use "Anonymous user" as the author name if there's no author // name available for some reason. if (!isset($message[$spec[1]]) || $message[$spec[1]] == '') { $messages[$id][$spec[3]] = $PHORUM["DATA"]["LANG"]["AnonymousUser"]; } elseif (!empty($message[$spec[0]])) { $url = str_replace('%spec_data%', $message[$spec[0]], $profile_url_template); $messages[$id]["URL"][$spec[4]] = $url; $messages[$id][$spec[3]] = empty($PHORUM["custom_display_name"]) ? htmlspecialchars($message[$spec[1]], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]) : $message[$spec[1]]; } elseif ($spec[2] !== NULL && !empty($message[$spec[2]]) && (empty($PHORUM['hide_email_addr']) || !empty($PHORUM["user"]["admin"]) || phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES) && PHORUM_MOD_EMAIL_VIEW || phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_USERS) && PHORUM_MOD_EMAIL_VIEW)) { $messages[$id][$spec[3]] = htmlspecialchars($message[$spec[1]], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); $email_url = phorum_api_format_html_encode("mailto:" . $message[$spec[2]]); $messages[$id]["URL"]["PROFILE"] = $email_url; } else { $messages[$id][$spec[3]] = htmlspecialchars($message[$spec[1]], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]); } if ($censor_search !== NULL) { $messages[$id][$spec[3]] = preg_replace($censor_search, $censor_replace, $messages[$id][$spec[3]]); } } } // A hook for module writers to apply custom message formatting. if (isset($PHORUM["hooks"]["format"])) { $messages = phorum_api_hook("format", $messages); } // A hook for module writers for doing post formatting fixups. if (isset($PHORUM["hooks"]["format_fixup"])) { $messages = phorum_api_hook("format_fixup", $messages); } // Clean up after the mods are done. foreach ($messages as $id => $message) { // Clean up line breaks inside pre and xmp tags. These tags // take care of showing newlines as breaks themselves. if (isset($message['body']) && $message['body'] != '') { foreach (array('pre', 'goep', 'xmp') as $tagname) { if (preg_match_all("/(<{$tagname}.*?>).+?(<\\/{$tagname}>)/si", $message['body'], $matches)) { foreach ($matches[0] as $match) { $stripped = str_replace($phorum_br, '', $match); $message['body'] = str_replace($match, $stripped, $message['body']); } } } // Remove line break after div, quote and code tags. These // tags have their own line break. Without this, there would // be to many white lines. $message['body'] = preg_replace("/\\s*(<\\/?(?:div|xmp|blockquote|pre)[^>]*>)\\s*\\Q{$phorum_br}\\E/", '$1', $message['body']); // Normalize the Phorum line breaks that are left. $messages[$id]['body'] = str_replace($phorum_br, "<br />", $message['body']); } } return $messages; }
* * return $user; * } * </hookcode> */ if ($hook_args && isset($PHORUM['hooks']['password_reset'])) { phorum_api_hook("password_reset", $hook_args); } } // ---------------------------------------------------------------------------- // Build template data and output the page // ---------------------------------------------------------------------------- $redir = htmlspecialchars($redir, ENT_COMPAT, $PHORUM['DATA']['HCHARSET']); // Fill the breadcrumbs-info. $PHORUM['DATA']['BREADCRUMBS'][] = array('URL' => '', 'TEXT' => $PHORUM['DATA']['LANG']['LogIn'], 'TYPE' => 'login'); // Fill the page heading info. $PHORUM['DATA']['HEADING'] = $heading; $PHORUM['DATA']['HTML_DESCRIPTION'] = ''; $PHORUM['DATA']['DESCRIPTION'] = ''; // Setup template data. $PHORUM['DATA']['LOGIN']['redir'] = $redir; $PHORUM['DATA']['URL']['REGISTER'] = phorum_api_url(PHORUM_REGISTER_URL); $PHORUM['DATA']['URL']['ACTION'] = phorum_api_url(PHORUM_LOGIN_ACTION_URL); $PHORUM['DATA']['LOGIN']['forum_id'] = (int) $PHORUM['forum_id']; $PHORUM['DATA']['LOGIN']['username'] = !empty($_POST['username']) ? htmlspecialchars($_POST['username'], ENT_COMPAT, $PHORUM['DATA']['HCHARSET']) : ''; $PHORUM['DATA']['ERROR'] = $error; $PHORUM['DATA']['OKMSG'] = $okmsg; $PHORUM['DATA']['POST_VARS'] .= "<input type=\"hidden\" name=\"redir\" value=\"{$redir}\" />\n"; $PHORUM['DATA']['FOCUS_TO_ID'] = $focus; // Display the login page. phorum_api_output($template);
if (!defined("PHORUM")) { return; } require_once PHORUM_PATH . '/include/api/file.php'; // Clean up unlinked attachments from the database. foreach ($message["attachments"] as $info) { if (!$info["linked"]) { if (phorum_api_file_check_delete_access($info["file_id"])) { phorum_api_file_delete($info["file_id"]); } } } $PHORUM["posting_template"] = "message"; $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["AttachCancel"]; $PHORUM["DATA"]["BACKMSG"] = $PHORUM["DATA"]["LANG"]["BackToList"]; $PHORUM["DATA"]["URL"]["REDIRECT"] = phorum_api_url(PHORUM_LIST_URL); $error_flag = true; /* * [hook] * posting_action_cancel_post * * [description] * Allow modules to perform custom action whenever the user cancels editing * of his post. This can be used to e.g. redirect the user immediately back * to the edited post where he came from. * * [category] * Message handling * * [when] * In <filename>action_cancel.php</filename> at the end of the file when
<td valign="left" style="white-space:nowrap; font-size: 10px">' . phorum_api_format_date($PHORUM['short_date'], $loginfo["datestamp"]) . '</td> <td valign="left" style="white-space:nowrap; font-size: 10px">' . phorum_api_format_date($PHORUM['short_time'], $loginfo["datestamp"]) . '</td> <td valign="middle" style="white-space:nowrap; font-size: 10px"> <a title="Extend filter using this source" href="' . $filter_base . '&source=' . urlencode($loginfo["source"]) . '">' . htmlspecialchars($loginfo["source"]) . '</a> </td> <td valign="middle" style="font-size: 10px"> <a title="Extend filter using this category" href="' . $filter_base . '&show_category[' . urlencode($loginfo["category"]) . ']=1' . '">' . $cat . '</a> </td> <td valign="middle" style="font-size: 12px">' . htmlspecialchars($message) . '</td> <td valign="middle"> <a href="#" onclick="return toggle_detail_visibility(' . $loginfo["log_id"] . ')"><small>details</small></a> </td> </tr> <tr> <td style="border-bottom: 1px solid #888"></td> <td colspan="6" style="border-bottom: 1px solid #888"> <div style="display:none;overflow:auto;border:1px solid #aaa; padding:10px; margin-bottom: 10px" id="detail_' . $loginfo["log_id"] . '"> <b>User info:</b><br/><br/>' . ($loginfo["user_id"] ? "User ID = <a title=\"Extend filter using this User ID\" href=\"" . htmlspecialchars("{$filter_base}&user_id=" . urlencode($loginfo["user_id"])) . "\">{$loginfo["user_id"]}</a>" . ($loginfo["username"] !== NULL ? ', username = '******'') . ' [ <a target="_new" href="' . phorum_api_url(PHORUM_PROFILE_URL, $loginfo["user_id"]) . '">view user\'s profile</a> ]' : "Anonymous user") . '<br/>' . 'User IP address = <a title="Extend filter using this IP address" href="' . htmlspecialchars($filter_base . '&ip=' . urlencode($loginfo["ip"])) . '">' . $loginfo["ip"] . '</a>' . ($loginfo["hostname"] !== NULL ? ', hostname = ' . htmlspecialchars($loginfo["hostname"]) : '') . '<br/>' . ($message_url !== NULL ? '<br/><b>Related message:</b><br/> Forum = ' . $loginfo["forum"] . '<br/> Message ID = ' . $loginfo["message_id"] . '<br/> [ <a target="_new" href="' . htmlspecialchars($message_url) . '">view message</a> ]<br/>' : '') . ($details !== NULL ? '<br/><b>Additional details:</b><br/><br/>' . nl2br(htmlspecialchars($details)) . '<br/>' : '') . '<br/> </div> </td> </tr>'; } ?> </tbody> </table>
/** * Returns the Phorum base URL. * * @return string * The base URL. */ function phorum_api_url_base() { return phorum_api_url(PHORUM_BASE_URL); }
} break; default: trigger_error("Illegal message subscription type: " . htmlspecialchars($message["subscription"])); break; } if ($subscribe_type === NULL) { phorum_api_user_unsubscribe($message["user_id"], $message["thread"]); } else { phorum_api_user_subscribe($message["user_id"], $message["thread"], $PHORUM["forum_id"], $subscribe_type); } } $PHORUM["posting_template"] = "message"; $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["MsgModEdited"]; $PHORUM['DATA']["BACKMSG"] = $PHORUM['DATA']["LANG"]["BackToThread"]; $PHORUM["DATA"]["URL"]["REDIRECT"] = phorum_api_url(PHORUM_READ_URL, $message["thread"], $message["message_id"]); /* * [hook] * posting_action_edit_post * * [description] * Allow modules to perform custom action whenever the user edits his post. * This can be used to e.g. redirect the user immediately back to the edited * post where he came from. * * [category] * Message handling * * [when] * In <filename>action_edit.php</filename> at the end of the file when * everything has been done.
$_POST['moderation_email'] = isset($_POST['moderation_email']) && phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES, PHORUM_ACCESS_ANY) ? 1 : 0; // Remember this for the template. if (isset($PHORUM['DATA']['PROFILE']['email_temp_part'])) { $email_temp_part = $PHORUM['DATA']['PROFILE']['email_temp_part']; } // do we need to send a confirmation-mail? if (isset($PHORUM['DATA']['PROFILE']['email_temp_part']) && !empty($_POST['email_verify_code']) && $PHORUM['DATA']['PROFILE']['email_temp_part'] . "|" . $_POST['email_verify_code'] == $PHORUM['DATA']['PROFILE']['email_temp']) { $_POST['email'] = $PHORUM['DATA']['PROFILE']['email_temp_part']; $_POST['email_temp'] = ""; $email_temp_part = ""; } elseif ($PHORUM['registration_control'] && !empty($_POST['email']) && strtolower($_POST['email']) != strtolower($PHORUM["DATA"]["PROFILE"]['email'])) { // ... generate the confirmation-code ... // $conf_code = mt_rand(1000000, 9999999); $_POST['email_temp'] = $_POST['email'] . "|" . $conf_code; // ... send email ... // $maildata = array('mailmessage' => wordwrap($PHORUM['DATA']['LANG']['EmailVerifyBody'], 72), 'mailsubject' => $PHORUM['DATA']['LANG']['EmailVerifySubject'], 'uname' => $PHORUM['DATA']['PROFILE']['username'], 'username' => $PHORUM['DATA']['PROFILE']['username'], 'newmail' => $_POST['email'], 'mailcode' => $conf_code, 'cc_url' => phorum_api_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_MAIL)); phorum_api_mail($_POST['email'], $maildata); // Remember this for the template. $email_temp_part = $_POST['email']; unset($_POST['email']); } list($error, $okmsg) = phorum_controlcenter_user_save($panel); } } if (!empty($email_temp_part)) { $PHORUM['DATA']['PROFILE']['email_temp_part'] = $email_temp_part; } // TEMPLATETODO // flip this due to db vs. UI wording. if (!empty($PHORUM['DATA']['PROFILE']["hide_email"])) { $PHORUM["DATA"]["PROFILE"]["hide_email_checked"] = "";