Example #1
0
        // we should not redirect to the listpage for moderators.
        // Else a moderator can never read an unapproved message.
        if (isset($PHORUM["postingargs"]["as_include"])) {
            if ($PHORUM["DATA"]["MODERATOR"]) {
                $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["UnapprovedMessage"];
                return;
            }
        }
        // In other cases, redirect users that are replying to
        // unapproved messages to the message list.
        phorum_api_redirect(PHORUM_LIST_URL);
    }
    // closed topic, show a message
    if ($top_parent["closed"]) {
        $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["ThreadClosed"];
        $PHORUM["posting_template"] = "message";
        return;
    }
}
// Do permission checks for editing messages.
if ($mode == "edit") {
    // Check if the user is allowed to edit this post.
    $timelim = $PHORUM["user_edit_timelimit"];
    $useredit = $message["user_id"] == $PHORUM["user"]["user_id"] && phorum_api_user_check_access(PHORUM_USER_ALLOW_EDIT) && !empty($top_parent) && !$top_parent["closed"] && (!$timelim || $message["datestamp"] + $timelim * 60 >= time());
    // Moderators are allowed to edit messages.
    $moderatoredit = $PHORUM["DATA"]["MODERATOR"] && $message["forum_id"] == $PHORUM["forum_id"];
    if (!$useredit && !$moderatoredit) {
        $PHORUM["DATA"]["ERROR"] = $PHORUM["DATA"]["LANG"]["EditPostForbidden"];
        return;
    }
}
Example #2
0
/**
 * 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('&nbsp;', $indent);
        $forum['url'] = $url;
        $forum['path'] = $forum['forum_path'];
        $tree[$forum["forum_id"]] = $forum;
    }
    return $tree;
}
Example #3
0
}
// Loop over all the folders (flat view sections) that we will show and get
// their child forums and folders.
foreach ($folders as $folder_id => $dummy) {
    // These folders are level zero folders. To the child forums and folders,
    // level 1 will be assigned. The level value can be used in the template
    // to see where a new top level folder starts.
    $forums[$folder_id]['level'] = 0;
    // Retrieve the children for the current folder. For the (v)root folder,
    // we only retrieve the contained forums, since its folders will be shown
    // as separate sections in the flat index view instead.
    $children = phorum_api_forums_get(NULL, $folder_id, NULL, $PHORUM['vroot'], $PHORUM['vroot'] == $folder_id ? PHORUM_FLAG_FORUMS : 0);
    foreach ($children as $child_forum_id => $child_forum) {
        // If inaccessible forums should be hidden on the index, then check
        // if the current user has rights to access the current forum.
        if (!$child_forum['folder_flag'] && $PHORUM['hide_forums'] && !phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, $child_forum_id)) {
            continue;
        }
        // These are level one forums and folders.
        $child_forum['level'] = 1;
        // Remember the data.
        $forums[$child_forum_id] = $child_forum;
        // Add the forum or folder to the child list for the current folder.
        $folders[$folder_id][$child_forum_id] = $child_forum_id;
    }
}
// --------------------------------------------------------------------
// Setup the template data and display the template
// --------------------------------------------------------------------
// Format the data for the forums and folders that we gathered.
$forums = phorum_api_format_forums($forums, PHORUM_FLAG_ADD_UNREAD_INFO);
Example #4
0
function phorum_build_forum_list()
{
    $PHORUM = $GLOBALS["PHORUM"];
    // Check what forums the current user can read.
    $allowed_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, PHORUM_ACCESS_LIST);
    $forum_picker = array();
    // build forum drop down data
    require_once './include/api/forums.php';
    $forums = phorum_api_forums_get($allowed_forums);
    foreach ($forums as $forum) {
        $tmp_forums[$forum["forum_id"]]["forum_id"] = $forum["forum_id"];
        $tmp_forums[$forum["forum_id"]]["parent"] = $forum["parent_id"];
        $tmp_forums[$forum["parent_id"]]["children"][] = $forum["forum_id"];
        if (empty($forums[$forum["parent_id"]]["childcount"])) {
            $forums[$forum["parent_id"]]["childcount"] = 1;
        } else {
            $forums[$forum["parent_id"]]["childcount"]++;
        }
    }
    $order = array();
    $stack = array();
    $curr_id = $PHORUM['vroot'];
    while (count($tmp_forums)) {
        if (empty($seen[$curr_id])) {
            if ($curr_id != $PHORUM['vroot']) {
                if ($forums[$curr_id]["active"]) {
                    $order[$curr_id] = $forums[$curr_id];
                }
                $seen[$curr_id] = true;
            }
        }
        array_unshift($stack, $curr_id);
        $data = $tmp_forums[$curr_id];
        if (isset($data["children"])) {
            if (count($data["children"])) {
                $curr_id = array_shift($tmp_forums[$curr_id]["children"]);
            } else {
                unset($tmp_forums[$curr_id]);
                array_shift($stack);
                $curr_id = array_shift($stack);
            }
        } else {
            unset($tmp_forums[$curr_id]);
            array_shift($stack);
            $curr_id = array_shift($stack);
        }
        if (!is_numeric($curr_id)) {
            break;
        }
    }
    foreach ($order as $forum) {
        if ($forum["folder_flag"]) {
            // Skip empty folders.
            if (empty($forums[$forum['forum_id']]['childcount'])) {
                continue;
            }
            $url = phorum_get_url(PHORUM_INDEX_URL, $forum["forum_id"]);
        } else {
            $url = phorum_get_url(PHORUM_LIST_URL, $forum["forum_id"]);
        }
        $indent = count($forum["forum_path"]) - 2;
        if ($indent < 0) {
            $indent = 0;
        }
        $forum_picker[$forum["forum_id"]] = array("forum_id" => $forum["forum_id"], "parent_id" => $forum["parent_id"], "folder_flag" => $forum["folder_flag"], "name" => $forum["name"], "stripped_name" => strip_tags($forum["name"]), "indent" => $indent, "indent_spaces" => str_repeat("&nbsp;", $indent), "url" => $url, "path" => $forum["forum_path"]);
    }
    return $forum_picker;
}
Example #5
0
$forums = phorum_db_get_forums(0, $parent_id);
$PHORUM["DATA"]["FORUMS"] = array();
$forums_shown = false;
$new_checks = array();
if ($PHORUM["DATA"]["LOGGEDIN"] && !empty($forums)) {
    if ($PHORUM["show_new_on_index"] == 2) {
        $new_checks = phorum_db_newflag_check(array_keys($forums));
    } elseif ($PHORUM["show_new_on_index"] == 1) {
        $new_counts = phorum_db_newflag_count(array_keys($forums));
    }
}
foreach ($forums as $forum) {
    if ($forum["folder_flag"]) {
        $forum["URL"]["LIST"] = phorum_get_url(PHORUM_INDEX_URL, $forum["forum_id"]);
    } else {
        if ($PHORUM["hide_forums"] && !phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, $forum["forum_id"])) {
            continue;
        }
        $forum["url"] = phorum_get_url(PHORUM_LIST_URL, $forum["forum_id"]);
        // if there is only one forum in Phorum, redirect to it.
        if ($parent_id == 0 && count($forums) < 2) {
            phorum_redirect_by_url($forum['url']);
            exit;
        }
        if ($forum["message_count"] > 0) {
            $forum["raw_last_post"] = $forum["last_post_time"];
            $forum["last_post"] = phorum_date($PHORUM["long_date_time"], $forum["last_post_time"]);
        } else {
            $forum["last_post"] = "&nbsp;";
        }
        $forum["URL"]["LIST"] = phorum_get_url(PHORUM_LIST_URL, $forum["forum_id"]);
Example #6
0
} elseif (isset($PHORUM['args']['onlyunapproved']) && !empty($PHORUM["args"]['onlyunapproved']) && is_numeric($PHORUM["args"]['onlyunapproved'])) {
    $showwaiting = (int) $PHORUM['args']['onlyunapproved'];
} else {
    $showwaiting = phorum_api_user_get_setting('cc_messages_onlyunapproved');
}
if (empty($showwaiting)) {
    $showwaiting = 0;
}
$PHORUM['DATA']['SELECTED'] = $moddays;
$PHORUM['DATA']['SELECTED_2'] = $showwaiting ? true : false;
// Store current selection for the user.
phorum_api_user_save_settings(array("cc_messages_moddays" => $moddays, "cc_messages_onlyunapproved" => $showwaiting));
// some needed vars
$numunapproved = 0;
$oldforum = $PHORUM['forum_id'];
$mod_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES, PHORUM_ACCESS_LIST);
$gotforums = count($mod_forums) > 0;
if ($gotforums && isset($_POST['deleteids']) && count($_POST['deleteids'])) {
    //print_var($_POST['deleteids']);
    $deleteids = $_POST['deleteids'];
    foreach ($deleteids as $did => $did_var) {
        $deleteids[$did] = (int) $did_var;
    }
    $delete_messages = phorum_db_get_message(array_keys($deleteids), 'message_id', true);
    //print_var($delete_messages);
    foreach ($deleteids as $msgthd_id => $doit) {
        // A hook to allow modules to implement extra or different
        // delete functionality.
        if ($doit && isset($mod_forums[$delete_messages[$msgthd_id]['forum_id']])) {
            $delete_handled = 0;
            if (isset($PHORUM["hooks"]["before_delete"])) {
Example #7
0
 /**
  * Retrieve the closest neighbour thread. What "neighbour" is, depends on the
  * float to top setting. If float to top is enabled, then the
  * modifystamp is used for comparison (so the time at which the last
  * message was posted to a thread). Otherwise, the thread id is used
  * (so the time at which a thread was started).
  *
  * @param integer $key
  *     The key value of the message for which the neighbour must be returned.
  *     The key value is either the modifystamp (if float to top is enabled)
  *     or the thread id.
  *
  * @param string $direction
  *     Either "older" or "newer".
  *
  * @return integer
  *     The thread id for the requested neigbour thread or 0 (zero) if there
  *     is no neighbour available.
  */
 public function get_neighbour_thread($key, $direction)
 {
     global $PHORUM;
     settype($key, 'int');
     $keyfield = $PHORUM['float_to_top'] ? 'modifystamp' : 'datestamp';
     $compare = "";
     $orderdir = "";
     switch ($direction) {
         case 'newer':
             $compare = '>';
             $orderdir = 'ASC';
             break;
         case 'older':
             $compare = '<';
             $orderdir = 'DESC';
             break;
         default:
             trigger_error(__METHOD__ . ': Illegal direction ' . '"' . htmlspecialchars($direction) . '"', E_USER_ERROR);
     }
     // If the active Phorum user is not a moderator for the forum, then
     // the neighbour message should be approved.
     $approvedval = '';
     if (!phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES)) {
         $approvedval = 'AND status = ' . PHORUM_STATUS_APPROVED;
     }
     // Select the neighbour from the database.
     $thread = $this->interact(DB_RETURN_VALUE, "SELECT thread\n             FROM   {$this->message_table}\n             WHERE  forum_id = {$PHORUM['forum_id']} AND\n                    parent_id = 0\n                    {$approvedval} AND\n                    {$keyfield} {$compare} {$key}\n             ORDER  BY {$keyfield} {$orderdir}", NULL, 0, 1);
     return $thread;
 }
