Example #1
0
 /**
  * Render a topic.
  *
  * @param  ?integer		Number of posts to show initially (NULL: no limit)
  * @param  integer		Maximum thread depth
  * @param  boolean		Whether the current user may reply to the topic (influences what buttons show)
  * @param  ?MEMBER		User to highlight the posts of (NULL: none)
  * @param  array			Review ratings rows
  * @param  AUTO_LINK		ID of forum this topic in in
  * @param  ?AUTO_LINK	Only show posts under here (NULL: show posts from root)
  * @param  boolean		Whether to just render everything as flat (used when doing AJAX post loading). NOT actually used since we wrote better post-orphaning-fixing code.
  * @return array			Tuple: Rendered topic, serialized options to render more posts, secure hash of serialized options to prevent tampering
  */
 function render_posts($num_to_show_limit, $max_thread_depth, $may_reply, $highlight_by_user, $all_individual_review_ratings, $forum_id, $parent_post_id = NULL, $maybe_missing_links = false)
 {
     require_code('feedback');
     if (get_forum_type() == 'ocf' && !addon_installed('ocf_forum')) {
         return array();
     }
     $posts = array();
     $queue = $this->all_posts_ordered;
     if (!is_null($parent_post_id) && !$maybe_missing_links) {
         $queue = $this->_grab_at_and_underneath($parent_post_id, $queue);
     }
     if (is_null($this->is_threaded)) {
         $this->is_threaded = false;
     }
     if (is_null($num_to_show_limit) || !$this->is_threaded) {
         $posts = $queue;
         $queue = array();
     } else {
         $posts = $this->_decide_what_to_render($num_to_show_limit, $queue);
     }
     require_javascript('javascript_ajax');
     require_javascript('javascript_more');
     require_javascript('javascript_thumbnails');
     // Precache member/group details in one fell swoop
     if (get_forum_type() == 'ocf') {
         require_code('ocf_topicview');
         $members = array();
         foreach ($posts as $_postdetails) {
             $members[$_postdetails['p_poster']] = 1;
         }
         ocf_cache_member_details(array_keys($members));
     }
     if (!is_null($this->topic_id)) {
         // If FALSE then Posts will have been passed in manually as full already anyway
         $posts = $this->_grab_full_post_details($posts);
     }
     if ($this->is_threaded) {
         $tree = $this->_arrange_posts_in_tree($parent_post_id, $posts, $queue, $max_thread_depth);
         if (count($posts) != 0) {
             global $M_SORT_KEY;
             $M_SORT_KEY = 'date';
             usort($posts, 'multi_sort');
             while (count($posts) != 0) {
                 $orphaned_post = array_shift($posts);
                 $tree2 = $this->_arrange_posts_in_tree($orphaned_post['id'], $posts, $queue, $max_thread_depth);
                 $orphaned_post['parent_id'] = NULL;
                 $orphaned_post['children'] = $tree2;
                 $tree[0][] = $orphaned_post;
             }
         }
     } else {
         $tree = array($posts);
     }
     $ret = $this->_render_post_tree($num_to_show_limit, $tree, $may_reply, $highlight_by_user, $all_individual_review_ratings, $forum_id);
     $other_ids = mixed();
     if ($this->is_threaded) {
         $other_ids = array();
         foreach ($tree[1] as $u) {
             $other_ids[] = strval($u['id']);
         }
     }
     $ret->attach(do_template('POST_CHILD_LOAD_LINK', array('NUM_TO_SHOW_LIMIT' => strval($num_to_show_limit), 'OTHER_IDS' => $other_ids, 'ID' => '', 'CHILDREN' => count($other_ids) == 0 ? '' : '1')));
     if (!is_null($this->topic_id)) {
         $serialized_options = serialize(array($this->topic_id, $num_to_show_limit, true, false, strval($forum_id), $this->reverse, $may_reply, $highlight_by_user, count($all_individual_review_ratings) != 0));
         $hash = best_hash($serialized_options, get_site_salt());
     } else {
         $serialized_options = mixed();
         $hash = mixed();
     }
     return array($ret, $serialized_options, $hash);
 }
Example #2
0
/**
 * 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;
}