/** * Get a map of details relating to the view of a certain forum of a certain member. * * @param integer The start row for getting details of topics in the forum (i.e. 0 is newest, higher is starting further back in time). * @param ?integer The maximum number of topics to get detail of (NULL: default). * @param ?MEMBER The member viewing (NULL: current member). * @return array The details. */ function ocf_get_forum_view($start = 0, $max = NULL, $forum_id = NULL) { if (is_null($max)) { $max = intval(get_option('forum_topics_per_page')); } $member_id = get_member(); load_up_all_module_category_permissions($member_id, 'forums'); if (is_null($forum_id)) { /*$forum_info[0]['f_name']=do_lang('ROOT_FORUM'); This optimisation was more trouble that it was worth, and constraining $forum_info[0]['f_description']=''; $forum_info[0]['f_parent_forum']=NULL;*/ $forum_id = db_get_first_id(); } $forum_info = $GLOBALS['FORUM_DB']->query_select('f_forums f', array('f_redirection', 'f_intro_question', 'f_intro_answer', 'f_order_sub_alpha', 'f_parent_forum', 'f_name', 'f_description', 'f_order'), array('f.id' => $forum_id), '', 1, NULL, false, array('f_description', 'f_intro_question')); if (!array_key_exists(0, $forum_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } if ($forum_info[0]['f_redirection'] != '' && looks_like_url($forum_info[0]['f_redirection'])) { header('Location: ' . $forum_info[0]['f_redirection']); exit; } if (!is_null($forum_id)) { if (!has_category_access($member_id, 'forums', strval($forum_id))) { access_denied('CATEGORY_ACCESS_LEVEL'); } // We're only allowed to view it existing from a parent forum, or nothing at all -- so access denied brother! } // Find our subforums first $order = $forum_info[0]['f_order_sub_alpha'] ? 'f_name' : 'f_position'; $_max_forum_detail = get_value('max_forum_detail'); $max_forum_detail = is_null($_max_forum_detail) ? 100 : intval($_max_forum_detail); $huge_forums = $GLOBALS['FORUM_DB']->query_value('f_forums', 'COUNT(*)') > $max_forum_detail; if ($huge_forums) { $_max_forum_inspect = get_value('max_forum_inspect'); $max_forum_inspect = is_null($_max_forum_inspect) ? 300 : intval($_max_forum_inspect); $subforum_rows = $GLOBALS['FORUM_DB']->query('SELECT f.* FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_forums f WHERE f.id=' . strval($forum_id) . ' OR f_parent_forum=' . strval($forum_id) . ' ORDER BY f_parent_forum,' . $order, $max_forum_inspect, NULL, false, false, array('f_description', 'f_intro_question')); if (count($subforum_rows) == $max_forum_inspect) { $subforum_rows = array(); } // Will cause performance breakage } else { $subforum_rows = $GLOBALS['FORUM_DB']->query_select('f_forums f', array('f.*'), NULL, 'ORDER BY f_parent_forum,' . $order, NULL, NULL, false, array('f_description', 'f_intro_question')); } $unread_forums = array(); if (!is_null($forum_id) && get_member() != $GLOBALS['OCF_DRIVER']->get_guest_id()) { // Where are there unread topics in subforums? $tree = array(); $subforum_rows_copy = $subforum_rows; $tree = ocf_organise_into_tree($subforum_rows_copy, $forum_id); if ($forum_id != db_get_first_id()) { $child_or_list = ocf_get_all_subordinate_forums($forum_id, 't_forum_id', $tree); } else { $child_or_list = ''; } if ($child_or_list != '') { $child_or_list .= ' AND '; } $query = 'SELECT DISTINCT t_forum_id,t.id FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics t LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_read_logs l ON (t.id=l_topic_id AND l_member_id=' . strval((int) get_member()) . ') WHERE ' . $child_or_list . 't_cache_last_time>' . strval(time() - 60 * 60 * 24 * intval(get_option('post_history_days'))) . ' AND (l_time<t_cache_last_time OR l_time IS NULL)'; if (!has_specific_permission(get_member(), 'jump_to_unvalidated')) { $query .= ' AND t_validated=1'; } $unread_forums = collapse_2d_complexity('t_forum_id', 'id', $GLOBALS['FORUM_DB']->query($query)); } // Find all the categories that are used $categories = array(); $or_list = ''; foreach ($subforum_rows as $tmp_key => $subforum_row) { if ($subforum_row['f_parent_forum'] != $forum_id) { continue; } if (!has_category_access($member_id, 'forums', strval($subforum_row['id']))) { unset($subforum_rows[$tmp_key]); continue; } $category_id = $subforum_row['f_category_id']; if (!array_key_exists($category_id, $categories)) { $categories[$category_id] = array('subforums' => array()); if ($or_list != '') { $or_list .= ' OR '; } $or_list .= 'id=' . strval((int) $category_id); } } if ($or_list != '') { $category_rows = $GLOBALS['FORUM_DB']->query('SELECT * FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_categories WHERE ' . $or_list); foreach ($category_rows as $category_row) { $category_id = $category_row['id']; $title = $category_row['c_title']; $description = $category_row['c_description']; $expanded_by_default = $category_row['c_expanded_by_default']; $categories[$category_id]['title'] = $title; $categories[$category_id]['description'] = $description; $categories[$category_id]['expanded_by_default'] = $expanded_by_default; } $categories[NULL]['title'] = ''; $categories[NULL]['description'] = ''; $categories[NULL]['expanded_by_default'] = true; foreach ($subforum_rows as $subforum_row) { if ($subforum_row['f_parent_forum'] != $forum_id) { continue; } $category_id = $subforum_row['f_category_id']; // if (!array_key_exists('position',$categories[$category_id])) $categories[$category_id]['position']=$subforum_row['f_position']; $subforum = array(); $subforum['id'] = $subforum_row['id']; $subforum['name'] = $subforum_row['f_name']; $subforum['description'] = get_translated_tempcode($subforum_row['f_description'], $GLOBALS['FORUM_DB']); $subforum['redirection'] = $subforum_row['f_redirection']; $subforum['intro_question'] = get_translated_tempcode($subforum_row['f_intro_question'], $GLOBALS['FORUM_DB']); $subforum['intro_answer'] = $subforum_row['f_intro_answer']; if (is_numeric($subforum_row['f_redirection'])) { $subforum_row = $GLOBALS['FORUM_DB']->query_select('f_forums', array('*'), array('id' => intval($subforum_row['f_redirection'])), '', 1); $subforum_row = $subforum_row[0]; } if ($subforum_row['f_redirection'] == '' || is_numeric($subforum_row['f_redirection'])) { $subforum['num_topics'] = $subforum_row['f_cache_num_topics']; $subforum['num_posts'] = $subforum_row['f_cache_num_posts']; $subforum['has_new'] = false; if (get_member() != $GLOBALS['OCF_DRIVER']->get_guest_id()) { $subforums_recurse = ocf_get_all_subordinate_forums($subforum['id'], NULL, $tree[$subforum['id']]['children']); foreach ($subforums_recurse as $subforum_potential) { if (array_key_exists($subforum_potential, $unread_forums)) { $subforum['has_new'] = true; } } } if (is_null($subforum_row['f_cache_last_forum_id']) || has_category_access($member_id, 'forums', strval($subforum_row['f_cache_last_forum_id']))) { $subforum['last_topic_id'] = $subforum_row['f_cache_last_topic_id']; $subforum['last_title'] = $subforum_row['f_cache_last_title']; $subforum['last_time'] = $subforum_row['f_cache_last_time']; $subforum['last_username'] = $subforum_row['f_cache_last_username']; $subforum['last_member_id'] = $subforum_row['f_cache_last_member_id']; $subforum['last_forum_id'] = $subforum_row['f_cache_last_forum_id']; } else { $subforum['protected_last_post'] = true; } // Subsubforums $subforum['children'] = array(); foreach ($subforum_rows as $tmp_key_2 => $subforum_row2) { if ($subforum_row2['f_parent_forum'] == $subforum_row['id'] && has_category_access($member_id, 'forums', strval($subforum_row2['id']))) { $subforum['children'][$subforum_row2['f_name'] . '__' . strval($subforum_row2['id'])] = array('id' => $subforum_row2['id'], 'name' => $subforum_row2['f_name'], 'redirection' => $subforum_row2['f_redirection']); } } global $M_SORT_KEY; $M_SORT_KEY = 'name'; uasort($subforum['children'], 'multi_sort'); } $categories[$category_id]['subforums'][] = $subforum; } } // Find topics $extra = ''; if (!has_specific_permission(get_member(), 'see_unvalidated') && !ocf_may_moderate_forum($forum_id, $member_id)) { $extra = 't_validated=1 AND '; } if (is_null($forum_info[0]['f_parent_forum'])) { $where = $extra . ' (t_forum_id=' . strval((int) $forum_id) . ')'; } else { $extra2 = ''; $parent_or_list = ocf_get_forum_parent_or_list($forum_id, $forum_info[0]['f_parent_forum']); if ($parent_or_list != '') { $extra2 = 'AND (' . $parent_or_list . ')'; } $where = $extra . ' (t_forum_id=' . strval((int) $forum_id) . ' OR (t_cascading=1 ' . $extra2 . '))'; } $order = get_param('order', $forum_info[0]['f_order']); $order2 = 't_cache_last_time DESC'; if ($order == 'first_post') { $order2 = 't_cache_first_time DESC'; } elseif ($order == 'title') { $order2 = 't_cache_first_title ASC'; } if (get_value('disable_sunk') !== '1') { $order2 = 't_sunk ASC,' . $order2; } if (is_guest()) { $query = 'SELECT ttop.*,t.text_parsed AS _trans_post,NULL AS l_time FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics ttop LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND ttop.t_cache_first_post=t.id WHERE ' . $where . ' ORDER BY t_cascading DESC,t_pinned DESC,' . $order2; } else { $query = 'SELECT ttop.*,t.text_parsed AS _trans_post,l_time FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics ttop LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_read_logs l ON (ttop.id=l.l_topic_id AND l.l_member_id=' . strval((int) get_member()) . ') LEFT JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND ttop.t_cache_first_post=t.id WHERE ' . $where . ' ORDER BY t_cascading DESC,t_pinned DESC,' . $order2; } $topic_rows = $GLOBALS['FORUM_DB']->query($query, $max, $start); if ($start == 0 && count($topic_rows) < $max) { $max_rows = $max; } else { $max_rows = $GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT COUNT(*) FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics WHERE ' . $where); } $topics = array(); $hot_topic_definition = intval(get_option('hot_topic_definition')); $or_list = ''; foreach ($topic_rows as $topic_row) { if ($or_list != '') { $or_list .= ' OR '; } $or_list .= 'p_topic_id=' . strval((int) $topic_row['id']); } if ($or_list != '' && !is_guest()) { $involved = $GLOBALS['FORUM_DB']->query('SELECT DISTINCT p_topic_id FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE (' . $or_list . ') AND p_poster=' . strval((int) get_member())); $involved = collapse_1d_complexity('p_topic_id', $involved); } else { $involved = array(); } foreach ($topic_rows as $topic_row) { $topics[] = ocf_get_topic_array($topic_row, $member_id, $hot_topic_definition, in_array($topic_row['id'], $involved)); } $description = get_translated_tempcode($forum_info[0]['f_description'], $GLOBALS['FORUM_DB']); $description_text = get_translated_text($forum_info[0]['f_description'], $GLOBALS['FORUM_DB']); $out = array('name' => $forum_info[0]['f_name'], 'description' => $description, 'categories' => $categories, 'topics' => $topics, 'max_rows' => $max_rows, 'order' => $order, 'parent_forum' => $forum_info[0]['f_parent_forum']); $GLOBALS['META_DATA'] += array('created' => '', 'creator' => '', 'publisher' => '', 'modified' => '', 'type' => 'Forum', 'title' => $forum_info[0]['f_name'], 'identifier' => '_SEARCH:forumview:misc:' . strval($forum_id), 'description' => $description_text, 'image' => find_theme_image('bigicons/forums')); // Is there a question/answer situation? $question = get_translated_tempcode($forum_info[0]['f_intro_question'], $GLOBALS['FORUM_DB']); if (!$question->is_empty()) { $is_guest = $member_id == $GLOBALS['OCF_DRIVER']->get_guest_id(); $test = $GLOBALS['FORUM_DB']->query_value_null_ok('f_forum_intro_ip', 'i_ip', array('i_forum_id' => $forum_id, 'i_ip' => get_ip_address(3))); if (is_null($test) && !$is_guest) { $test = $GLOBALS['FORUM_DB']->query_value_null_ok('f_forum_intro_member', 'i_member_id', array('i_forum_id' => $forum_id, 'i_member_id' => $member_id)); } if (is_null($test)) { $out['question'] = $question; $out['answer'] = $forum_info[0]['f_intro_answer']; } } if (ocf_may_post_topic($forum_id, $member_id)) { $out['may_post_topic'] = 1; } if (ocf_may_moderate_forum($forum_id, $member_id)) { $out['may_change_max'] = 1; $out['may_move_topics'] = 1; if (has_specific_permission(get_member(), 'multi_delete_topics')) { $out['may_delete_topics'] = 1; } // Only super admins can casually delete topics - other staff are expected to trash them. At least deleted posts or trashed topics can be restored! } return $out; }
/** * Get an OR list of a forums parents, suited for selection from the f_topics table. * * @param AUTO_LINK The ID of the forum. * @param ?AUTO_LINK The ID of the parent forum (-1: get it from the DB) (NULL: there is no parent, as it is the root forum). * @return string The OR list. */ function ocf_get_forum_parent_or_list($forum_id, $parent_id = -1) { if (is_null($forum_id)) { return ''; } if ($parent_id == -1) { $parent_id = $GLOBALS['FORUM_DB']->query_value_null_ok('f_forums', 'f_parent_forum', array('id' => $forum_id)); if (is_null($parent_id)) { return ''; } } $from_below = ocf_get_forum_parent_or_list($parent_id); $term = 't_forum_id=' . strval((int) $forum_id); return $term . ($from_below != '' ? ' OR ' . $from_below : ''); }