Example #8
0
// Retrieve the recent messages.
$recent = $PHORUM['DB']->get_recent_messages($count, 0, $forum_id, $thread_id, $threads_only);
unset($recent["users"]);
// Add newflag info to the messages.
if ($PHORUM["DATA"]["LOGGEDIN"]) {
    $type = $threads_only ? PHORUM_NEWFLAGS_BY_THREAD : PHORUM_NEWFLAGS_BY_MESSAGE;
    $recent = phorum_api_newflags_apply_to_messages($recent, $type);
}
// Format the messages.
$recent = phorum_api_format_messages($recent);
// Apply the list hook to the messages.
if (isset($PHORUM["hooks"]["list"])) {
    $recent = phorum_api_hook("list", $recent);
}
// Retrieve information about the forums for the active user.
$allowed_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, PHORUM_ACCESS_LIST);
$forums = $PHORUM['DB']->get_forums($allowed_forums);
foreach ($forums as $id => $forum) {
    $forums[$id]['url'] = phorum_get_url(PHORUM_LIST_URL, $forum['forum_id']);
}
// Add forum info to the messages and clean up data.
foreach ($recent as $id => $message) {
    $recent[$id]['foruminfo'] = array('id' => $message['forum_id'], 'name' => $forums[$message['forum_id']]['name'], 'url' => $forums[$message['forum_id']]['url']);
    // Strip fields that the caller should not see in the return data.
    unset($recent[$id]['email']);
    unset($recent[$id]['ip']);
    unset($recent[$id]['meta']);
    unset($recent[$id]['msgid']);
}
// Return the results.
phorum_ajax_return(array_values($recent));
Example #9
0
$PHORUM['DATA']['URL']['CC3'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_USERINFO);
$PHORUM['DATA']['URL']['CC4'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_SIGNATURE);
$PHORUM['DATA']['URL']['CC5'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_MAIL);
$PHORUM['DATA']['URL']['CC6'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_BOARD);
$PHORUM['DATA']['URL']['CC7'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_PASSWORD);
$PHORUM['DATA']['URL']['CC8'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_UNAPPROVED);
$PHORUM['DATA']['URL']['CC9'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_FILES);
$PHORUM['DATA']['URL']['CC10'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_USERS);
$PHORUM['DATA']['URL']['CC14'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_PRIVACY);
$PHORUM['DATA']['URL']['CC15'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_GROUP_MODERATION);
$PHORUM['DATA']['URL']['CC16'] = phorum_get_url(PHORUM_CONTROLCENTER_URL, "panel=" . PHORUM_CC_GROUP_MEMBERSHIP);
// Determine if the user files functionality is available.
$PHORUM["DATA"]["MYFILES"] = $PHORUM["file_uploads"] || $PHORUM["user"]["admin"];
// Determine if the user is a moderator.
$PHORUM["DATA"]["MESSAGE_MODERATOR"] = phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES, PHORUM_ACCESS_ANY);
$PHORUM["DATA"]["USER_MODERATOR"] = phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_USERS, PHORUM_ACCESS_ANY);
$PHORUM["DATA"]["GROUP_MODERATOR"] = phorum_api_user_check_group_access(PHORUM_USER_GROUP_MODERATOR, PHORUM_ACCESS_ANY);
$PHORUM["DATA"]["MODERATOR"] = $PHORUM["DATA"]["USER_MODERATOR"] + $PHORUM["DATA"]["MESSAGE_MODERATOR"] + $PHORUM["DATA"]["GROUP_MODERATOR"] > 0;
// If global email hiding is not enabled, then give the user a chance
// to choose for hiding himself.
$PHORUM['DATA']['SHOW_EMAIL_HIDE'] = empty($PHORUM['hide_email_addr']) ? 1 : 0;
// If pm email notifications are enabled, then give the user a chance
// to disable it.
$PHORUM['DATA']['SHOW_PM_EMAIL_NOTIFY'] = !empty($PHORUM["allow_pm_email_notify"]);
// The form action for the common form.
$PHORUM["DATA"]["URL"]["ACTION"] = phorum_get_url(PHORUM_CONTROLCENTER_ACTION_URL);
// fill the breadcrumbs-info
$PHORUM['DATA']['BREADCRUMBS'][] = array('URL' => $PHORUM['DATA']['URL']['REGISTERPROFILE'], 'TEXT' => $PHORUM['DATA']['LANG']['MyProfile'], 'TYPE' => 'control');
$user = $PHORUM['user'];
// Security messures.
unset($user["password"]);
Example #10
0
/**
 * 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;
}
Example #11
0
/**
 * Check if the active user has permission to delete a file.
 *
 * @example file_delete.php Delete a file.
 *
 * @param integer $file_id
 *     The file_id of the file for which to check the delete access.
 *
 * @return boolean
 *     TRUE if the user has rights to delete the file, FALSE otherwise.
 */
