/** * Render posts. * * @param integer Maximum to load if non-threaded * @param array Tree structure of posts * @param boolean Whether the current user may reply to the topic (influences what buttons show) * @param ?AUTO_LINK Only show posts under here (NULL: show posts from root) * @param array Review ratings rows * @param AUTO_LINK ID of forum this topic in in * @return tempcode Rendered tree structure */ function _render_post_tree($num_to_show_limit, $tree, $may_reply, $highlight_by_user, $all_individual_review_ratings, $forum_id) { list($rendered, ) = $tree; $sequence = new ocp_tempcode(); foreach ($rendered as $post) { if (get_forum_type() == 'ocf') { require_code('ocf_topicview'); require_code('ocf_posts'); $post += ocf_get_details_to_show_post($post); } // Misc details $datetime_raw = $post['date']; $datetime = get_timezoned_date($post['date']); $poster_url = is_guest($post['user']) ? new ocp_tempcode() : $GLOBALS['FORUM_DRIVER']->member_profile_url($post['user'], false, true); $poster_name = array_key_exists('username', $post) ? $post['username'] : $GLOBALS['FORUM_DRIVER']->get_username($post['user']); if (is_null($poster_name)) { $poster_name = do_lang('UNKNOWN'); } $highlight = $highlight_by_user === $post['user']; // Find review, if there is one $individual_review_ratings = array(); foreach ($all_individual_review_ratings as $potential_individual_review_rating) { if ($potential_individual_review_rating['r_post_id'] == $post['id']) { $individual_review_ratings[$potential_individual_review_rating['r_rating_type']] = array('REVIEW_TITLE' => $potential_individual_review_rating['r_rating_type'], 'REVIEW_RATING' => float_to_raw_string($potential_individual_review_rating['r_rating'])); } } // Edit URL $emphasis = new ocp_tempcode(); $buttons = new ocp_tempcode(); $last_edited = new ocp_tempcode(); $last_edited_raw = ''; $unvalidated = new ocp_tempcode(); $poster = mixed(); $poster_details = new ocp_tempcode(); $is_spacer_post = false; if (get_forum_type() == 'ocf') { // Spacer post fiddling if (!is_null($this->first_post_id) && !is_null($this->topic_title) && !is_null($this->topic_description) && !is_null($this->topic_description_link)) { $is_spacer_post = $post['id'] == $this->first_post_id && substr($post['message_comcode'], 0, strlen('[semihtml]' . do_lang('SPACER_POST_MATCHER'))) == '[semihtml]' . do_lang('SPACER_POST_MATCHER'); if ($is_spacer_post) { $c_prefix = do_lang('COMMENT') . ': #'; if (substr($this->topic_description, 0, strlen($c_prefix)) == $c_prefix && $this->topic_description_link != '') { list($linked_type, $linked_id) = explode('_', substr($this->topic_description, strlen($c_prefix)), 2); $linked_url = $this->topic_description_link; require_code('ocf_posts'); list($new_description, $new_post) = ocf_display_spacer_post($linked_type, $linked_id); //if (!is_null($new_description)) $this->topic_description=$new_description; Actually, it's a bit redundant if (!is_null($new_post)) { $post['message'] = $new_post; } $highlight = false; $this->topic_title = do_lang('SPACER_TOPIC_TITLE_WRAP', $this->topic_title); $post['title'] = do_lang('SPACER_TOPIC_TITLE_WRAP', $post['title']); $this->topic_description = ''; } } } // Misc meta details for post $emphasis = ocf_get_post_emphasis($post); $unvalidated = $post['validated'] == 0 ? do_lang_tempcode('UNVALIDATED') : new ocp_tempcode(); if (array_key_exists('last_edit_time', $post)) { $last_edited = do_template('OCF_TOPIC_POST_LAST_EDITED', array('LAST_EDIT_DATE_RAW' => is_null($post['last_edit_time']) ? '' : strval($post['last_edit_time']), 'LAST_EDIT_DATE' => $post['last_edit_time_string'], 'LAST_EDIT_PROFILE_URL' => $GLOBALS['FORUM_DRIVER']->member_profile_url($post['last_edit_by'], false, true), 'LAST_EDIT_USERNAME' => $post['last_edit_by_username'])); $last_edited_raw = is_null($post['last_edit_time']) ? '' : strval($post['last_edit_time']); } // Post buttons if (!$is_spacer_post) { if (!is_null($this->topic_id)) { if (is_null($this->topic_info)) { $this->topic_info = ocf_read_in_topic($this->topic_id, 0, 0, false, false); } require_lang('ocf'); $buttons = ocf_render_post_buttons($this->topic_info, $post, $may_reply); } } // OCF renderings of poster static $hooks = NULL; if (is_null($hooks)) { $hooks = find_all_hooks('modules', 'topicview'); } static $hook_objects = NULL; if (is_null($hook_objects)) { $hook_objects = array(); foreach (array_keys($hooks) as $hook) { require_code('hooks/modules/topicview/' . filter_naughty_harsh($hook)); $object = object_factory('Hook_' . filter_naughty_harsh($hook), true); if (is_null($object)) { continue; } $hook_objects[$hook] = $object; } } if (!$is_spacer_post) { if (!is_guest($post['poster'])) { require_code('ocf_members2'); $poster_details = ocf_show_member_box($post, false, $hooks, $hook_objects, false); } else { $custom_fields = new ocp_tempcode(); if (array_key_exists('ip_address', $post) && addon_installed('ocf_forum')) { $custom_fields->attach(do_template('OCF_TOPIC_POST_CUSTOM_FIELD', array('NAME' => do_lang_tempcode('IP_ADDRESS'), 'VALUE' => $post['ip_address']))); $poster_details = do_template('OCF_GUEST_DETAILS', array('CUSTOM_FIELDS' => $custom_fields)); } else { $poster_details = new ocp_tempcode(); } } } if (addon_installed('ocf_forum')) { if (!is_guest($post['poster'])) { $poster = do_template('OCF_POSTER_MEMBER', array('ONLINE' => member_is_online($post['poster']), 'ID' => strval($post['poster']), 'POSTER_DETAILS' => $poster_details, 'PROFILE_URL' => $GLOBALS['FORUM_DRIVER']->member_profile_url($post['poster'], false, true), 'POSTER_USERNAME' => $post['poster_username'])); } else { $ip_link = array_key_exists('ip_address', $post) && has_actual_page_access(get_member(), 'admin_lookup') ? build_url(array('page' => 'admin_lookup', 'param' => $post['ip_address']), get_module_zone('admin_lookup')) : new ocp_tempcode(); $poster = do_template('OCF_POSTER_GUEST', array('IP_LINK' => $ip_link, 'POSTER_DETAILS' => $poster_details, 'POSTER_USERNAME' => $post['poster_username'])); } } else { $poster = make_string_tempcode(escape_html($post['poster_username'])); } } // Child posts $children = mixed(); // NULL $other_ids = array(); if (array_key_exists('children', $post)) { foreach ($post['children'][1] as $u) { $other_ids[] = strval($u['id']); } if ($this->is_threaded) { $children = $this->_render_post_tree($num_to_show_limit, $post['children'], $may_reply, $highlight_by_user, $all_individual_review_ratings, $forum_id); } } if (get_forum_type() == 'ocf') { require_code('feedback'); actualise_rating(true, 'post', strval($post['id']), get_self_url(), $post['title']); $rating = display_rating(get_self_url(), $post['title'], 'post', strval($post['id']), 'RATING_INLINE_DYNAMIC', $post['user']); } else { $rating = new ocp_tempcode(); } if (array_key_exists('intended_solely_for', $post)) { decache('side_ocf_personal_topics', array(get_member())); decache('_new_pp', array(get_member())); } // Render $sequence->attach(static_evaluate_tempcode(do_template('POST', array('_GUID' => 'eb7df038959885414e32f58e9f0f9f39', 'INDIVIDUAL_REVIEW_RATINGS' => $individual_review_ratings, 'HIGHLIGHT' => $highlight, 'TITLE' => $post['title'], 'TIME_RAW' => strval($datetime_raw), 'TIME' => $datetime, 'POSTER_ID' => strval($post['user']), 'POSTER_URL' => $poster_url, 'POSTER_NAME' => $poster_name, 'POSTER' => $poster, 'POSTER_DETAILS' => $poster_details, 'ID' => strval($post['id']), 'POST' => $post['message'], 'POST_COMCODE' => isset($post['message_comcode']) ? $post['message_comcode'] : NULL, 'CHILDREN' => $children, 'OTHER_IDS' => count($other_ids) == 0 ? NULL : $other_ids, 'RATING' => $rating, 'EMPHASIS' => $emphasis, 'BUTTONS' => $buttons, 'LAST_EDITED_RAW' => $last_edited_raw, 'LAST_EDITED' => $last_edited, 'TOPIC_ID' => is_null($this->topic_id) ? '' : strval($this->topic_id), 'UNVALIDATED' => $unvalidated, 'IS_SPACER_POST' => $is_spacer_post, 'NUM_TO_SHOW_LIMIT' => strval($num_to_show_limit))))); } return $sequence; }
/** * Read in a great big map of details relating to a topic. * * @param ?AUTO_LINK The ID of the topic we are getting details of (NULL: whispers). * @param integer The start row for getting details of posts in the topic (i.e. 0 is start of topic, higher is further through). * @param integer The maximum number of posts to get detail of. * @param boolean Whether we are viewing poll results for the topic (if there is no poll for the topic, this is irrelevant). * @param boolean Whether to check permissions. * @return array The map of details. */ function ocf_read_in_topic($topic_id, $start, $max, $view_poll_results = false, $check_perms = true) { if (!is_null($topic_id)) { $_topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics t LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_forums f ON f.id=t.t_forum_id', array('t.*', 'f.f_is_threaded'), array('t.id' => $topic_id), '', 1); if (!array_key_exists(0, $_topic_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $topic_info = $_topic_info[0]; // Are we allowed into here? // Check forum $forum_id = $topic_info['t_forum_id']; if (!is_null($forum_id)) { if ($check_perms) { if (!has_category_access(get_member(), 'forums', strval($forum_id))) { access_denied('CATEGORY_ACCESS_LEVEL'); } } } else { // It must be a personal topic. Do we have access? $from = $topic_info['t_pt_from']; $to = $topic_info['t_pt_to']; if ($from != get_member() && $to != get_member() && !ocf_has_special_pt_access($topic_id) && !has_specific_permission(get_member(), 'view_other_pt')) { access_denied('SPECIFIC_PERMISSION', 'view_other_pt'); } decache('_new_pp', array(get_member())); decache('side_ocf_personal_topics', array(get_member())); } // Check validated if ($topic_info['t_validated'] == 0) { if (!has_specific_permission(get_member(), 'jump_to_unvalidated')) { access_denied('SPECIFIC_PERMISSION', 'jump_to_unvalidated'); } } if (is_null(get_param_integer('threaded', NULL))) { if ($start > 0) { if ($topic_info['f_is_threaded'] == 1) { $_GET['threaded'] = '0'; } } } $is_threaded = get_param_integer('threaded', is_null($topic_info['f_is_threaded']) ? 0 : $topic_info['f_is_threaded']); if ($is_threaded != 1) { $is_threaded = 0; } // In case of invalid URLs causing inconsistent handling // Some general info $out = array('num_views' => $topic_info['t_num_views'], 'num_posts' => $topic_info['t_cache_num_posts'], 'validated' => $topic_info['t_validated'], 'title' => $topic_info['t_cache_first_title'], 'description' => $topic_info['t_description'], 'description_link' => $topic_info['t_description_link'], 'emoticon' => $topic_info['t_emoticon'], 'forum_id' => $topic_info['t_forum_id'], 'first_post' => $topic_info['t_cache_first_post'], 'first_poster' => $topic_info['t_cache_first_member_id'], 'first_post_id' => $topic_info['t_cache_first_post_id'], 'pt_from' => $topic_info['t_pt_from'], 'pt_to' => $topic_info['t_pt_to'], 'is_open' => $topic_info['t_is_open'], 'is_threaded' => $is_threaded, 'is_really_threaded' => is_null($topic_info['f_is_threaded']) ? 0 : $topic_info['f_is_threaded'], 'last_time' => $topic_info['t_cache_last_time'], 'meta_data' => array('created' => date('Y-m-d', $topic_info['t_cache_first_time']), 'creator' => $topic_info['t_cache_first_username'], 'publisher' => '', 'modified' => date('Y-m-d', $topic_info['t_cache_last_time']), 'type' => 'Forum topic', 'title' => $topic_info['t_cache_first_title'], 'identifier' => '_SEARCH:topicview:misc:' . strval($topic_id), 'numcomments' => strval($topic_info['t_cache_num_posts']), 'image' => find_theme_image('bigicons/forums'))); // Poll? if (!is_null($topic_info['t_poll_id'])) { require_code('ocf_polls'); $voted_already = $GLOBALS['FORUM_DB']->query_value_null_ok('f_poll_votes', 'pv_member_id', array('pv_poll_id' => $topic_info['t_poll_id'], 'pv_member_id' => get_member())); $out['poll'] = ocf_poll_get_results($topic_info['t_poll_id'], $view_poll_results || !is_null($voted_already)); $out['poll']['voted_already'] = $voted_already; $out['poll_id'] = $topic_info['t_poll_id']; } // Post query $where = ocf_get_topic_where($topic_id); $query = 'SELECT p.*,t.text_parsed AS text_parsed,t.text_original AS message_comcode,h.h_post_id FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts p LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_post_history h ON (h.h_post_id=p.id AND h.h_action_date_and_time=p.p_last_edit_time) LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND p.p_post=t.id WHERE ' . $where . ' ORDER BY p_time,p.id'; } else { $out = array('num_views' => 0, 'num_posts' => 0, 'validated' => 1, 'title' => do_lang('INLINE_PERSONAL_POSTS'), 'description' => '', 'description_link' => '', 'emoticon' => '', 'forum_id' => NULL, 'first_post' => NULL, 'first_poster' => NULL, 'first_post_id' => NULL, 'pt_from' => NULL, 'pt_to' => NULL, 'is_open' => 1, 'is_threaded' => 0, 'last_time' => time(), 'meta_data' => array()); // Post query $where = 'p_intended_solely_for=' . strval(get_member()); $query = 'SELECT p.*,t.text_parsed AS text_parsed,t.text_original AS message_comcode,h.h_post_id FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts p LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_post_history h ON (h.h_post_id=p.id AND h.h_action_date_and_time=p.p_last_edit_time) LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND p.p_post=t.id WHERE ' . $where . ' ORDER BY p_time,p.id'; } // Posts if ($out['is_threaded'] == 0) { $_postdetailss = list_to_map('id', $GLOBALS['FORUM_DB']->query($query, $max, $start)); if ($start == 0 && count($_postdetailss) < $max) { $out['max_rows'] = $max; } else { $out['max_rows'] = $GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE ' . $where); } $posts = array(); // Precache member/group details in one fell swoop $members = array(); foreach ($_postdetailss as $_postdetails) { $members[$_postdetails['p_poster']] = 1; if ($out['title'] == '') { $out['title'] = $_postdetails['p_title']; } } ocf_cache_member_details(array_keys($members)); $i = 0; foreach ($_postdetailss as $_postdetails) { if (is_null($_postdetails['message_comcode'])) { $_postdetails['message_comcode'] = get_translated_text($_postdetails['p_post'], $GLOBALS['FORUM_DB']); } $linked_type = ''; $linked_id = ''; $linked_url = ''; // If it's a spacer post, see if we can detect it better $is_spacer_post = $i == 0 && substr($_postdetails['message_comcode'], 0, strlen('[semihtml]' . do_lang('SPACER_POST_MATCHER'))) == '[semihtml]' . do_lang('SPACER_POST_MATCHER'); if ($is_spacer_post) { $c_prefix = do_lang('COMMENT') . ': #'; if (substr($out['description'], 0, strlen($c_prefix)) == $c_prefix && $out['description_link'] != '') { list($linked_type, $linked_id) = explode('_', substr($out['description'], strlen($c_prefix)), 2); $linked_url = $out['description_link']; $out['description'] = ''; } } // Load post if (get_page_name() == 'search' || is_null($_postdetails['text_parsed']) || $_postdetails['text_parsed'] == '' || $_postdetails['p_post'] == 0) { $_postdetails['message'] = get_translated_tempcode($_postdetails['p_post'], $GLOBALS['FORUM_DB']); } else { $_postdetails['message'] = new ocp_tempcode(); if (!$_postdetails['message']->from_assembly($_postdetails['text_parsed'], true)) { $_postdetails['message'] = get_translated_tempcode($_postdetails['p_post'], $GLOBALS['FORUM_DB']); } } // Fake a quoted post? (kind of a nice 'tidy up' feature if a forum's threading has been turned off, leaving things for flat display) if (!is_null($_postdetails['p_parent_id']) && strpos($_postdetails['message_comcode'], '[quote') === false) { $p = mixed(); // NULL if (array_key_exists($_postdetails['p_parent_id'], $_postdetailss)) { $p = $_postdetailss[$_postdetails['p_parent_id']]; // Load post if (get_page_name() == 'search' || is_null($p['text_parsed']) || $p['text_parsed'] == '' || $p['p_post'] == 0) { $p['message'] = get_translated_tempcode($p['p_post'], $GLOBALS['FORUM_DB']); } else { $p['message'] = new ocp_tempcode(); if (!$p['message']->from_assembly($p['text_parsed'], true)) { $p['message'] = get_translated_tempcode($p['p_post'], $GLOBALS['FORUM_DB']); } } } else { $_p = $GLOBALS['FORUM_DB']->query_select('f_posts', array('*'), array('id' => $_postdetails['p_parent_id']), '', 1); if (array_key_exists(0, $_p)) { $p = $_p[0]; $p['message'] = get_translated_tempcode($p['p_post'], $GLOBALS['FORUM_DB']); } } $temp = $_postdetails['message']; $_postdetails['message'] = new ocp_tempcode(); $_postdetails['message'] = do_template('COMCODE_QUOTE_BY', array('SAIDLESS' => false, 'BY' => $p['p_poster_name_if_guest'], 'CONTENT' => $p['message'])); $_postdetails['message']->attach($temp); } // Spacer posts may have a better first post put in place if ($is_spacer_post) { require_code('ocf_posts'); list($new_description, $new_post) = ocf_display_spacer_post($linked_type, $linked_id); //if (!is_null($new_description)) $out['description']=$new_description; Actually, it's a bit redundant if (!is_null($new_post)) { $_postdetails['message'] = $new_post; } $out['title'] = do_lang('SPACER_TOPIC_TITLE_WRAP', $out['title']); $_postdetails['p_title'] = do_lang('SPACER_TOPIC_TITLE_WRAP', $_postdetails['p_title']); } // Put together $collated_post_details = ocf_get_details_to_show_post($_postdetails, $start == 0 && count($_postdetailss) == 1); $collated_post_details['is_spacer_post'] = $is_spacer_post; $posts[] = $collated_post_details; $i++; } $out['posts'] = $posts; } // Any special topic/for-any-post-in-topic controls? if (!is_null($topic_id)) { $out['last_poster'] = $topic_info['t_cache_last_member_id']; $out['last_post_id'] = $topic_info['t_cache_last_post_id']; if (is_null($forum_id) || ocf_may_post_in_topic($forum_id, $topic_id, $topic_info['t_cache_last_member_id'])) { $out['may_reply'] = true; } if (ocf_may_report_post()) { $out['may_report_posts'] = true; } if (ocf_may_make_personal_topic()) { $out['may_pt_members'] = true; } if (ocf_may_edit_topics_by($forum_id, get_member(), $topic_info['t_cache_first_member_id'])) { $out['may_edit_topic'] = true; } require_code('ocf_moderation'); require_code('ocf_forums'); if (ocf_may_warn_members()) { $out['may_warn_members'] = true; } if (ocf_may_delete_topics_by($forum_id, get_member(), $topic_info['t_cache_first_member_id'])) { $out['may_delete_topic'] = true; } if (ocf_may_perform_multi_moderation($forum_id)) { $out['may_multi_moderate'] = true; } if (has_specific_permission(get_member(), 'use_quick_reply')) { $out['may_use_quick_reply'] = true; } $may_moderate_forum = ocf_may_moderate_forum($forum_id); if ($may_moderate_forum) { if ($topic_info['t_is_open'] == 0) { $out['may_open_topic'] = 1; } else { $out['may_close_topic'] = 1; } if ($topic_info['t_pinned'] == 0) { $out['may_pin_topic'] = 1; } else { $out['may_unpin_topic'] = 1; } if ($topic_info['t_sunk'] == 0) { $out['may_sink_topic'] = 1; } else { $out['may_unsink_topic'] = 1; } if ($topic_info['t_cascading'] == 0) { $out['may_cascade_topic'] = 1; } else { $out['may_uncascade_topic'] = 1; } $out['may_move_topic'] = 1; $out['may_post_closed'] = 1; $out['may_move_posts'] = 1; $out['may_delete_posts'] = 1; $out['may_validate_posts'] = 1; $out['may_make_personal'] = 1; $out['may_change_max'] = 1; } else { if ($topic_info['t_cache_first_member_id'] == get_member() && has_specific_permission(get_member(), 'close_own_topics') && $topic_info['t_is_open'] == 1) { $out['may_close_topic'] = 1; } } if (!is_null($topic_info['t_poll_id'])) { require_code('ocf_polls'); if (ocf_may_edit_poll_by($forum_id, $topic_info['t_cache_first_member_id'])) { $out['may_edit_poll'] = 1; } if (ocf_may_delete_poll_by($forum_id, $topic_info['t_cache_first_member_id'])) { $out['may_delete_poll'] = 1; } } else { require_code('ocf_polls'); if (ocf_may_attach_poll($topic_id, $topic_info['t_cache_first_member_id'], !is_null($topic_info['t_poll_id']), $forum_id)) { $out['may_attach_poll'] = 1; } } } else { $out['last_poster'] = NULL; $out['last_post_id'] = NULL; $out['may_reply'] = false; } return $out; }