function phorum_api_file_check_delete_access($file_id)
{
    global $PHORUM;
    settype($file_id, "int");
    // Administrator users always have rights to delete files.
    if ($PHORUM["user"]["admin"]) {
        return TRUE;
    }
    // Anonymous users never have rights to delete files.
    if (empty($PHORUM["user"]["user_id"])) {
        return FALSE;
    }
    // For other users, the file information has to be retrieved
    // to be able to check the delete access.
    $file = phorum_api_file_check_read_access($file_id, PHORUM_FLAG_IGNORE_PERMS);
    // To prevent permission errors after deleting the same file twice,
    // we'll return TRUE if we did not find a file (if the file is not found,
    // then there's no harm in deleting it; the file storage API will
    // silently ignore deleting non-existent files). If some other error
    // occurred, then we return FALSE (most likely, the user does not
    // even have read permission for the file, so delete access would
    // be out of the question too).
    if ($file === FALSE) {
        if (phorum_api_errno() == PHORUM_ERRNO_NOTFOUND) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
    // We don't care about deleting temporary files and files that
    // are linked to the posting editor (during writing a post).
    // Those are both intermediate states for files, without them
    // being available on the forum. So for those, we always grant
    // delete access.
    if ($file["link"] == PHORUM_LINK_TEMPFILE || $file["link"] == PHORUM_LINK_EDITOR) {
        return TRUE;
    }
    // If the file is owned by the user, then the user has rights
    // to delete the file (this would be a personal user file).
    if (!empty($file["user_id"]) && $file["user_id"] == $PHORUM["user"]["user_id"]) {
        return TRUE;
    }
    // The file is not owned by the user. In that case, the user only has
    // rights to delete it if it is a file that is linked to a message which
    // the user posted himself of which was posted in a forum for which
    // the user is a moderator.
    if ($file["link"] == PHORUM_LINK_MESSAGE) {
        // Retrieve the message to which the file is linked.
        $message = phorum_db_get_message($file["message_id"]);
        // If the message cannot be found, we do not care if the linked
        // file is deleted. It's clearly an orphin file.
        if (!$message) {
            return TRUE;
        }
        // Check if the user posted the message himself.
        if (!empty($message["user_id"]) && $message["user_id"] == $PHORUM["user"]["user_id"]) {
            return TRUE;
        }
        // Check if the user is moderator for the forum_id of the message.
        if (phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES, $message["forum_id"])) {
            return TRUE;
        }
    }
    // The default policy for any unhandled case is to deny access.
    return FALSE;
}
Example #12
0
    return;
}
// somehow we got to a folder
if ($PHORUM["folder_flag"]) {
    phorum_api_redirect(PHORUM_INDEX_URL, $PHORUM['forum_id']);
}
if (isset($PHORUM["args"][1]) && is_numeric($PHORUM["args"][1])) {
    $message_id = $PHORUM["args"][1];
} else {
    phorum_api_redirect(PHORUM_INDEX_URL, $PHORUM['forum_id']);
}
$message = $PHORUM['DB']->get_message($message_id);
if (empty($message)) {
    phorum_api_redirect(PHORUM_INDEX_URL, $PHORUM["forum_id"]);
}
$PHORUM["DATA"]["MODERATOR"] = phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES);
$edit_tracks = $PHORUM['DB']->get_message_edits($message_id);
if (count($edit_tracks) == 0 || $PHORUM["track_edits"] == PHORUM_EDIT_TRACK_OFF || $PHORUM["track_edits"] == PHORUM_EDIT_TRACK_MODERATOR && !$PHORUM["DATA"]["MODERATOR"]) {
    phorum_api_redirect(PHORUM_READ_URL, $message['thread'], $message_id);
}
$diffs = array_reverse($edit_tracks);
// push an empty diff for the current status
array_push($diffs, array());
$prev_body = -1;
$prev_subject = -1;
foreach ($diffs as $diff_info) {
    if (!isset($diff_info["user_id"])) {
        $this_version["username"] = empty($PHORUM['custom_display_name']) ? htmlspecialchars($message["author"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]) : $message["author"];
        $this_version["user_id"] = $message["user_id"];
        $this_version["date"] = phorum_api_format_date($PHORUM["long_date_time"], $message["datestamp"]);
        $this_version["original"] = true;
Example #13
0
/**
 * Formats forum messages.
 *
 * @param array $data
 *     An array containing an array of messages to be formatted.
 *
 * @param array $author_specs
 *     By default, the formatting function will create  author info
 *     data out of the fields "user_id", "author" and "email".
 *     This will create $data["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 $data["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 field that contains a user_id,
 *     the field for the name of the author and the field for the email
 *     address (can be NULL if none available), the name of the field
 *     to store the author name in and the name of the URL field to store
 *     the profile/email link in. For the default author field like
 *     describe above, this array would be:
 *
 *     array("user_id", "author", "email", "author", "PROFILE");
 *
 * @return data - The formatted messages.
 */
function phorum_format_messages($data, $author_specs = NULL)
{
    $PHORUM = $GLOBALS["PHORUM"];
    // Prepare author specs.
    if ($author_specs === NULL) {
        $author_specs = array();
    }
    $author_specs[] = array("user_id", "author", "email", "author", "PROFILE");
    // Prepare the bad-words replacement code.
    $bad_word_check = false;
    $banlists = NULL;
    if (!empty($PHORUM['cache_banlists']) && !empty($PHORUM['banlist_version'])) {
        $cache_key = $PHORUM['forum_id'];
        $banlists = phorum_cache_get('banlist', $cache_key, $PHORUM['banlist_version']);
    }
    // not found or no caching enabled
    if ($banlists === NULL) {
        $banlists = phorum_db_get_banlists();
        if (!empty($PHORUM['cache_banlists']) && !empty($PHORUM['banlist_version'])) {
            phorum_cache_put('banlist', $cache_key, $banlists, 7200, $PHORUM['banlist_version']);
        }
    }
    if (isset($banlists[PHORUM_BAD_WORDS]) && is_array($banlists[PHORUM_BAD_WORDS])) {
        $replace_vals = array();
        $replace_words = array();
        foreach ($banlists[PHORUM_BAD_WORDS] as $item) {
            $replace_words[] = "/\\b" . preg_quote($item['string'], '/') . "(ing|ed|s|er|es)*\\b/i";
            $replace_vals[] = PHORUM_BADWORD_REPLACE;
            $bad_word_check = true;
        }
    }
    // A special <br> tag to keep track of breaks that are added by phorum.
    $phorum_br = '<phorum break>';
    // prepare url-templates used later on
    $profile_url_template = phorum_get_url(PHORUM_PROFILE_URL, '%spec_data%');
    // Apply Phorum's formatting rules to all messages.
    foreach ($data as $key => $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'])) {
            $data[$key]['message_id'] = $message['message_id'] = $key;
        }
        // Work on the message body ========================
        if (isset($message["body"])) {
            $body = $message["body"];
            // Convert legacy <> urls into bare urls.
            $body = preg_replace("/<((http|https|ftp):\\/\\/[a-z0-9;\\/\\?:@=\\&\$\\-_\\.\\+!*'\\(\\),~%]+?)>/i", "\$1", $body);
            // Escape special HTML characters.
            $escaped_body = htmlspecialchars($body, ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]);
            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 Phorum did vs the user.
            $body = str_replace("\n", "{$phorum_br}\n", $body);
            // Run bad word replacement code.
            if ($bad_word_check) {
                $body = preg_replace($replace_words, $replace_vals, $body);
            }
            $data[$key]["body"] = $body;
        }
        // Work on the other fields ========================
        // Run bad word replacement code on subject and author.
        if ($bad_word_check) {
            if (isset($message["subject"])) {
                $data[$key]["subject"] = preg_replace($replace_words, $replace_vals, $data[$key]["subject"]);
            }
            if (isset($message["author"])) {
                $data[$key]["author"] = preg_replace($replace_words, $replace_vals, $data[$key]["author"]);
            }
        }
        // Escape special HTML characters in fields.
        if (isset($message["email"])) {
            $data[$key]["email"] = htmlspecialchars($data[$key]["email"], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]);
        }
        if (isset($message["subject"])) {
            $data[$key]["subject"] = htmlspecialchars($data[$key]["subject"], 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]] == '') {
                $data[$key][$spec[3]] = $PHORUM["DATA"]["LANG"]["AnonymousUser"];
            } elseif (!empty($message[$spec[0]])) {
                $url = str_replace('%spec_data%', $message[$spec[0]], $profile_url_template);
                $data[$key]["URL"][$spec[4]] = $url;
                $data[$key][$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)) {
                $data[$key][$spec[3]] = htmlspecialchars($message[$spec[1]], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]);
                $email_url = phorum_html_encode("mailto:" . $message[$spec[2]]);
                $data[$key]["URL"]["PROFILE"] = $email_url;
            } else {
                $data[$key][$spec[3]] = htmlspecialchars($message[$spec[1]], ENT_COMPAT, $PHORUM["DATA"]["HCHARSET"]);
            }
        }
    }
    // A hook for module writers to apply custom message formatting.
    if (isset($PHORUM["hooks"]["format"])) {
        $data = phorum_hook("format", $data);
    }
    // A hook for module writers for doing post formatting fixups.
    if (isset($PHORUM["hooks"]["format_fixup"])) {
        $data = phorum_hook("format_fixup", $data);
    }
    // Clean up after the mods are done.
    foreach ($data as $key => $message) {
        // Clean up line breaks inside pre and xmp tags. These tags
        // take care of showing newlines as breaks themselves.
        if (isset($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.
            $data[$key]["body"] = str_replace($phorum_br, "<br />", $message["body"]);
        }
    }
    return $data;
}
Example #14
0
    $mode = "reply";
}
// Do ban list checks. Only check the bans on entering and
// on finishing up. No checking is needed on intermediate requests.
if ($initial || $finish || $preview) {
    include './include/posting/check_banlist.php';
}
// Determine the abilities that the current user has.
// Is the forum running in a moderated state?
$PHORUM["DATA"]["MODERATED"] = $PHORUM["moderation"] == PHORUM_MODERATE_ON && !phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES);
// Does the user have administrator permissions?
$PHORUM["DATA"]["ADMINISTRATOR"] = $PHORUM["user"]["admin"];
// Does the user have moderator permissions?
$PHORUM["DATA"]["MODERATOR"] = phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES);
// Ability: Do we allow attachments?
$PHORUM["DATA"]["ATTACHMENTS"] = $PHORUM["max_attachments"] > 0 && phorum_api_user_check_access(PHORUM_USER_ALLOW_ATTACH);
// What options does this user have for a message?
$PHORUM["DATA"]["OPTION_ALLOWED"] = array("sticky" => FALSE, "allow_reply" => FALSE, "subscribe" => FALSE, "subscribe_mail" => FALSE);
// Subscribing to threads for new messages by authenticated users or for
// editing messages posted by authenticated users (in which case the
// thread subscription for the user that posted the message can be
// updated).
if (($mode == "post" || $mode == "reply") && $PHORUM["DATA"]["LOGGEDIN"] || $mode == "edit" && !empty($message["user_id"])) {
    $PHORUM["DATA"]["OPTION_ALLOWED"]["subscribe"] = TRUE;
    $PHORUM["DATA"]["OPTION_ALLOWED"]["subscribe_mail"] = !empty($PHORUM['allow_email_notify']) ? TRUE : FALSE;
}
// For moderators and administrators.
if (($PHORUM["DATA"]["MODERATOR"] || $PHORUM["DATA"]["ADMINISTRATOR"]) && $message["parent_id"] == 0) {
    $PHORUM["DATA"]["OPTION_ALLOWED"]["sticky"] = true;
    $PHORUM["DATA"]["OPTION_ALLOWED"]["allow_reply"] = true;
}
Example #15
0
/**
 * Check if the user has read permission for a forum page.
 * 
 * If the user does not have read permission for the currently active
 * forum, then an error message is shown. What message to show depends
 * on the exact case. Possible cases are:
 *
 * - The user is logged in: final missing read permission message;
 * - The user is not logged in, but wouldn't be allowed to read the
 *   forum, even if he were logged in: final missing read permission message;
 * - The user is not logged in, but could be allowed to read the
 *   forum if he were logged in: please login message.
 *
 * @return boolean
 *     TRUE in case the user is allowed to read the forum,
 *     FALSE otherwise.
 */
function phorum_check_read_common()
{
    global $PHORUM;
    $retval = TRUE;
    if ($PHORUM["forum_id"] > 0 && !$PHORUM["folder_flag"] && !phorum_api_user_check_access(PHORUM_USER_ALLOW_READ)) {
        if ($PHORUM["DATA"]["LOGGEDIN"]) {
            // if they are logged in and not allowed, they don't have rights
            $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["NoRead"];
        } else {
            // Check if they could read if logged in.
            // If so, let them know to log in.
            if (empty($PHORUM["DATA"]["POST"]["parentid"]) && $PHORUM["reg_perms"] & PHORUM_USER_ALLOW_READ) {
                $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["PleaseLoginRead"];
            } else {
                $PHORUM["DATA"]["OKMSG"] = $PHORUM["DATA"]["LANG"]["NoRead"];
            }
        }
        phorum_build_common_urls();
        phorum_api_output("message");
        $retval = FALSE;
    }
    return $retval;
}
Example #16
0
//   This program is distributed in the hope that it will be useful,          //
//   but WITHOUT ANY WARRANTY, without even the implied warranty of           //
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     //
//                                                                            //
//   You should have received a copy of the Phorum License                    //
//   along with this program.                                                 //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
if (!defined("PHORUM_CONTROL_CENTER")) {
    return;
}
$template = "cc_start";
$PHORUM['DATA']['UserPerms'] = phorum_readable_permissions();
$PHORUM['DATA']['PROFILE']['raw_date_added'] = $PHORUM['DATA']['PROFILE']['date_added'];
$PHORUM['DATA']['PROFILE']['date_added'] = phorum_api_format_date($PHORUM['short_date_time'], $PHORUM['DATA']['PROFILE']['date_added']);
if ($PHORUM["track_user_activity"] && (!empty($PHORUM["user"]["admin"]) || phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES) || phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_USERS) || !$PHORUM['DATA']['PROFILE']["hide_activity"])) {
    $PHORUM["DATA"]["PROFILE"]["raw_date_last_active"] = $PHORUM["DATA"]["PROFILE"]["date_last_active"];
    $PHORUM["DATA"]["PROFILE"]["date_last_active"] = phorum_api_format_date($PHORUM['short_date_time'], $PHORUM["DATA"]["PROFILE"]["date_last_active"]);
} else {
    unset($PHORUM["DATA"]["PROFILE"]["date_last_active"]);
}
if (isset($PHORUM["hooks"]["profile"])) {
    $PHORUM["DATA"]["PROFILE"] = phorum_api_hook("profile", $PHORUM["DATA"]["PROFILE"]);
}
/* --------------------------------------------------------------- */
function phorum_readable_permissions()
{
    global $PHORUM;
    $newperms = array();
    if (isset($PHORUM["user"]["permissions"])) {
        $forums = phorum_api_forums_get(array_keys($PHORUM["user"]["permissions"]));
Example #17
0
/**
 * Subscribe a user to a thread.
 *
 * Remark: Currently, there is no active support for subscribing to forums
 * using subscription type PHORUM_SUBSCRIPTION_DIGEST in the Phorum core.
 *
 * @param integer $user_id
 *     The id of the user to create the subscription for.
 *
 * @param integer $thread
 *     The id of the thread to describe to.
 *
 * @param integer $forum_id
 *     The id of the forum in which the thread to subscribe to resides.
 *
 * @param integer $type
 *     The type of subscription. Available types are:
 *     - {@link PHORUM_SUBSCRIPTION_NONE}
 *     - {@link PHORUM_SUBSCRIPTION_MESSAGE}
 *     - {@link PHORUM_SUBSCRIPTION_BOOKMARK}
 *     - {@link PHORUM_SUBSCRIPTION_DIGEST}
 */
function phorum_api_user_subscribe($user_id, $thread, $forum_id, $type)
{
    // Check if the user is allowed to read the forum.
    if (!phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, $forum_id)) {
        return;
    }
    // Setup the subscription.
    phorum_db_user_subscribe($user_id, $thread, $forum_id, $type);
}
Example #18
0
 /**
  * Search the database using the provided search criteria and return
  * an array containing the total count of matches and the visible
  * messages based on the page $offset and $length.
  *
  * @param string $search
  *     The query to search on in messages and subjects.
  *
  * @param mixed $author
  *     The query to search on in the message authors or a numerical user_id
  *     if searching for all messages for a certain user_id.
  *
  * @param boolean $return_threads
  *     Whether to return the results as threads (TRUE) or messages (FALSE).
  *     When searching for a user ($match_type = USER_ID), then only the
  *     thread starter messages that were posted by the user are returned.
  *
  * @param integer $page
  *     The result page offset starting with 0.
  *
  * @param integer $limit
  *     The result page limit (nr. of results per page).
  *
  * @param string $match_type
  *     The type of search. This can be one of:
  *     - ALL:     search on all of the words (uses $search)
  *     - ANY:     search on any of the words (uses $search)
  *     - PHRASE:  search for an exact phrase (uses $search)
  *     - USER_ID: search for an author id (uses $author)
  *
  * @param integer $days
  *     The number of days to go back in the database for searching
  *     (last [x] days) or zero to search within all dates.
  *
  * @param string $match_forum
  *     The forum restriction. This can be either the string "ALL" to search
  *     in any of the readable forums or a comma separated list of forum_ids.
  *
  * @return array
  *     An array containing two fields:
  *     - "count" contains the total number of matching messages.
  *     - "rows" contains the messages that are visible, based on the page
  *       $page and page $limit. The messages are indexed by message_id.
  */
 public function search($search, $author, $return_threads, $page, $limit, $match_type, $days, $match_forum)
 {
     global $PHORUM;
     $fulltext_mode = isset($PHORUM['DBCONFIG']['mysql_use_ft']) && $PHORUM['DBCONFIG']['mysql_use_ft'];
     $search = trim($search);
     $author = trim($author);
     settype($return_threads, 'bool');
     settype($page, 'int');
     settype($limit, 'int');
     settype($days, 'int');
     // For spreading search results over multiple pages.
     $offset = $page * $limit;
     // Initialize the return data.
     $return = array('count' => 0, 'rows' => array());
     // Return immediately if the search queries are empty.
     if ($search == '' && $author == '') {
         return $return;
     }
     // Check what forums the active Phorum user can read.
     $allowed_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, PHORUM_ACCESS_LIST);
     // If the user is not allowed to search any forum or the current
     // active forum, then return the emtpy search results array.
     if (empty($allowed_forums) || $PHORUM['forum_id'] > 0 && !in_array($PHORUM['forum_id'], $allowed_forums)) {
         return $return;
     }
     // Prepare forum_id restriction.
     $match_forum_arr = explode(",", $match_forum);
     $search_forums = array();
     foreach ($match_forum_arr as $forum_id) {
         if ($forum_id == "ALL") {
             $search_forums = $allowed_forums;
             break;
         }
         if (isset($allowed_forums[$forum_id])) {
             $search_forums[] = $forum_id;
         }
     }
     if (count($search_forums)) {
         $forum_where = "AND forum_id in (" . implode(",", $search_forums) . ")";
     } else {
         // Hack attempt or error. Return empty search results.
         return $return;
     }
     // Prepare day limit restriction.
     if ($days > 0) {
         $ts = time() - 86400 * $days;
         $datestamp_where = "AND datestamp >= {$ts}";
     } else {
         $datestamp_where = '';
     }
     // We make use of temporary tables for storing intermediate search
     // results. These tables are stored in $tables during processing.
     $tables = array();
     // -------------------------------------------------------------------
     // Handle search for user_id only.
     // -------------------------------------------------------------------
     if ($search == '' && $author != '' && $match_type == 'USER_ID') {
         $user_id = (int) $author;
         if (empty($user_id)) {
             return $return;
         }
         // Search for messages.
         $where = "user_id = {$user_id} AND\n                      status=" . PHORUM_STATUS_APPROVED . " AND\n                      moved=0";
         if ($return_threads) {
             $where .= " AND parent_id = 0";
         }
         $sql = "SELECT SQL_CALC_FOUND_ROWS *\n                    FROM   {$this->message_table} " . ($this->_can_USE_INDEX ? "USE INDEX (user_messages)" : "") . "WHERE  {$where} {$forum_where}\n                    ORDER  BY datestamp DESC";
         // Retrieve the message rows.
         $rows = $this->interact(DB_RETURN_ASSOCS, $sql, "message_id", NULL, $limit, $offset);
         // Retrieve the number of found messages.
         $count = $this->interact(DB_RETURN_VALUE, "SELECT found_rows()");
         // Fill the return data.
         $return = array("count" => $count, "rows" => $rows);
         return $return;
     }
     // -------------------------------------------------------------------
     // Handle search for message and subject.
     // -------------------------------------------------------------------
     if ($search != '') {
         $match_str = '';
         $tokens = array();
         if ($match_type == "PHRASE") {
             $search = str_replace('"', '', $search);
             $match_str = '"' . $this->interact(DB_RETURN_QUOTED, $search) . '"';
         } else {
             // Surround with spaces so matching is easier.
             $search = " {$search} ";
             // Pull out all grouped terms, e.g. (nano mini).
             $paren_terms = array();
             if (strstr($search, '(')) {
                 preg_match_all('/ ([+\\-~]*\\(.+?\\)) /', $search, $m);
                 $search = preg_replace('/ [+\\-~]*\\(.+?\\) /', ' ', $search);
                 $paren_terms = $m[1];
             }
             // Pull out all the double quoted strings,
             // e.g. '"iMac DV" or -"iMac DV".
             $quoted_terms = array();
             if (strstr($search, '"')) {
                 preg_match_all('/ ([+\\-~]*".+?") /', $search, $m);
                 $search = preg_replace('/ [+\\-~]*".+?" /', ' ', $search);
                 $quoted_terms = $m[1];
             }
             // Finally, pull out the rest words in the string.
             $norm_terms = preg_split("/\\s+/", $search, 0, PREG_SPLIT_NO_EMPTY);
             // Merge all search terms together.
             $tokens = array_merge($quoted_terms, $paren_terms, $norm_terms);
         }
         // Handle full text message / subject search.
         if ($fulltext_mode) {
             // Create a match string based on the parsed query tokens.
             if (count($tokens)) {
                 $match_str = '';
                 foreach ($tokens as $term) {
                     if (!strstr("+-~", substr($term, 0, 1))) {
                         if (strstr($term, ".") && !preg_match('!^".+"$!', $term) && substr($term, -1) != "*") {
                             $term = "\"{$term}\"";
                         }
                         if ($match_type == "ALL") {
                             $term = "+" . $term;
                         }
                     }
                     $match_str .= "{$term} ";
                 }
                 $match_str = trim($match_str);
                 $match_str = $this->interact(DB_RETURN_QUOTED, $match_str);
             }
             $table_name = $this->search_table . "_ft_" . md5(microtime());
             $this->interact(DB_RETURN_RES, "CREATE TEMPORARY TABLE {$table_name} (\n                         KEY (message_id)\n                     ) ENGINE=HEAP\n                       SELECT message_id\n                       FROM   {$this->search_table}\n                       WHERE  MATCH (search_text)\n                              AGAINST ('{$match_str}' IN BOOLEAN MODE)");
             $tables[] = $table_name;
         } else {
             if (count($tokens)) {
                 $condition = $match_type == "ALL" ? "AND" : "OR";
                 foreach ($tokens as $tid => $token) {
                     $tokens[$tid] = $this->interact(DB_RETURN_QUOTED, $token);
                 }
                 $match_str = "('%" . implode("%' {$condition} '%", $tokens) . "%')";
             }
             $table_name = $this->search_table . "_like_" . md5(microtime());
             $this->interact(DB_RETURN_RES, "CREATE TEMPORARY TABLE {$table_name} (\n                         KEY (message_id)\n                     ) ENGINE=HEAP\n                       SELECT message_id\n                       FROM   {$this->search_table}\n                       WHERE search_text LIKE {$match_str}");
             $tables[] = $table_name;
         }
     }
     // -------------------------------------------------------------------
     // Handle search for author.
     // -------------------------------------------------------------------
     if ($author != '') {
         $table_name = $this->search_table . "_author_" . md5(microtime());
         // Search either by user_id or by username.
         if ($match_type == "USER_ID") {
             $author = (int) $author;
             $author_where = "user_id = {$author}";
         } else {
             $author = $this->interact(DB_RETURN_QUOTED, $author);
             $author_where = "author = '{$author}'";
         }
         $this->interact(DB_RETURN_RES, "CREATE TEMPORARY TABLE {$table_name} (\n                   KEY (message_id)\n                 ) ENGINE=HEAP\n                   SELECT message_id\n                   FROM   {$this->message_table}\n                   WHERE  {$author_where}");
         $tables[] = $table_name;
     }
     // -------------------------------------------------------------------
     // Gather the results.
     // -------------------------------------------------------------------
     if (count($tables)) {
         // If we only have one temporary table, we can use it directly.
         if (count($tables) == 1) {
             $table = array_shift($tables);
         } else {
             $table = $this->search_table . "_final_" . md5(microtime());
             $joined_tables = "";
             $main_table = array_shift($tables);
             foreach ($tables as $tbl) {
                 $joined_tables .= "INNER JOIN {$tbl} USING (message_id)";
             }
             $this->interact(DB_RETURN_RES, "CREATE TEMPORARY TABLE {$table} (\n                       KEY (message_id)\n                     ) ENGINE=HEAP\n                       SELECT m.message_id\n                       FROM   {$main_table} m {$joined_tables}");
         }
         // When only threads need to be returned, then join the results
         // that we have so far with the message table into a result set
         // that only contains the threads for the results.
         if ($return_threads) {
             $threads_table = $this->search_table . "_final_threads_" . md5(microtime());
             $this->interact(DB_RETURN_RES, "CREATE TEMPORARY TABLE {$threads_table} (\n                       KEY (message_id)\n                     ) ENGINE=HEAP\n                       SELECT distinct thread AS message_id\n                       FROM   {$this->message_table}\n                              INNER JOIN {$table}\n                              USING (message_id)");
             $table = $threads_table;
         }
         // Retrieve the found messages.
         $rows = $this->interact(DB_RETURN_ASSOCS, "SELECT SQL_CALC_FOUND_ROWS *\n                 FROM   {$this->message_table}\n                        INNER JOIN {$table} USING (message_id)\n                 WHERE  status=" . PHORUM_STATUS_APPROVED . "\n                        {$forum_where}\n                        {$datestamp_where}\n                 ORDER  BY datestamp DESC", "message_id", NULL, $limit, $offset);
         // Retrieve the number of found messages.
         $count = $this->interact(DB_RETURN_VALUE, "SELECT found_rows()");
         // Fill the return data.
         $return = array("count" => $count, "rows" => $rows);
     }
     return $return;
 }
Example #19
0
File: pm.php Project: netovs/Core
         $msg = phorum_pm_quoteformat($message["author"], $message["user_id"], $msg);
         // Include the other recipient, excecpt the active
         // user himself, when replying to all.
         if (isset($_POST["reply_to_all"])) {
             foreach ($message["recipients"] as $rcpt) {
                 if ($user_id == $rcpt["user_id"]) {
                     continue;
                 }
                 $msg["recipients"][$rcpt["user_id"]] = array("display_name" => $rcpt["display_name"], "user_id" => $rcpt["user_id"]);
             }
         }
         $hide_userselect = 1;
         // Setup data for replying privately to a forum post.
     } elseif (isset($PHORUM["args"]["message_id"])) {
         $message = $PHORUM['DB']->get_message($PHORUM["args"]["message_id"], "message_id", true);
         if (phorum_api_user_check_access(PHORUM_USER_ALLOW_READ) && ($PHORUM["forum_id"] == $message["forum_id"] || $message["forum_id"] == 0)) {
             // get url to the message board thread
             $origurl = phorum_api_url(PHORUM_READ_URL, $message["thread"], $message["message_id"]);
             // Get the data for the user that we reply to.
             $user = phorum_api_user_get($message["user_id"]);
             $msg["subject"] = $message["subject"];
             $msg["message"] = $message["body"];
             $msg["recipients"][$message["user_id"]] = array('display_name' => $user["display_name"], 'user_id' => $user["user_id"]);
             $msg = phorum_pm_quoteformat($user["display_name"], $user["user_id"], $msg, $origurl);
         }
         $hide_userselect = 1;
     }
 }
 /**
  * [hook]
  *     pm_send_init
Example #20
0
            // 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"] = "";
} else {
    // more html stuff in the code. yuck.
    $PHORUM["DATA"]["PROFILE"]["hide_email_checked"] = " checked=\"checked\"";
}
if (phorum_api_user_check_access(PHORUM_USER_ALLOW_MODERATE_MESSAGES, PHORUM_ACCESS_ANY)) {
    $PHORUM["DATA"]["PROFILE"]["show_moderate_options"] = true;
    if (!empty($PHORUM['DATA']['PROFILE']["moderation_email"])) {
        $PHORUM["DATA"]["PROFILE"]["moderation_email_checked"] = " checked=\"checked\"";
    } else {
        $PHORUM["DATA"]["PROFILE"]["moderation_email_checked"] = "";
    }
} else {
    $PHORUM["DATA"]["PROFILE"]["show_moderate_options"] = false;
}
$PHORUM["DATA"]["PROFILE"]["EMAIL_CONFIRM"] = $PHORUM["registration_control"];
$PHORUM['DATA']['PROFILE']['MAILSETTINGS'] = 1;
$template = "cc_usersettings";
Example #21
0
     $row["URL"]["SPLIT"] = str_replace(array('%action_id%', '%message_id%'), array(PHORUM_SPLIT_THREAD, $row["message_id"]), $moderation_url_template);
     if ($row['is_unapproved']) {
         $row["URL"]["APPROVE"] = str_replace(array('%action_id%', '%message_id%'), array(PHORUM_APPROVE_MESSAGE, $row["message_id"]), $moderation_url_template);
     } else {
         $row["URL"]["HIDE"] = str_replace(array('%action_id%', '%message_id%'), array(PHORUM_HIDE_POST, $row["message_id"]), $moderation_url_template);
     }
     if ($build_move_url) {
         $row["URL"]["MOVE"] = $URLS["move_url"];
     }
     $row["URL"]["MERGE"] = $URLS["merge_url"];
     $row["URL"]["CLOSE"] = $URLS["close_url"];
     $row["URL"]["REOPEN"] = $URLS["reopen_url"];
 }
 // allow editing only if logged in, allowed for forum, the thread is open,
 // its the same user, and its within the time restriction
 if ($PHORUM["user"]["user_id"] == $row["user_id"] && phorum_api_user_check_access(PHORUM_USER_ALLOW_EDIT) && !$thread_is_closed && ($PHORUM["user_edit_timelimit"] == 0 || $row["datestamp"] + $PHORUM["user_edit_timelimit"] * 60 >= time())) {
     $row["edit"] = 1;
     if (!$PHORUM["DATA"]["MODERATOR"]) {
         $row["URL"]["EDIT"] = str_replace(array('%action_id%', '%message_id%'), array("edit", $row["message_id"]), $edit_url_template);
     }
 }
 // this stuff is used in threaded and non threaded.
 $row["raw_short_datestamp"] = $row["datestamp"];
 $row["short_datestamp"] = phorum_date($PHORUM["short_date_time"], $row["datestamp"]);
 $row["raw_datestamp"] = $row["datestamp"];
 $row["datestamp"] = phorum_date($PHORUM["long_date_time"], $row["datestamp"]);
 $row["URL"]["READ"] = str_replace(array('%thread_id%', '%message_id%'), array($row["thread"], $row["message_id"]), $read_url_template_both);
 $row["URL"]["REPLY"] = str_replace(array('%thread_id%', '%message_id%'), array($row["thread"], $row["message_id"]), $reply_url_template);
 $row["URL"]["QUOTE"] = str_replace(array('%thread_id%', '%message_id%'), array($row["thread"], $row["message_id"]), $reply_url_template_quote);
 $row["URL"]["PM"] = false;
 if ($PHORUM["DATA"]["LOGGEDIN"]) {
function sphinx_search_action($arrSearch)
{
    global $PHORUM;
    // No pecl class, try php version
    if (!class_exists('SphinxClient')) {
        // loads from php include_path
        require_once 'sphinxapi.php';
    }
    // these are the index-names set in sphinx.conf - one for searching messages, the other for searching by authors only
    // both contain an additional index for the deltas - changes done after the last full reindex
    $index_name_msg = 'phorum5_msg_d phorum5_msg';
    $index_name_author = 'phorum5_author phorum5_author_d';
    // excerpts_index is just one index as that function only accepts one, it used for determining charsets / mapping tables, nothing more
    $excerpts_index = 'phorum5_msg';
    $index = $index_name_msg;
    if ($arrSearch['match_type'] == 'ALL') {
        $match_mode = SPH_MATCH_ALL;
    } elseif ($arrSearch['match_type'] == 'ANY') {
        $match_mode = SPH_MATCH_ANY;
    } elseif ($arrSearch['match_type'] == 'PHRASE') {
        $match_mode = SPH_MATCH_PHRASE;
    } elseif ($arrSearch['match_type'] == 'AUTHOR') {
        $match_mode = SPH_MATCH_PHRASE;
        $index = $index_name_author;
    } else {
        // Return search control to Phorum in case the search type isn't handled by the module.
        return $arrSearch;
    }
    if (empty($arrSearch['search']) && !empty($arrSearch['author'])) {
        $arrSearch['search'] = $arrSearch['author'];
        $index = $index_name_author;
    }
    $sphinx = new SphinxClient();
    $sphinx->SetServer($PHORUM['mod_sphinx_search']['hostname'], $PHORUM['mod_sphinx_search']['port']);
    $sphinx->SetMatchMode($match_mode);
    // set the limits for paging
    $sphinx->SetLimits($arrSearch['offset'], $arrSearch['length']);
    // set the timeframe to search
    if ($arrSearch['match_dates'] > 0) {
        $min_ts = time() - 86400 * $arrSearch['match_dates'];
        $max_ts = time();
        $sphinx->SetFilterRange('datestamp', $min_ts, $max_ts);
    }
    // Check what forums the active Phorum user can read.
    $allowed_forums = phorum_api_user_check_access(PHORUM_USER_ALLOW_READ, PHORUM_ACCESS_LIST);
    // If the user is not allowed to search any forum or the current
    // active forum, then return the emtpy search results array.
    if (empty($allowed_forums) || $PHORUM['forum_id'] > 0 && !in_array($PHORUM['forum_id'], $allowed_forums)) {
        $arrSearch['results'] = array();
        $arrSearch['totals'] = 0;
        $arrSearch['continue'] = 0;
        $arrSearch['raw_body'] = 1;
        return $arrSearch;
    }
    // Prepare forum_id restriction.
    $search_forums = array();
    foreach (explode(',', $arrSearch['match_forum']) as $forum_id) {
        if ($forum_id == 'ALL') {
            $search_forums = $allowed_forums;
            break;
        }
        if (isset($allowed_forums[$forum_id])) {
            $search_forums[] = $forum_id;
        }
    }
    $sphinx->SetFilter('forum_id', $search_forums);
    // set the sort-mode
    $sphinx->SetSortMode(SPH_SORT_ATTR_DESC, 'datestamp');
    // do the actual query
    $results = $sphinx->Query($arrSearch['search'], $index);
    $res = $sphinx->GetLastWarning();
    if ($res) {
        error_log("sphinx_search.php: WARNING: {$res}");
    }
    $res = $sphinx->GetLastError();
    if ($res) {
        error_log("sphinx_search.php: ERROR: {$res}");
    }
    // if no messages were found, then return empty handed.
    if (!isset($results['matches'])) {
        $arrSearch['results'] = array();
        $arrSearch['totals'] = 0;
        $arrSearch['continue'] = 0;
        $arrSearch['raw_body'] = 1;
        return $arrSearch;
    }
    $search_msg_ids = $results['matches'];
    // get the messages we found
    $found_messages = phorum_db_get_message(array_keys($search_msg_ids), 'message_id', true);
    // sort them in reverse order of the message_id to automagically sort them by date desc this way
    krsort($found_messages);
    reset($found_messages);
    // prepare the array for building highlighted excerpts
    $docs = array();
    foreach ($found_messages as $id => $data) {
        // remove hidden text in the output - only added by the hidden_msg module
        $data['body'] = preg_replace("/(\\[hide=([\\#a-z0-9]+?)\\](.+?)\\[\\/hide\\])/is", '', $data['body']);
        $docs[] = htmlspecialchars(phorum_strip_body($data['body']));
    }
    $words = '';
    if (!empty($results['words'])) {
        $words = implode(' ', array_keys($results['words']));
    }
    $opts = array('chunk_separator' => ' [...] ');
    // build highlighted excerpts
    $highlighted = $sphinx->BuildExcerpts($docs, $excerpts_index, $words, $opts);
    $res = $sphinx->GetLastWarning();
    if ($res) {
        error_log("sphinx_search.php: WARNING: {$res}");
    }
    $res = $sphinx->GetLastError();
    if ($res) {
        error_log("sphinx_search.php: ERROR: {$res}");
    }
    $cnt = 0;
    foreach ($found_messages as $id => $content) {
        $found_messages[$id]['short_body'] = $highlighted[$cnt];
        $cnt++;
    }
    $arrSearch['results'] = $found_messages;
    // we need the total results
    $arrSearch['totals'] = $results['total_found'];
    if ($arrSearch['totals'] > 1000) {
        $arrSearch['totals'] = 1000;
    }
    // don't run the default search
    $arrSearch['continue'] = 0;
    // tell it to leave the body alone
    $arrSearch['raw_body'] = 1;
    return $arrSearch;
}